Skip to content

Instantly share code, notes, and snippets.

@crcx
Forked from lsparrish/gist:267334
Created January 2, 2010 06:21
Show Gist options
  • Save crcx/267405 to your computer and use it in GitHub Desktop.
Save crcx/267405 to your computer and use it in GitHub Desktop.
commentary on do/until loops

First, the header describing the library.

( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
( do ... until                                                )
( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )
( Value n is taken from the stack and stored to a virtual     )
( variable. When this number is equal to the TOS at the time  )
( until is executed, the loop terminates.                     )
( ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ )

Start a private namespace.

{{

Two definitions are defined. First, skipped-nop:

: skipped-nop ( - ) 8 , here 2 + ,  0 , ;

Taking this piece by piece:

8 ,          ::: JUMP opcode [ngaro]
here 2 + ,   ::: Target for jump. Skip over the next cell.
0 ,          ::: NOP opcode

Next is virtual-var

: virtual-var ( R:   -a  C:   -aa )
  here dup 1-
  dup literal, ;

Again, breaking it down:

here dup 1-   ::: Get address of the previous cell
dup literal,  ::: Compile it as a literal, and leave a
              ::: copy on the stack for later use

The rest of the words will be visible in the dictionary:

---reveal---

Now on to the main words. First up do:

: do          ( R: nn-n? C:   -aa )
  ` 2dup ` >if
    skipped-nop
    virtual-var ` !  ; compile-only

This is a compiler macro (compile-only), and will lay down some code in any definition using it.

` 2dup ` >if     ::: Compile a call to 2dup and execute >if when the macro is run
skipped-nop      ::: Call skipped-nop to lay down a jump and virtual variable
virtual-var ` !  ::: Get a reference to the virtual variable and store TOS to it

The word until is also a compiler macro:

: until       ( R: ?n-   C: aa-   )
  ` dup literal, ` @
  ` > ` if swap 8 , 3 + ,
  ` then ` drop
  ` else ` 2drop ` then ; compile-only

Breaking until down:

` dup           :::
literal, ` @    :::
` > ` if        :::
swap 8 , 3 + ,  :::
` then ` drop   :::
` else ` 2drop  :::
` then          :::

Finally, close out the private namespace, leaving only the public words visible:

}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment