Her

  Charles H. Moore, der Erfinder von Forth   Vergrößern Charles H. Moore, der Erfinder von Forth
Paradigma: prozedural, Stack-orientiert
Erschien in: 1970er
Entworfen von: Charles H. Moore
Schreibdisziplin: Typenlos
Wichtige Implementierungen: Forth, Inc., gForth, MPE, Offene Firmware
Dialekte: colorForth, FCode
Beeinflusst von: Burroughs große Systeme, Lisp, APL
Beeinflusst: PostScript, Faktor

Her ist ein Programmiersprache und Programmierumgebung, ursprünglich entwickelt von Charles H. Moore am US National Radio Astronomy Observatory in den frühen 1970er Jahren. Es wurde 1977 formalisiert und 1994 von ANSI standardisiert. Forth wird manchmal in Großbuchstaben geschrieben, wie es in früheren Jahren üblich war, obwohl der Name kein Akronym ist.

Forth ist eine prozedurale, Stack-orientierte und reflektierende Programmiersprache ohne Typprüfung und bietet sowohl die interaktive Ausführung von Befehlen (wodurch sie als Shell für Systeme geeignet ist, denen ein formaleres Betriebssystem fehlt) als auch die Fähigkeit, Befehlssequenzen für die spätere Ausführung zu kompilieren. Einige Forth-Versionen (insbesondere frühe) kompilieren Thread-Code, aber viele Implementierungen generieren heute optimierten Maschinencode wie andere Sprachcompiler.

Forth heißt so, weil '[t] die Datei, die den Interpreter enthält, mit FORTH bezeichnet wurde, für Software der 4. (nächsten) Generation - aber das Betriebssystem beschränkte Dateinamen auf 5 Zeichen.' Moores Verwendung des Ausdrucks Software der 4. (nächsten) Generation scheint vor der Definition von Programmiersprachen der vierten Generation zu liegen; Er sah Forth als Nachfolger von Compiler-Link-Go-Programmiersprachen der dritten Generation oder Software für Hardware der '4. Generation', nicht als 4GL, wie der Begriff verwendet wird.



Überblick

Forth bietet eine eigenständige Programmierumgebung, die aus einem Stack-orientierten, interaktiven, inkrementellen Interpreter und Compiler besteht. Die Programmierung in Forth ist ein interaktiver, iterativer Prozess. Ein Forth-System besteht aus Wörter (der Begriff, der für Forth-Subroutinen verwendet wird); neue Wörter werden anhand alter Wörter definiert, und es wird kein Unterschied zwischen den Wörtern gemacht, die die Forth-Sprache definieren, und denen, die der Programmierer erstellt. Ein typisches Forth-Paket besteht aus einem vorkompilierten Kernel der Kernwörter, die der Programmierer verwendet, um neue Wörter für die Anwendung zu definieren. Die fertige Bewerbung kann als Bild gespeichert werden, wobei die neuen Wörter bereits zusammengestellt sind. Im Allgemeinen erweitern Programmierer den anfänglichen Kern mit Wörtern, die für die von ihnen geschriebenen Anwendungstypen nützlich sind, und speichern dies als ihre Arbeitsgrundlage.

Forth verwendet getrennte Stapel zum Speichern von Subroutinenparametern und Subroutinenaktivierungsaufzeichnungen. Das Parameter oder Datenstapel (allgemein bezeichnet als die Stapel ) wird verwendet, um Daten an Wörter zu übergeben und die Ergebnisse zu speichern, die die Wörter zurückgeben. Das Verknüpfung oder Stapel zurückgeben (allgemein bezeichnet als die Stapel ) wird verwendet, um Rücksprungadressen zu speichern, wenn Wörter verschachtelt sind (das Äquivalent eines Unterprogrammaufrufs), und um lokale Variablen zu speichern. Es gibt Standardwörter zum Verschieben von Daten zwischen den Stacks und zum Laden und Speichern von Variablen auf dem Stack.

