Articles

Forth

2007 Schulen Wikipedia Auswahl. Verwandte Themen: Computerprogrammierung

Forth

Charles H. Moore, der Erfinder von Forth

Vergrößern

Charles H. Moore, der Erfinder von Forth

Paradigma:

prozedural, stapelorientiert

Erschienen in:

1970er Jahre

Entworfen von:

Charles H. Moore

Typing discipline:

Typenlos

Wichtige Implementierungen:

Forth, Inc., gForth, MPE, Open Firmware

Dialekte:

colorForth, FCode

Beeinflusst von:

Burroughs Large systems, Lisp, APL

Beeinflusst:

PostScript, Faktor

Forth ist eine Programmiersprache und Programmierumgebung, die ursprünglich von Charles H. Moore an der US National Radio Astronomy Observatorium in den frühen 1970er Jahren. Es wurde 1977 formalisiert und 1994 von ANSI standardisiert. Forth wird manchmal in allen Großbuchstaben nach dem üblichen Gebrauch in seinen früheren Jahren geschrieben, obwohl der Name kein Akronym ist.Als prozedurale, stapelorientierte und reflektierende Programmiersprache ohne Typprüfung bietet Forth sowohl die interaktive Ausführung von Befehlen (wodurch es sich als Shell für Systeme eignet, denen ein formelleres Betriebssystem fehlt) als auch die Möglichkeit, Befehlssequenzen für die spätere Ausführung zu kompilieren. Einige Forth-Versionen (insbesondere frühe) kompilieren Threaded-Code, aber viele Implementierungen generieren heute optimierten Maschinencode wie andere Sprachcompiler.

Forth wird so genannt, weil „die Datei, die den Interpreter hält, als 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 Compile-Link-Go-Programmiersprachen der dritten Generation oder Software für Hardware der „4. Generation“, nicht als 4GL, wie der Begriff verwendet wurde.

Übersicht

Forth bietet eine eigenständige Programmierumgebung, die aus einem stapelorientierten, interaktiven, inkrementellen Interpreter und Compiler besteht. Programmieren in Forth ist ein interaktiver, iterativer Prozess. Ein Forth-System besteht aus Wörtern (der Begriff für Forth-Unterprogramme); neue Wörter werden in Bezug auf alte Wörter definiert, und es wird nicht zwischen den Wörtern unterschieden, die die Forth-Sprache definieren, und denen, die der Programmierer erstellt. Ein typisches Forth-Paket besteht aus einem vorkompilierten Kernel der Kernwörter, mit dem der Programmierer neue Wörter für die Anwendung definiert. Die ausgefüllte Anwendung kann als Bild gespeichert werden, wobei die neuen Wörter bereits kompiliert 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 Arbeitsgrundlage.

Forth verwendet separate Stapel zum Speichern von Unterprogrammparametern und Unterprogrammaktivierungsdatensätzen. Der Parameter- oder Datenstapel (allgemein als Stapel bezeichnet) wird verwendet, um Daten an Wörter zu übergeben und die Ergebnisse zu speichern, die die Wörter zurückgeben. Der Verknüpfungs- oder Rückgabestapel (allgemein als rstack bezeichnet) wird verwendet, um Rücksprungadressen zu speichern, wenn Wörter verschachtelt sind (das Äquivalent eines Unterprogrammaufrufs), und lokale Variablen zu speichern. Es gibt Standardwörter, um Daten zwischen den Stapeln zu verschieben und Variablen auf dem Stapel zu laden und zu speichern.

Die logische Struktur von Forth ähnelt einer virtuellen Maschine. Forth, insbesondere frühe Versionen, implementiert einen inneren Interpreter, der indirekt Threaded-Maschinencode verfolgt und kompakten und schnellen High-Level-Code liefert, 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 für die kleinen Mikrocomputer dieser Zeit geeignet war, da es kompakt und tragbar ist. Mindestens ein Heimcomputer, der britische Jupiter ACE, hatte Forth in seinem ROM-residenten Betriebssystem. Forth wird heute noch in vielen eingebetteten Systemen (kleine computergestützte Geräte) aufgrund seiner Portabilität, effizienten Speichernutzung, kurzen Entwicklungszeit und schnellen Ausführungsgeschwindigkeit verwendet. Es wurde effizient auf modernen RISC-Prozessoren implementiert, und Prozessoren, die Forth als Maschinensprache verwenden, wurden hergestellt. Andere Verwendungen von Forth umfassen die Open Firmware-Boot-ROMs, die von Apple, IBM und Sun verwendet werden, und als Boot-Controller der ersten Stufe des FreeBSD-Betriebssystems.

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

