Compiler macros are often used to lay down code in the calling word. You'll see something like:
: foo ['] + compile ['] . compile ; immediate
This is fine, but sometimes you need to deal with other macros:
Original from docl: | |
: :: here ] ; | |
: nv-key ['] key 2 + compile ; immediate ( unvectored key ) | |
:: nv-key dup 27 =if nv-key dup . nip ;then ; is key | |
Rather than "nv-key", a more generic word to get the default (non-vectored) definition can be used: | |
: default: ' drop which @ d->xt @ 2 + compile ; immediate |
Compiler macros are often used to lay down code in the calling word. You'll see something like:
: foo ['] + compile ['] . compile ; immediate
This is fine, but sometimes you need to deal with other macros:
It's sometimes useful to be able to create an empty stub which will be pointed to a real definition later. | |
The simple solution is just to do: | |
: foo ; | |
This creates a new defintion ("foo"), with no runtime action. In Retro all colon definitions can be revectored, so this is all that is strictly required. It does have a downside with regard to readability. We can address this by defining a new word specifically to create stubs. | |
: stub ( "- ) create 0 , 0 , 9 , ['] .word last @ d->class ! ; |
: :create ( $- ) | |
push :: save string pointer | |
here last dup @ , ! :: start new header, pointing to here | |
['] .data , :: class of .data | |
here 0 , :: xt = 0 (patched later) | |
pop dup getLength here :: get length of string, setup for copy | |
swap dup allot :: but first, allocate space for the name | |
copy 0 , :: copy name to allocated space, terminate string properly | |
here swap ! ; :: go back and patch the xt to point to here |
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. )
chain: parable | |
{{ | |
create stack here , 10 allot | |
: push stack dup ++ @ ! ; | |
: pop stack dup @ @ swap -- ; | |
: empty? stack dup @ = ; | |
: nest compiler on here push 0 , 0 , ; | |
: unnest pop empty? not !compiler ; | |
---reveal--- | |
: [ nest ; immediate |
with quotes' | |
( compare two strings from the beginning and return how many ) | |
( similar characters there are before the strings diverge. ) | |
: ^match ( $$-n ) | |
0 -rot repeat @+ [ swap @+ ] dip =if rot 1+ -rot else 2drop ;then again ; | |
( test each word in the dictionary for similarity. if similar up ) | |
( to the current point, add to the suggestions queue. ) | |
create list here , 100 allot |