Ein klassisches ``indirect threaded'' Forth birgt in sich – ohne daá
der Benutzer darauf direkten Zugriff hätte – eine virtuelle Maschine
mit vier Registern, davon zwei Stackpointer in die beiden Stacks, und
einigen Grundoperationen.
Die Register der virtuellen Maschine sind: Daten-Stack-Pointer SP und Return-Stack-Pointer RP, der Instruction-Pointer
IP und ein weniger einleuchtendes aber wichtiges Register
namens W, das stets in das Datenfeld9 der aktuell ausgeführten Code-Definition zeigt.
Um all das zu erreichen, was der dpANS vorschreibt, genügt es nach wie
vor, wenn ein Forth-System – neben einer geeignet ausgewählten Menge
von Primitives – die elementaren Grundoperationen der virtuellen
Maschine realisiert:
- next
- eine gewisse Menge (je weniger, desto besser) von
Maschinenbefehlen, die zum nächsten auszuführenden Primitive
springen. Wohlgemerkt ist das im klassischen Forth kein
Unterprogrammsprung, sondern ein Weiterspringen, von dem es keine
Rückkehr gibt. Die Kontrolle über den Programmfluá wird durch die
anderen Grundoperationen ausgeübt. Mit den Registern der virtuellen
Maschine und einem Hilfsregister X läát sich die Aktion next so beschreiben:
W |
← |
(IP) |
IP |
← |
IP + 1 Cells |
X |
← |
(W) |
W |
← |
W + 1 Cells |
SprungnachX |
- nest
- ist der zunächst von einer :-Definition ausgeführte Code.
Legt den Instruction-Pointer IP auf dem Return-Stack ab und
setzt den IP auf den Beginn des Datenfeldes der aktuell
ausgeführten Definition:
RP |
← |
RP - 1 Cells |
(RP) |
← |
IP |
IP |
← |
W |
Aktionvonnext |
Next führt nun das erste Wort aus der Liste von Worten aus, die
das compilierte High-Level-Wort ausmachen.
- unnest
- Umkehrfunktion von nest, kehrt zum rufenden Wort
zurück indem der von nest gesicherte Wert vom Return-Stack
zurückgeholt wird:
IP |
← |
(RP) |
RP |
← |
RP + 1 Cells |
Aktionvonnext |
- does
- Mit nest verwandt ist eine Funktion der virtuellen
Maschine zur Unterstützung von CREATE...DOES>-Definitionen.
Ein mit einem Definitionswort DEF definiertes Wort W muá
im Sinne einer high-level Definition compilierten Code
ausführen, der aber nicht im Datenfeld des Wortes W steht,
sondern irgendwo anders, vorzugsweise innerhalb des Wortes DEF.
Nur auf die Operation unnest hat der Programmierer direkten
Zugriff, sie wird durch das Wort EXIT repräsentiert. Die übrigen
Grundoperationen der virtuellen Maschine sind dem Forth-Programmierer
nicht zugänglich. nest wird vom Compiler bei Bedarf eingeplant
und next bildet das Ende jeder Code-Definition, tritt für den
Programmierer nur dann in Erscheinung, wenn er selbst
Code-Definitionen hinzufügt, also den in viele Systeme integrierten
Assembler benutzt.