Programmiererperspektive

Forth stützt sich stark auf die explizite Verwendung eines Datenstapels und der umgekehrten polnischen Notation (RPN oder Postfix-Notation), die üblicherweise in Taschenrechnern von Hewlett-Packard verwendet wird. In RPN wird der Operator nach seinen Operanden platziert, im Gegensatz zu der gebräuchlicheren Infix-Notation, bei der der Operator zwischen seinen Operanden platziert wird. Die Postfix-Notation erleichtert das Parsen und Erweitern der Sprache; Forth verwendet keine BNF-Grammatik und hat keinen monolithischen Compiler. Um den Compiler zu erweitern, muss nur ein neues Wort geschrieben werden, anstatt eine Grammatik zu ändern 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 Zahlen 25 und 10 auf den impliziten Stapel.

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.

Selbst die strukturellen Merkmale von Forth sind stapelbasiert. Beispielsweise:

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

Dieser Code definiert ein neues Wort (wiederum ist „word“ der Begriff für ein Unterprogramm) mit dem Namen FLOOR5 mit den folgenden Befehlen: DUP dupliziert die Nummer auf dem Stapel; < vergleicht die beiden Zahlen auf dem Stapel und ersetzt sie durch einen True-oder-false-Wert; IF nimmt einen True-oder-false-Wert und wählt Befehle unmittelbar danach aus oder springt zum ELSEDROP verwirft den Wert auf dem Stapel; 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

Interpreter

Forth Parsing ist einfach, da es keine explizite Grammatik hat. Der Interpreter liest eine Eingabezeile vom Benutzereingabegerät, die dann mit Leerzeichen als Trennzeichen nach einem Wort analysiert wird; Einige Systeme erkennen zusätzliche Leerzeichen. Wenn der Dolmetscher ein Wort findet, versucht er, das Wort im Wörterbuch nachzuschlagen. Wenn das Wort gefunden wird, führt der Interpreter den mit dem Wort verknüpften Code aus und kehrt dann zurück, um zu analysieren, was vom Eingabestream übrig bleibt. 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. Andernfalls, wenn sowohl die Suche als auch die Zahlenkonvertierung fehlschlagen, druckt der Interpreter das Wort, gefolgt von einer Fehlermeldung, die angibt, dass das Wort nicht erkannt wird, löscht den Eingabestream und wartet auf neue Benutzereingaben.

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. Wenn Sie 10 X an der Konsole eingeben, wird 11 10 .

Assembler

Die meisten Forth-Systeme enthalten einen speziellen Assembler, der ausführbare Wörter erzeugt. Der Assembler ist ein spezieller Dialekt des Compilers. Forth-Assembler verwenden häufig eine umgekehrte polnische Syntax, in der die Parameter einer Anweisung der Anweisung vorangehen. Das übliche Design eines Forth-Assemblers besteht darin, die Anweisung auf dem Stapel zu konstruieren und sie dann als letzten Schritt in den Speicher zu kopieren. Register können durch den vom Hersteller verwendeten Namen referenziert werden, nummeriert (0..n, wie im eigentlichen Operationscode verwendet) oder für ihren Zweck im Forth-System benannt: zB „S“ für das Register, das als Stapelzeiger verwendet wird.

Betriebssystem, Dateien und Multitasking

