Wenn Sie eine Definition konstruiert haben, die
aaa IF bbb THEN ccc
enthält, und wenn Sie das dann decompilieren,
dann werden Sie etwas in der Art von
aaa, JOF adr, bbb, ccc
zu sehen bekommen.
IF ist zu
JOF (jump on false) geworden,
auf was dann eine (relative) Adresse folgt.
THEN ist verschwunden.
Logisch, denn die Adresse verweist, sehr wahrscheinlich in Form eines Offsets,
schon auf
ccc.
Diese Adresse ist in dem Moment, in dem
IF erreicht wird,
noch nicht bekannt.
Wie der Compiler das schafft?
Eigentlich macht der Compiler das gar nicht.
Das machen
IF und
THEN selbst.
: IF ( -- ) ?COMPILING \ Erklaerung folgt
POSTPONE JOF
HERE IFMARKE COMPOST!
0 , ; IMMEDIATE
: THEN ( -- ) ?COMPILING
HERE COMPOST@
IFMARKE ?PAIRS
OFFSET! ; IMMEDIATE
-
?COMPILING verursacht eine Fehlermeldung,
wenn Sie nicht beim Compilieren sind.
-
IFMARKE ist eine Konstante, die der Wiedererkennung dient.
-
COMPOST! ( adr const -- ) schickt Post (ein Päckchen mit zwei Zahlen)
an den Compiler.
-
COMPOST@ ( -- adr const ) verlangt das zuletzt geschickte
Päckchen wieder zurück.
-
?PAIRS ( x y - ) gibt eine Fehlermeldung aus, wenn x<>y ist.
-
OFFSET! ( adr1 adr2 -- ) bewahrt adr1 als Offset in adr2 auf.
Alle Nichtstandardnamen in dieser Geschichte habe ich mir selbst ausgedacht.
Ich verwende sie nur, um deutlich zu machen, was da passiert.
In jedem Forth werden diese Namen und auch die Details anders sein,
der generelle Gang der Handlung wird aber genau so sein, wie oben beschrieben.
BEGIN und
UNTIL sollten nun kein Problem mehr darstellen.
: BEGIN ( -- )
HERE BEGINMARKE COMPOST! ; IMMEDIATE