204b
««   «»   »»

 

2. The compiler

When having a definition with
... aaa IF bbb THEN ccc ...
inside, and it's decompiled, something like the following will show up:
... aaa, JOF addr, bbb, ccc, ...
IF has turned into JOF (jump on false) followed by a (relative) address.
THEN has completely vanished, which makes sense because the address already points to ccc , most likely in the form of an offset. The needed address however, is not yet known at the moment IF is reached.

How did the compiler pull that of?

In fact, the compiler doesn't, IF and THEN have taken care of it themselves.

: IF ( -- ) ?COMPILING \ Explanation follows
  POSTPONE JOF
  HERE IFADMIN COMADMIN!
  0 , ; IMMEDIATE

: THEN ( -- ) ?COMPILING
  HERE COMADMIN@
  IFADMIN ?PAIRS
  OFFSET! ; IMMEDIATE
?COMPILING causes an error message when not compiling.
IFADMIN a constant used for recognition purposes.
COMADMIN! ( addr const -- ) sends admin (a packet of two numbers) to the compiler.
COMADMIN@ ( -- addr const ) asks back the last packet sent.
?PAIRS ( x y - ) gives an error message when x <> y.
OFFSET! ( addr1 addr2 -- ) stores addr1 as an offset in addr2.

All non-standard names in this article are made up. They're only used to clarify what happens. In any particular Forth these names and details will differ. However, the global way of working will match the above description.

BEGIN and UNTIL should not pose a problem any more.

: BEGIN ( -- )
  HERE BEGINADMIN COMADMIN! ; IMMEDIATE