Klassische Betriebssysteme verwenden traditionell weder Betriebssystem noch Dateisystem. Anstatt Code in Dateien zu speichern, wird Quellcode in Festplattenblöcken gespeichert, die auf physische Festplattenadressen geschrieben werden. Das Wort BLOCK wird verwendet, um die Nummer eines 1K-großen Speicherblocks in die Adresse eines Puffers mit den Daten zu übersetzen, der automatisch vom Betriebssystem verwaltet wird. Einige implementieren zusammenhängende Festplattendateien mithilfe des Festplattenzugriffs des Systems, wobei sich die Dateien in festen Festplattenblockbereichen befinden. Normalerweise werden diese als binäre Datensätze fester Länge mit einer ganzzahligen Anzahl von Datensätzen pro Festplattenblock implementiert. Eine schnelle Suche wird durch Hash-Zugriff auf Schlüsseldaten erreicht.Multitasking, am häufigsten kooperative Round-Robin-Planung, ist normalerweise verfügbar (obwohl Multitasking-Wörter und -Unterstützung nicht vom ANSI Forth-Standard abgedeckt werden). 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 Aufgabe hat ihre eigenen Stapel, private Kopien einiger Steuervariablen und einen Scratch-Bereich. Das Austauschen von Aufgaben ist einfach und effizient; Daher sind diese Multitasker auch 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 Microsoft Windows, Linux oder einer Version von Unix und verwenden das Dateisystem des Host-Betriebssystems für Quell- und Datendateien; der ANSI Forth-Standard beschreibt die Wörter, die für E / A verwendet werden. Normalerweise haben sie einen größeren und anderen Satz von Wörtern als das PAUSE -Wort des eigenständigen Programms für die Erstellung, Aussetzung, Zerstörung und Änderung der Priorität von Aufgaben.

Selbstkompilierung und Kreuzkompilierung

Ein voll ausgestattetes 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 übereinstimmt) Meta-Kompilierung, wie es normalerweise definiert ist). Die übliche Methode besteht darin, die Handvoll Wörter neu zu definieren, die kompilierte Bits in den Speicher legen. Die Wörter des Compilers verwenden speziell benannte Versionen von fetch und store, die in einen Pufferbereich im Speicher umgeleitet werden können. Der Pufferbereich simuliert oder greift auf einen Speicherbereich zu, der an einer anderen Adresse beginnt als der Code-Puffer. Solche Compiler definieren Wörter, um sowohl auf den Speicher des Zielcomputers als auch auf den Speicher des Hostcomputers (Kompilieren) zuzugreifen.

Nachdem die Fetch- und Store-Operationen für den Coderaum, den Compiler, den Assembler usw. neu definiert wurden. werden mit den neuen Definitionen von fetch und store 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 Speicher wird auf die Festplatte geschrieben, und es werden Möglichkeiten bereitgestellt, ihn vorübergehend zum Testen in den Speicher zu laden. Wenn die neue Version zu funktionieren scheint, wird sie über die vorherige Version geschrieben.

Es gibt zahlreiche Variationen solcher Compiler für verschiedene Umgebungen. Für eingebettete Systeme kann der Code stattdessen auf einen anderen Computer geschrieben werden, eine Technik, die als Kreuzkompilierung bekannt ist, über eine serielle Schnittstelle oder sogar ein einzelnes TTL-Bit, während die Wortnamen und andere nicht ausführende Teile des Wörterbuchs im ursprünglichen Kompilierungscomputer beibehalten werden. Die Mindestdefinitionen für einen solchen Forth-Compiler sind die Wörter, die ein Byte abrufen und speichern, und das Wort, das die Ausführung eines Forth-Wortes befiehlt. Oft ist der zeitaufwändigste Teil des Schreibens eines Remote-Ports der Aufbau des anfänglichen Programms zum Implementieren von Fetch, Store und execute, aber viele moderne Mikroprozessoren verfügen über integrierte Debugging-Funktionen (wie die Motorola CPU32), die diese Aufgabe eliminieren.

Struktur der Sprache

Die grundlegende Datenstruktur von Forth ist das „Wörterbuch“, das „Wörter“ ausführbarem Code oder benannten Datenstrukturen zuordnet. Das Wörterbuch wird im Speicher als verknüpfte Liste angelegt, wobei die Links vom neuesten (zuletzt) definierten Wort zum ältesten gehen, bis ein Sentinel, normalerweise ein Nullzeiger, gefunden wird.

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

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 Körper zur neuen Plattform wechselt. In einigen Umgebungen (z. B. eingebetteten Systemen) belegen die Köpfe unnötig Speicher. Einige Cross-Compiler können jedoch Köpfe in das Ziel einfügen, wenn erwartet wird, dass das Ziel selbst eine interaktive Schnittstelle unterstützt.

