Als je een definitie hebt gemaakt met
aaa IF bbb THEN ccc
erin, en je decompileert dat, dan zul je iets te zien krijgen in de trant van
aaa, JOF adr, bbb, ccc
IF is geworden:
JOF (jump on false) gevolgd door een (relatief) adres.
THEN is verdwenen.
Logisch, want het adres verwijst, waarschijnlijk in de vorm van een offset,
al naar
ccc.
Dat adres is nog niet bekend op het moment dat
IF bereikt is.
Hoe de compiler dat voor elkaar krijgt?
Eigenlijk doet de compiler dat niet, dat doen
IF en
THEN zelf.
: IF ( -- ) ?COMPILING \ Uitleg volgt
POSTPONE JOF
HERE IFKENMERK COMPOST!
0 , ; IMMEDIATE
: THEN ( -- ) ?COMPILING
HERE COMPOST@
IFKENMERK ?PAIRS
OFFSET! ; IMMEDIATE
-
?COMPILING veroorzaakt een foutmelding als je niet aan het compileren bent.
- IFKENMERK is een constante die dient ter herkenning.
- COMPOST! ( adr const -- ) stuurt post (een pakketje met twee getallen)
naar de compiler.
- COMPOST@ ( -- adr const ) vraagt het laatst gestuurde pakketje weer terug.
- ?PAIRS ( x y - ) geeft een foutmelding als x<>y.
- OFFSET! ( adr1 adr2 -- ) slaat adr1 als offset op in adr2.
Alle niet-standaardnamen in dit verhaaltje heb ik zelf verzonnen. Ik gebruik ze slechts om duidelijk te maken wat er gebeurt. In iedere Forth zullen deze namen en ook de details anders zijn, maar de globale gang van zaken zal zijn als hierboven beschreven.
BEGIN en
UNTIL zullen nu geen probleem meer vormen.
: BEGIN ( -- )
HERE BEGINKENMERK COMPOST! ; IMMEDIATE