Probleme

Die erste Idee for(;;) (*ip++)() eignet sich bei näherer Betrachtung nur zur Ausführung von Worten, die ausschlieálich aus Primitives zusammencompiliert sind. Denn es wird angenommen, daá compilierter Forth-Code aus Listen von Zeigern auf ausführbare Funktionen besteht. Ein High-Level-Wort ist aber keine ausführbare C-Funktion.

Die L÷sung besteht natürlich in der Einführung einer weiteren Indirektion: Ein compiliertes Forth-Wort ist ein Zeiger auf einen Platz, in dem ein Zeiger steht, der über die Bedeutung des Wortes entscheidet. Der innere Interpreter wird zu:

for (;;) (**ip++) ();
Daraus und aus der angestrebten Traditionalität ergibt sich eine vorläufige Struktur für den Kopf einer Funktion im Dictionary:
Countbyte
Name
Link
CFA
Body
...
Wie üblich werden also Name und Realisierung eines Wortes beieinander ins Dictionary geschrieben. CFA kann man jetzt als C-Funktions-Adresse lesen. Ihr Sinn ist derselbe wie in traditionellem indirect threaded Forth derjenige der Code Field Address: Dorthin wird verzweigt zur Ausführung des Wortes. Primitives haben hier die Adresse einer C-Funktion stehen, die die Semantik des Wortes bereitstellt und keinen Body. High-level-Definitionen haben hier einen Zeiger auf eine Runtime-Funktion (in C) stehen, die die im Body beginnende Liste von compilierten Adressen zu interpretieren beginnt: nest.

Wie kommt die Runtime-Funktion nest zu dem Body der Funktion, von der aus sie aufgerufen wurde? Sie kann ihn etwas trickreich aus IP schlieáen: ip = &ip [-1][1] (mit einigen Type-Casts). Besser man erleichtert ihr diese Aufgabe indem man im inneren Interpreter die Variable W der virtuellen Maschine einführt:

for (;;)
  {
    w = *ip++;
    (*w) ();
  }
Mit dieser endgültigen Form des inneren Interpreters lauten nest und unnest:
nest () {
  *--rp = ip;
  ip = ++w;
}
unnest () {
  ip = *rp++;
}

Ein weiteres Problem ergibt sich mit Definitionsworten. Wie gesagt ist für alle Definitionsworte der Code in der CFA eines von ihnen definierten Wortes derselbe. Das Datenfeld beginnt zwingend unmittelbar hinter der CFA. Wo also kann vermerkt werden, von welchem Definitionswort ein Wort definiert wurde?11 Die wenig befriedigende L÷sung besteht in der Einführung eines weiteren Zeigers aux in den Kopf jeder Definition, der im Fall einer von einem Definitionswort definierten Definition diese Information enthalten kann:

Countbyte
Name
Link
Aux
CFA
Body
...
Dieser Zeiger hilft glücklicherweise auch bei anderen Gelegenheiten: Er stellt z.B. den Zusammenhang her zwischen der compilierten Laufzeitsemantik von Kontrollstrukturen und der Definition, die diese Laufzeitsemantik compiliert hat. Dadurch kann der Decompiler SEE zu einem compilierten ?BRANCH entscheiden, ob er von einem IF oder einem WHILE her stammt und eine entsprechend strukturierte Ausgabe erzeugen.