Die logische Struktur von Forth ähnelt einer virtuellen Maschine. Forth, insbesondere frühe Versionen, implementiert eine innerer Dolmetscher Verfolgen von Maschinencode mit indirektem Thread, wodurch kompakter und schneller High-Level-Code entsteht, der schnell kompiliert werden kann. Viele moderne Implementierungen generieren optimierten Maschinencode wie andere Sprachcompiler.

Forth wurde in den 1980er Jahren sehr populär, weil es gut zu den kleinen Mikrocomputern dieser Zeit passte, da es kompakt und tragbar war. Mindestens ein Heimcomputer, der britische Jupiter ACE, hatte Forth in seinem ROM-residenten Betriebssystem. Forth wird aufgrund seiner Portabilität, effizienten Speichernutzung, kurzen Entwicklungszeit und schnellen Ausführungsgeschwindigkeit noch heute in vielen eingebetteten Systemen (kleinen computergestützten Geräten) verwendet. Es wurde auf modernen RISC-Prozessoren effizient implementiert, und es wurden Prozessoren produziert, die Forth als Maschinensprache verwenden. Andere Anwendungen von Forth sind die von Apple, IBM und Sun verwendeten Open-Firmware-Boot-ROMs und als First-Stage-Boot-Controller des FreeBSD-Betriebssystems.

Forth ist eine einfache, aber erweiterbare Sprache; seine Modularität und Erweiterbarkeit erlauben das Schreiben von High-Level-Programmen wie CAD-Systemen. Die Erweiterbarkeit hilft jedoch auch armen Programmierern, unverständlichen Code zu schreiben, was Forth den Ruf einer „Nur-Schreiben“-Sprache eingebracht hat. Forth wurde erfolgreich in großen, komplexen Projekten eingesetzt, während Anwendungen, die von kompetenten, disziplinierten Fachleuten entwickelt wurden, sich über Jahrzehnte hinweg als problemlos auf sich entwickelnden Hardwareplattformen warten lassen.

Perspektive des Programmierers

Forth stützt sich stark auf die explizite Verwendung eines Datenstapels und der umgekehrten polnischen Notation (RPN- oder Postfix-Notation), die häufig in Taschenrechnern von Hewlett-Packard verwendet wird. In RPN wird der Operator nach seinen Operanden platziert, im Gegensatz zur üblicheren Infix-Notation, bei der der Operator zwischen seinen Operanden platziert wird. Die Postfix-Notation erleichtert das Analysieren und Erweitern der Sprache; Forth verwendet keine BNF-Grammatik und keinen monolithischen Compiler. Das Erweitern des Compilers erfordert nur das Schreiben eines neuen Wortes, anstatt eine Grammatik zu modifizieren und die zugrunde liegende Implementierung zu ändern.

Mit RPN könnte man das Ergebnis des mathematischen Ausdrucks (25 * 10 + 50) auf diese Weise erhalten:

25 10 * 50 + .
300 ok

Diese Befehlszeile legt zuerst die Nummern 25 und 10 auf den impliziten Stack.

Das Wort * multipliziert die beiden Zahlen oben auf dem Stapel und ersetzt sie durch ihr Produkt.

Dann wird die Zahl 50 auf den Stapel gelegt.

Das Wort + fügt es dem vorherigen Produkt hinzu. Schließlich gibt der Befehl . das Ergebnis auf dem Terminal des Benutzers aus.

Sogar die strukturellen Merkmale von Forth sind stapelbasiert. Zum Beispiel:

: FLOOR5 ( n -- n' )   DUP 6 < IF DROP 5 ELSE 1 - THEN ;

Dieser Code definiert ein neues Wort (wiederum ist „Wort“ der für eine Unterroutine verwendete Begriff) mit dem Namen FLOOR5 unter Verwendung der folgenden Befehle: DUP dupliziert die Zahl auf dem Stapel; < vergleicht die beiden Zahlen auf dem Stapel und ersetzt sie durch einen Wahr-oder-Falsch-Wert; IF nimmt einen Wahr-oder-Falsch-Wert an und führt Befehle unmittelbar danach aus oder springt zu ELSE; DROP verwirft den Wert auf dem Stack; und THEN beendet die Bedingung. Der Text in Klammern ist ein Kommentar, der darauf hinweist, dass dieses Wort eine Zahl auf dem Stapel erwartet und eine möglicherweise geänderte Zahl zurückgibt. Das Nettoergebnis verhält sich ähnlich wie diese in der Programmiersprache C geschriebene Funktion:

int floor5(int v) { return v < 6 ? 5 : v - 1; }

Einrichtungen

Dolmetscher

Forth-Parsing ist einfach, da es keine explizite Grammatik hat. Der Interpreter liest eine Eingabezeile von der Benutzereingabevorrichtung, die dann unter Verwendung von Leerzeichen als Trennzeichen nach einem Wort analysiert wird; Einige Systeme erkennen zusätzliche Leerzeichen. Wenn der Dolmetscher ein Wort findet, versucht er, das Wort in der nachzuschlagen Wörterbuch . Wenn das Wort gefunden wird, führt der Interpreter den mit dem Wort verknüpften Code aus und kehrt dann zurück, um zu parsen, was vom Eingabestrom übrig ist. Wenn das Wort nicht gefunden wird, wird angenommen, dass das Wort eine Zahl ist, und es wird versucht, es in eine Zahl umzuwandeln und auf den Stapel zu schieben; Bei Erfolg fährt der Interpreter mit dem Analysieren des Eingabestroms fort. Andernfalls, wenn sowohl die Suche als auch die Zahlenkonvertierung fehlschlagen, gibt der Interpreter das Wort aus, gefolgt von einer Fehlermeldung, die angibt, dass das Wort nicht erkannt wird, löscht den Eingabestrom und wartet auf eine neue Benutzereingabe.

Compiler

Die Definition eines neuen Wortes beginnt mit dem Wort : (Doppelpunkt) und endet mit dem Wort ; (Semikolon). Zum Beispiel

: X DUP 1+ . . ;

kompiliert das Wort X. Bei Ausführung durch Eingabe von 10 X an der Konsole wird 11 10 ausgegeben.

Monteur

Die meisten Forth-Systeme enthalten einen spezialisierten Assembler, der ausführbare Wörter erzeugt. Der Assembler ist ein spezieller Dialekt des Compilers. Forth-Assembler verwenden oft eine umgekehrte polnische Syntax, bei der die Parameter einer Anweisung der Anweisung vorangehen. Das übliche Design eines Forth-Assemblers besteht darin, die Anweisung auf dem Stapel zu erstellen und sie dann als letzten Schritt in den Speicher zu kopieren. Auf Register kann mit dem vom Hersteller verwendeten Namen verwiesen, nummeriert (0..n, wie im eigentlichen Operationscode verwendet) oder nach ihrem Zweck im Forth-System benannt werden: z. 'S' für das als Stapelzeiger verwendete Register.

Betriebssystem, Dateien und Multitasking

Klassische Forth-Systeme verwenden traditionell weder Betriebssystem noch Dateisystem. Anstatt Code in Dateien zu speichern, wird Quellcode in Plattenblöcken gespeichert, die an physische Plattenadressen geschrieben werden. Das Wort BLOCK wird verwendet, um die Nummer eines 1K-großen Plattenplatzblocks in die Adresse eines Puffers zu übersetzen, der die Daten enthält, die automatisch vom Forth-System verwaltet werden. Einige implementieren zusammenhängende Plattendateien unter Verwendung des Plattenzugriffs des Systems, wobei sich die Dateien in festen Plattenblockbereichen befinden. Normalerweise werden diese als binäre Datensätze mit fester Länge implementiert, mit einer ganzzahligen Anzahl von Datensätzen pro Plattenblock. Eine schnelle Suche wird durch gehashten Zugriff auf Schlüsseldaten erreicht.

Multitasking, am häufigsten kooperatives Round-Robin-Scheduling, ist normalerweise verfügbar (obwohl Multitasking-Wörter und -Unterstützung nicht durch den ANSI Forth-Standard abgedeckt sind). Das Wort PAUSE wird verwendet, um den Ausführungskontext der aktuellen Aufgabe zu speichern, die nächste Aufgabe zu lokalisieren und ihren Ausführungskontext wiederherzustellen. Jede Task hat ihre eigenen Stacks, private Kopien einiger Steuervariablen und einen Scratch-Bereich. Das Austauschen von Aufgaben ist einfach und effizient; Infolgedessen sind Forth-Multitasker sogar auf sehr einfachen Mikrocontrollern wie Intel 8051, Atmel AVR und TI MSP430 verfügbar.

Im Gegensatz dazu laufen einige Forth-Systeme unter einem Host-Betriebssystem wie z Microsoft Windows , Linux oder eine Version von Unix und das Dateisystem des Host-Betriebssystems für Quell- und Datendateien verwenden; der ANSI Forth Standard beschreibt die für E/A verwendeten Wörter. Andere nicht standardmäßige Einrichtungen umfassen einen Mechanismus zum Ausgeben von Aufrufen an das Host-Betriebssystem oder Fenstersysteme, und viele stellen Erweiterungen bereit, die die vom Betriebssystem bereitgestellte Zeitplanung verwenden. Typischerweise haben sie einen größeren und anderen Satz von Wörtern als das eigenständige Wort PAUSE von Forth für die Erstellung, Aussetzung, Zerstörung und Änderung der Priorität von Aufgaben.

Selbstkompilierung und Cross-Kompilierung

Ein voll funktionsfähiges Forth-System mit dem gesamten Quellcode kompiliert sich selbst, eine Technik, die von Forth-Programmierern allgemein als Meta-Kompilierung bezeichnet wird (obwohl der Begriff nicht genau mit der Meta-Kompilierung übereinstimmt, wie sie normalerweise definiert wird). Die übliche Methode besteht darin, die Handvoll Wörter neu zu definieren, die kompilierte Bits in den Speicher stellen. Die Wörter des Compilers verwenden speziell benannte Versionen von Abrufen und Speichern, die in einen Pufferbereich im Speicher umgeleitet werden können. Der Pufferbereich simuliert oder greift auf einen Speicherbereich zu, der an einer anderen Adresse als der Codepuffer beginnt. Solche Compiler definieren Wörter, um sowohl auf den Speicher des Zielcomputers als auch auf den Speicher des Host-(Kompilierungs-)Computers zuzugreifen.

Nachdem die Abruf- und Speicheroperationen für den Coderaum neu definiert wurden, werden der Compiler, Assembler usw. unter Verwendung der neuen Definitionen von Abruf und Speicherung neu kompiliert. Dadurch wird der gesamte Code des Compilers und Interpreters effektiv wiederverwendet. Dann wird der Code des Forth-Systems kompiliert, aber diese Version wird im Puffer gespeichert. Der Puffer im Arbeitsspeicher wird auf die Festplatte geschrieben, und es werden Möglichkeiten bereitgestellt, ihn zum Testen vorübergehend in den Arbeitsspeicher zu laden. Wenn die neue Version zu funktionieren scheint, wird sie über die vorherige Version geschrieben.

Es gibt zahlreiche Variationen solcher Compiler für unterschiedliche Umgebungen. Bei eingebetteten Systemen kann der Code stattdessen über eine serielle Schnittstelle oder sogar ein einzelnes TTL-Bit auf einen anderen Computer geschrieben werden, eine Technik, die als Kreuzkompilierung bekannt ist, während die Wortnamen und andere nicht ausführende Teile des Wörterbuchs in der ursprünglichen Kompilierung beibehalten werden Computer. Die Mindestdefinitionen für einen solchen vierten Compiler sind die Wörter, die ein Byte abrufen und speichern, und das Wort, das die Ausführung eines vierten Wortes befiehlt. Der zeitaufwändigste Teil beim Schreiben eines Remote-Ports ist häufig das Erstellen des anfänglichen Programms zum Implementieren von Abrufen, Speichern und Ausführen, aber viele moderne Mikroprozessoren verfügen über integrierte Debugging-Funktionen (z. B. die Motorola CPU32), die diese Aufgabe beseitigen.

Aufbau der Sprache

Die grundlegende Datenstruktur von Forth ist das „Wörterbuch“, das „Wörter“ auf ausführbaren Code oder benannte Datenstrukturen abbildet. Das Wörterbuch wird im Speicher als verknüpfte Liste angelegt, wobei die Verknüpfungen vom neuesten (zuletzt) ​​definierten Wort zum ältesten fortschreiten, bis ein Wächter, normalerweise ein NULL-Zeiger, gefunden wird.

Ein definiertes Wort besteht im Allgemeinen aus Kopf und Karosserie mit dem Kopf, bestehend aus der Namensfeld (NF) und die Linkfeld (LF) und Körper bestehend aus der Codefeld (CF) und die Parameterfeld (PF).

Kopf und Körper eines Wörterbucheintrags werden getrennt behandelt, da sie möglicherweise nicht zusammenhängend sind. Wenn beispielsweise ein Forth-Programm für eine neue Plattform neu kompiliert wird, kann der Kopf auf dem kompilierenden Computer verbleiben, während der Hauptteil auf die neue Plattform wechselt. In einigen Umgebungen (z. B. eingebetteten Systemen) belegen die Köpfe unnötigerweise Speicher. Einige Cross-Compiler können jedoch Köpfe in das Ziel einfügen, wenn erwartet wird, dass das Ziel selbst ein interaktives Forth unterstützt.

Eintrag im Wörterbuch

Das genaue Format eines Wörterbucheintrags ist nicht vorgeschrieben, und Implementierungen variieren. Bestimmte Komponenten sind jedoch fast immer vorhanden, obwohl die genaue Größe und Reihenfolge variieren kann. Als Struktur beschrieben, könnte ein Wörterbucheintrag so aussehen:

structure
  byte:       flag           \ 3bit flags + length of word's name
  char-array: name           \ name's runtime length isn't known at compile time
  address:    previous       \ link field, backward ptr to previous word
  address:    codeword       \ ptr to the code to execute this word
  any-array:  parameterfield \ unknown length of data, words, or opcodes
end-structure forthword

Das Namensfeld beginnt mit einem Präfix, das die Länge des Wortnamens angibt (typischerweise bis zu 32 Byte), und mehreren Bits für Flags. Die Zeichendarstellung des Wortnamens folgt dann dem Präfix. Abhängig von der jeweiligen Implementierung von Forth können ein oder mehrere NUL-Bytes ('\0') für die Ausrichtung vorhanden sein.

Das Verknüpfungsfeld enthält einen Zeiger auf das zuvor definierte Wort. Der Zeiger kann eine relative Verschiebung oder eine absolute Adresse sein, die auf das nächstälteste Geschwister zeigt.

Der Codefeldzeiger ist entweder die Adresse des Wortes, das den Code oder die Daten im Parameterfeld ausführt, oder der Beginn des Maschinencodes, den der Prozessor direkt ausführt. Für durch Doppelpunkte definierte Wörter zeigt der Codefeldzeiger auf das Wort, das den aktuellen Forth-Befehlszeiger (IP) auf dem Rückgabestapel speichert und das IP mit der neuen Adresse lädt, von der aus die Ausführung von Wörtern fortgesetzt wird. Dies ist das Gleiche wie die Call/Return-Instruktionen eines Prozessors.

Aufbau des Compilers

Der Compiler selbst besteht aus für das System sichtbaren Forth-Wörtern, nicht aus einem monolithischen Programm. Dies ermöglicht einem Programmierer, die Wörter des Compilers für spezielle Zwecke zu ändern.

Das „compile time“-Flag im Namensfeld wird für Wörter mit „compile time“-Verhalten gesetzt. Die meisten einfachen Wörter führen denselben Code aus, unabhängig davon, ob sie in eine Befehlszeile eingegeben oder in Code eingebettet werden. Beim Kompilieren platziert der Compiler einfach Code oder einen Thread-Zeiger auf das Wort.

Wörter zur Kompilierzeit werden tatsächlich vom Compiler ausgeführt. Die klassischen Beispiele für Wörter zur Kompilierzeit sind die Steuerstrukturen wie IF und WHILE. Alle Kontrollstrukturen von Forth und fast alle Compiler sind als Wörter zur Kompilierzeit implementiert.

Zusammenstellungsstatus und Interpretationsstatus

Das Wort : (Doppelpunkt) nimmt einen Namen als Parameter, erstellt einen Wörterbucheintrag (a Doppelpunkt-Definition ) und wechselt in den Kompilierungsstatus. Der Interpreter fährt fort, durch Leerzeichen getrennte Wörter von der Benutzereingabevorrichtung zu lesen. Wenn ein Wort gefunden wird, führt der Interpreter das aus Kompilierungssemantik mit dem Wort verbunden, statt der Interpretation Semantik . Die standardmäßige Kompilierungssemantik eines Wortes besteht darin, seine Interpretationssemantik an die aktuelle Definition anzuhängen.

Das Wort ; (Semikolon) beendet die aktuelle Definition und kehrt zum Interpretationszustand zurück. Es ist ein Beispiel für ein Wort, dessen Kompilierungssemantik sich von der Standardeinstellung unterscheidet. Die Interpretationssemantik von ; (Semikolon) und mehreren anderen Wörtern ist in ANS Forth nicht definiert.

Der Interpreterstatus kann manuell mit den Wörtern [ (linke Klammer) und ] (rechte Klammer) geändert werden, die den Interpretationsstatus bzw. den Kompilierungsstatus eingeben. Diese Wörter können mit dem Wort LITERAL verwendet werden, um während einer Kompilierung einen Wert zu berechnen und den berechneten Wert in die aktuelle Doppelpunktdefinition einzufügen. LITERAL hat die Kompilierungssemantik, um ein Objekt aus dem Datenstapel zu nehmen und Semantik an die aktuelle Doppelpunktdefinition anzuhängen, um dieses Objekt auf dem Datenstapel zu platzieren.

In ANS Forth kann der aktuelle Status des Interpreters aus dem Flag STATE gelesen werden, das im Kompilierungsstatus den Wert true und andernfalls den Wert false enthält. Dies ermöglicht die Implementierung von sog Zustand kluge Worte mit Verhalten, das sich entsprechend dem aktuellen Zustand des Interpreters ändert.

Unbenannte Wörter und Ausführungstoken

In ANS Forth können unbenannte Wörter mit dem Wort :NONAME definiert werden, das die folgenden Wörter bis zum nächsten ; (Semikolon) zusammenfasst und ein hinterlässt Ausführungstoken auf dem Datenstack. Das Ausführungstoken bietet ein undurchsichtiges Handle für die kompilierte Semantik, ähnlich den Funktionszeigern der Programmiersprache C.

Ausführungstoken können in Variablen gespeichert werden. Das Wort EXECUTE nimmt ein Ausführungstoken aus dem Datenstapel und führt die zugehörige Semantik aus. Das Wort COMPILE, (compile-comma) nimmt ein Ausführungstoken aus dem Datenstapel und hängt die zugehörige Semantik an die aktuelle Definition an.

Das Wort ' (Tick) nimmt den Namen eines Wortes als Parameter und gibt das Ausführungstoken zurück, das diesem Wort auf dem Datenstapel zugeordnet ist. Im Interpretationszustand entspricht ' RANDOM-WORD EXECUTE RANDOM-WORD.

Parsing von Wörtern und Kommentaren

The words : (colon), POSTPONE, ' (tick) and :NONAME are examples of Wörter analysieren die ihre Argumente vom Benutzereingabegerät statt vom Datenstapel nehmen. Ein weiteres Beispiel ist das Wort ( (Paren), das die folgenden Wörter bis einschließlich der nächsten rechten Klammer liest und ignoriert und verwendet wird, um Kommentare in einer Doppelpunktdefinition zu platzieren. Ebenso wird das Wort \ (umgekehrter Schrägstrich) für Kommentare verwendet, die bis zum Ende der aktuellen Zeile fortgesetzt werden. Um korrekt geparst zu werden, müssen ( (Paren) und \ (Backslash) durch Leerzeichen vom folgenden Kommentartext getrennt werden.

Struktur des Codes

In den meisten Forth-Systemen besteht der Hauptteil einer Codedefinition entweder aus Maschinensprache oder aus irgendeiner Form von Thread-Code. Traditionell wurde Code mit indirektem Thread verwendet, aber Forths mit direktem Thread und Unterroutinen-Thread waren ebenfalls beliebt. Die schnellsten modernen Forths verwenden Subroutinen-Threading, fügen einfache Wörter als Makros ein und führen Peephole-Optimierung oder andere Optimierungsstrategien durch, um den Code kleiner und schneller zu machen.

Datenobjekte

Wenn ein Wort eine Variable oder ein anderes Datenobjekt ist, zeigt die CF auf den Laufzeitcode, der dem definierenden Wort zugeordnet ist, das es erzeugt hat. Ein definierendes Wort hat ein charakteristisches 'definierendes Verhalten' (Erstellen eines Wörterbucheintrags plus möglicherweise Zuweisen und Initialisieren von Datenraum) und spezifiziert auch das Verhalten einer Instanz der Klasse von Wörtern, die durch dieses definierende Wort konstruiert wird. Beispiele beinhalten:

VARIABLE
Benennt einen nicht initialisierten Speicherort mit einer Zelle. Das Instanzverhalten eines VARIABLE gibt seine Adresse auf dem Stack zurück.
CONSTANT
Benennt einen Wert (angegeben als Argument für CONSTANT). Das Instanzverhalten gibt den Wert zurück.
CREATE
Nennt einen Ort; An dieser Stelle kann Speicherplatz zugewiesen werden, oder es kann so eingestellt werden, dass es eine Zeichenfolge oder einen anderen initialisierten Wert enthält. Das Instanzverhalten gibt die Adresse des Anfangs dieses Bereichs zurück.

Forth stellt auch eine Einrichtung bereit, durch die ein Programmierer neue anwendungsspezifische Definitionswörter definieren kann, die sowohl ein benutzerdefiniertes Definitionsverhalten als auch ein Instanzverhalten spezifizieren. Einige Beispiele umfassen Ringpuffer, benannte Bits an einem I/O-Port und automatisch indizierte Arrays.

Durch diese und ähnliche Wörter definierte Datenobjekte haben einen globalen Geltungsbereich. Die von lokalen Variablen in anderen Sprachen bereitgestellte Funktion wird vom Datenstapel in Forth bereitgestellt. Der vierte Programmierstil verwendet im Vergleich zu anderen Sprachen nur sehr wenige benannte Datenobjekte. typischerweise werden solche Datenobjekte verwendet, um Daten zu enthalten, die von einer Anzahl von Wörtern oder Aufgaben (in einer Multitasking-Implementierung) verwendet werden.

Forth erzwingt keine Konsistenz der Datentypnutzung; Es liegt in der Verantwortung des Programmierers, geeignete Operatoren zu verwenden, um Werte abzurufen und zu speichern oder andere Operationen an Daten durchzuführen.

Programmierung

In Forth geschriebene Wörter werden in eine ausführbare Form kompiliert. Die klassischen Implementierungen mit 'indirektem Thread' stellen Listen von Adressen von Wörtern zusammen, die der Reihe nach ausgeführt werden sollen; Viele moderne Systeme generieren tatsächlichen Maschinencode (einschließlich Aufrufen einiger externer Wörter und Codes für andere, die an Ort und Stelle erweitert werden). Einige Systeme haben optimierende Compiler. Im Allgemeinen wird ein Forth-Programm als Speicherabbild des kompilierten Programms mit einem einzigen Befehl (z. B. RUN) gespeichert, der ausgeführt wird, wenn die kompilierte Version geladen wird.

Während der Entwicklung verwendet der Programmierer den Interpreter, um jedes kleine Stück während der Entwicklung auszuführen und zu testen. Die meisten Forth-Programmierer befürworten daher ein lockeres Top-Down-Design und eine Bottom-Up-Entwicklung mit kontinuierlichem Testen und Integration.

Das Top-down-Design ist normalerweise die Aufteilung des Programms in 'Vokabulare', die dann als High-Level-Toolsets verwendet werden, um das endgültige Programm zu schreiben. Ein gut gestaltetes Forth-Programm liest sich wie natürliche Sprache und implementiert nicht nur eine einzelne Lösung, sondern auch eine Reihe von Tools, um verwandte Probleme anzugehen.

Der Toolbox-Ansatz ist einer der Gründe, warum Forth so schwer zu meistern ist. Während das Erlernen der Syntax einfach ist, kann das Beherrschen der Tools, die mit einem professionellen Forth-System geliefert werden, bei Vollzeitbeschäftigung mehrere Monate dauern. Die Aufgabe ist tatsächlich schwieriger, als das eigene Forth-System von Grund auf neu zu schreiben. Leider geht bei einem Rewrite auch die in einem typischen professionellen Forth-Werkzeugkasten angesammelte Erfahrung verloren.

Codebeispiele

Hallo Welt

Eine mögliche Implementierung:

: HELLO  ( -- )  CR ." Hello, world!" ;
HELLO

Das Wort CR bewirkt, dass die folgende Ausgabe in einer neuen Zeile angezeigt wird. Das Analysewort ." (Punkt-Anführungszeichen) liest eine durch doppelte Anführungszeichen getrennte Zeichenfolge und fügt Code an die aktuelle Definition an, sodass die analysierte Zeichenfolge bei der Ausführung angezeigt wird. Das Leerzeichen, das das Wort ." von der Zeichenfolge Hello, world! trennt, ist nicht Teil der Zeichenfolge. Es wird benötigt, damit der Parser ." als Forth-Wort erkennt.

Ein Standard-Forth-System ist auch ein Interpreter, und die gleiche Ausgabe kann erhalten werden, indem Sie das folgende Codefragment in die Forth-Konsole eingeben:

CR .( Hello, world!)

.( (dot-paren) ist ein unmittelbares Wort, das eine durch Klammern getrennte Zeichenfolge analysiert und anzeigt. Wie beim Wort ." ist das Leerzeichen, das .( von Hello, world! trennt, nicht Teil der Zeichenfolge.

Das Wort CR steht vor dem zu druckenden Text. Per Konvention beginnt der Forth-Interpreter die Ausgabe nicht in einer neuen Zeile. Ebenfalls per Konvention wartet der Interpreter auf die Eingabe am Ende der vorherigen Zeile, nach einer ok-Eingabeaufforderung. In CR von Forth gibt es keine implizite „Flush-Buffer“-Aktion, wie dies manchmal in anderen Programmiersprachen der Fall ist.

Kompilierungsstatus und Interpretationsstatus mischen

Hier ist die Definition eines Wortes EMIT-Q, das bei Ausführung das einzelne Zeichen Q ausgibt:

: EMIT-Q   81 ( the ASCII value for the character 'Q' ) EMIT ;

Diese Definition wurde geschrieben, um die zu verwenden ASCII Wert des Zeichens Q (81) direkt. Der Text zwischen den Klammern ist ein Kommentar und wird vom Compiler ignoriert. Das Wort EMIT nimmt einen Wert aus dem Datenstapel und zeigt das entsprechende Zeichen an.

The following redefinition of EMIT-Q uses the words [ (left-bracket), ] (right-bracket), CHAR and LITERAL to temporarily switch to interpreter state, calculate the ASCII value of the Q character, return to compilation state and append the calculated value zur aktuellen Doppelpunktdefinition:

: EMIT-Q   [ CHAR Q ]  LITERAL  EMIT ;

Das Analysewort CHAR nimmt ein durch Leerzeichen getrenntes Wort als Parameter und legt den Wert seines ersten Zeichens auf dem Datenstapel ab. Das Wort [CHAR] ist eine unmittelbare Version von CHAR. Unter Verwendung von [CHAR] könnte die Beispieldefinition für EMIT-Q wie folgt umgeschrieben werden:

: EMIT-Q   [CHAR] Q  EMIT ; \ Emit the single character 'Q'

Diese Definition verwendete \ (umgekehrter Schrägstrich) für den beschreibenden Kommentar.

Sowohl CHAR als auch [CHAR] sind in ANS Forth vordefiniert. Mit IMMEDIATE und POSTPONE hätte [CHAR] wie folgt definiert werden können:

: [CHAR]   CHAR  POSTPONE LITERAL ; IMMEDIATE