▲ | lebuffon 2 days ago | |
The hard part I think is grokking the fact that the FORTH can compile and interpret inside the same definition. Also one must understand the operation of the Forth primitives HERE and comma (,) I will take a run at explaining IF ENDIF (endif is the Fig Forth term, used here to avoid confusion) ?BRANCH is an instruction in the virtual machine. It jumps if top of stack=0 . The offset (or address)that it jumps to is the memory word right after the ?BRANCH token. Like this: <?BRANCH><number> Forth definition of IF : IF COMPILE ?BRANCH HERE 0 , ; IMMEDIATE At compile time IF "compiles" the token for ?BRANCH but then interprets "HERE 0 ," (IF is an IMMEDIATE word that executes even if the compiler is turned on) HERE is like $ in Assembler, ie: the address where code is being laid down. It is simply left on the data stack. HERE is the address where the <number> will be stored... later. 0 is a zero, that is pushed onto the data stack. "Comma" (,) pops the zero and puts it in memory address HERE but! it advances the system memory pointer 1 integer width. The zero is now a place holder in memory to be filled in by ENDIF. : ENDIF( addr -- ) HERE OVER - SWAP ! ; IMMEDIATE ENDIF needs that address left behind by IF shown in comment as addr. ENDIF gets the new value of HERE which of course is different because we will have compiled some code after the IF keyword. All we need to do is do NEWHERE-OLDHERE to get the offset for ?BRANCH. That is covered by the forth code ( oldhere-on-stack) HERE OVER - This will make the data stack be: ( OLDHERE offset ) If we do a SWAP we just need the store operator '!' to put the offset into memory. For the morbidly curious here is the definition of ELSE. :-) : ELSE COMPILE BRANCH HERE 0 , SWAP [COMPILE] ENDIF ; IMMEDIATE So loops are just more of the same... (all loops jump back to BEGIN. BRANCH is an unconditional jump instruction) : BEGIN HERE ; IMMEDIATE : AGAIN COMPILE BRANCH HERE - , ; IMMEDIATE : UNTIL COMPILE ?BRANCH HERE - , ; IMMEDIATE : WHILE [COMPILE] IF SWAP ; IMMEDIATE : REPEAT [COMPILE] AGAIN [COMPILE] ENDIF ; IMMEDIATE |