Wörterbucheintrag

Das genaue Format eines Wörterbucheintrags ist nicht vorgeschrieben, und die 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 folgendermaßen 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 opcodesend-structure forthword

Das Namensfeld beginnt mit einem Präfix, das die Länge des Wortnamens angibt (normalerweise bis zu 32 Byte), und mehreren Bits für Flags. Die Zeichendarstellung des Namens des Wortes folgt dann dem Präfix. Abhängig von der speziellen Implementierung von Forth kann es ein oder mehrere NUL (‚\0‘) Bytes für die Ausrichtung geben.

Das Linkfeld 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 Anfang des Maschinencodes, den der Prozessor direkt ausführt. Bei bereits definierten Wörtern zeigt der Codefeldzeiger auf das Wort, das den aktuellen vierten Befehlszeiger (IP) auf dem Rückgabestapel speichert, und lädt die IP mit der neuen Adresse, von der aus die Ausführung von Wörtern fortgesetzt werden soll. Dies ist dasselbe wie die Call / Return-Anweisungen eines Prozessors.

Struktur des Compilers

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

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

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

Kompilierungszustand und Interpretationszustand

Das Wort : (Doppelpunkt) nimmt einen Namen als Parameter, erstellt einen Wörterbucheintrag (eine Doppelpunktdefinition) und tritt in den Kompilierungszustand ein. Der Interpreter liest weiterhin durch Leerzeichen getrennte Wörter vom Benutzereingabegerät. Wenn ein Wort gefunden wird, führt der Interpreter die dem Wort zugeordnete Kompilierungssemantik anstelle der Interpretationssemantik aus. 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 in den Interpretationszustand zurück. Es ist ein Beispiel für ein Wort, dessen Kompilierungssemantik von der Standardeinstellung abweicht. Die Interpretationssemantik von ; (Semikolon) und mehreren anderen Wörtern ist in ANS Forth nicht definiert.

Der Interpreterstatus kann manuell mit den Wörtern (rechte Klammer) geändert werden, die den Interpretationsstatus bzw. den Kompilierungsstatus eingeben. Diese Wörter können mit dem Wort LITERAL verwendet werden, um einen Wert während einer Kompilierung 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 Zustand des Interpreters aus dem Flag STATE gelesen werden, das im Kompilierungszustand den Wert true und ansonsten false enthält. Dies ermöglicht die Implementierung sogenannter State-Smart-Wörter mit einem Verhalten, das sich je nach aktuellem 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) kompiliert und ein Ausführungstoken auf dem Datenstapel hinterlässt. Das Ausführungstoken stellt ein undurchsichtiges Handle für die kompilierte Semantik bereit, ä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. In diesem Zustand entspricht ' RANDOM-WORD EXECUTERANDOM-WORD .

Parsen von Wörtern und Kommentaren

Die Wörter : (Doppelpunkt), POSTPONE' (Häkchen) und :NONAME sind Beispiele für das Parsen von Wörtern, die ihre Argumente vom Benutzereingabegerät anstelle des Datenstapels. Ein weiteres Beispiel ist das Wort ( (paren), das die folgenden Wörter bis einschließlich der nächsten rechten Klammer liest und ignoriert und zum Platzieren von Kommentaren in einer Doppelpunktdefinition verwendet wird. In ähnlicher Weise wird das Wort \ (Backslash) für Kommentare verwendet, die bis zum Ende der aktuellen Zeile fortgesetzt werden. Um korrekt analysiert 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 einer Form von Thread-Code. Traditionell wurde indirekter Threaded-Code verwendet, aber auch Direct-Threaded- und Subroutinen-Threaded-Forths waren beliebt. Die schnellsten modernen Forks verwenden Subroutinen-Threading, fügen einfache Wörter als Makros ein und führen eine Gucklochoptimierung oder andere Optimierungsstrategien durch, um den Code kleiner und schneller zu machen.

Datenobjekte

Wenn ein Wort eine Variable oder ein anderes Datenobjekt ist, zeigt der CF auf den Laufzeitcode, der dem definierenden Wort zugeordnet ist, das es erstellt 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 werden. Beispiele hierfür sind:

VARIABLEBenennt einen nicht initialisierten Speicherort mit einer Zelle. Instanzverhalten einesVARIABLEgibt seine Adresse auf dem Stapel zurück.CONSTANTBenennt einen Wert (angegeben als Argument fürCONSTANT). Instanzverhalten gibt den Wert zurück.CREATEBenennt einen Speicherort; An diesem Speicherort kann Speicherplatz zugewiesen oder ein String oder ein anderer initialisierter Wert enthalten sein. Instanzverhalten gibt die Adresse des Beginns dieses Bereichs zurück.

Forth bietet auch eine Möglichkeit, mit der ein Programmierer neue anwendungsspezifische definierende Wörter definieren kann, die sowohl ein benutzerdefiniertes definierendes Verhalten als auch ein Instanzverhalten angeben. Einige Beispiele umfassen kreisförmige Puffer, benannte Bits an einem E / A-Port und automatisch indizierte Arrays.

Datenobjekte, die durch diese und ähnliche Wörter definiert werden, haben einen globalen Gültigkeitsbereich. Die Funktion, die von lokalen Variablen in anderen Sprachen bereitgestellt wird, wird vom Datenstapel in Forth bereitgestellt. Der Forth-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 verwendet werden (in einer Multitasking-Implementierung).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 „indirekten Threaded“ -Implementierungen kompilieren Listen von Adressen von Wörtern, die nacheinander ausgeführt werden sollen; viele moderne Systeme generieren tatsächlichen Maschinencode (einschließlich Aufrufen einiger externer Wörter und Code für andere, die bereits vorhanden sind). 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 auszuführen und zu testen, während es entwickelt wird. Die meisten Forth-Programmierer befürworten daher ein lockeres Top-Down-Design und eine Bottom-Up-Entwicklung mit kontinuierlichen Tests und Integration.Das Top-Down-Design ist in der Regel die Trennung des Programms in „Vokabulare“, die dann als High-Level-Sätze von Werkzeugen 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 einzige Lösung, sondern auch eine Reihe von Tools, um verwandte Probleme anzugreifen.

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 mit einem professionellen Forth-System gelieferten Tools mehrere Monate dauern und Vollzeit arbeiten. Die Aufgabe ist eigentlich schwieriger, als das eigene Betriebssystem von Grund auf neu zu schreiben. Leider verliert ein Umschreiben auch die Erfahrung, die in einem typischen professionellen Werkzeugkasten gesammelt wurde.

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 ." (dot-quote) liest eine durch doppelte Anführungszeichen getrennte Zeichenfolge und hängt 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 viertes Wort erkennt.

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

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. Konventionell startet der Forth-Interpreter die Ausgabe nicht in einer neuen Zeile. Ebenfalls konventionell wartet der Interpreter nach einer ok Eingabeaufforderung auf die Eingabe am Ende der vorherigen Zeile. Es gibt keine implizite „Flush-buffer“ -Aktion in Forths CR , wie es manchmal in anderen Programmiersprachen der Fall ist.

Mischen von Kompilierungszustand und Interpretationszustand

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

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

Diese Definition wurde geschrieben, um den ASCII-Wert des Q -Zeichens (81) direkt zu verwenden. 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.

Die folgende Neudefinition von EMIT-Q verwendet die Wörter (rechte Klammer), CHAR und LITERAL Um vorübergehend in den Interpreter-Zustand zu wechseln, berechnen Sie den ASCII-Wert der Zeichen, kehren Sie in den Kompilierungszustand zurück und hängen Sie den berechneten Wert an die aktuelle Doppelpunktdefinition an:

: EMIT-Q LITERAL EMIT ;

Das Analysewort CHAR nimmt ein durch Leerzeichen getrenntes Wort als Parameter und platziert den Wert seines ersten Zeichens auf dem Datenstapel. Das Wort ist eine unmittelbare Version von CHAR. Mit könnte die Beispieldefinition für EMIT-Q folgendermaßen umgeschrieben werden:

: EMIT-Q Q EMIT ; \ Emit the single character 'Q'