mirror of
https://github.com/forth-ev/VolksForth.git
synced 2024-11-29 21:49:17 +00:00
13105 lines
348 KiB
Plaintext
13105 lines
348 KiB
Plaintext
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Handbuch zum PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
Die Autoren haben sich in diesem Handbuch um eine vollständige und akkurate
|
|||
|
Darstellung bemüht. Die im Handbuch enthaltenen Informationen dienen jedoch
|
|||
|
allein der Produktbeschreibung und sind nicht als zugesicherte Eigenschaften im
|
|||
|
Rechtssinne aufzufassen. Etwaige Schadensersatzansprüche gegen die Autoren gleich
|
|||
|
aus welchem Rechtsgrund, sind ausgeschlossen. Es wird keine Gewähr übernommen,
|
|||
|
daß die angegebenen Verfahren frei von Schutzrechten Dritter sind.
|
|||
|
|
|||
|
Alle Rechte vorbehalten. Ein Nachdruck, auch auszugsweise, ist nur zulässig mit
|
|||
|
Einwilligung der Autoren und genauer Quellenangabe sowie Einsendung eines Beleg-
|
|||
|
exemplars an die Autoren.
|
|||
|
|
|||
|
(c) 1985,1986 Bernd Pennemann, Georg Rehfeld, Dietrich Weineck
|
|||
|
(c) 1988,1989 Klaus Schleisiek, Jörg Staben, Klaus Kohl
|
|||
|
|
|||
|
- Mitglieder der FORTH Gesellschaft e.V. -
|
|||
|
|
|||
|
Unser Dank gilt der gesamten FORTH-Gemeinschaft,
|
|||
|
insbesondere Charles Moore, Michael Perry und Henry Laxen
|
|||
|
|
|||
|
1. Auflage Mai 1989
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Inhaltsverzeichnis
|
|||
|
|
|||
|
1.1 Interpreter und Compiler
|
|||
|
1.2 Warum stellen wir dieses System frei zur Verfügung ?rereeeeneenesnsnnenesennnnnennnen 9
|
|||
|
1.3 Warum soll man in volksFORTH83 programmieren ?
|
|||
|
1.4 Hinweise des Lektors
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
2.„Einstieg ins. VOIRSKORTHL........0042 200200 deennn sans aan em ene ee anne sense Tnngt oe speed Reaasen 12
|
|||
|
2E1 3DIEISVSTEMAISKELDE eur veransen kann scene nase rerre en ersatz ana Fiese sera este 12
|
|||
|
22 "DIE. Oberflächerens. aussen nenn urn ee Mengen ae rear 14
|
|||
|
2.3 Arbeiten mit Programm- und Datenfiles........csessesensensensunsnnnnnennnnnnnnnnnnsnnenen 15
|
|||
|
|
|||
|
2.4 Der Editor
|
|||
|
|
|||
|
|
|||
|
|
|||
|
2.4.3 Tastenbelegung. des. BAItORS ....0rsccauocnnenunenc Aifeihnen reset er haree hecharnsen
|
|||
|
|
|||
|
32:4,4 BEISDIEISOES)..veeneaseeee sone anessennaareneshannesu taten ne ee
|
|||
|
|
|||
|
2:4,5 Compilieren im. Editor. ciesseressunnene re Tree ee
|
|||
|
2.5 Erstellen einer Applikation ......eeessseeenneenennene Se.
|
|||
|
2.6 Das Erstellen eines eigenen FORTH-Systems ...e.eenseneneennennsnnnnnensennnnnnnensnnsnnen
|
|||
|
257 Ausdrucken VON SCIHEENS!esnuerucnenueasernaenennn scene ET FE nee
|
|||
|
2.8 Druckeranpassung ....nennenncen: Re ET ER E 26
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
3.2 Arithmetische Funktionen ... 5
|
|||
|
3:3 Logik-und Vergleiche... une te er ee ee
|
|||
|
9.4, 92Bit=Wörtenesensssessunnassnens een een hear are Tele ran Hebandsae Türe tEr ea ige
|
|||
|
3.5 Stack-Operationen ....unseneeeeeener Ar
|
|||
|
8:8.1,2Datenstack=0peratlonen .......crenseneennenanenenenen en ee
|
|||
|
3.5.2 Returnstack-Operationen
|
|||
|
|
|||
|
4. Kontrollstrukturen
|
|||
|
|
|||
|
4.1 Programm-Strukturen .............
|
|||
|
4.2 Worte zur Fehlerbehandlung
|
|||
|
4.3, Eallunterscheidung.inRORTH. u. MEER ee ,
|
|||
|
4.3.1. Strukturierung mit IE ELSE - THENY/#ENDIEN....Aelenernssneoensensnoenenee 47
|
|||
|
4.9.2. Behandlung einer. CASE --Sittuatlonmeimi.M.. Tee ersetehee hend leben 5ß
|
|||
|
4.3,2.1.Strukturelles. CASE... EEE NTR A EEEN es 50
|
|||
|
4.3:2.27Bositionelles-CASE rn. ve ee ee Ale 54
|
|||
|
4,.3,2.3 Bingatzmöglichkelten ungen en nsnrk 57
|
|||
|
AFASREKULSTONL. 2 0naceunn ser seen ee ae Tee rn Ehe alone nenne een nen nie ne none een 59
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Inhaltsverzeichnis Zn 2]
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-G
|
|||
|
|
|||
|
esellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5. Ein / Ausgabe im. VoOlkSEORTH. auneean
|
|||
|
|
|||
|
5.1
|
|||
|
5.2
|
|||
|
5.3
|
|||
|
5.4
|
|||
|
5.5
|
|||
|
5.6
|
|||
|
5.7
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein- / Ausgabebefehle im volksFORTH
|
|||
|
Ein» / Ausgaben über Ternmina) een
|
|||
|
Drucker-Ausgaben ..............-
|
|||
|
Ein- / Ausgabe von Zahlen
|
|||
|
Bin= / Ausgabe über einen Port au — 67
|
|||
|
Eingabe von Zeichen...
|
|||
|
Ausgabe’ von Zeichen... neu nenn en
|
|||
|
|
|||
|
|
|||
|
|
|||
|
6: Strings ne een
|
|||
|
|
|||
|
6.1
|
|||
|
6.2
|
|||
|
|
|||
|
6.3
|
|||
|
6.4
|
|||
|
|
|||
|
7. Umgan
|
|||
|
7.1
|
|||
|
UR
|
|||
|
7.3
|
|||
|
7.4
|
|||
|
7.5
|
|||
|
7.6
|
|||
|
7.7
|
|||
|
7.8
|
|||
|
7.9
|
|||
|
|
|||
|
8. Speich
|
|||
|
81
|
|||
|
8.2
|
|||
|
|
|||
|
BERIRE EIS TIER nen eat een
|
|||
|
Suche nach Strings .....
|
|||
|
6.2.1 In normalem Fließtext
|
|||
|
8:2.2, IN DIensonar
|
|||
|
|
|||
|
®-terminated Strings ....enererensnensnnnnensnnnnnnenensnnnnnnsnnsnsensenenssntnonssssnsunsnssenrnenne
|
|||
|
|
|||
|
Konyvertlerungen: Strings -—— Zahlen eo ann 8
|
|||
|
6.4.1 String in Zahlen wandeln... ni
|
|||
|
64.2 Zahlen. in’ Strineswandeln a... Dane
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
e mit Datelen au ara neun kan Kuss
|
|||
|
Pfad-Unterstützung „een teen es nee era thehi ee tnnture
|
|||
|
DOS-Befehle
|
|||
|
Block-orientierte Dateien
|
|||
|
Verwaltung: der-Block=Puffer.. u... 0 dene aan 97
|
|||
|
Index-, Verschiebe- und Kopierfunktionen für Block-Files ........cnereen 99
|
|||
|
PEBsörlentierte Dateien. run una RT es erele
|
|||
|
|
|||
|
HANDLE-orientierte Dateien .... 2
|
|||
|
Direkt=Zugriff uf Diskatien an
|
|||
|
Eehlerbenandlunge..eerssien era ans een ee
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
eroperationen...nn anni est ehe ranlasi rasieren 187
|
|||
|
Speicheroperationen im 16-Bit-Adressraum.... i
|
|||
|
Segmentierte :Speicheröperatlonen seinen un ı1l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
9. Datentypen ame u urn 113
|
|||
|
|
|||
|
9.1
|
|||
|
9.2
|
|||
|
|
|||
|
Ein- ünd.zweidimensionale; Belder.. „tn nenne 118
|
|||
|
Methoden der objektorientierte Programmierung ......eresenessesseeeneneenennnensnn en 121
|
|||
|
|
|||
|
18. Manipulieren des Systemverhalten..................zuscsssssesssnonensesnenenennennneenensnenennenanee
|
|||
|
|
|||
|
19.1
|
|||
|
10.2
|
|||
|
19.3
|
|||
|
19.4
|
|||
|
18.5
|
|||
|
10.6
|
|||
|
|
|||
|
Pätchen von EORTH-Befehlen....... Minen sn
|
|||
|
Verwendung von DEFER-Wörtern u
|
|||
|
Neudefinition von. Befehlen... Anke ARE nase
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Vektoren im volksFORTH83 . ar
|
|||
|
GIOSSAT nannten nen ee een Ersenenshainelleneiee
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Inhaltsverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V, PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
11-2Vokabular=Struktüf .....cssnessconcsen nenn ars a rennen nahen anne de
|
|||
|
11.1 Die Suchreihenfolge
|
|||
|
11.2 Glossar
|
|||
|
|
|||
|
|
|||
|
|
|||
|
12. Dietionary-Strüktür .....uesseesonsswsanesesneenn een nun nern Irre ann engen dee TRERBE RER Bnsnanene nen 136
|
|||
|
12.1 AUfdau cn nn nee ee rin Tee EEE 136
|
|||
|
12.2 OS. una een a er 1408
|
|||
|
|
|||
|
13.,Der_ HRAP...... u. ceneswasnussnnssiensesscsiassreegteg age enssgnna sera get eeee sinne 144
|
|||
|
|
|||
|
14. Die Ausführung von FORTH-Worten.i......0..00.0-s00220sreBeeraesse sonne sneenasssnessaennessssen nen 146
|
|||
|
14.1 Der. Aufbau ‚des Adressinterprneters.........ernsenenenesanaseesnenitennnte nennen 146
|
|||
|
14.2 Die Funktion des Adressinterpreters ....reeesesenssenenennenensnnnnnsnnnnnnnennnunsn sun nee 146
|
|||
|
14,3. VEerBchiadene IMMEINATE = WOLTE enteo ing se rnen een serehre na sn unernene 148
|
|||
|
14454. Die’Does>=struktun. an ersten ee Er erunnenessesantineerennnonenenens 149
|
|||
|
|
|||
|
14.5 Glossar
|
|||
|
|
|||
|
|
|||
|
|
|||
|
15. Der Assembler
|
|||
|
VENIMReEISTErDEICRUN GM een erg ennenee teens
|
|||
|
15.2 Registeroperationen
|
|||
|
15.3 Besonderheiten im volksFORTH83
|
|||
|
TOTANGIOSSATIN N nee ee ee EEE ent lenscnses arattene
|
|||
|
15.5 Kontrollstrukturen im Assembler
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
15.6 Beispiele aus dem VolKSFORTH..........2022ecrs0ueonnnnenansseenesssnesenennsnersenundanennnne
|
|||
|
16. DerXMultitasker. .............. nen ee area nun dee een tens teuer here 165
|
|||
|
|
|||
|
16.1 Implementatlon. er. ne en een meer iginennanenenn nee 166
|
|||
|
|
|||
|
236.2.Semaphore UNd-LOcCK"....:. 6 EEE anne 167
|
|||
|
|
|||
|
16.3 Glossar
|
|||
|
|
|||
|
|
|||
|
|
|||
|
17..Debugging-Töchniken... .zaszeseeszessessuscsugassnsssenganngssanessehea teren keikderkennesannen 174
|
|||
|
IKUNMDER BRACH euere ne nannten nein nee ere een 174
|
|||
|
17.2 Debüp... 2 IE RE N ee LITT 178
|
|||
|
|
|||
|
172.2>16Beispiel:!" EXAMPEE.2n.. MIR a ee ent: 178
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
17.2.2 NEST und UNNEST
|
|||
|
17:37Stacksichemneilll....... uses se ea een
|
|||
|
17.4 Aufrufgeschichte
|
|||
|
IT DU en nn en ER NIRERETTETE
|
|||
|
17.6 Dekompiler
|
|||
|
17.7 Glossar
|
|||
|
|
|||
|
118., BEPTITKE..... ncenseeeeuge need seen a aan ea renne no gene nee innen abe enernsen nee ee
|
|||
|
18.1 Entscheidungskriterien
|
|||
|
18.2 Definition der Begriffe
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Inhaltsverzeichnis = Su
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
1. Prolog
|
|||
|
|
|||
|
volksFORTH83 ist eine Sprache, die in verschiedener Hinsicht ungewöhnlich ist.
|
|||
|
Denn FORTH selbst ist nicht nur eine Sprache, sondern ein im Prinzip grenzenloses
|
|||
|
Programmiersystem. Eines der Hauptmerkmale des Programmiersystems FORTH ist
|
|||
|
seine Modularität. Diese Modularität wird durch die kleinste Einheit eines FORTH-
|
|||
|
Systems, das WORT, gewährleistet.
|
|||
|
|
|||
|
In FORTH werden die Begriffe Prozedur, Routine, Programm, Definition und Befehl
|
|||
|
alle gleichbedeutend mit Wort gebraucht. FORTH besteht also, wie jede andere na-
|
|||
|
türliche Sprache auch, aus Wörtern.
|
|||
|
|
|||
|
Diese FORTH-Worte kann man als bereits kompilierte Module betrachten, wobei
|
|||
|
immer ein Kern aus einigen hundert Worten durch eigene Worte erweitert wird.
|
|||
|
Diese Worte des Kerns sind in einem FORTH83-Standard festgelegt und stellen
|
|||
|
sicher, daß Standard-Programme ohne Änderungen auf dem jeweiligen FORTH-System
|
|||
|
lauffähig sind. -
|
|||
|
|
|||
|
Ungewöhnlich ist, daß der Programmtext des Kerns selbst ein FORTH-Programm ist,
|
|||
|
im Gegensatz zu anderen Programmiersprachen, denen ein Maschinensprach-Pro-
|
|||
|
gramm zugrunde liegt. Aus diesem Kern wird durch ein besonderes FORTH-Programm,
|
|||
|
den MetaCompiler, das lauffähige KERNEL.COM erzeugt:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
MetaCompiler
|
|||
|
|
|||
|
| Kernel.scr ===) | Kernel.com
|
|||
|
|
|||
|
Wie fügt man nun diesem lauffähigen Kern eigene Worte hinzu?
|
|||
|
Das Kompilieren der Worte wird in FORTH mit COLON ":" eingeleitet und mit
|
|||
|
SEMICOLON ";" abgeschlossen:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
erwartet bei der Ausführung einen Namen und ordnet diesem Namen
|
|||
|
alle nachfolgenden Wörter zu.
|
|||
|
|
|||
|
beendet diese Zuweisung von Wörtern an den Namen und stellt das
|
|||
|
neue Wort unter diesem Namen für Aufrufe bereit.
|
|||
|
|
|||
|
1.1 Interpreter und Compiler
|
|||
|
|
|||
|
Ein klassisches FORTH-System stellt immer sowohl einen Interpreter als auch einen
|
|||
|
Compiler zur Verfügung. Nach der Einschaltmeldung oder einem Druck auf die <CR>-
|
|||
|
Taste wartet der FORTH-Interpreter mit dem FORTH-typischen "ok" auf Ihre Ein-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
rm Prolog
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
gabe. Sie können ein oder mehrere Befehlswörter in eine Zeile schreiben. volks-
|
|||
|
FORTH beginnt erst nach einem Druck auf die RETURN-Taste <CR> mit seiner Ar-
|
|||
|
beit, indem es der Reihe nach jeden Befehl in der Eingabezeile abarbeitet. Dabei
|
|||
|
werden Befehlsworte durch Leerzeichen begrenzt. Der Delimiter (Begrenzer) für
|
|||
|
FORTH-Prozeduren ist also das Leerzeichen, womit auch schon die Syntax der
|
|||
|
Sprache FORTH beschrieben wäre.
|
|||
|
|
|||
|
Der Compiler eines FORTH-Systems ist also Teil der Interpreteroberfläche. Es gibt
|
|||
|
daher keinen Compiler-Lauf zur Erstellen des Programmtextes wie in anderen Com-
|
|||
|
piler-Sprachen, sondern der Interpreter wird mit allen zur Problemlösung notwen-
|
|||
|
digen Worten als Anwenderprogramm abgespeichert.
|
|||
|
|
|||
|
Auch : (COLON) und ; (SEMICOLON) sind kompilierte Worte, die aber für das Sys-
|
|||
|
tem den Compiler ein- und ausschalten. Da sogar die Worte, die den Compiler
|
|||
|
steuern, "normale" FORTH-Worte sind, fehlen in FORTH die in anderen Sprachen
|
|||
|
üblichen Compiler-Optionen oder Compiler-Schalter. Der FORTH-Compiler wird mit
|
|||
|
FORTH-Worten gesteuert.
|
|||
|
|
|||
|
Der Aufruf eines FORTH-Wortes erfolgt über seinen Namen ohne ein explizites CALL
|
|||
|
oder GOSUB. Dies führt zum FORTH-typischen Aussehen der Wortdefinitionen:
|
|||
|
|
|||
|
: <name)
|
|||
|
<wort1) <wort2) <wort3) ... ;
|
|||
|
|
|||
|
Die Standard-Systemantwort in FORTH ist das berühmte "ok". Ein Anforderungszei-
|
|||
|
chen wie 'A>' bei DOS oder ']' beim guten APPLE II gibt es nicht! Das kann dazu
|
|||
|
|
|||
|
führen, daß nach einer erfolgreichen Aktion der Bildschirm völlig leer bleibt; getreu
|
|||
|
der Devise:
|
|||
|
|
|||
|
Keine Nachrichten sind immer gute Nachrichten !
|
|||
|
|
|||
|
Und - ungewöhnlicherweise - benutzt FORTH die sogenannte Postfix notation (UPN)
|
|||
|
vergleichbar den HP-Taschenrechnern, die in machen Kreisen sehr beliebt sind. Das
|
|||
|
bedeutet, FORTH erwartet immer erst die Argumente, dann die Aktion. Statt
|
|||
|
3+2 und (5 +5) * 10
|
|||
|
heißt es 23% und 9537719 %
|
|||
|
|
|||
|
Da die Ausdrücke von links nach rechts ausgewertet werden, gibt es in FORTH
|
|||
|
keine Klammern.
|
|||
|
|
|||
|
Stack
|
|||
|
|
|||
|
Ebenso ungewöhnlich ist, daß FORTH nur ausdrücklich angeforderte Aktionen aus-
|
|||
|
führt: Das Ergebnis Ihrer Berechnungen bleibt solange in einem speziellen Spei-
|
|||
|
cherbereich, dem Stack, bis es mit einem Ausgabebefehl (meist . ) auf den Bild-
|
|||
|
schirm oder dem Drucker ausgegeben wird.
|
|||
|
|
|||
|
Da die FORTH-Worte den Unterprogrammen und Funktionen anderer Programmier-
|
|||
|
sprachen entsprechen, benötigen sie gleichfalls die Möglichkeit, Daten zur Verar-
|
|||
|
beitung zu übernehmen und das Ergebnis abzulegen. Diese Funktion übernimmt der
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Prolog = 70
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
STACK. In FORTH werden Parameter für Prozeduren selten in Variablen abgelegt,
|
|||
|
sondern meist über den Stack übergeben.
|
|||
|
|
|||
|
Assembler
|
|||
|
|
|||
|
Innerhalb einer FORTH-Umgebung kann man sofort in der Maschinensprache des
|
|||
|
Prozessors programmieren, ohne den Interpreter verlassen zu müssen. Assembler-
|
|||
|
Definitionen sind den FORTH-Programmen gleichwertige FORTH-Worte.
|
|||
|
|
|||
|
Vokabular-Konzept
|
|||
|
|
|||
|
Das volksFORTH verfügt über eine erweiterte Vokabular-Struktur, die von W. Rags-
|
|||
|
dale vorgeschlagen wurde. Dieses Vokabular-Konzept erlaubt das Einordnen der
|
|||
|
FORTH-Worte in logische Gruppen.
|
|||
|
|
|||
|
Damit können Sie notwendige Befehle bei Bedarf zuschalten und nach Gebrauch
|
|||
|
wieder wegschalten. Darüberhinaus ermöglichen die Vokabulare den Gebrauch glei-
|
|||
|
cher Namen für verschiedene Worte, ohne in einen Namenskonflikt zu kommen. Eine
|
|||
|
im Ansatz ähnliche Vorgehensweise bietet das UNIT-Konzept moderner PASCAL-
|
|||
|
oder MODULA-Compiler.
|
|||
|
|
|||
|
FORTH-Dateien
|
|||
|
|
|||
|
FORTH verwendet oftmals besondere Dateien für seine Programme. Dies ist his-
|
|||
|
torisch begründet und das Erbe einer Zeit, als FORTH noch sehr oft Aufgaben des
|
|||
|
Betriebssystems übernahm. Da gab es ausschließlich FORTH-Systeme, die den
|
|||
|
Massenspeicher vollständig selbst ohne ein DOS verwalteten und dafür ihre eigenen
|
|||
|
Dateistrukturen benutzten.
|
|||
|
|
|||
|
Diese Dateien sind sogenannte Blockfiles und bestehen aus einer Aneinanderreihung
|
|||
|
von 1824 Byte großen Blöcken. Ein solcher Block, der gerne SCREEN genannt wird,
|
|||
|
ist die Grundlage der Quelltext-Bearbeitung in FORTH.
|
|||
|
|
|||
|
Allerdings können mit dem volks4TH auch Dateien bearbeitet werden, die im Datei-
|
|||
|
format des MS-DOS vorliegen, sog. "Stream Files".
|
|||
|
|
|||
|
Generell steht hinter jeder Sprache ein bestimmtes Konzept, und nur mit Kenntnis
|
|||
|
dieses Konzeptes ist möglich, eine Sprache effizient einzusetzen. Das Sprachkonzept
|
|||
|
von FORTH wird beschrieben in dem Buch "In FORTH denken" von Leo Brodie
|
|||
|
(Hanser Verlag).
|
|||
|
|
|||
|
Einen ersten Eindruck vom volksFORTH83 und von unserem Stolz darüber soll
|
|||
|
dieser Prolog vermitteln. volksFORTH83 ist ein "Public-Domain"-System, bei dessen
|
|||
|
Leistungsfähigkeit sich die Frage stellt:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 4 Prolog
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
1.2 Warum stellen wir dieses System frei zur Verfügung ?
|
|||
|
|
|||
|
Die Verbreitung, die die Sprache FORTH gefunden hat, war wesentlich an. die
|
|||
|
Existenz von figFORTH geknüpft. Auch figFORTH ist ein public domain Programm,
|
|||
|
d.h. es darf weitergegeben und kopiert werden. Trotzdem haben sich bedauerlicher-
|
|||
|
weise verschiedene Anbieter die einfache Adaption des figFORTH an verschiedene
|
|||
|
Rechner sehr teuer bezahlen lassen.
|
|||
|
|
|||
|
Das im Jahr 1979 erschienene figFORTH ist heute nicht mehr so aktuell, weil mit
|
|||
|
der weiteren Verbreitung von Forth eine Fülle von eleganten Konzepten entstanden
|
|||
|
sind, die z.T. in den Forth83-Standard Eingang gefunden haben. Daraufhin wurde
|
|||
|
von Laxen und Perry das F83 geschrieben und als Public Domain verbreitet. Dieses
|
|||
|
freie 83er-Standard-FORTH mit seinen zahlreichen Utilities ist recht komplex und
|
|||
|
wird auch nicht mit Handbuch geliefert.
|
|||
|
|
|||
|
Wir haben ein neues Forth für verschiedene Rechner entwickelt. Das Ergebnis ist
|
|||
|
das volksFORTH83, eines der besten Forth-Systeme, die es gibt. Das volksFORTH
|
|||
|
soll an die Tradition der oben genannten Systeme, insbesondere des F83, anknüpfen
|
|||
|
und die Verbreitung der Sprache FORTH fördern.
|
|||
|
|
|||
|
volksFORTH wurde unter dem Namen ultraFORTH zunächst für den C64 geschrieben.
|
|||
|
Nach Erscheinen der Rechner der Atari ST-Serie entschlossen wir uns, auch für sie
|
|||
|
ein volksFORTH83 zu entwickeln. Die erste ausgelieferte Version 3.7 war, was
|
|||
|
Editor und Massenspeicher betraf, noch stark an den C64 angelehnt. Sie enthielt
|
|||
|
jedoch schon einen verbesserten Tracer, die GEM-Bibliothek und die anderen Tools
|
|||
|
für den ST. Der nächste Schritt bestand in der Einbindung der Betriebssystem-
|
|||
|
Files. Nun konnten Quelltexte auch vom Desktop und mit anderen Utilities verar-
|
|||
|
beitet werden. Die dritte Adaption des volksFORTH entstand für die CP/M-Rechner
|
|||
|
(80880-Prozessoren), wobei speziell für den Schneider CPC auch die Grafikfähigkeit
|
|||
|
unterstützt wird. Zuletzt wurde das volksFORTH für die weitverbreiteten Rechner
|
|||
|
der IBM PC-Serie angepaßt. Mit der jetzt ausgelieferten Version 3.81 ist das
|
|||
|
volksFORTH vollständig.
|
|||
|
|
|||
|
1.3 Warum soll man in volksFORTH83 programmieren ?
|
|||
|
|
|||
|
Das volksFORTH83 ist ein ausgesprochen leistungsfähiges und kompaktes Werkzeug.
|
|||
|
|
|||
|
Durch residente Runtime-library, Compiler, Editor und Debugger sind die ermüden-
|
|||
|
den ECLG-Zyklen ("Edit, Compile, Link and Go") überflüssig. Der Code wird Modul’
|
|||
|
für Modul entwickelt, kompiliert und getestet.
|
|||
|
|
|||
|
Der integrierte Debugger ist die perfekte Testumgebung für Worte. Es gibt keine
|
|||
|
riesigen Hexdumps oder Assemblerlistings, die kaum Ähnlichkeit mit dem Quelltext
|
|||
|
haben.
|
|||
|
|
|||
|
Ein anderer wichtiger Aspekt ist das Multitasking. So wie man ein Programm in
|
|||
|
einzelne, unabhängige Module oder Worte aufteilt, so sollte man es auch in ein-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Prolog 9
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
zelne, unabhängige Prozesse aufteilen können. Das ist in den meisten Sprachen
|
|||
|
nicht möglich. Das volksFORTH83 besitzt einen einfachen, aber leistungsfähigen
|
|||
|
Multitasker.
|
|||
|
|
|||
|
Schließlich besitzt das volksFORTH83 noch eine Fülle von Details, über die andere
|
|||
|
FORTH-Systeme nicht verfügen:
|
|||
|
|
|||
|
aa Es benutzt an vielen Stellen Vektoren und sog. deferred Worte, die
|
|||
|
eine einfache Umgestaltung des Systems für verschiedene Gerätekon-
|
|||
|
figurationen ermöglichen.
|
|||
|
|
|||
|
Es besitzt einen Heap für "namenlose" Worte oder für Code, der nur
|
|||
|
zeitweilig benötigt wird.
|
|||
|
|
|||
|
- Der Blockmechanismus ist so schnell, daß er auch sinnvoll für die
|
|||
|
Bearbeitung großer Datenmengen, die in Files vorliegen, eingesetzt
|
|||
|
werden kann.
|
|||
|
|
|||
|
= Das System umfaßt Tracer, Decompiler, Multitasker, Assembler,
|
|||
|
Editor, Printer-interface ...
|
|||
|
|
|||
|
Das volksFORTH83 erzeugt, verglichen mit anderen FORTH-Systemen, relativ
|
|||
|
schnellen Code, der aber langsamer als der anderer Compilersprachen ist.
|
|||
|
|
|||
|
Mit diesem Handbuch soll die Unterstützung des volksFORTH83 noch nicht Zuende
|
|||
|
sein. Die FORTH Gesellschaft e.V., ein gemeinnütziger Verein, bietet dafür die
|
|||
|
Plattform. Sie gibt die Vereins-FORTH-Zeitschrift "VIERTE DIMENSION" heraus und
|
|||
|
betreibt den FORTH-Tree, eine ungewöhnliche, aber sehr leistungsfähige Mailbox.
|
|||
|
|
|||
|
Die im Frühsommer 1989 aktuelle Adressen:
|
|||
|
FORTH-Büro:
|
|||
|
|
|||
|
FORTH Gesellschaft e.V.
|
|||
|
Postfach 1116
|
|||
|
|
|||
|
8944 Unterschleißheim
|
|||
|
Tel. 0889/3173784
|
|||
|
|
|||
|
volksFORTH-Vertrieb:
|
|||
|
|
|||
|
Michael & Klaus Kohl
|
|||
|
Pestalozzistr. 69
|
|||
|
8985 Mering
|
|||
|
|
|||
|
Tel. 88233/30524
|
|||
|
|
|||
|
|
|||
|
|
|||
|
-10 - Prolog
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
1.4 Hinweise des Lektors
|
|||
|
|
|||
|
Diesem Handbuch zum PC-volksFORTH83 ist sowohl als Nachschlagewerk als auch
|
|||
|
als Lehrbuch für FORTH (speziell volksFORTH) gedacht. Deshalb handelt es sich
|
|||
|
nicht, wie bei den anderen volksFORTH-Handbücher, um eine Auflistung des Voka-
|
|||
|
bulars. Statt dessen wird mit ausführlichen Beschreibungen und Programmbeispielen
|
|||
|
in vielen Kapiteln die Möglichkeiten des FORTH-Systems erklärt. Ergänzt werden
|
|||
|
die einzelnen Kapitel jeweils um Wortbeschreibungen der darin vorkommenden Be-
|
|||
|
fehle (Glossar). Sollten bestimmte Befehle gesucht werden, so ist die Seitennummer
|
|||
|
aus dem ausführlichen Index zu entnehmen.
|
|||
|
|
|||
|
Zur Unterscheidung von Beschreibung, FORTH-Worten, Programm-Eingaben und
|
|||
|
__-ausgaben wird mit unterschriftlichen Schrifttypen gearbeitet:
|
|||
|
|
|||
|
seschreibungen erfolgen in Proportionalschrift mit Randausgleich.
|
|||
|
FORTH-Befehle werden im Text durch Fettschrift hervorgehoben.
|
|||
|
Eingaben und
|
|||
|
|
|||
|
Programnlistings verwenden die nichtproportionale Schriftart Courier.
|
|||
|
Ausgaben des FORTH-Interpreter/Compiler sind unterstrichen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Prolog en
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
2. Einstieg ins volksFORTH
|
|||
|
|
|||
|
Damit Sie sofort beginnen können, wird in diesem Kapitel beschrieben,
|
|||
|
- wie man das System startet
|
|||
|
- wie man sich im System zurechtfindet
|
|||
|
- wie man ein fertiges Anwendungsprogramm erstellt
|
|||
|
- wie man ein eigenes Arbeitssystem zusammenstellt
|
|||
|
|
|||
|
2.1 Die Systemdiskette
|
|||
|
|
|||
|
Zu Ihrem Handbuch haben Sie eine Diskette erhalten. Fertigen Sie auf jeden Fall
|
|||
|
mit dem DOS-Befehl diskcopy eine Sicherheitskopie dieser Diskette an. Die Gefahr
|
|||
|
eines Datenverlustes ist groß, da FORTH Ihnen in jeder Hinsicht freie Hand läßt -
|
|||
|
auch beim versehentlichen Löschen Ihrer Systemdisketten !!
|
|||
|
|
|||
|
Die Diskette, auf der Ihr volKsFORTH-System ausgeliefert wird, enthält folgende
|
|||
|
Dateien:
|
|||
|
|
|||
|
INSTALL BAT ist ein Installationsprogramm, das volks4TH auf einem
|
|||
|
angegebenen Laufwerk einrichtet.
|
|||
|
|
|||
|
PKXARC COM ist ein Dienstprogramm zum Komprimieren und De-
|
|||
|
komprimieren von Dateien.
|
|||
|
|
|||
|
KERNEL COM
|
|||
|
|
|||
|
MINIMAL COM
|
|||
|
|
|||
|
VOLKS4TH COM diese drei COM-Files sind drei volksFORTH-Systeme
|
|||
|
in verschiedenen Ausbaustufen.
|
|||
|
|
|||
|
FORTHI ARC
|
|||
|
|
|||
|
FORTH2 ARC diese beiden ARC-Dateien enthalten die Quelltexte
|
|||
|
des gesamten FORTH-Systems, müssen aber erst von
|
|||
|
PKXARC entpackt werden.
|
|||
|
|
|||
|
VOLKS4TH DOC ist eine ergänzende Dokumentation, die Nachträge
|
|||
|
enthält.
|
|||
|
|
|||
|
READ ME enthält zusätzliche wichtige Hinweise.
|
|||
|
|
|||
|
Wenn Sie Ihr System, wie in der Datei READ.ME auf der Diskette beschrieben,
|
|||
|
idealerweise auf einer Festplatte installiert haben, finden Sie deutlich mehr Files
|
|||
|
|
|||
|
|
|||
|
|
|||
|
-.12.= Einstieg ins volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
vor. Ein Zeichen für die Platzersparnis durch das Datei-Kompressionsprogramm
|
|||
|
PKARC.
|
|||
|
|
|||
|
VOLKS4TH COM als Ihr komplettes Arbeitsssystem enthält resident
|
|||
|
das Fileinterface, den Editor, den Assembler und von
|
|||
|
Ihnen eingefügte Werkzeuge (tools).
|
|||
|
|
|||
|
MINIMAL COM ist eine Grundversion, die oft benötigte Systemteile
|
|||
|
enthält. Diese ist notwendig, da FORTH-Systeme all-
|
|||
|
gemein nicht über einen Linker verfügen, sondern
|
|||
|
ausgehend vom Systemkern die zur Problemlösung
|
|||
|
notwendigen Einzelprogramme schrittweise hinzukompi-
|
|||
|
liert werden.
|
|||
|
|
|||
|
KERNEL COM ist eine Grundversion, die nur den Sprachkern ent-
|
|||
|
hält. Damit können Sie eigene FORTH-Versionen mit
|
|||
|
z.B. einem veränderten Editor zusammenstellen und
|
|||
|
dann mit SAVESYSTEM <name> als fertiges System
|
|||
|
abspeichern. In der gleichen Art können Sie auch fer-
|
|||
|
tige Applikationen herstellen, denen man ihre FORTH-
|
|||
|
Abstammung nicht mehr ansieht.
|
|||
|
|
|||
|
KERNEL SCR enthält die Quelltexte des Sprachkerns. Eben dieser
|
|||
|
Quelltext ist mit einem Target-Compiler kompiliert
|
|||
|
worden und entspricht exakt dem KERNEL.COM. Sie
|
|||
|
können sich also den Compiler ansehen, wenn Sie
|
|||
|
wissen wollen, wie das volksFORTH83 funktioniert !
|
|||
|
|
|||
|
VOLKS4TH Sys enthält einen Ladeblock (Block 1), der alle Teile
|
|||
|
kompiliert, die zu Ihrem Arbeitssystem gehören. Mit
|
|||
|
diesem Loadscreen ist aus KERNEL.COM das File
|
|||
|
VOLKS4TH.COM zusammengestellt worden.
|
|||
|
|
|||
|
EXTEND SCR enthält Erweiterungen des Systems. Hier tragen Sie
|
|||
|
auch persönliche Erweiterungen ein.
|
|||
|
|
|||
|
CED SCR enthält den Quelltext des Kommandozeilen Editors, mit
|
|||
|
dem die Kommandozeile des Interpreters editiert
|
|||
|
werden kann. Soll dieser CED ins System eingefügt
|
|||
|
werden, so ist diese Datei mit
|
|||
|
|
|||
|
include ced.scr
|
|||
|
savesystem volks4TH.com
|
|||
|
ins volksFORTH einzukompilieren.
|
|||
|
|
|||
|
HISTORY wird von CED angelegt und enthält die zuletzt einge-
|
|||
|
gebenen Kommandos.
|
|||
|
|
|||
|
STREAM SCR enthält zwei oft gewünschte Dienstprogramme:
|
|||
|
Die Umwandlung von Text-Dateien (stream files) in
|
|||
|
Block-Dateien (block files) und zurück.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Einstieg ins volksFORTH er 138-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DISASM SCR enthält den Dis-Assembler, der - wie beim CED be-
|
|||
|
schrieben - ins System eingebaut werden kann.
|
|||
|
|
|||
|
2.2 Die Oberfläche
|
|||
|
|
|||
|
Wenn Sie VOLKS4TH von der DOS-Ebene starten, meldet sich volksFORTH83 mit
|
|||
|
einer Einschaltmeldung, die die Versionsnummer rev. <xxxx> enthält.
|
|||
|
|
|||
|
Was Sie nun von vVolksFORTH sehen, ist die Oberfläche des Interpreters. FORTH-
|
|||
|
Systeme und damit auch volksFORTH sind fast immer interaktive Systeme, in denen
|
|||
|
Sie einen gerade entwickelten Gedankengang sofort überprüfen und verwirklichen
|
|||
|
können. Das Auffälligste an der volksFORTH-Oberfläche ist die inverse Statuszeile
|
|||
|
in der unteren Bildschirmzeile, die sich mit status off aus- und mit status on
|
|||
|
wieder einschalten läßt.
|
|||
|
|
|||
|
Diese Statuszeile zeigt von links nach rechts folgende Informationen, wobei ! für
|
|||
|
"oder" steht:
|
|||
|
<218110116> die zur Zeit gültige Zahlenbasis (dezimal)
|
|||
|
|
|||
|
Ss xx) nennt die Anzahl der Zahlenwerte, die zum Verarbei-
|
|||
|
ten bereitliegen "
|
|||
|
|
|||
|
Die <xxxx> nennt den freien Speicherplatz
|
|||
|
|
|||
|
Ser <xx> ist die Nummer des aktuellen Quelltextblocks
|
|||
|
|
|||
|
A:lC: gibt das aktuelle Laufwerk an
|
|||
|
|
|||
|
<name>.<ext> zeigt den Namen der Date, die gerade bearbeitet wird.
|
|||
|
|
|||
|
Dateien haben im MSDOS sowohl einen Namen <name>
|
|||
|
als auch eine dreibuchstabige Kennung, die Extension
|
|||
|
<ext>, wobei auch Dateien ohne Extension angelegt
|
|||
|
werden können.
|
|||
|
|
|||
|
FORTH FORTH FORTH zeigt die aktuelle Suchreihenfolge gemäß dem Voka-
|
|||
|
|
|||
|
bularkonzept.
|
|||
|
Ein Beispiel dafür sind die Assembler-Befehle:
|
|||
|
Diese befinden sich in einem Vokabular namens
|
|||
|
ASSEMBLER und assenmbler words zeigt Ihnen den
|
|||
|
Befehlsvorrat des Assemblers an. Achten Sie bitte auf
|
|||
|
die rechte Seite der Statuszeile, wo jetzt
|
|||
|
|
|||
|
assembler forth forth
|
|||
|
zu sehen ist. Da Sie aber jetzt - noch - keine
|
|||
|
Assembler-Befehle einsetzen wollen, schalten Sie bitte
|
|||
|
mit _ forth die Suchlaufpriorität wieder um. Die
|
|||
|
Statuszeile zeigt wieder das gewohnte
|
|||
|
|
|||
|
forth forth forth.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 144- Einstieg ins volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Zur Orientierung im Arbeitssystem stellt das volksFORTH einige standardkonforme
|
|||
|
Wörter zur Verfügung:
|
|||
|
|
|||
|
words zeigt Ihnen die Befehlsliste von FORTH, die verfügbaren Wörter.
|
|||
|
Diese Liste stoppt bei einem Tastendruck mit der Ausgabe oder
|
|||
|
bricht bei einem <ESC> ab.
|
|||
|
|
|||
|
files zeigt alle im System angelegten logischen Datei-Variablen, die zuge-
|
|||
|
hörigen handle Nummern, Datum und Uhrzeit des letzten Zugriffs
|
|||
|
und ihre entsprechenden physikalischen DOS-Dateien. Eine solche
|
|||
|
FORTH-Datei wird allein durch die Nennung ihres Namens angemel-
|
|||
|
det. Die MSDOS-Dateien im Directory werden mit dir angezeigt.
|
|||
|
|
|||
|
path informiert über eine vollständige Pfadunterstützung nach dem
|
|||
|
MSDOS-Prinzip, allerdings vollkommen unabhängig davon.
|
|||
|
Ist kein Suchpfad gesetzt, so gibt path nichts aus.
|
|||
|
|
|||
|
order beschreibt die Suchreihenfolge in den Befehlsverzeichnissen (Voka-
|
|||
|
bular).
|
|||
|
vocs nennt alle diese Unterverzeichnisse (vocabularies).
|
|||
|
|
|||
|
2.3 Arbeiten mit Programm- und Datenfiles
|
|||
|
|
|||
|
Um überhaupt Programmtexte (Quelltexte) schreiben zu können, brauchen Sie eine
|
|||
|
Datei, die diese Programmtexte aufnimmt. Diese Datei muß zur Bearbeitung ange-
|
|||
|
meldet werden.
|
|||
|
|
|||
|
volksFORTH geht nach dem Systemstart erst einmal von der Datei VOLKS4TH.SYS als
|
|||
|
aktueller Datei aus. VOLKS4TH.SYS ist aber die Steuerdatei, aus der Ihr FORTH-
|
|||
|
System aufgebaut wurde; deshalb deklarieren Sie die Datei, die Sie bearbeiten
|
|||
|
wollen, mit dieser Befehlsfolge:
|
|||
|
|
|||
|
use (name).<(ext>
|
|||
|
|
|||
|
Als Beispiel wird die Datei test.scr mit use test.scr angemeldet.
|
|||
|
|
|||
|
Möchten Sie allerdings eine vollkommen neue Datei für Ihre Programme benutzen, so
|
|||
|
überlegen Sie sich einen Namen <name>, eine Kennung <extension> und eine ver-
|
|||
|
nünftige Größe in KByte. Anschließend geben Sie ein:
|
|||
|
|
|||
|
makefile (name).<ext) <«Größenangabe) more
|
|||
|
|
|||
|
Daraufhin wird die Datei auf dem Laufwerk angelegt und zum Bearbeiten ange-
|
|||
|
meldet. Ein use ist danach nicht mehr notwendig.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Einstieg ins volksFORTH ZelloR =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
2.4 Der Editor
|
|||
|
|
|||
|
Zum Bearbeiten von Quelltext-Blöcken enthalten ältere FORTH-Systeme meist Edi-
|
|||
|
toren, die diesen Namen höchstens zu einer Zeit verdient haben, als man noch die
|
|||
|
Bits einzeln mit Lochzange und Streifenleser an die Hardware übermitteln mußte.
|
|||
|
Demgegenüber bot ein Editor, mit dem man jeweils eine ganze Zeile bearbeiten
|
|||
|
kann, sicher schon einigen Komfort. Da man jedoch mit solch einem Zeileneditor
|
|||
|
heute keinen Staat mehr machen und erst recht nicht mit anderen Sprachen kon-
|
|||
|
kurrieren kann, können Sie im volksFORTH selbstverständlich mit einem komfortab-
|
|||
|
len Fuliscreen-Editor arbeiten.
|
|||
|
|
|||
|
In diesem Editor kann man zwei Dateien gleichzeitig bearbeiten:
|
|||
|
|
|||
|
Eine Vordergrund-Datei, das aktuelle isfille und ein Hintergrundfile fromfile . Da-
|
|||
|
her werden im Editor zwei Dateinamen angezeigt. Das Wort use meldet eine Datei
|
|||
|
automatisch sowohl als isfile als auch als fromfile an, so daß sich Verschiebe-
|
|||
|
und Kopieroperationen nur auf diese eine Datei beziehen.
|
|||
|
|
|||
|
Im Editor wird immer ein FORTH-Screen - also 1824 Bytes - in der üblichen Auf-
|
|||
|
teilung in 16 Zeilen mit je 64 Spalten dargestellt.
|
|||
|
|
|||
|
Es gibt einen Zeichen- und einen Zeilenspeicher. Damit lassen sich Zeichen bzw.
|
|||
|
Zeilen innerhalb eines Screens oder auch zwischen zwei Screens bewegen oder ko-
|
|||
|
pieren. Dabei wird verhindert, daß versehentlich Text verloren geht, indem Funk-
|
|||
|
tionen nicht ausgeführt werden, wenn dadurch Zeichen nach unten oder zur Seite
|
|||
|
aus dem Bildschirm geschoben würden.
|
|||
|
|
|||
|
2.4.1 HELP und VIEW
|
|||
|
|
|||
|
Der Editor unterstützt das 'Shadow-Konzept'. Zu jedem Quelltext-Screen gibt es
|
|||
|
einen Kommentar-Screen. Dieser erhöht die Lesbarkeit von FORTH-Programmen er-
|
|||
|
heblich, Sie wissen ja, guter FORTH-Stil ist selbstdokumentierend ! Auf den
|
|||
|
Tastendruck CRTL-F9 stellt der Editor den Kommentar-Screen zur Verfügung. So
|
|||
|
können Kommentare 'deckungsgleich' zu den Quelltexten angefertigt werden. Dieses
|
|||
|
shadow Konzept wird auch bei dem Wort help ausgenutzt, das zu einem Wort einen
|
|||
|
erklärenden Text ausgibt. Dieses Wort wird so eingesetzt:
|
|||
|
|
|||
|
help (name)
|
|||
|
|
|||
|
HELP zeigt natürlich nur dann korrekt eine Erklärung an, wenn ein entsprechen-
|
|||
|
der Text auf einem shadow screen vorhanden ist.
|
|||
|
|
|||
|
Häufig möchte man sich auch die Definition eines Wortes ansehen, um z.B. den
|
|||
|
Stackkommentar oder die genaue Arbeitsweise nachzulesen. Dafür gibt es das
|
|||
|
Kommando
|
|||
|
|
|||
|
view (name)
|
|||
|
|
|||
|
Damit wird der Screen - und natürlich auch das File - aufgerufen, auf dem
|
|||
|
<name> definiert wurde. Dieses Verfahren ersetzt (fast) einen Decompiler, weil es
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 16, - Einstieg ins volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3,81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
natürlich sehr viel bequemer ist und Ihnen ja auch sämtliche Quelltexte des Sys-
|
|||
|
tems zur Verfügung stehen.
|
|||
|
|
|||
|
Werfen Sie doch bitte mit view u? einen Blick auf das Wort, das Ihnen den Inhalt
|
|||
|
einer Variablen ausgibt. Benutzen Sie
|
|||
|
|
|||
|
fix (name)
|
|||
|
|
|||
|
( engl. = reparieren), so wird zugleich der Editor zugeschaltet, so daß Sie sofort
|
|||
|
gezielt Änderungen im Quelltext vornehmen können. Im Editor werden Sie zuerst
|
|||
|
nach einer Eingabe gefragt "Enter your id:*, die Sie einfach mit dem Druck auf die
|
|||
|
<cr>-Taste beantworten.
|
|||
|
|
|||
|
Dann befinden Sie sich im Editor, mit dem man die Quelltextblöcke bearbeitet. Der
|
|||
|
Cursor steht hinter dem gefundenen Wort u? . Nun können Sie mit PgUp oder
|
|||
|
PgDn in den Screens blättern oder mit <ESC> aus dem Editor zum FORTH zurück-
|
|||
|
kehren.
|
|||
|
|
|||
|
Natürlich müssen für view , fix und help die entsprechenden Files auf den
|
|||
|
Laufwerken 'griffbereit' sein, sonst erscheint eine Fehlermeldung. Die VIEW-Funk-
|
|||
|
tion steht auch innerhalb des Editors zur Verfügung, man kann dann mit dem Tas-
|
|||
|
tendruck CTRL-F das rechts vom Cursor stehende Wort anfordern. Dies ist insbe-
|
|||
|
sondere nützlich, wenn man eine Definition aus einem anderen File übernehmen
|
|||
|
möchte oder nicht mehr sicher ist, wie der Stackkommentar eines Wortes lautet.
|
|||
|
|
|||
|
2.4.2 Öffnen und Editieren eines Files
|
|||
|
|
|||
|
Nun aber zum Erstellen und Ändern von Quelltexten für Programme - eine schöne
|
|||
|
Definition von Editieren. Sie haben sich bestimmt eine Datei test.scr wie oben
|
|||
|
beschrieben mit
|
|||
|
|
|||
|
makefile test.scr 6 more
|
|||
|
|
|||
|
angelegt. Damit haben Sie ein File namens TEST.SCR mit einer Länge von 6 Blöcken
|
|||
|
(6144 Byte = 6KB), bestehend aus den Screens @ bis 5 ; davon sind die Nummern
|
|||
|
® bis 2 für Quelltexte, die anderen für Kommentare bestimmt.
|
|||
|
|
|||
|
Um in den Editor zu gelangen gibt es drei Möglichkeiten:
|
|||
|
‘screen#) edit
|
|||
|
oder <scer#) 1
|
|||
|
ruft den Screen mit der Nummer <scr#> auf. Hat man bereits editiert, ruft
|
|||
|
|
|||
|
v
|
|||
|
|
|||
|
den zuletzt bearbeiteten Screen wieder auf. Dies ist der zuletzt editierte oder aber,
|
|||
|
und das ist sehr hilfreich, derjenige, der einen Abbruch beim Kompilieren verur-
|
|||
|
sacht hat. volksFORTH bricht - wie die meisten modernen Systeme -— bei einem
|
|||
|
Programmfehler während des Kompilierens ab und markiert die Stelle, wo der Fehler
|
|||
|
auftrat. Dann brauchen Sie nur v einzugeben. Der fehlerhafte Screen wird in den
|
|||
|
Editor geladen und der Cursor steht hinter dem Wort, das den Abbruch des Kom-
|
|||
|
pilierens verursachte.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Einstieg ins volksFORTH =-käi-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Als Beispiel soll der Block #1 editiert werden:
|
|||
|
1 edit
|
|||
|
|
|||
|
Sie werden nach der Eingabe des dreibuchstabigen Kürzels gefragt. Dieses Kürzel
|
|||
|
wird dann rechts oben in den Screen eingetragen und gibt die programmer's id
|
|||
|
wieder. Wenn Sie nichts eingeben möchten, drücken Sie bitte nur <cr?). Zum Be-
|
|||
|
nutzen dieser Blöcke gibt es noch einige Vereinbarungen, von denen ich hier zwei
|
|||
|
nennen möchte:
|
|||
|
|
|||
|
1. wird der Block Nr.@ nie !! für Programmtexte benutzt - dort finden
|
|||
|
sich meist Erklärungen und Hinweise zum Programm und zum Autor.
|
|||
|
2. In die Zeile © eines Blockes wird immer ein Kommentar eingetragen,
|
|||
|
|
|||
|
der mit \ (skip line) eingeleitet wird. Dieser Backslash sorgt
|
|||
|
dafür, daß die nachfolgende Zeile als Kommentar überlesen wird. In
|
|||
|
diese Zeile ® schreibt man oft die Namen der Wörter, die im Block
|
|||
|
definiert werden.
|
|||
|
|
|||
|
2.4.3 Tastenbelegung des Editors
|
|||
|
|
|||
|
Beim Editieren stehen Ihnen folgende Funktionen zur Verfügung:
|
|||
|
|
|||
|
Fi gibt Hilfestellung für den Editor
|
|||
|
|
|||
|
ESC verläßt den Editor mit dem sofortigen Abspeichern der Änderungen.
|
|||
|
|
|||
|
CTRL-U (undo) macht alle Änderungen rückgängig, die noch nicht auf Disk
|
|||
|
zurückgeschrieben wurden.
|
|||
|
|
|||
|
CTRL-E verläßt den Editor ohne sofortiges Abspeichern.
|
|||
|
|
|||
|
CTRL-F (fix) sucht das Wort rechts vom Cursor, ohne den Editor zu ver-
|
|||
|
lassen.
|
|||
|
|
|||
|
CTRL-L (showload) lädt den Screen ab Cursorposition.
|
|||
|
|
|||
|
CTRL-N fügt an Cursorposition eine neue Zeile ein.
|
|||
|
|
|||
|
CTRL-PgDn splittet innerhalb einer Zeile diese Zeile.
|
|||
|
|
|||
|
CTRL-S (Scr#) legt die Nummer des gerade editierten Screens auf dem Stack
|
|||
|
ab; z.B. für ein folgendes load oder plist.
|
|||
|
|
|||
|
CTRL=-Y löscht die Zeile an Cursorposition
|
|||
|
|
|||
|
CTRL-PgUp fügt innerhalb einer Zeile den rechten Teil der unteren Zeile an die
|
|||
|
obere Zeile (join).
|
|||
|
|
|||
|
TAB bewegt den Cursor einen großen TABulator vor.
|
|||
|
|
|||
|
SHIFT TAB bewegt den Cursor einen kleinen TABulator zurück.
|
|||
|
|
|||
|
F2 (suchen/ersetzen) erwartet eine Zeichenkette, die gesucht werden
|
|||
|
|
|||
|
soll und eine Zeichenkette, die statt dessen eingefügt werden soll.
|
|||
|
Wird eine Übereinstimmung gefunden, kann man
|
|||
|
|
|||
|
mit _R (replace) die gefundene Zeichenkette ersetzen,
|
|||
|
mit <er? den Suchvorgang abbrechen
|
|||
|
|
|||
|
oder mit jeder anderen Taste die nächste Übereinstimmung suchen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 18.- Einstieg ins volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
F3
|
|||
|
F5
|
|||
|
E7.
|
|||
|
F4
|
|||
|
F6
|
|||
|
F8
|
|||
|
F9
|
|||
|
|
|||
|
SHIFT F9
|
|||
|
|
|||
|
F18
|
|||
|
|
|||
|
Auf diese Weise kann man die Quelltexte auch nach einer Zeichen-
|
|||
|
kette durchsuchen lassen. Als Ersatz-String wird dann <CR> einge-
|
|||
|
geben.
|
|||
|
|
|||
|
bringt eine Zeile in den Zeilenpuffer und löscht sie im Screen.
|
|||
|
bringt die Kopie einer Zeile in den Zeilenpuffer.
|
|||
|
|
|||
|
fügt die Zeile aus dem Zeilenpuffer in den Screen ein.
|
|||
|
|
|||
|
wie F3, nur für ein einzelnes Zeichen.
|
|||
|
|
|||
|
wie F5, jedoch für ein einzelnes Zeichen.
|
|||
|
|
|||
|
entspricht F7, bezogen auf ein Zeichen.
|
|||
|
|
|||
|
vertauscht die aktuelle Datei (isfile) mit der Hintergrunddatei
|
|||
|
(fromfile). Erneutes F9-Drücken vertauscht erneut und stellt damit
|
|||
|
den alten Zustand wieder her. Diese Funktion ist dann sinnvoll,
|
|||
|
wenn Sie eine Datei bearbeiten, sich zwischendurch aber mit CRTL-
|
|||
|
F ein Wort anzeigen lassen. Dann stellt F9 (=fswap) die alte Datei-
|
|||
|
verteilung wieder her, die sich durch das fix geändert hat.
|
|||
|
schaltet auf die Kommentartexte (shadowscreens) um und beim
|
|||
|
nächsten Drücken wieder zurück.
|
|||
|
|
|||
|
legt den aktuellen Screen kurz beiseite, um ihn dann mit einem
|
|||
|
Druck auf F9 wieder bearbeiten zu können. Sollte Ihnen das volks-
|
|||
|
FORTH eine der Kopierfunktionen copy oder convey mit der Mel-
|
|||
|
dung TARGET BLOCK NOT EMPTY verweigern, weil isfile und fromfile
|
|||
|
unterschiedlich sind, so sorgt F1@ wieder für klare Verhältnisse.
|
|||
|
|
|||
|
Noch ein Hinweis zum Editor:
|
|||
|
|
|||
|
Der Editor unterstützt nur das Kopieren von Zeilen. Man kann auf diese Art auch
|
|||
|
Screens kopieren, aber beim gelegentlich erforderlichen Einfügen von Screens in der
|
|||
|
Mitte eines Files ist das etwas mühselig. Zum Kopieren ganzer Screens innerhalb
|
|||
|
eines Files oder von einem File in ein anderes werden im volksFORTH83 die Worte
|
|||
|
COPY und CONVEY verwendet.
|
|||
|
|
|||
|
2.4.4 Beispiel: CLS
|
|||
|
|
|||
|
.ür Ihr erstes Programm tragen Sie nun bitte den folgenden Quelltext in Screen 1
|
|||
|
|
|||
|
ein:
|
|||
|
|
|||
|
\ CLS löscht den gesanten Bildschirm
|
|||
|
|
|||
|
. cls
|
|||
|
|
|||
|
(--) £ull page ;
|
|||
|
|
|||
|
Nun drücken Sie SHIFT-F9 und tragen einen Kommentar in diesen Screen ein, wobei
|
|||
|
die Erklärung zu CLS in der gleichen Zeile, wie die Definition des Quelltextes, z.B.:
|
|||
|
|
|||
|
\\ CLs
|
|||
|
|
|||
|
CLS löscht den gesamten Bildschirm, indem es auf die Worte
|
|||
|
|
|||
|
full (Bildschirmfenster auf volle Größe) und PAGE (Bild
|
|||
|
schirmfenster löschen) zurückgreift.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Einstieg ins volksFORTH 95
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein nochmaliges SHIFT-F9 bringt Sie wieder zum Quelltext (source code) zurück..
|
|||
|
Damit bekommen Sie diesen erklärenden Text nach dem Kompilieren mit help cls
|
|||
|
angezeigt.
|
|||
|
|
|||
|
Wenn Sie einen Block vollgeschrieben haben, blättern Sie nur mit PgUp vor oder
|
|||
|
mit PgDn zurück zum nächsten Block. Sind Sie mit Ihrem Programm zufrieden, so
|
|||
|
drücken Sie ESC ; dann wird der geänderte Screen sofort abgespeichert.
|
|||
|
|
|||
|
Danach werden Sie wieder etwas bemerken: Der Bildschirm arbeitet nicht mehr
|
|||
|
korrekt, es bleiben oben Zeilen stehen, die nicht scrollen.
|
|||
|
|
|||
|
Das ist richtig, damit der zuletzt bearbeitete Quelltext nicht nach oben wegscrollt.
|
|||
|
Um nicht weitere zwei Zeilen des Bildschirms zu verlieren, hat das Fenster, in dem
|
|||
|
Sie gerade arbeiten, keinen Rahmen. Wie man mit Rahmen und Fenstern arbeitet,
|
|||
|
wird im Editor vorgeführt, der wie alle anderen Systemteile im Quelltext vorliegt.
|
|||
|
|
|||
|
Um sich in Zukunft schnell aus der mißlichen Lage mit der reduzierten
|
|||
|
Bildschirmgröße zu befreien, benutzen Sie Ihr erstes selbstgeschriebenes Programm
|
|||
|
cls . Denn die Eingabe von full stellt Ihnen wieder die gesamten Bildschirmfläche
|
|||
|
zur Verfügung, wogegen page nur das aktuelle Fenster löscht.
|
|||
|
|
|||
|
In volks4TH wird das Kompilieren - wie in den meisten FORTH-Systemen - über
|
|||
|
<ser#> load durchgeführt:
|
|||
|
1 load
|
|||
|
|
|||
|
kompiliert Ihr Wort CLS mit für 'C'- oder Pascal-Programmierer unvorstellbarer
|
|||
|
Geschwindigkeit ins FORTH. Damit steht Ihr Mini-Programm jetzt zur Ausführung
|
|||
|
bereit. Zugleich erhalten Sie die Meldung, daß ein Wort namens CLS bereits be-
|
|||
|
steht: "CLS exists" . Dies hat nur die Konsequenz, daß nach einer Redefinition das
|
|||
|
alte Wort gleichen Namens nicht mehr zugegriffen werden kann. Eine Möglichkeit,
|
|||
|
diese Namensgleichheit mit einem bereits existierenden Wort zu vermeiden, wäre der
|
|||
|
Einsatz eines Vokabulares.
|
|||
|
Geben Sie einmal words ein, dann werden Sie feststellen, daß Ihr neues Wort CLS
|
|||
|
ganz oben im Dictionary steht (drücken Sie die <ESC>-Taste, um die Ausgabe von
|
|||
|
words abzubrechen oder irgendeine andere Taste, um sie anzuhalten).
|
|||
|
Um das Ergebnis Ihres ersten Programmierversuchs zu überprüfen, geben Sie nun
|
|||
|
ein:
|
|||
|
|
|||
|
cls
|
|||
|
|
|||
|
Und siehe da, der gesamte Bildschirm wird dunkel. Schöner wäre es allerdings,
|
|||
|
wenn Ihr Programm seine Arbeit mit einer Meldung beenden würde Um dies zu
|
|||
|
ändern, werfen Sie bitte erst einmal das alte Wort CLS weg:
|
|||
|
|
|||
|
forget cls
|
|||
|
|
|||
|
Bitte kontrollieren Sie mit words ,ob CLS wirklich vergessen wurde. Rufen Sie
|
|||
|
dann erneut den Editor mit v auf. Nun benutzen Sie das Wort für den Beginn
|
|||
|
einer Zeichenkette ." , das Wort für ihr Ende " und das Wort für einen Zeilen-
|
|||
|
vorschub cr. Ihr Screen 1 sieht dann so aus :!
|
|||
|
|
|||
|
\ CLS löscht den Bildschirm mit Meldung
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= Einstieg ins volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Decks Au== )
|
|||
|
full page
|
|||
|
." Bildschirm ordnungsgemäß gelöscht!" cr ;
|
|||
|
|
|||
|
Nach dem ." muß ein Leerzeichen stehen. Denn FORTH benutzt standardmäßig das
|
|||
|
Leerzeichen als Trennzeichen zwischen einzelnen Worten, so daß dies Leerzeichen
|
|||
|
nicht mit zur Zeichenkette (string) zählt. Dann verlassen Sie den Editor und
|
|||
|
kompilieren Sie Ihr Programm wie gehabt und starten es. Die Änderung erweist sich
|
|||
|
als erfolgreich, und Sie haben gelernt, wie einfach in FORTH das Schreiben, Aus-
|
|||
|
testen und Ändern von Programmteilen ist.
|
|||
|
|
|||
|
Eine große Hilfe sowohl für den Programmierer als auch für den späteren Benutzer
|
|||
|
sind Informationen darüber, was gerade geladen wird und was schon kompiliert
|
|||
|
wurde. Fügt man
|
|||
|
|
|||
|
er .( Funktion installiert )
|
|||
|
ein, so werden während des Ladens diese Meldungen ausgegeben. Das Wort .( leitet
|
|||
|
|
|||
|
einen Kommentar im Interpreter ein, die schließende Klammer ) beendet ihn und cr
|
|||
|
ist natürlich für den Zeilenvorschub, das carriage return, verantwortlich.
|
|||
|
|
|||
|
2.4.5 Compilieren im Editor - Showload
|
|||
|
|
|||
|
Eine Besonderheit von volksFORTH ist, daß selbst im Editor Funktionen des Inter-
|
|||
|
preters/Compilers zur Verfügung stehen. Dieses Interpretieren und Kompilieren im
|
|||
|
Editor nennt sich Showload.
|
|||
|
|
|||
|
CTRL-F (fix) sucht und zeigt das Wort rechts vom Cursor, ohne den Editor
|
|||
|
zu verlassen.
|
|||
|
CTRL-L (showload) lädt den Screen ab Cursorposition.
|
|||
|
|
|||
|
Um zu sehen, was diese Showload-Funktion leistet, geben Sie nun bitte folgenden
|
|||
|
Screen ein:
|
|||
|
\ Ein Test für das showload
|
|||
|
:sinetiiHt;
|
|||
|
2.den..I2.%
|
|||
|
\\
|
|||
|
15 ine .
|
|||
|
15 inc dec .
|
|||
|
15 15 + 2 spaces .
|
|||
|
|
|||
|
Dieser Screen soll jetzt im Editor kompiliert und interpretiert werden !!
|
|||
|
|
|||
|
Dazu setzen Sie bitte den Cursor durch die Taste CTRL-home in die erste Zeile auf
|
|||
|
das Zeichen \ (skip line). Drücken Sie nun CTRL-L zum Laden des Screens.
|
|||
|
volksFORTH kompiliert nun bis zu der Zeile, die mit \\ (skip screen) beginnt. Die
|
|||
|
Wörter inc und dec sind dem System jetzt bekannt und können benutzt werden.
|
|||
|
Anschließend bewegen Sie den Cursor hinter das \\ und drücken CTRL-L zum
|
|||
|
weiteren Interpretieren im Editor. Sofort sehen Sie die Ausgaben an der entspre-
|
|||
|
chenden Stelle im Editor erscheinen. Dabei bleibt der Inhalt des Screens selbst-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Einstieg ins volksFORTH Sr
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
verständlich unversehrt - verlassen Sie den Editor mit ESC und sehen Sie sich den
|
|||
|
Inhalt den Screens mit <scr#> list an; Sie sehen nur die Anweisungen, aber
|
|||
|
nicht mehr die Ausgaben vor sich.
|
|||
|
|
|||
|
Eine typische Anwendung dieses showload wäre das Neukompilieren eines Wortes
|
|||
|
nach einer kleinen Änderung oder das interaktive Hinzufügen von Wörtern, die man
|
|||
|
gerade mal braucht.
|
|||
|
|
|||
|
2.5 Erstellen einer Applikation
|
|||
|
|
|||
|
Sie wollen Ihr 'Programm' nun als eigenständige Anwendung abspeichern. Dazu
|
|||
|
erweitern Sie es zunächst ein klein wenig (Editor mit v aufrufen.) FÜgen Sie nun
|
|||
|
noch folgende Definition in einer neuen Zeile hinzu:
|
|||
|
|
|||
|
: runalone cls bye ;
|
|||
|
|
|||
|
RUNALONE führt zuerst CLS aus und kehrt dann zum Betriebssystem zurück. Kompi-
|
|||
|
lieren Sie nun erneut, wobei Sie die Meldung erhalten "CLS exists". Sie führen
|
|||
|
RUNALONE aber nicht aus, sonst würden Sie FORTH ja verlassen (bye).
|
|||
|
|
|||
|
Das Problem besteht vielmehr darin, das System so abzuspeichern, daß es gleich
|
|||
|
nach dem Laden RUNALONE ausführt und sonst gar nichts. volksFORTH83 ist an
|
|||
|
zwei Stellen für solche Zwecke vorbereitet. In den Worten COLD und RESTART be-
|
|||
|
finden sich zwei 'deferred words' namens 'COLD bzw. 'RESTART , die im Normalfall
|
|||
|
nichts tun, vom Anwender aber nachträglich verändert werden können.
|
|||
|
|
|||
|
Sie benutzen hier 'COLD, um auch schon die Startmeldung zu unterbinden. Geben
|
|||
|
Sie also ein
|
|||
|
|
|||
|
" runalone Is 'cold
|
|||
|
|
|||
|
und speichern Sie das Ganze mit
|
|||
|
savesystem cls.com
|
|||
|
|
|||
|
auf Disk zurück. Sie haben Ihre erste Applikation erstellt, die Sie von MSDOS-
|
|||
|
Ebene aus mit CLS aufrufen können !
|
|||
|
|
|||
|
Etwas enttäuschend ist es aber schon. Das angeblich so kompakte FORTH benötigt
|
|||
|
über 26KByte, um eine so lächerliche Funktion auszuführen ?? Da stimmt doch
|
|||
|
etwas nicht. Natürlich, es wurden ja eine Reihe von Systemteilen mit abgespeichert,
|
|||
|
vom Fileinterface über den Assembler, den Editor usw., die für unser Programm
|
|||
|
überhaupt nicht benötigt werden.
|
|||
|
|
|||
|
Um dieses und ähnliche Probleme zu lösen, gibt es das File KERNEL.COM. Dieses
|
|||
|
Programm enthält nur den Systemkern und das Fileinterface und entspricht damit
|
|||
|
der Laufzeit-Bilbliothek (runtime library) anderer Sprachen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
2 Einstieg ins volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Anwendung.com
|
|||
|
|
|||
|
|
|||
|
|
|||
|
volksFORTH.com
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Minimal.com
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kernel.com
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
+ Basisfunktionen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
+ Editor, Debugger etc.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
+ Anwendungsprogramm
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Laden Sie also KERNEL.COM und kompilieren Sie Ihre Applikation mit
|
|||
|
|
|||
|
include multi.vid
|
|||
|
include test.scr
|
|||
|
|
|||
|
Das vorherige Laden von MULTI.VID ist nötig, weil FORTH-Systeme selten über
|
|||
|
Linker verfügen; wird MULTI.VID nicht vorher geladen, so ist dem FORTH-System
|
|||
|
das Wort full unbekannt. Dann wie gehabt RUNALONE in 'COLD eintragen und
|
|||
|
das System auf Disk zurückspeichern. Von der MS-DOS Ebene aus läßt sich diese
|
|||
|
Programmerstellung mit
|
|||
|
|
|||
|
kernel include mulit.vid include test.scr
|
|||
|
|
|||
|
durchführen, wobei diese beiden Zeilen
|
|||
|
|
|||
|
runalone Is 'cold
|
|||
|
savesystem dark.con
|
|||
|
|
|||
|
die letzten Anweisungen auf Ihrem Screen sind. Damit wird der FORTH-Interpreter
|
|||
|
angewiesen, die fertige Anwendung DARK.com auf Disk zu speichern.
|
|||
|
|
|||
|
Sie haben jetzt eine verhältnismäßig kompakte Version vorliegen. Natürlich ließe
|
|||
|
sich auch diese noch erheblich kürzen, aber dafür bräuchten Sie einen Target-
|
|||
|
Compiler, mit dem Sie nur noch die wirklich benötigten Systemteile selektiv aus
|
|||
|
dem Quelltext zusammenstellen könnten. Mit der beschriebenen Methode lassen sich
|
|||
|
|
|||
|
aber auch größere Programme kompilieren und als Stand-alone-Applikationen ab-
|
|||
|
speichern.
|
|||
|
|
|||
|
2.6 Das Erstellen eines eigenen FORTH-Systems
|
|||
|
|
|||
|
Das File VOLKS4TH.COM ist als Arbeitsversion gedacht.
|
|||
|
|
|||
|
Es enthält alle wichtigen Systemteile wie Editor, Printer-Interface, Tools, Decom-
|
|||
|
piler, Tracer usw. Sollte Ihnen die Zusammenstellung nicht gefallen, können Sie
|
|||
|
sich jederzeit ein Ihren speziellen Wünschen angepaßtes System zusammenstellen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Einstieg ins volksFORTH - 20.»
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Schlüssel dazu ist der Loadscreen des Files VOLKS4TH.SYS . Sie können dort
|
|||
|
Systemteile, die Sie nicht benötigen, mit dem Backslash \ wegkommentieren oder
|
|||
|
die entsprechenden Zeilen ganz löschen. Ebenso können Sie natürlich dem Load-
|
|||
|
screen eigene Files hinzufügen. Entspricht der Loadscreen Ihren Wünschen, spei-
|
|||
|
chern Sie ihn mit <ESC> zurück, und verlassen Sie das System mit BYE. Laden Sie
|
|||
|
nun das File KERNEL.COM . Geben Sie dann ein:
|
|||
|
|
|||
|
include volks4TH.sys
|
|||
|
|
|||
|
Ist das System fertig kompiliert, schreibt die Anweisung
|
|||
|
savesystem volks4TH.com
|
|||
|
|
|||
|
des Load-Screens eine neue Version von volks4TH.com auf Disk. Damit wird Ihr
|
|||
|
altes File überschrieben (Sicherheitskopie !!!), sodaß Sie beim nächsten Laden von
|
|||
|
volks4TH.com Ihr eigenes System erhalten.
|
|||
|
|
|||
|
Natürlich können Sie 'Ihr' System auch unter einem anderen Namen abspeichern.
|
|||
|
Ebenso können Sie Systemvoreinstellungen ändern. Unsere Arbeitsversion arbeitet
|
|||
|
- voreingestellt - neuerdings im dezimalen Zahlensystem. Natürlich können Sie
|
|||
|
mit hex auf Hexadezimalsystem umstellen; wir halten das für sehr viel sinn-
|
|||
|
voller, weil vor allem Speicheradressen im Dezimalsystem kaum etwas aussagen
|
|||
|
(oder wissen Sie, ob Speicherstelle 978584 im Bildschirmspeicher liegt oder nicht ?).
|
|||
|
Wollen Sie bereits unmittelbar nach dem Laden im Hexadezimalsystem arbeiten,
|
|||
|
können Sie sich dies mit SAVESYSTEM abspeichern, indem Sie von der FORTH-
|
|||
|
Kommandozeile aus savesystem volks4TH.com eingeben.
|
|||
|
|
|||
|
Im Übrigen empfehlen wir bei allen Zahlen über 9 dringend die Benutzung der so-
|
|||
|
genannten Präfixe:
|
|||
|
|
|||
|
$ für Hexadezimal-,
|
|||
|
& für Dezimal- und
|
|||
|
% für Binärzahlen,
|
|||
|
|
|||
|
Man vermeidet so, daß irgendwelche Files nicht - oder noch schlimmer, falsch -
|
|||
|
kompiliert werden, weil man gerade im anderen Zahlensystem ist. Außerdem ist es
|
|||
|
“möglich, hexadezimale und dezimale Zahlen beliebig zu kombinieren, je nachdem,
|
|||
|
was gerade sinnvoller ist. In den Quelltexten finden Sie genug entsprechende Bei-
|
|||
|
spiele.
|
|||
|
|
|||
|
Besonders schnell und komfortabel arbeitet volksFORTH natürlich, wenn alle Teile
|
|||
|
des Systems auf einer Festplatte abgelegt sind. Sie sollten dafür ein eigenes
|
|||
|
Directory einrichten und PATH und DIR entsprechend einstellen.
|
|||
|
|
|||
|
Auch die Arbeit mit einer RAM-Disk ist prinzipiell möglich, allerdings nicht sehr zu
|
|||
|
empfehlen. FORTH ist sehr maschinennah und Systemabstürze daher vor allem zu
|
|||
|
Anfang nicht so ganz auszuschließen.
|
|||
|
|
|||
|
Das Ausdrucken der Quelltexte des Systems ist sicher sinnvoll, um Beispiele für
|
|||
|
den Umgang mit volksFORTH83 zu sehen. So stellen z.B. der Screen-Editor und der
|
|||
|
Kommando-Editor vollständige Anwendungen dar, die im Quelltext vorliegen.
|
|||
|
|
|||
|
Welche Files sich im Einzelnen auf Ihren Disketten befinden und ob sie Kommen-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= DA = Einstieg ins volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
tarscreens enthalten, steht im File README.DOC. Zunächst müssen Sie das Printer-
|
|||
|
Interface hinzuladen, falls es nicht schon vorhanden ist. Reagiert Ihr volksFORTH83
|
|||
|
auf die Eingabe von PRINTER mit einem ? „so ist das Printerinterface nicht vor-
|
|||
|
handen.
|
|||
|
|
|||
|
2.7 Ausdrucken von Screens
|
|||
|
|
|||
|
Sollte in Ihrem System kein Druckerinterface vorhanden sein, so laden Sie es von
|
|||
|
der FORTH-Kommandozeile aus mit
|
|||
|
|
|||
|
include <Druckername).prn
|
|||
|
|
|||
|
nach. Sollte Ihr Drucker in der Liste nicht erscheinen, so benutzen Sie statt
|
|||
|
dessen graphic.prn oder epson.prn . Die meisten Drucker können als IBM-Graphic-
|
|||
|
Printer oder als EPSON FX/LX-Drucker arbeiten.
|
|||
|
|
|||
|
Im Printer-Interface sind einige Worte zur Ausgabe eines formatierten Listings
|
|||
|
enthalten. PTHRU druckt einen Bereich von Screens, jeweils 6 Screens auf einer DIN
|
|||
|
A4 Seite in komprimierter Schrift. Ganz ähnlich arbeitet das Wort DOCUMENT „,
|
|||
|
jedoch wird bei diesem Wort neben einen Quelltextscreen der zugehörige
|
|||
|
Shadowscreen gedruckt. LISTING druckt ein ganzes File so aus, man erhält so ein
|
|||
|
übersichtliches Listing eines Files mit ausführlichen Kommentaren.
|
|||
|
|
|||
|
Glossar
|
|||
|
|
|||
|
pthru ( von bis -- )
|
|||
|
druckt die angegebenen Blöcke immer zu sechst auf einer Seite aus.
|
|||
|
|
|||
|
document ( von bis -- )
|
|||
|
arbeitet wie pthru , druckt aber jeweils drei Quelltextblöcke und drei
|
|||
|
Kommentarblöcke auf einer Seite aus.
|
|||
|
|
|||
|
listing (--)
|
|||
|
erstellt ein Listing der gesamten Datei, indem jeweils drei Quelltext-
|
|||
|
Blöcke und drei Kommentar-Blöcke auf einer Seite ausgedruckt werden.
|
|||
|
|
|||
|
plist (scr# -- )
|
|||
|
druckt einen angegebenen Block auf dem Drucker aus.
|
|||
|
|
|||
|
ser ( -- addr )
|
|||
|
ist eine Variable, die die Nummer des gerade editierten Screens enthält.
|
|||
|
Vergl. r# , list, (error
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Einstieg ins volksFORTH 2er
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
r# ( -- addr )
|
|||
|
ist eine Variable, die den Abstand des gerade editierten Zeichens von
|
|||
|
Anfang des gerade editierten Screens enthält.
|
|||
|
|
|||
|
2.8 Druckeranpassung
|
|||
|
|
|||
|
Die Druckeranpassung das Arbeitssystems wird im File VOLKS4TH.SYS durch die
|
|||
|
Zeile
|
|||
|
|
|||
|
include <printer).prn
|
|||
|
vorgenommen. In dieser Anpassung sind - zusätzlich zu den reinen Ausgaberou-
|
|||
|
tinen - eine Reihe nützlicher Worte enthalten, mit denen die Druckersteuerung
|
|||
|
sehr komfortabel vorgenommen werden kann.
|
|||
|
Im Arbeitssystem ist das Printerinterface bereits enthalten. Müssen Sie Änderungen
|
|||
|
vornehmen, können Sie mit dem Editor den Loadscreen von VOLKS4TH.SYS ändern
|
|||
|
und sich ein neues Arbeitssystem zusammenstellen mit:
|
|||
|
|
|||
|
kernel include volks4TH.sys
|
|||
|
|
|||
|
Sie können natürlich auch den Loadscreen in seiner jetzigen Fassung benutzen und
|
|||
|
das Printer-Interface jedesmal 'von Hand' mit
|
|||
|
|
|||
|
include <printer>.prn
|
|||
|
|
|||
|
nachladen.
|
|||
|
|
|||
|
Leider sind im Moment im volksFORTH noch deutsche und englische Fehlermeldungen
|
|||
|
gemischt und die help Funktion zeigt Ihnen einen erklärenden Text nur, wenn
|
|||
|
dieser vorhanden ist.
|
|||
|
|
|||
|
Die wichtigsten Befehle noch einmal im Überblick:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
status steuert die Status-Zeile
|
|||
|
|
|||
|
words zeigt die gerade verfügbaren Befehle an
|
|||
|
|
|||
|
files zeigt die angemeldeten Dateien
|
|||
|
|
|||
|
path verändert oder nennt den Datei-Suchpfad
|
|||
|
|
|||
|
order listet die Suchreihenfolge der Befehlsgruppen auf
|
|||
|
|
|||
|
vocs nennt alle verfügbaren Befehlsgruppen
|
|||
|
|
|||
|
view zeigt und
|
|||
|
|
|||
|
fix editiert den Quelltext eines bestimmten Wortes
|
|||
|
|
|||
|
help zeigt - wenn vorhanden - den Kommentartext eines Wort
|
|||
|
full schaltet das Bildschirmfenster auf die volle Größe
|
|||
|
|
|||
|
page löscht das aktuelle Fenster
|
|||
|
|
|||
|
index - nicht resident - zeigt den Inhalt einer Block-Datei
|
|||
|
list zeigt den Inhalt eines Screens.
|
|||
|
|
|||
|
— BL - Einstieg ins volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
include lädt eine ganze Befehlsgruppe oder einen Programteil
|
|||
|
|
|||
|
Nun sollten Sie bereits zu einem begleitenden Buch zu greifen. Denn volksFORTH
|
|||
|
ist ein komplexes multitaskingfähiges Entwicklungssystem, das man nicht von heute
|
|||
|
auf morgen beherrscht.
|
|||
|
[1] Leo Brodie Programmieren in FORTH
|
|||
|
|
|||
|
( Hanser Verlag )
|
|||
|
[2) Leo Brodie In FORTH denken
|
|||
|
|
|||
|
( Hanser Verlag )
|
|||
|
|
|||
|
[3J) R. Zech FORTH 83
|
|||
|
( Franzis Verlag )
|
|||
|
|
|||
|
[4] H.-W. Beilstein Wie man in FORTH programmiert
|
|||
|
( Chip Wissen )
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Einstieg ins volksFORTH 327.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
3. Arithmetik
|
|||
|
|
|||
|
3.1 Stacknotation
|
|||
|
|
|||
|
Im foigenden werden hauptsächlich Worte in ihrer Einzelfunktion beschrieben. In
|
|||
|
dieser Form der Beschreibung, die Sie bereits kennengelernt haben, wird die Wir-
|
|||
|
kung eines Wortes auf den Stack in Klammern angegeben und zwar in folgender
|
|||
|
|
|||
|
Form:
|
|||
|
( vorher -- nachher )
|
|||
|
vorher : Werte auf dem Stack vor Ausführung des Wortes
|
|||
|
nachher : Werte auf dem Stack nach Ausführung des Wortes
|
|||
|
|
|||
|
In dieser Notation wird das oberste Element des Stacks (tos) immer ganz rechts
|
|||
|
geschrieben. Sofern nicht anders angegeben, beziehen sich alle Stacknotationen auf
|
|||
|
die spätere Ausführung des Wortes. Bei immediate Worten wird auch die Auswirkung
|
|||
|
des Wortes auf den Stack während der Kompilierung angegeben. Worte werden ferner
|
|||
|
durch folgende Symbole gekennzeichnet:
|
|||
|
|
|||
|
c Dieses Wort kann nur während der Kompilation einer :-Definition
|
|||
|
benutzt werden.
|
|||
|
|
|||
|
I Dieses Wort ist ein immediate Wort, das auch im kompilierenden Zu-
|
|||
|
stand ausgeführt wird.
|
|||
|
|
|||
|
83 Dieses Wort wird im 83-Standard definiert und muß auf allen
|
|||
|
Standardsystemen äquivalent funktionieren.
|
|||
|
|
|||
|
U Kennzeichnet eine Uservariable.
|
|||
|
|
|||
|
Weicht die Aussprache eines Wortes von der natürlichen englischen Aussprache ab,
|
|||
|
so wird sie in Anführungszeichen angegeben. Gelegentlich folgt auch eine deutsche
|
|||
|
Übersetzung.
|
|||
|
|
|||
|
Die Namen der Stackparameter folgen, sofern nicht suggestive Bezeichnungen ge-
|
|||
|
wählt wurden, dem nachstehendem Schema. Die Bezeichnungen können mit einer
|
|||
|
nachfolgenden Ziffer versehen sein.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Stack- Zahlentyp Wertebereich minimale
|
|||
|
notation in Dezimal Feldbreite
|
|||
|
flag logischer Wert ö=falsch, sonst=true 16 Bit
|
|||
|
true (tf) logischer Wert -1 (als Ergebnis) 16 Bit
|
|||
|
false (ff) logischer Wert ® 16 Bit
|
|||
|
b Bit 8..1 1 Bit
|
|||
|
char Zeichen 0..127 (8..256) 7(8Bit)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
28 = z Arithmetik
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V.
|
|||
|
|
|||
|
PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
8b
|
|||
|
|
|||
|
|
|||
|
|
|||
|
8 beliebige Bits nicht anwendbar 8
|
|||
|
16b 16 beliebige Bits nicht anwendbar 16
|
|||
|
n Zahl,bewertete Bits -32768..32767 16
|
|||
|
+n positive Zahl 0..32767 16
|
|||
|
u vorzeichenlose Zahl B..65535 16
|
|||
|
w Zahl, n oder u -32768..65535 16
|
|||
|
addr Adresse, wie u 8..65535 16
|
|||
|
32b 32 beliebige Bits nicht anwendbar 32
|
|||
|
d doppelt genaue Zahl -2,147,483,648... 32
|
|||
|
2,147,483,647
|
|||
|
+d pos. doppelte Zahl 08..2,147,483,647 32
|
|||
|
ud vorzeichenlose 08..4,294,967,295 32
|
|||
|
doppelt genaue Zahl
|
|||
|
Sys systemabhängige Werte nicht anwendbar nicht anwendbar
|
|||
|
3.2 Arithmetische Funktionen
|
|||
|
-1 >= -1)
|
|||
|
8 (--8)
|
|||
|
1 (--1)
|
|||
|
2 ))
|
|||
|
3 (-- 3)
|
|||
|
4 (--4)
|
|||
|
Oft benutzte Zahlenwerte wurden zu Konstanten gemacht. Definiert in der
|
|||
|
Form :
|
|||
|
n Constant n
|
|||
|
Dadurch wird Speicherplatz eingespart und die Ausführungszeit ver-
|
|||
|
kürzt.
|
|||
|
1+ (w1 --w2) 83 "one-plus"
|
|||
|
w2 ist das Ergebnis von Eins plus wi. Die Operation 1 + wirkt genauso.
|
|||
|
1= (w1l1--w2) 83 "one-minus"
|
|||
|
w2 ist das Ergebnis von wi minus Eins. Die Operation 1 - wirkt genauso.
|
|||
|
2+ (w1--w2) 83 "two-plus"
|
|||
|
w2 ist das Ergebnis von wi plus Zwei. Die Operation 2 + wirkt genauso.
|
|||
|
2- (w1l--w2) 83 "two-minus"
|
|||
|
w2 ist das Ergebnis von wl minus Zwei. Die Operation 2 - wirkt genauso.
|
|||
|
Arithmetik “2s-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
2% (wl --w2) ; "two-times"
|
|||
|
wl wird um ein Bit nach links geschoben und das ergibt w2. In das nie-
|
|||
|
derwertigste Bit wird eine Null geschrieben. Die Operation 2 * wirkt ge-
|
|||
|
nauso.
|
|||
|
|
|||
|
2/ t NE --In2®) 83 "two-divide"
|
|||
|
nl wird um ein Bit nach rechts verschoben und das ergibt n2. Das Vor-
|
|||
|
zeichen wird berücksichtigt und bleibt unverändert. Die Operation 2 /
|
|||
|
wirkt genauso.
|
|||
|
|
|||
|
3+ (w1 --w2) "three-plus"
|
|||
|
w2 ist das Ergebnis von wıi plus Drei. Die Operation 3 + wirkt genauso.
|
|||
|
|
|||
|
abs (n--u) 83 "absolute"
|
|||
|
u ist der Betrag von n. Wenn n gleich -32768 ist, hat u denselben Wert
|
|||
|
wie n. Vergleiche auch Zweierkomplement.
|
|||
|
|
|||
|
not (w1--w2) 83
|
|||
|
Jedes Bit von wi wird einzeln invertiert und das ergibt w2.
|
|||
|
|
|||
|
negate (nl --n2) 83
|
|||
|
n2 hat den gleichen Betrag, aber das umgekehrte Vorzeichen von nl. n2
|
|||
|
ist gleich der Differenz von Null minus nl.
|
|||
|
|
|||
|
even (ul -- 2)
|
|||
|
ist im 8886-FORTH ein noop-Befehl ohne Funktion.
|
|||
|
|
|||
|
max (nin2--n3) 83 "maximum"
|
|||
|
n3 ist die Größere der beiden Werte nl und n2. Benutzt die Operation
|
|||
|
> . Die größte Zahl für ni oder n2 ist 32767.
|
|||
|
|
|||
|
min (nın2--n3) 83 "minimum"
|
|||
|
n3 ist die Kleinere der beiden Werte nl und n2. Benutzt die Operation
|
|||
|
< . Die kleinste Zahl für nl oder n2 ist -32768.
|
|||
|
|
|||
|
+ (wlw2 -- w3) 83 "plus"
|
|||
|
wl und w2 addiert ergibt w3.
|
|||
|
|
|||
|
- (wlw2 -- w3) 83 "minus"
|
|||
|
w2 von w1l subtrahiert ergibt w3.
|
|||
|
|
|||
|
- 30 - Arithmetik
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
mod
|
|||
|
|
|||
|
/mod
|
|||
|
|
|||
|
*/mod
|
|||
|
|
|||
|
u/mod
|
|||
|
|
|||
|
(wlw2 --w3) 83 "times"
|
|||
|
Der Wert wi wird mit w2 multipliziert. w3 sind die niederwertigen
|
|||
|
16 Bits des Produktes. Ein Überlauf wird nicht angezeigt.
|
|||
|
|
|||
|
(nın2--n3) 83 "divide"
|
|||
|
n3 ist der Quotient aus der Division von ni durch den Divisor n2. Eine
|
|||
|
Fehlerbedingung besteht, wenn der Divisor Null ist oder der Quotient
|
|||
|
außerhalb des Intervalls (-32768...32767) liegt.
|
|||
|
|
|||
|
(nin2--n3) 83 "mod"
|
|||
|
n3 ist der Rest der Division von nl durch den Divisor n2. n3 hat daßelbe
|
|||
|
Vorzeichen wie n2 oder ist Null. Eine Fehlerbedingung besteht, wenn der
|
|||
|
Divisor Null ist oder der Quotient außerhalb des Intervalls (-
|
|||
|
32768..32767) liegt.
|
|||
|
|
|||
|
(nin2 --n3n4a) 83 "divide-mod"
|
|||
|
n3 ist der Rest und n4 der Quotient aus der Division von ni durch den
|
|||
|
Divisor n2. n3 hat dasselbe Vorzeichen wie n2 oder ist Null. Eine
|
|||
|
Fehlerbedingung besteht, wenn der Divisor Null ist oder der Quotient
|
|||
|
außerhalb des Intervalls (-32768..32767) liegt.
|
|||
|
|
|||
|
(nin2n3--nA) 83 "times-divide"
|
|||
|
Zuerst wird nl mit n2 multipliziert und ein 32-bit Zwischenergebnis er-
|
|||
|
zeugt. n4 ist der Quotient aus dem 32-bit Zwischenergebnis und dem
|
|||
|
Divisior n3. Das Produkt von nl mal n2 wird als 32-bit Zwischenergebnis
|
|||
|
dargestellt, um eine größere Genauigkeit gegenüber dem sonst gleichwer-
|
|||
|
tigen Ausdruck ni n2 * n3 / zu erhalten. Eine Fehlerbedingung besteht,
|
|||
|
wenn der Divisor Null ist, oder der Quotient außerhalb des Intervalls (-
|
|||
|
32768.. 32767) liegt.
|
|||
|
|
|||
|
(nin2n3--n4an5) 83 "times-divide-mod"
|
|||
|
Zuerst wird nl mit n2 multipliziert und ein 32-bit Zwischenergebnis er-
|
|||
|
zeugt. n4 ist der Rest und n5 der Quotient aus dem 32-bit-Zwischener-
|
|||
|
gebnis und dem Divisor n3. n4 hat das gleiche Vorzeichen wie n3 oder
|
|||
|
ist Null. Das Produkt von ni mal n2 wird als 32-bit Zwischenergebnis
|
|||
|
dargestellt, um eine größere Genauigkeit gegenüber dem sonst gleichwer-
|
|||
|
tigen Ausdruck nl n2 * n3 /mod zu erhalten. Eine Fehlerbedingung be-
|
|||
|
steht, falls der Divisor Null ist oder der Quotient außerhalb des Inter-
|
|||
|
valls (-32768...32767) liegt.
|
|||
|
|
|||
|
(ul u2 -- u3u4) "u-divide-mod"
|
|||
|
u3 ist der Rest und u4 der Quotient aus der Division von ul durch den
|
|||
|
Divisor u2. Die Zahlen u sind vorzeichenlose 16-Bit Werte (unsigned
|
|||
|
integer). Eine Fehlerbedingung besteht, wenn der Divisor Null ist.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Arithmetik 4, =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V.
|
|||
|
|
|||
|
PC-volksFOR
|
|||
|
|
|||
|
TH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
umax
|
|||
|
|
|||
|
umin
|
|||
|
|
|||
|
true
|
|||
|
|
|||
|
false
|
|||
|
|
|||
|
Bo
|
|||
|
|
|||
|
D<
|
|||
|
|
|||
|
0
|
|||
|
|
|||
|
(ulu2 --u3)
|
|||
|
|
|||
|
u3 ist der Größere der beiden Werte ul und u2. Benutzt
|
|||
|
tion. Die größte Zahl für ul oder u2 ist 65535.
|
|||
|
|
|||
|
(ulu2 -- u3)
|
|||
|
|
|||
|
u3 ist der Kleinere der beiden Werte ul und u2. Benutzt
|
|||
|
tion. Die kleinste Zahl für ul oder u2 ist Null.
|
|||
|
|
|||
|
3.3 Logik und Vergleiche
|
|||
|
|
|||
|
(===)
|
|||
|
|
|||
|
hinterläßt -1 als Zeichen für logisch wahr auf dem Stack.
|
|||
|
|
|||
|
(==9)
|
|||
|
|
|||
|
"u-maximum"
|
|||
|
die U> Opera-
|
|||
|
|
|||
|
"u-minimum"
|
|||
|
die U< Opera-
|
|||
|
|
|||
|
Hinterläßt Null als Zeichen für logisch-falsch auf dem Stack.
|
|||
|
|
|||
|
(w-- flag)
|
|||
|
|
|||
|
Wenn w gleich Null ist, ist flag wahr.
|
|||
|
|
|||
|
Un-- flag)
|
|||
|
|
|||
|
83
|
|||
|
|
|||
|
Wenn n verschieden von Null ist, ist flag wahr.
|
|||
|
|
|||
|
(n-- flag)
|
|||
|
|
|||
|
83
|
|||
|
|
|||
|
Wenn n kleiner als Null (negativ) ist,
|
|||
|
dann der Fall, wenn das höchstwertige Bit von n gesetzt ist. Deswegen
|
|||
|
kann dieser Operator zum Testen dieses Bits benutzt werden.
|
|||
|
|
|||
|
(n-- flag)
|
|||
|
|
|||
|
83
|
|||
|
|
|||
|
Wenn n größer als Null ist, ist flag wahr.
|
|||
|
|
|||
|
ist flag wahr.
|
|||
|
|
|||
|
(wi w2 -- flag ) 83
|
|||
|
Wenn wi gleich w2 ist, ist flag wahr.
|
|||
|
|
|||
|
(nin2--flag) 83
|
|||
|
wenn nl kleiner als n2 ist, ist flag wahr. z.B. -32768
|
|||
|
wahr. -32768 6 <£ ist wahr.
|
|||
|
|
|||
|
{nm -- flag) 83.
|
|||
|
|
|||
|
Wenn nl größer als n2 ist, ist flag wahr.z.B. -32768 3276
|
|||
|
|
|||
|
32768 8
|
|||
|
|
|||
|
>»:
|
|||
|
|
|||
|
ist falsch.
|
|||
|
|
|||
|
"zero-equals"
|
|||
|
|
|||
|
"zero-less"
|
|||
|
Dies ist immer
|
|||
|
|
|||
|
"Zero-greater"
|
|||
|
|
|||
|
"equals"
|
|||
|
|
|||
|
"less-than"
|
|||
|
32767 &£ ist
|
|||
|
|
|||
|
"greater-than"
|
|||
|
7 > ist falsch.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Arithmetik
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
u<
|
|||
|
|
|||
|
u)
|
|||
|
|
|||
|
and
|
|||
|
|
|||
|
or
|
|||
|
|
|||
|
xor
|
|||
|
|
|||
|
uwithin
|
|||
|
|
|||
|
case?
|
|||
|
|
|||
|
extend
|
|||
|
|
|||
|
(ul u2 -- flag ) 83 "u-less-than"
|
|||
|
Wenn ul kleiner als u2 ist, ist flag wahr. Die Zahlen u sind vorzeichen-
|
|||
|
lose 16-Bit Werte. Wenn Adressen verglichen werden sollen, muß U< be-
|
|||
|
nutzt werden, sonst passieren oberhalb von 32K seltsame Dinge !
|
|||
|
|
|||
|
(ul u2 -- flag ) 3 "u-greater-than"
|
|||
|
Wenn ul größer als u2 ist, ist flag wahr. Ansonsten gilt das gleiche wie
|
|||
|
für UX.
|
|||
|
|
|||
|
(wl1w2 --w3) 83
|
|||
|
wl wird mit w2 bitweise logisch UND verknüpft und das ergibt w3.
|
|||
|
|
|||
|
(w1w2 --w3) 83
|
|||
|
w1 wird mit w2 logisch ODER verknüpft und das ergibt w3.
|
|||
|
|
|||
|
(w1w2 --w3) 83 X70Or"
|
|||
|
wl wird mit w2 bitweise logisch EXKLUSIV ODER verknüpft und das ergibt
|
|||
|
w3.
|
|||
|
|
|||
|
(uulu2 -- flag)
|
|||
|
Wenn ul kleiner oder gleich u und u kleiner u2 ist (ul<=u<u2), ist flag
|
|||
|
wahr. Benutzt die U< Operation. "
|
|||
|
|
|||
|
( 16b1 16b2 -- 16b1l false j true: ) "case-question"
|
|||
|
Vergleicht die beiden Werte 16bl und 16b2 miteinander. Sind sie gleich,
|
|||
|
verbleibt TRUE auf dem Stack. Sind sie verschieden, verbleibt FALSE und
|
|||
|
der darunterliegende Wert 16bl auf dem Stack. Wird z.B. in der folgenden
|
|||
|
Form benutzt :
|
|||
|
|
|||
|
key :
|
|||
|
Ascii a case? IF ... exit THEN
|
|||
|
|
|||
|
Ascii b case? IF ... exit THEN
|
|||
|
|
|||
|
drop n
|
|||
|
Entspricht dem Ausdruck over = dup IF nip THEN .
|
|||
|
|
|||
|
3.4 32Bit-Worte
|
|||
|
|
|||
|
(n-=-%0)
|
|||
|
Der Wert n wird auf den doppelt genauen Wert d vorzeichenrichtig er-
|
|||
|
weitert. Benutze für das in der Literatur oft auftretende s>d
|
|||
|
|
|||
|
“ extend Alias s)d
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Arithmetik = gr =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Geseilschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
dabs (d-- ud) 83 "d-absolut"
|
|||
|
ud ist der Betrag von d. Wenn d gleich -2.147.483.648 ist, hat ud den
|
|||
|
selben Wert wie d.
|
|||
|
|
|||
|
dnegate (d1ı--(d2) 83 "d-negate"
|
|||
|
d2 hat den gleichen Betrag aber ein anderes Vorzeichen als dl.
|
|||
|
|
|||
|
d+ (d1d2 -- d3) 83 "d-plus"
|
|||
|
dl und d2 addiert ergibt d3.
|
|||
|
|
|||
|
d- {di d2 -= d3) "d-minus"
|
|||
|
d2 minus di ergibt d3.
|
|||
|
|
|||
|
d* ( Ada" 49)) "d-times"
|
|||
|
di multipliziert mit d2 ergibt d93.
|
|||
|
|
|||
|
d= (di d2 -- flag ) "d-equal"
|
|||
|
Wenn dl gleich d2 ist, ist flag wahr.
|
|||
|
|
|||
|
d< (dıd2 -- flag ) 83 "d-less-than"
|
|||
|
Wenn di kleiner als d2 ist, ist flag wahr.
|
|||
|
|
|||
|
deß= (d -- flag) 83 "d-zero-equals"
|
|||
|
Wenn d gleich Null ist, ist flag wahr.
|
|||
|
|
|||
|
m* (nin2--d) "m-times"
|
|||
|
Der Wert von nl wird mit n2 multiplizert und d ist das doppelt genaue
|
|||
|
Produkt.
|
|||
|
|
|||
|
um* (ulu2 -- ud) 83 "u-m-times"
|
|||
|
Die Werte ul und u2 werden mulitpliziert und das ergibt das doppelt ge-
|
|||
|
naue Produkt ud. UM* ist die anderen multiplizierenden Worten zugrunde-
|
|||
|
liegende Routine.
|
|||
|
|
|||
|
m/mod (dnl--n2n3) "m-divide-mod"
|
|||
|
|
|||
|
n2 ist der Rest und n3 der Quotient aus der Division der doppelt ge-
|
|||
|
nauen Zahl d durch den Divisor nl. Der Rest n2 hat dasselbe Vorzeichen
|
|||
|
wie nl oder ist Null. Eine Fehlerbedingung besteht, wenn der Divisor Null
|
|||
|
ist oder der Quotient außerhalb des Intervalls (-32768..32767) liegt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 84. Arithmetik
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ud/mod (udl ul -- u2 ud2 ) "u-d-divide-mod"
|
|||
|
u2 ist der Rest und ud2 der doppelt genaue Quotient aus der Divison der
|
|||
|
doppelt genauen Zahl udl durch den Divisor ul. Die Zahlen u sind vor-
|
|||
|
zeichenlose 16-Bit Werte (unsigned integer). Eine Fehlerbedingung be-
|
|||
|
steht, wenn der Divisor Null ist.
|
|||
|
|
|||
|
um/mod (udul -- 2 u) 83 "u-m-divide-mod"
|
|||
|
u2 ist der Rest und u3 der Quotient aus der Division von ud durch den
|
|||
|
Divisor ul. Die Zahlen u sind vorzeichenlose Zahlen. Eine Fehlerbe-
|
|||
|
dingung besteht, wenn der Divisor Null ist oder der Quotient außerhalb
|
|||
|
des Intervalls (8..65535) liegt.
|
|||
|
|
|||
|
3.5 Stack-Operationen
|
|||
|
|
|||
|
Herkömmliche Programmiersprachen enthalten mehr oder weniger ausgeprägt das
|
|||
|
Konzept der PROZEDUREN:
|
|||
|
|
|||
|
Für bestimmte Programmfunktionen notwendige Operatoren werden in benannten
|
|||
|
Programmteilen zusammengefaßt, um diese Programmfunktionen an mehreren Stellen
|
|||
|
innerhalb eines Programmes über ihren Namen aktivieren zu können. Da FORTH
|
|||
|
ohne jede Einschränkung prozedural ist, macht FORTH auch keinen Unterschied
|
|||
|
zwischen Prozeduren und Funktionen oder seinen Operatoren. Alles wird als ein
|
|||
|
WORT bezeichnet.
|
|||
|
|
|||
|
FORTH als Programmier-SPRACHE besteht also aus Wörtern.
|
|||
|
|
|||
|
Somit können FORTH-Wörter sein:
|
|||
|
|
|||
|
1. Datenbereiche
|
|||
|
2. Algorithmen (Befehle)
|
|||
|
3. Programme
|
|||
|
|
|||
|
Um Prozeduren sinnvoll benutzen zu können, kennen die meisten Sprachen auch
|
|||
|
PARAMETER:
|
|||
|
|
|||
|
Dies sind Daten, die einer Prozedur bei ihrem Aufruf zur Bearbeitung übergeben
|
|||
|
|
|||
|
werden. Daten, die ausschließlich innerhalb einer Prozedur benötigt werden, heißen
|
|||
|
|
|||
|
LOKAL zu dieser Prozedur; im Gegensatz dazu nennt man Daten, die außerhalb von
|
|||
|
bestimmten Prozeduren zur Verfügung stehen und auf die von allen Prozeduren aus
|
|||
|
mit allen Operatoren zugegriffen werden kann, GLOBAL.
|
|||
|
|
|||
|
Die erste Möglichkeit der Parameterübergabe zwischen Prozeduren ist die Verein-
|
|||
|
barung von benannten GLOBALEN Variablen. Diese globalen Variablen sind für die
|
|||
|
gesamte Laufzeit des Programmes statisch existent und können von allen Proze-
|
|||
|
duren manipuliert werden.
|
|||
|
|
|||
|
Eine andere Möglichkeit der Parameterübergabe besteht im Einrichten eines Spei-
|
|||
|
cherbereiches, in dem während das Aufrufes eines Wortes namentlich benannte
|
|||
|
Parameter dynamisch verwaltetet werden.
|
|||
|
|
|||
|
Diesen Mechanismus für benannte lokale Variable stellt Standard-FORTH nicht zur
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Arithmetik =rgBbr-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Verfügung, weil die Organisation dieser lokalen Variablen mit einem Verlust sowohl
|
|||
|
der lokalen Daten nach der Ausführung des Wortes als auch einem Verlust in der
|
|||
|
Ausführungsgeschwindigkeit des Wortes verbunden sind. Für das volks4TH wurde in
|
|||
|
der VD 1/88 eine Implementierung benannter lokaler Variabler vorgestellt.
|
|||
|
|
|||
|
FORTH benutzt zur gegenseitigen Übergabe von Parametern an Wörter hauptsächlich
|
|||
|
den STACK, einen bestimmten Speicherbereich, in dem die Wörter ihre Parameter er-
|
|||
|
warten. Diese Parameter erhalten keine Namen, sondern ihre Interpretation ergibt
|
|||
|
sich aus der Position innerhalb des Stack-Speicherbereiches. Daraus resultiert die
|
|||
|
vielzahl von Operatoren zur Änderung der Stack-Position eines Wertes, für die
|
|||
|
FORTH berühmt/berüchtigt ist.
|
|||
|
|
|||
|
Damit deutlich wird, welche und wieviele Parameter ein Wort benötigt, werden all- 5
|
|||
|
gemein STACK-KOMMENTARE verwendet:
|
|||
|
|
|||
|
Der öffnenden runden Klammer folgt eine Aufzählung der Parameter. Dabei steht
|
|||
|
der Parameter, der als oberstes Stack-Element erwartet wird, ganz rechts. Dann
|
|||
|
folgt ein " -- ", das die Ausführung des Wortes symbolisieren soll. Anschließend
|
|||
|
wird der Zustand des Stacks nach der Ausführung des Wortes dargestellt, wobei das
|
|||
|
oberste Stackelement wieder ganz rechts steht. Die schließende. runde Klammer
|
|||
|
beendet den Stack-Kommentar.
|
|||
|
|
|||
|
Ein Wort SQRT, das die Quadratwurzel einer Integerzahl liefert, würde in FORTH so
|
|||
|
benannt und beschrieben:
|
|||
|
|
|||
|
sqrt (number -- sart )
|
|||
|
|
|||
|
Wird dieses neue Wort aufgerufen, so werden alle darin enthaltenen Wörter
|
|||
|
ausgeführt, eventuell bereitgestellte Parameter bearbeitet und daraus resultierende
|
|||
|
Ergebnisse auf dem Stack übergeben.
|
|||
|
|
|||
|
Der Aufruf von Prozeduren erfolgt in FORTH implizit durch die Nennung des
|
|||
|
Namens, ebenso wie auch die Datenübergabe zwischen Wörtern meist implizit erfolgt.
|
|||
|
|
|||
|
3.5.1 Datenstack-Operationen
|
|||
|
|
|||
|
drop ( 16b --) 83
|
|||
|
Der Wert 16b wird vom Stack entfernt.
|
|||
|
|
|||
|
2drop 82h #=+ ) 83 "two-drop"
|
|||
|
Der Wert 32b wird vom Stack entfernt.
|
|||
|
|
|||
|
dup ( 16b -- 16b i6b ) 83
|
|||
|
Der Wert 16b wird dupliziert.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
gon® Arithmetik
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
?dup
|
|||
|
|
|||
|
2dup
|
|||
|
|
|||
|
swap
|
|||
|
|
|||
|
2swap
|
|||
|
|
|||
|
nip
|
|||
|
|
|||
|
over
|
|||
|
|
|||
|
2over
|
|||
|
|
|||
|
under
|
|||
|
|
|||
|
rot
|
|||
|
|
|||
|
-rot
|
|||
|
|
|||
|
roll
|
|||
|
|
|||
|
roll
|
|||
|
|
|||
|
( 16b -- 16b 16b ! 8) 83 "question-dup"
|
|||
|
Nur wenn der Wert 16b von Null verschieden ist, wird er verdoppelt.
|
|||
|
|
|||
|
( 32b -- 32b 32b ) 83 "two-dup"
|
|||
|
Der Wert 32b wird dupliziert.
|
|||
|
|
|||
|
{ 16b1 16b2 -- 16b2 16bl ) 83
|
|||
|
Die beiden obersten 16-Bit Werte werden vertauscht.
|
|||
|
|
|||
|
( 32b1 32b2 -- 32b2 32b1 ) 83 "two-swap"
|
|||
|
Die beiden obersten 32-Bit Werte 32b1l und 32b2 werden vertauscht.
|
|||
|
|
|||
|
{ 16bl 1652 -- 16b2:)
|
|||
|
Der Wert 16bl, der unter 16b2 auf dem Stack liegt, wird vom Stack
|
|||
|
entfernt.
|
|||
|
|
|||
|
( 16b1 16b2 -- 16b1l 16b2 16b1 ) 83
|
|||
|
Der Wert 16b1l wird über 16b2 herüberkopiert.
|
|||
|
|
|||
|
( 32b1 32b2 -- 32b1l 32b2 31bl ) "two-over"
|
|||
|
Der Wert 32b1 wird über den Wert 32b2 herüber kopiert.
|
|||
|
|
|||
|
( 16b1 16b2 -- 16b2 16b1 16b2 )
|
|||
|
Eine Kopie des obersten Wertes auf dem Stack wird unter dem zweiten
|
|||
|
Wert eingefügt.
|
|||
|
|
|||
|
( 16b1 16b2 16b3 -- 16b2 16b3 16bl1 ) 83
|
|||
|
Die drei obersten Werte auf dem Stack werden rotiert, sodaß der unterste
|
|||
|
zum obersten wird.
|
|||
|
|
|||
|
( 16b1 16b2 16b3 -- 16b3 16bl 16b2 ) "minus-rot"
|
|||
|
Die drei obersten 16b Werte werden rotiert, sodaß der oberste Wert zum
|
|||
|
Untersten wird. Hebt rot auf.
|
|||
|
|
|||
|
( 16bn 16bm..16b@ +n -- 16bm..16bd 16bn ) 83
|
|||
|
Das +n-te Glied einer Kette von n Werten wird nach oben auf den Stack
|
|||
|
gerollt. Dabei wird +n selbst nicht mitgezählt.
|
|||
|
|
|||
|
( 16bn .. 16bl 16b® +n -- 16b8 16bn .. 16bl )
|
|||
|
Das oberste Glied einer Kette von +n Werten wird an die n-te Position
|
|||
|
gerollt. Dabei wird +n selbst nicht mitgezählt.
|
|||
|
2 -roll wirkt wie -rot ,„ ® -roll verändert nichts.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Arithmetik u
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
pick { 16bn..16b8 +n -- 16bn..16b® 16bn ) 83
|
|||
|
Der +n-te Wert auf dem Stack wird nach oben auf den Stack kopiert.
|
|||
|
Dabei wird +n selbst nicht mitgezählt.
|
|||
|
|
|||
|
8 pick wirkt wie dup , 1 pick wie over.
|
|||
|
|
|||
|
.S (--) "dot-s"
|
|||
|
Gibt alle Werte, die auf dem Stack liegen aus, ohne den Stack zu ver-
|
|||
|
ändern. Oft benutzt, um neue Worte auszutesten. Die Ausgabe der Werte
|
|||
|
erfolgt von links nach rechts, der oberste Stackwert zuerst, so daß der
|
|||
|
top of stack (tos) ganz links steht!
|
|||
|
|
|||
|
clearstack Goa ==)
|
|||
|
|
|||
|
Löscht den Datenstack. Alle Werte, die sich vorher auf dem Stack befan-
|
|||
|
den, sind verloren,
|
|||
|
|
|||
|
depth ("-n)
|
|||
|
|
|||
|
n ist die Anzahl der Werte, die auf dem Stack lagen, bevor DEPTH ausge-
|
|||
|
führt wurde.
|
|||
|
|
|||
|
sd ( -- addr ) ‘ "s-zero"
|
|||
|
addr ist die Adresse einer Uservariablen, in der. die Startadresse des
|
|||
|
Stacks steht. Der Ausdruck s® @ sp! wirkt wie clearstack und leert
|
|||
|
den Stack.
|
|||
|
|
|||
|
sp! ( addr -- ) "s-p-store"
|
|||
|
Setzt den Stackzeiger (stack pointer) auf die Adresse addr. Der oberste
|
|||
|
Wert auf dem Stack ist dann der, welcher in der Adresse addr steht.
|
|||
|
|
|||
|
sp@® ( -- addr ) "s-p-fetch"
|
|||
|
Holt die Adresse addr aus dem Stackzeiger. Der oberste Wert im Stack
|
|||
|
stand in der Speicherstelle bei addr, bevor sp@ ausgeführt wurde.
|
|||
|
|
|||
|
3.5.2 Returnstack-Operationen
|
|||
|
|
|||
|
rdepth (--n) "r-depth"
|
|||
|
n ist die Anzahl der Werte, die auf dem Returnstack liegen.
|
|||
|
|
|||
|
»r (16b --) c,83 "to=r"
|
|||
|
Der Wert 16b wird auf den Returnstack gelegt. Siehe auch RD.
|
|||
|
|
|||
|
r> C--166) 0,83 "r-from"
|
|||
|
Der Wert 16b wird vom Returnstack geholt. Vergleiche R>.
|
|||
|
|
|||
|
= 38 - Arithmetik
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
r®
|
|||
|
|
|||
|
rdrop
|
|||
|
|
|||
|
ro
|
|||
|
|
|||
|
— rp®
|
|||
|
|
|||
|
rp!
|
|||
|
|
|||
|
push
|
|||
|
|
|||
|
( -- 16b ) c,83 "r-fetch"
|
|||
|
Der Wert 16b ist eine Kopie des obersten Wertes auf dem Returnstack.
|
|||
|
|
|||
|
==) © "r-drop"
|
|||
|
Der oberste Wert wird vom Returnstack entfernt. Der Datenstack wird
|
|||
|
nicht verändert. Entspricht der Operation r> drop.
|
|||
|
|
|||
|
( -- addr ) U "r-zero"
|
|||
|
addr ist die Adresse einer Uservariablen, in der die Startadresse des
|
|||
|
Returnstacks steht.
|
|||
|
|
|||
|
( ==eiaddr ) "r-p-fetch"
|
|||
|
Holt die Adresse addr aus dem Returnstackzeiger. Der oberste Wert im
|
|||
|
Returnstack steht in der Speicherstelle bei addr.
|
|||
|
|
|||
|
(addr. ==) "r-p-store"
|
|||
|
Setzt den Returnstackzeiger (return stack pointer) auf die Adresse addr.
|
|||
|
Der oberste Wert im Returnstack ist nun der, welcher in der Speicher-
|
|||
|
stelle bei addr steht.
|
|||
|
|
|||
|
( addr -- )
|
|||
|
Der Inhalt aus der Adresse addr wird bis zum nächsten EXIT oder
|
|||
|
auf dem Returnstack verwahrt und sodann nach addr zurückgeschrieben.
|
|||
|
Dies ermöglicht die lokale Verwendung von Variablen innerhalb einer
|
|||
|
:-Definition. Wird z.B. benutzt in der Form :
|
|||
|
|
|||
|
: hex. (n--) base push hex.;
|
|||
|
Hier wird innerhalb von HEX. in der Zahlenbasis HEX gearbeitet, um
|
|||
|
eine Zahl auszugeben. Nachdem HEX. ausgeführt worden ist, besteht die
|
|||
|
gleiche Zahlenbasis wie vorher, durch HEX wird sie also nur innerhalb
|
|||
|
von HEX. verändert.
|
|||
|
|
|||
|
’
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Arithmetik =99--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4. Kontrollstrukturen
|
|||
|
|
|||
|
4.1 Programm-Strukturen
|
|||
|
|
|||
|
wil Baden, auf den Sie in der englischsprachigen Literatur oft stoßen, hat in
|
|||
|
seinem Beitrag ESCAPING FORTH folgendes dargelegt:
|
|||
|
Es gibt vier Arten von Steueranweisungen :
|
|||
|
|
|||
|
- die Abfolge von Anweisungen,
|
|||
|
|
|||
|
- die Auswahl von Programmteilen,
|
|||
|
|
|||
|
- die Wiederholung von Anweisungen und Programmteilen
|
|||
|
|
|||
|
- den Abbruch.
|
|||
|
|
|||
|
Die ersten drei Möglichkeiten sind zwingend notwendig und in den älteren Sprachen
|
|||
|
wie PASCAL ausschließlich vorhanden. Entsprechend steht im volksFORTH eine
|
|||
|
Anweisung für die Auswahl von Programmteilen zur Verfügung, wobei die
|
|||
|
Ausführung vom Resultat eines logischen Ausdrucks abhängig gemacht wird:
|
|||
|
|
|||
|
flag IF <Anweisungen)> THEN
|
|||
|
flag IF <Anweisungen)> ELSE <Anweisungen> THEN
|
|||
|
|
|||
|
Soll dagegen im Programm ein Rücksprung erfolgen, um Anweisungen wiederholt
|
|||
|
auszuführen, wird bei einer gegebenen Anzahl von Durchläufen diese Anweisung
|
|||
|
eingesetzt, wobei der aktuelle Index über I und J zur Verfügung steht:
|
|||
|
|
|||
|
“Grenzen? DO / ?DO <Anweisungen) LOOP
|
|||
|
“Grenzen? DO / ?DO <Anweisungen)> (Schrittweite) +LOOP
|
|||
|
|
|||
|
Wenn eine Wiederholung von Anweisungen ausgeführt werden soll, ohne daß die
|
|||
|
Anzahl der Durchläufe bekannt ist, so ist eine Indexvariable mitzuführen oder
|
|||
|
sonstwie zum Resultat eines logischen Ausdrucks zu kommen. Die folgende Kon-
|
|||
|
struktion ermöglicht eine Endlos-Schleife;
|
|||
|
|
|||
|
BEGIN <Anweisungen)> REPEAT
|
|||
|
Die Wiederholungsanweisungen sind insoweit symmetrisch, daß eine Anweisung so-
|
|||
|
lange (while) ausgeführt wird, wie ein Ausdruck wahr ist, oder eine Anweisung
|
|||
|
wiederholt wird, bis (until) ein Ausdruck wahr wird.
|
|||
|
|
|||
|
BEGIN <Anweisungen> flag UNTIL
|
|||
|
|
|||
|
BEGIN (Anweisungen) flag WHILE (Anweisungen) REPEAT
|
|||
|
Beide Möglichkeiten lassen sich in volksFORTH auch kombinieren, wobei auch
|
|||
|
mehrere (multiple) WHILE in einer Steueranweisung auftreten dürfen.
|
|||
|
|
|||
|
BEGIN “Anweisungen? flag WHILE (Anweisungen) flag UNTIL
|
|||
|
|
|||
|
Nun tritt in Anwendungen häufig der Fall auf, daß eine Steueranweisung verlassen
|
|||
|
werden sol), weil sich etwas ereignet hat.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=.40.= Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Dann ist die vierte Situation, der Abbruch, gegeben. C stellt dafür die Funktionen:
|
|||
|
break, continue, return und exit zur Verfügung; volksFORTH bietet hier exit
|
|||
|
leave endloop quit abort abort" und abort( an.
|
|||
|
|
|||
|
In FORTH wird EXIT dazu benutzt, um die Definition zu verlassen, in der es er-
|
|||
|
scheint; LEAVE dagegen verläßt die kleinste umschließende DO...LOOP-Schleife.
|
|||
|
|
|||
|
Glossar
|
|||
|
|
|||
|
Ab der Version 3.81.3 verfügt volksFORTH über eine zusätzliche Steueranweisung
|
|||
|
für den Compiler, die bedingte Kompilierung in der Form:
|
|||
|
|
|||
|
have <word) not .IF <actioni) .ELSE <action2) „THEN
|
|||
|
|
|||
|
Diese Worte werden außerhalb von Colon-Definitionen eingesetzt und ersetzen das
|
|||
|
\needs früherer Versionen.
|
|||
|
|
|||
|
have ( -- flag )
|
|||
|
prüft, ob ein Wort im Wörterbuch in der Suchreihenfolge existiert und
|
|||
|
hinterläßt ein entsprechendes Flag. In der Literatur und in Quelltexten
|
|||
|
findet man auch exists? als Synonym.
|
|||
|
|
|||
|
exit (--)
|
|||
|
ist ein Synonym für unnest .
|
|||
|
Dieses wird von ";" (Semicolon) als Abschluß einer Colondefinition compi-
|
|||
|
liert. Ebenso dient EXIT als Austritt aus einem Wort, wobei das Programm
|
|||
|
in der aufrufenden Ebene fortgesetzt wird (return to caller).
|
|||
|
Ein EXIT ist innerhalb von DO..LOOP-Strukturen nicht ohne weiteres
|
|||
|
möglich (siehe endloop).
|
|||
|
Diese Steueranweisung ist nicht umkehrbar, der Sprung in eine hier-
|
|||
|
archisch niedrigere Ebene ist nicht erlaubt.
|
|||
|
Typisch: flag IF exit THEN
|
|||
|
|
|||
|
?exit {flag --) "question-exit"
|
|||
|
führt EXIT aus, falls das Flag wahr ist. Ist das Flag falsch, so ge-
|
|||
|
schieht nichts. Hierbei soll daran erinnert werden, daß jede Zahl ungleich
|
|||
|
NULL als wahr interpretiert wird.
|
|||
|
|
|||
|
Entspricht: true IF exit THEN
|
|||
|
|
|||
|
ö=exit tag —) "zero-equals-exit"
|
|||
|
führt EXIT aus, falls das Flag falsch ist. Ist das Flag wahr, so geschieht
|
|||
|
nichts. Es entspricht 0= IF exit THEN und wird typisch so eingesetzt:
|
|||
|
|
|||
|
key #cr - O=exit
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen = GR -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
IE (flag --) 83,1,C
|
|||
|
(--sys) compiling
|
|||
|
wird in der folgenden Art benutzt;
|
|||
|
flag IF ... ELSE ... THEN
|
|||
|
oder: flag IF ... THEN
|
|||
|
Ist das Flag wahr, so werden die Worte zwischen IF und ELSE ausgeführt
|
|||
|
und die Worte zwischen ELSE und THEN ignoriert.
|
|||
|
Der ELSE-Teil ist optional. Ist das Flag falsch, so werden die Worte
|
|||
|
zwischen IF und ELSE (bzw. zwischen IF und THEN , falls ELSE nicht
|
|||
|
vorhanden ist) ignoriert.
|
|||
|
|
|||
|
Je ist das IF für den Interpretermodus.
|
|||
|
THEN (==) 83,1,C
|
|||
|
(sys --) compiling
|
|||
|
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
|
|||
|
IF (...ELSE) ... THEN
|
|||
|
Hinter THEN ist die Programmverzweigung zuende. .
|
|||
|
Weil viele FORTH-Freunde die "alte" Schreibweise vor der Festlegung des
|
|||
|
83er Standards besser und deutlicher finden, sei hier die Definition von
|
|||
|
ENDIF gezeigt:
|
|||
|
|
|||
|
' THEN Alias ENDIF immediate restrict
|
|||
|
|
|||
|
.THEN ist das THEN für den Interpretermodus.
|
|||
|
|
|||
|
ELSE (--) 83,1,C
|
|||
|
( sysi -- sys2 ) compiling
|
|||
|
wird in der foigenden Art benutzt:
|
|||
|
flag IF ... ELSE ... THEN
|
|||
|
ELSE wird unmittelbar nach dem Wahr-Teil, der auf IF folgt, ausge-
|
|||
|
führt. ELSE setzt die Ausführung unmittelbar hinter THEN fort.
|
|||
|
|
|||
|
‚ELSE ist das ELSE für den Interpretermodus.
|
|||
|
DO (ww--) 83,1,C
|
|||
|
(sys --) compiling
|
|||
|
beginnt eine Schleife und entspricht somit ?DO , jedoch wird der
|
|||
|
|
|||
|
Schleifenrumpf mindestens einmal durchlaufen. Der Schleifenindex beginnt
|
|||
|
mit w2, Grenze ist wl..
|
|||
|
Ist wl1=w2 , so wird der Schleifenrumpf 65536-mal durchlaufen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
I
|
|||
|
En
|
|||
|
D
|
|||
|
|
|||
|
!
|
|||
|
|
|||
|
Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
?DO
|
|||
|
|
|||
|
LOOP
|
|||
|
|
|||
|
+LOOP
|
|||
|
|
|||
|
leave
|
|||
|
|
|||
|
(wlw2 --) 83,1,C "question-do"
|
|||
|
(--sys ) compiling
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
?DO ... LOOP bzw. ?DO ... +LOOP
|
|||
|
Beginnt eine Schleife. Der Schleifenindex beginnt mit w2, Limit ist wl. .
|
|||
|
Ist w2=wl, so wird der Schleifenrumpf überhaupt nicht durchlaufen.
|
|||
|
Für Details über die Beendigung von Schleifen siehe +LOOP
|
|||
|
|
|||
|
(==) 83,1,C
|
|||
|
( --sys ) compiling
|
|||
|
entspricht +LOOP, jedoch mit einer festen Schrittweite von 1.
|
|||
|
|
|||
|
(n--) 83,1,C "plus-loop"
|
|||
|
(sys--) compiling
|
|||
|
Die Schrittweite n wird zum Loopindex addiert. Falls durch die Addition
|
|||
|
die Grenze zwischen limit-1 und limit überschritten wurde, so wird die
|
|||
|
Schleife beendet und die Loop-Parameter werden entfernt. Wurde die
|
|||
|
Schleife nicht beendet, so wird sie hinter dem korrespondierenden DO
|
|||
|
bzw. ?DO fortgesetzt.
|
|||
|
|
|||
|
(--w) 83,C
|
|||
|
wird zwischen DO und LOOP benutzt, um eine Kopie .des Schleifenindex
|
|||
|
auf den Stack zu holen.
|
|||
|
|
|||
|
(--w) 83,C
|
|||
|
wird in zwei geschachtelten DO...LOOP-Schleifen zwischen DO .. DO und
|
|||
|
LOOP .. LOOP benutzt, um eine Kopie des Schleifenindex der äusseren
|
|||
|
|
|||
|
Schleife auf den Stack zu holen.
|
|||
|
|
|||
|
(=) 83,C
|
|||
|
beendet die zugehörige Schleife und setzt die Ausführung des Programmes
|
|||
|
hinter dem nächsten LOOP oder +LOOP fort. Mehr als ein LEAVE pro
|
|||
|
Schleife ist möglich, ferner kann LEAVE zwischen anderen Kontroll-
|
|||
|
strukturen auftreten. Der FORTH83-Standard schreibt abweichend vom
|
|||
|
volksFORTH vor, daß LEAVE ein immediate Wort ist.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen - 48 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
endloop ( ==
|
|||
|
ermöglicht ein EXIT innerhalb einer DO...LOOP. Es wird so eingesetzt:
|
|||
|
(Grenzen)DO "
|
|||
|
“Anweisungen)
|
|||
|
flag IF endloop exit THEN
|
|||
|
LOOP
|
|||
|
Damit kann exit auch in einer DO...LOOP-Schleife verwendet werden,
|
|||
|
vorausgesetzt, Sie halten sich an zwei Regeln:
|
|||
|
1. Sie dürfen das System nicht mit Returnstack-Manipulatio-
|
|||
|
nen aus dem Gleichgewicht gebracht haben.
|
|||
|
2, Bei geschachtelten DO...LOOP-Schleife muß für jede Schlei-
|
|||
|
fenebene ein endloop dem abbrechenden exit vorangehen.
|
|||
|
In der Literatur findet man auch UNDO als Synonym für ENDLOOP.
|
|||
|
bounds ( start count -- limit start )
|
|||
|
dient dazu, ein Intervall, das durch Anfangswert und Länge gegeben ist,
|
|||
|
in ein Intervall umzurechnen, das durch Anfangswert und Endwert+i1
|
|||
|
beschrieben wird. Beispiel:
|
|||
|
106 3 bounds DO...LOOP
|
|||
|
führt dazu, das I die Werte 18 11 12 annimmt.
|
|||
|
BEGIN (==) 4 83,1,C
|
|||
|
(sys --- ) compiling
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
BEGIN ( ...£lag WHILE ) ... flag UNTIL
|
|||
|
oder: BEGIN ( ...£flag WHILE ) ... REPEAT
|
|||
|
BEGIN markiert den Anfang einer Schleife. Der ()-Ausdruck ist optional
|
|||
|
und kann beliebig oft auftreten. Die Schleife wird wiederholt, bis das
|
|||
|
Flag vor UNTIL wahr oder oder das Flag vor WHILE falsch ist. REPEAT
|
|||
|
setzt die Schleife immer fort.
|
|||
|
Die Schleife BEGIN <Anweisungen) flag UNTIL wird immer mindestens
|
|||
|
einmal durchlaufen, da die Abbruchbedingung erst nach dem ersten
|
|||
|
Durchlauf geprüft wird.
|
|||
|
Um dazu vollständige Symmetrie zu erreichen, kann im Ausdruck
|
|||
|
BEGIN <action)> flag WHILE.<action) REPEAT
|
|||
|
der Anweisungsteil vor WHILE entfallen:
|
|||
|
BEGIN flag WHILE <Anweisungen)? REPEAT
|
|||
|
prüft die Abbruchbedingung vor dem Eintritt in die Schleife.
|
|||
|
= 44 = Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
REPEAT
|
|||
|
|
|||
|
UNTIL
|
|||
|
|
|||
|
WHILE
|
|||
|
|
|||
|
execute
|
|||
|
|
|||
|
perform
|
|||
|
|
|||
|
case?
|
|||
|
|
|||
|
==) 83,1,C
|
|||
|
|
|||
|
(--sys) compiling
|
|||
|
wird in der folgenden Form benutzt:
|
|||
|
|
|||
|
BEGIN (.. WHILE) .. REFEAT
|
|||
|
REPEAT setzt die Ausführung der Schleife unmittelbar hinter BEGIN fort.
|
|||
|
Der ()-Ausdruck ist optional und kann beliebig oft auftreten. Deshalb
|
|||
|
gibt es kein AGAIN ‚, benutzen Sie statt dessen REPEAT oder
|
|||
|
|
|||
|
definieren: ' REPEAT Alias AGAIN immediate restrict
|
|||
|
(flag -- ) 83,1,C
|
|||
|
(sys -- ) compiling
|
|||
|
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
|
|||
|
BEGIN (... flag WHILE) ... flag UNTIL
|
|||
|
Markiert das Ende einer Schleife, deren Abbruch durch flag herbeigeführt
|
|||
|
wird. Ist das Flag vor UNTIL wahr, so wird die Schleife beendet, ist es
|
|||
|
falsch, so wird die Schleife unmittelbar hinter BEGIN fortgesetzt.
|
|||
|
|
|||
|
(flag --) 83,1,C
|
|||
|
|
|||
|
( sysl -- sys2 ) compiling
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
|
|||
|
BEGIN .. flag WHILE .. REPEAT
|
|||
|
oder: BEGIN .. flag WHILE .. flag UNTIL
|
|||
|
Ist das Flag vor WHILE wahr, so wird die Ausführung der Schleife bis
|
|||
|
UNTIL oder REPEAT fortgesetzt, ist es falsch, so wird die Schleife be-
|
|||
|
endet und das Programm hinter UNTIL bzw. REPEAT fortgesetzt. Es kön-
|
|||
|
nen mehrere WHILE in einer Schleife verwendet werden.
|
|||
|
|
|||
|
( addr -- ) 83
|
|||
|
Das Wort, dessen Kompilationsadresse addr ist, wird ausgeführt.
|
|||
|
|
|||
|
( addr -- )
|
|||
|
addr ist eine Adresse, unter der sich ein Zeiger auf die Kompilations-
|
|||
|
adresse eines Wortes befindet. Dieses Wort wird ausgeführt. Entspricht
|
|||
|
der Sequenz @ execute .
|
|||
|
|
|||
|
( 16bl 16b2 -- 16b1 false ! true ) "case-question"
|
|||
|
vergleicht die beiden Werte 16bl und 16b2 miteinander.
|
|||
|
Sind sie gleich, verbleibt TRUE auf dem Stack. Sind sie verschieden, ver-
|
|||
|
bleibt FALSE und der darunterliegende Wert 16bl auf dem Stack.
|
|||
|
Wird z.B. in der folgenden Form benutzt :
|
|||
|
key
|
|||
|
Ascii a case? IF ... exit THEN
|
|||
|
Ascii b case? IF ... exit THEN
|
|||
|
drop
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen u a
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
stop?
|
|||
|
|
|||
|
(-- flag ) "stop-question"
|
|||
|
ist ein komfortables Wort, das es dem Benutzer gestattet, einen Pro-
|
|||
|
grammablauf anzuhalten oder zu beenden,
|
|||
|
|
|||
|
Steht vom Eingabegerät ein Zeichen zur Verfügung, so wird es eingelesen.
|
|||
|
Ist es #ESC oder CTRL-C , so ist flag TRUE, sonst wird auf das nächste
|
|||
|
Zeichen gewartet. Ist dieses jetzt #ESC oder CTRL-C , so wird STOP? mit
|
|||
|
TRUE verlassen, sonst mit FALSE.
|
|||
|
|
|||
|
Steht kein Zeichen zur Verfügung, so ist das Flag FALSE . STOP? prüft
|
|||
|
also einen Tastendruck auf #ESC oder CTRL-C .
|
|||
|
|
|||
|
4.2 Worte zur Fehlerbehandlung
|
|||
|
|
|||
|
Diese arbeiten auch wie Steueranweisungen, wie die Definitionen von ARGUMENTS
|
|||
|
und IS-DEPTH zeigen:
|
|||
|
|
|||
|
is-depth (n--)
|
|||
|
depth 1- - abort" falsche Parameterzahl!" ;
|
|||
|
|
|||
|
IS-DEPTH überprüft den Stack auf eine gegebene Anzahl Stackelemente (depth) hin.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
abort (=>n 83,1
|
|||
|
leert den Stack, führt END-TRACE 'ABORT STANDARDI/O und QUIT
|
|||
|
aus.
|
|||
|
|
|||
|
'abort (==) "tick-abort"
|
|||
|
ist ein deferred Wort, das mit NOOP vorbesetzt ist. Es wird in ABORT
|
|||
|
ausgeführt, bevor QUIT aufgerufen wird.
|
|||
|
|
|||
|
abort" ( flag ) 83,1,C "abort-quote"
|
|||
|
|
|||
|
(==) compiling
|
|||
|
wird in der folgenden Form benutzt:
|
|||
|
flag Abort" ccc"
|
|||
|
Wird ABORT" später ausgeführt, ‘so geschieht nichts, "wenn: das Flag
|
|||
|
falsch ist. Ist das Flag wahr, so wird der Stack geleert und der Inhalt
|
|||
|
von ERRORHANDLER ausgeführt. Beachten Sie bitte, daß im Gegensatz zu
|
|||
|
ABORT kein END-TRACE ausgeführt wird.
|
|||
|
error" ( flag ) L,C "error-quote"
|
|||
|
(=) compiling
|
|||
|
Dieses Wort entspricht ABORT" , jedoch mit dem Unterschied, daß der
|
|||
|
Stack nicht geleert wird.
|
|||
|
- 46 - Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
errorhandler € -- addr )
|
|||
|
addr ist die Adresse einer Uservariablen, deren Inhalt die Kompilations-
|
|||
|
adresse eines Wortes ist. Dieses Wort wird ausgeführt, wenn das Flag, das
|
|||
|
ABORT" bzw. ERROR" verbrauchen, wahr ist. Der Inhalt von
|
|||
|
ERRORHANDEER ist normalerweise (ERROR.
|
|||
|
|
|||
|
(error ( string -- ) "paren-error"
|
|||
|
Dieses Wort steht normalerweise in der Variablen ERRORHANDLER und
|
|||
|
wird daher bei ABORT" und ERROR" ausgeführt. string ist dann die
|
|||
|
Adresse des auf ABORT" bzw. ERROR" folgenden Strings. (ERROR gibt das
|
|||
|
letzte Wort des Quelltextes gefolgt von dem String auf dem Bildschirm
|
|||
|
aus. Die Position des letzten Wortes im Quelltext, bei dem der Fehler
|
|||
|
auftrat, wird in SCR und R# abgelegt.
|
|||
|
|
|||
|
T# ( -- addr ) "r-sharp"
|
|||
|
addr ist die Adresse einer Variablen, die den Abstand des gerade edi-
|
|||
|
tierten Zeichens vom Anfang des gerade editierten Screens enthält.
|
|||
|
Vergleiche (ERROR und SCR .
|
|||
|
|
|||
|
ser ( -- addr ) 83 "s-c-r"
|
|||
|
addr ist die Adresse einer Variablen, die die Nummer des gerade
|
|||
|
editierten Screens enthält.
|
|||
|
|
|||
|
Vergleiche R# ,„ (ERROR und LIST.
|
|||
|
|
|||
|
quit (==) "quit"
|
|||
|
entleert den Returnstack und schaltet den interpretierenden Zustand ein.
|
|||
|
|
|||
|
?pairs (nin2 --) "question-pairs"
|
|||
|
Ist nl <> n2 ,„ so wird die Fehlermeldung "unstructured" ausgegeben.
|
|||
|
Dieses Wort wird benutzt, um die korrekte Schachtelung der Kontroll-
|
|||
|
strukturen zu überprüfen.
|
|||
|
|
|||
|
4.3 Fallunterscheidung in FORTH
|
|||
|
|
|||
|
4.3.1 Strukturierung mit IF ELSE THEN / ENDIF
|
|||
|
|
|||
|
An dieser Stelle soll kurz die vielfältigen Möglichkeiten gezeigt werden, mit denen
|
|||
|
eine Fallunterscheidung in FORTH getroffen werden kann. Kennzeichnend für eine
|
|||
|
solche Programmsituation ist, daß von verschiedenen Möglichkeiten des Programm-
|
|||
|
flusses genau eine ausgesucht werden soll.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen - 47 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-voliksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ausgehend von einer übersichtlichen Problemstellung, einem Spiel, werden die not-
|
|||
|
wendigen Grundlagendefinitionen und die Entwicklung der oben beschriebenen
|
|||
|
Kontrollstruktur beschrieben.
|
|||
|
|
|||
|
Als Beispiel dient ein Spiel mit einfachen Regeln:
|
|||
|
|
|||
|
Bei diesem Trinkspiel, das nach [1] auch CRAPS genannt wird, geht es darum, einen
|
|||
|
Vorrat von gefüllten Gläsern unter den Mitspielern mit Hilfe des Würfels zu ver-
|
|||
|
teilen und leerzutrinken:
|
|||
|
|
|||
|
- Bei einer EINS wurde ein Glas aus dem Vorrat in der Tischmitte ge-
|
|||
|
nommen und vor sich gestellt.
|
|||
|
|
|||
|
_ Bei einer ZWEI oder einer DREI bekam der Nachbar/ die Nachbarin
|
|||
|
links ein Glas des eigenen Vorrates zugeschoben.
|
|||
|
Bei einer VIER oder einer FÜNF wurde dem Nachbarn/ der Nachbarin
|
|||
|
rechts ein Glas des eigenen Vorrates vorgesetzt.
|
|||
|
|
|||
|
- Bei einer SECHS wurden alle Gläser, die der Spieler/ die Spielerin
|
|||
|
vor sich stehen hatte, leergetrunken.
|
|||
|
|
|||
|
Zuordnung ist also: I=nehmen, 2/3=links, 4/5=rechts, 6=trinken und entsprechend
|
|||
|
der Augenzahl des Würfels soll eine der 6 möglichen Aktionen ausgeführt werden.
|
|||
|
Das Programm soll sich darauf beschränken, das Ergebnis dieses Würfelns einzu-
|
|||
|
lesen und auszuwerten. Daraufhin wird eine Meldung ausgegeben, welche der sechs
|
|||
|
Handlungen auszuführen ist.
|
|||
|
|
|||
|
Für ein solches Programm ist eine Zahleneingabe notwendig. Diese wurde hier mit
|
|||
|
dem Wort F83-NUMBER? realisiert:
|
|||
|
|
|||
|
: F83-number? ( string --d£f)
|
|||
|
number? ?dup
|
|||
|
|
|||
|
IF
|
|||
|
0< IF extend THEN
|
|||
|
true exit
|
|||
|
|
|||
|
THEN
|
|||
|
|
|||
|
drop 08 false ;
|
|||
|
|
|||
|
: input# ( <string® -- n)
|
|||
|
pad c/1l 1- >expect
|
|||
|
pad F83-number? 2drop ;
|
|||
|
|
|||
|
Die Definition der Wörter, die sechs oben genannten Aktionen symbolisch aus-
|
|||
|
|
|||
|
führen sollen, richtet sich nach den Spielregeln. die für jedes Würfelergebis genau
|
|||
|
eine Handlung vorschreiben:
|
|||
|
|
|||
|
\ nehmen trinken links rechts schieben
|
|||
|
|
|||
|
: nehmen bright .” ein Glas nehmen” normal 2 spaces ;
|
|||
|
ı trinken bright ." alle Gläser austrinken" normal 2 spaces ;
|
|||
|
: links bright ." ein Glas nach LINKS" normal 2 spaces ;
|
|||
|
: rechts bright ." ein Glas nach RECHTS" normal 2 spaces ;
|
|||
|
|
|||
|
: schieben
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 48 - Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
SCHIEBEN ist eine Dummyprozedur, ein Füllsel, dessen Notwendigkeit sich erst sehr
|
|||
|
spät ergibt.
|
|||
|
Für den Dialog mit dem Anwender wird definiert:
|
|||
|
|
|||
|
: Anfrage er ." Sollen Sie nehmen, trinken oder schieben? "
|
|||
|
er ." Bitte Ihre Augenzahl und (cr) : " ,
|
|||
|
|
|||
|
: Glückwunsch cr ." Viel Glück beim nächsten Wurf ... " ;
|
|||
|
|
|||
|
Das Wort AUSWERTUNG soll entsprechend einem Selektor genau eine von 6 mög-
|
|||
|
lichen Prozeduren ausführen. Also wird man prüfen, ob diese oder diese oder ... der
|
|||
|
Möglichkeiten in Frage kommt. Hinzu kommt noch die Prüfung, ob der übergebene
|
|||
|
Parameter zwischen (between) 1 und 6 lag.
|
|||
|
|
|||
|
Die Definition von BETWEEN ist volksFORTH-gemäß recht kurz:
|
|||
|
|
|||
|
Wert Untergrenze Obergrenze -- false oder )
|
|||
|
|
|||
|
(
|
|||
|
( -- true wenn Untergrenze<Wert<sObergrenze )
|
|||
|
: between 1+ wwithin ;
|
|||
|
|
|||
|
: Auswertung.i ( Wurfergebnis -- )
|
|||
|
dup 1 = IF nehmen ELSE
|
|||
|
dup 2 = IF links schieben ELSE
|
|||
|
|
|||
|
dup 3 = IF links schieben ELSE
|
|||
|
dup 4 = IF rechts schieben ELSE
|
|||
|
dup 5 = IF rechts schieben ELSE
|
|||
|
dup 6 = IF trinken THEN
|
|||
|
THEN
|
|||
|
THEN
|
|||
|
THEN
|
|||
|
THEN
|
|||
|
THEN
|
|||
|
|
|||
|
1 6 between not IF invers ." Betrug!" normal THEN ;
|
|||
|
|
|||
|
Ein Verzicht auf den ELSE-Teil führt schon zu einer übersichtlicheren Form:
|
|||
|
: Auswertung.2 ( Wurfergebnis --)
|
|||
|
|
|||
|
dup 1 = IF nehnen THEN
|
|||
|
dup 2 = IF links schieben THEN
|
|||
|
dup 3 = IF links schieben THEN
|
|||
|
dup 4 = IF rechts schieben THEN
|
|||
|
dup 5 = IF rechts schieben THEN
|
|||
|
dup 6 = IF trinken THEN
|
|||
|
|
|||
|
1 6 between not IF inverse ." Betrug!" normal THEN ;
|
|||
|
|
|||
|
Da eine solche Prüfung auf Gleichheit in der Programmierpraxis oft vorkommt, stellt
|
|||
|
das volks4TH dafür das Wort case? zur Verfügung. case? vergleicht die obersten
|
|||
|
beiden Stackwerte miteinander. Bei Ungleichheit bleibt der Testwert (Selektor)
|
|||
|
erhalten, so daß die Worte DUP und = dadurch ersetzt werden.
|
|||
|
|
|||
|
: Auswertung.3 { Wurfergebnis -- }
|
|||
|
|
|||
|
case? IF nehmen exit THEN
|
|||
|
case? IF links schieben exit THEN
|
|||
|
case? IF links schieben exit THEN
|
|||
|
case? IF rechts schieben exit THEN
|
|||
|
case? IF rechts schieben exit THEN
|
|||
|
|
|||
|
bmw
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen - 49 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.31
|
|||
|
|
|||
|
|
|||
|
|
|||
|
6 case? IF trinken exit THEN
|
|||
|
|
|||
|
drop invers ." Betrug!" normal v
|
|||
|
|
|||
|
Bei dieser Auswertung wird aus dem Quelltext zu wenig deutlich, daß bei ZWEI
|
|||
|
und DREI dieselbe Handlung ausgeführt wird, wie auch VIER und FÜNF die glei-
|
|||
|
chen Aktionen zur Folge haben.
|
|||
|
|
|||
|
=OR prüft deshalb einen Testwert n2 auf Gleichheit mit einer unter einem Flag fl
|
|||
|
liegenden Zahl n2. Das Ergebnis dieses Tests wird mit dem bereits vorliegenden
|
|||
|
Flag OR-verknüpft. Dieses neue Flag f2 und der Testwert nl werden übergeben:
|
|||
|
|
|||
|
code =or {nl fin2 --n1£2)
|
|||
|
AD xchg D pop
|
|||
|
SWnov
|
|||
|
W)Acmp
|
|||
|
= ?[ -1 #Dnov )?
|
|||
|
next
|
|||
|
end-code
|
|||
|
|
|||
|
\:=or (nl fin2--ni f2) 2pick=or ;
|
|||
|
|
|||
|
Dieses Wortes bringt im Quelltext eine deutliche Verbesserung:
|
|||
|
|
|||
|
: Auswertung.4 ( Wurfergebnis --)
|
|||
|
|
|||
|
dup
|
|||
|
1 6 between IF
|
|||
|
dup 1 = IF nehnen THEN
|
|||
|
dup 2 = 3 =or IF links schieben THEN
|
|||
|
dup 4 = 5 =or IF rechts schieben THEN
|
|||
|
dup 6 = IF trinken THEN
|
|||
|
ELSE
|
|||
|
invers ." Betrug!" nornal
|
|||
|
THEN
|
|||
|
drop :
|
|||
|
|
|||
|
Damit wurde ohne eine CASE-Anweisung eine sehr übersichtliche Steuerung des
|
|||
|
Programm-Flusses geschaffen. :
|
|||
|
|
|||
|
Die Plausibilitätsprüfung, ob die eingegeben Zahl zwischen 1 und 6 lag, ist hier an
|
|||
|
den Anfang gerückt und wird in einem einzigen ELSE-Zweig abgearbeitet.
|
|||
|
|
|||
|
4.3.2 Behandlung einer CASE - Situation
|
|||
|
|
|||
|
4.3.2.1 Strukturelles CASE
|
|||
|
|
|||
|
Viele Programmiersprachen eine CASE-Anweisung zur Verfügung, die wie in PASCAL
|
|||
|
mit Hilfe eines Fall-Indices eine Liste von Fall-Konstanten auswertet und eine
|
|||
|
entsprechende Anweisung ausführt. |
|
|||
|
|
|||
|
Obwohl ein solches CASE-Konstrukt - wie oben gezeigt - nicht notwendig ist,
|
|||
|
macht es Programme besser lesbar und liegt bei Problemstellungen wie der Auswer-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- BR Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
tung eines gegebenen Index eigentlich näher.
|
|||
|
|
|||
|
Dies ist in [1] ausführlich diskutiert worden, wobei aber der ältere Eaker-CASE f2}
|
|||
|
von Dr. Charles Eaker sicherlich der bekanntere ist, der auch in der Literatur und
|
|||
|
in Quelltexten häufig Erwähnung und Verwendung findet.
|
|||
|
|
|||
|
Herr H. Schnitter hat diesen Eaker-CASE für das volks4TH implementiert und dabei-
|
|||
|
Veränderungen in der Struktur und Verbesserungen in der Anwendung vorgenommen.
|
|||
|
\ caselist initlist »marklist »resolvelist
|
|||
|
|
|||
|
t variable caselist
|
|||
|
|
|||
|
I : initlist ( list -- addr )
|
|||
|
dup @ swap off
|
|||
|
|
|||
|
.
|
|||
|
’
|
|||
|
|
|||
|
t : >narklist (list -- )
|
|||
|
here over @ , swap !
|
|||
|
|
|||
|
t : >resolvelist ( addr list -- )
|
|||
|
BEGIN dup @
|
|||
|
WHILE dup dup @ dup @ rot ! )resolve
|
|||
|
REPEAT !
|
|||
|
|
|||
|
’
|
|||
|
\ case elsecase endcase
|
|||
|
|
|||
|
CASE caselist initlist 4
|
|||
|
imnediate restrict
|
|||
|
|
|||
|
.
|
|||
|
|
|||
|
ELSECASE A ?pairs
|
|||
|
compile drop 6
|
|||
|
immediate restrict
|
|||
|
|
|||
|
>
|
|||
|
|
|||
|
ENDCASE dup 4 =
|
|||
|
IF drop compile drop
|
|||
|
ELSE 6 ?pairs
|
|||
|
THEN caselist >resolvelist
|
|||
|
; immediate restrict
|
|||
|
|
|||
|
\ o£ endof
|
|||
|
|
|||
|
: OF 4 ?pairs
|
|||
|
compile over
|
|||
|
conpile =
|
|||
|
|
|||
|
compile ?branch
|
|||
|
»mark compile drop 5
|
|||
|
immediate restrict
|
|||
|
|
|||
|
Er
|
|||
|
|
|||
|
: ENDOF 5 ?pairs
|
|||
|
compile branch
|
|||
|
caselist >marklist
|
|||
|
Yresolve 4
|
|||
|
|
|||
|
; immediate restrict
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen -üm-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Diese Implementierung des Eaker-CASE stellt eine Verbesserung gegenüber dem
|
|||
|
Original dar, indem Herr Schnitter die Kontrollstruktur um ELSECASE erweitert hat.
|
|||
|
Selbstverständlich ist die neue Version vollkommen aufwärtskompatibel mit der
|
|||
|
Original-version.
|
|||
|
|
|||
|
Verbesserung:
|
|||
|
|
|||
|
In der Originalversion der CASE-Struktur ist es nicht möglich, zwischen dem
|
|||
|
letzten ENDOF und ENDCASE einen Wert oder ein Flag auf den Stapel zu legen, da
|
|||
|
ENDCASE grundsätzlich den "Top of Stack" entfernte. :
|
|||
|
|
|||
|
In der verbesserten Version bereinigt ELSECASE den Stapel. ELSECASE muß jedoch
|
|||
|
nicht aufgerufen werden; in diesem Fall kompiliert ENDCASE wie bisher ein DROP.
|
|||
|
Es ist jetzt möglich, zwischen den Worten ELSECASE und ENDCASE - wie auch
|
|||
|
zwischen OF und ENDOF - einen Wert auf den Stapel zu legen und diesen außer-
|
|||
|
halb der CASE-Kontrollstruktur zu verwenden.
|
|||
|
|
|||
|
Änderung:
|
|||
|
|
|||
|
Die Vorwärtsreferenzen werden nicht über den Stack aufgelöst, sondern über eine
|
|||
|
verkettete Liste.
|
|||
|
|
|||
|
Die Variable caselist enthält die Startadresse für noch nicht bekannte Sprung-
|
|||
|
adressen. Die Schachtelungstiefe mehrerer CASE-Konstruktionen ist beliebig und
|
|||
|
wird durch initlist gelöst. >marklist füllt zur Kompilierzeit die Liste der Vorwärts-
|
|||
|
referenzen und >resolvelist löst sie wieder auf.
|
|||
|
|
|||
|
Anwendungshinweis:
|
|||
|
|
|||
|
Wenn diese Definitionen außerhalb der Zusammenstellung des Arbeitssystems zuge-
|
|||
|
laden werden, sollten nach dem Compilieren die Namen der mit ! als headerless
|
|||
|
markierten Worte mit clear entfernt werden.
|
|||
|
|
|||
|
Das Beispiel einer Tastatuabfrage auf CTRL-Tasten zeigt , wie dieses CASE-Kon-
|
|||
|
strukt einzusetzen ist. Wichtig ist hierbei, daß das OF selbst die Gleichheit der
|
|||
|
beiden vorliegenden Werte prüft und in diesem Fall die Anweisungen zwischen OF
|
|||
|
und ENDOF ausführt.
|
|||
|
|
|||
|
: Control bl word 1+ c@ SBF and state @
|
|||
|
|
|||
|
IF [compile] Literal THEN
|
|||
|
; immediate
|
|||
|
|
|||
|
: Tastaturabfrage
|
|||
|
." exit mit ctrl x" cr
|
|||
|
BEGIN key
|
|||
|
CASE control A OF ." action "a " cr false ENDOF
|
|||
|
eontrol B OF ." action "b " cr false ENDOF
|
|||
|
control C OF ." action "ce " cr false ENDOF
|
|||
|
control D OF ." action "d " cr false ENDOF
|
|||
|
control X OF ." exit " true ENDOF
|
|||
|
ELSECASE °
|
|||
|
." befehl unbekannt " cr false
|
|||
|
ENDCASE
|
|||
|
UNTIL ’
|
|||
|
|
|||
|
|
|||
|
|
|||
|
nl Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Mit dieser CASE-Anweisung läßt sich die Zuordnung ‘der sechs Möglichkeiten zu den
|
|||
|
sechs Anweisungen ähnlich wie in PASCAL schreiben, lediglich Bereiche wie 9..255
|
|||
|
als Fall-Konstanten sind nicht erlaubt.
|
|||
|
|
|||
|
: Auswertung.5 ( Augenzahl -- )
|
|||
|
|
|||
|
CASE
|
|||
|
1 OF nehnen ENDOF
|
|||
|
2 OF links schieben ENDOF
|
|||
|
3 OF links schieben ENDOF
|
|||
|
4 OF rechts schieben ENDOF
|
|||
|
5 OF rechts schieben ENDOF
|
|||
|
6 OF trinken ENDOF
|
|||
|
|
|||
|
ELSECASE
|
|||
|
invers ." Betrug!" normal
|
|||
|
|
|||
|
ENDCASE
|
|||
|
|
|||
|
Das vollständige Programm kann so geschrieben werden, wobei die typische Drei-
|
|||
|
teilung Eingabe-Verarbeitung-Ausgabe deutlich wird:
|
|||
|
|
|||
|
: craps (--)
|
|||
|
|
|||
|
cr Anfrage cr
|
|||
|
input#
|
|||
|
Auswertung
|
|||
|
|
|||
|
cr Glückwunsch
|
|||
|
|
|||
|
’
|
|||
|
Wil Baden hat in [1} ausgeführt, das eine CASE-Anweisung nur syntaktischer
|
|||
|
Zucker für ein Programm ist und letztendlich nichts weiter ist, als das Compilieren
|
|||
|
einer verschachtelten IF... THEN-Anweisung.
|
|||
|
Eine solche Implemetierung für das volksFORTH83 wurde von Herrn K. Schleisiek-
|
|||
|
Kern geschrieben:
|
|||
|
|
|||
|
\ CASE OF ENDOF ENDCASE BREAK
|
|||
|
|
|||
|
2 CASE (nl --nint) dup;
|
|||
|
: oF (conmpile] IF compile drop ; immediate restrict
|
|||
|
: ENDOF [compile) ELSE 4+ ; immediate restrict
|
|||
|
|
|||
|
: ENDCASE compile drop
|
|||
|
BEGIN
|
|||
|
3 case?
|
|||
|
WHILE
|
|||
|
>resolve
|
|||
|
REPEAT ; immediate restrict
|
|||
|
|
|||
|
Wil Badens Implementierung hält sich sehr eng an die logischen Grundlagen, wobei
|
|||
|
der Unterschied zum EAKER-CASE hauptsächlich darin besteht, daß hier jedes
|
|||
|
TRUE-Flag den Anweisungsteil zwischen OF und ENDOF ausführt; das OF nimmt
|
|||
|
keine Prüfung auf Gleichheit vor, sondern beliebige Ausdrücke können zu einem
|
|||
|
Flag führen, das dann von OF ausgewertet wird. So ist das Auswerten des Fall-
|
|||
|
Index variabler als beim EAKER-CASE:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen =1893.>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
: Auswertung.6 ( Augenzahl -- )
|
|||
|
up
|
|||
|
1 6 between not
|
|||
|
IF invers ." Betrug!” normal drop exit THEN
|
|||
|
|
|||
|
CASE 1 = OF nehmen ENDOF
|
|||
|
CASE 6 = OF trinken ENDOF
|
|||
|
CASE 4 € OF links schieben -ENDOF
|
|||
|
CASE 3 > OF rechts schieben ENDOF
|
|||
|
ENDCASE ;
|
|||
|
|
|||
|
Hier bei dieser Konstruktion steht die Plausibilitätsprüfung ganz vorn, um den
|
|||
|
ELSECASE-Fall durch ein EXIT aus dem Wort zu erreichen. Wird keines der Worte
|
|||
|
aus der Auswahl-Liste ausgeführt, läßt sich mit BREAK eine andere Lösung
|
|||
|
erreichen: .
|
|||
|
|
|||
|
: BREAK compile exit
|
|||
|
[compile] THEN ; immediate restrict
|
|||
|
|
|||
|
Dadurch, daß BREAK ein EXIT aus dem Wort darstellt, wird ein (implizites)
|
|||
|
ELSECASE erreichen, indem man die Anweisungen der Auswahl-Liste mit OF und
|
|||
|
BREAK klammert und die Anweisungen für den ELSE-Fall nach ENDCASE aufführt:
|
|||
|
|
|||
|
: Auswertung.? { Augenzahl -- )
|
|||
|
|
|||
|
CASE 1 = OF nehmen BREAK
|
|||
|
CASE 2 = 3 =or OF links schieben BREAK
|
|||
|
CASE 4 = 5 =or OF rechts schieben BREAK
|
|||
|
CASE 6 = OF trinken BREAK
|
|||
|
ENDCASE
|
|||
|
|
|||
|
invers ." Betrug!" normal ;
|
|||
|
|
|||
|
4.3.2.2 Positionelles CASE
|
|||
|
|
|||
|
Eine ganz anderen Lösungsansatz bietet ein positioneller CASE Konstrukt, .bei dem
|
|||
|
die Fallunterscheidung durch den Fall-Index tabellarisch vorgenommen wird.
|
|||
|
|
|||
|
Bei den bisherigen Lösungen wurden immer eine Reihe von Vergleichen zwischen
|
|||
|
einem Fall-index und einer Liste von Fall-Konstanten vorgenommen; nun wird der
|
|||
|
Fall-Index selbst benutzt, die gewünschte Prozedur auszuwählen. Die Verwendung
|
|||
|
des Fall-Index als Selektor: bringt auch Vorteile in der Laufzeit, da die Vergleiche
|
|||
|
entfallen.
|
|||
|
|
|||
|
Wenn FORTH-Worte in Tabellen abgelegt werden sollen, stellt sich das Problem, daß
|
|||
|
ein FORTH-Wort bei seinem Aufruf normalerweise die eincompilierten Worte aus-
|
|||
|
führt. ,
|
|||
|
|
|||
|
Bei einer Tabelle ist das nicht erwünscht; dort ist sinnvollerweise gefordert, daß
|
|||
|
die Startadresse der Tabelle übergeben wird, um der Fall-Index als Offset in diese
|
|||
|
Tabelle zu nutzen.
|
|||
|
|
|||
|
Dies läßt sich in volksFORTH entweder auf die traditionelle Weise mit |] und [
|
|||
|
oder dem volksFORTH-spezifischen Create: lösen: j
|
|||
|
|
|||
|
|
|||
|
|
|||
|
l
|
|||
|
an
|
|||
|
be
|
|||
|
|
|||
|
!
|
|||
|
|
|||
|
Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Create Glas
|
|||
|
] nehmen links schieben
|
|||
|
|
|||
|
rechts schieben trinken [
|
|||
|
Create: Glas
|
|||
|
|
|||
|
nehmen
|
|||
|
|
|||
|
links schieben
|
|||
|
|
|||
|
rechts schieben
|
|||
|
|
|||
|
trinken ;
|
|||
|
|
|||
|
Diese Tabelle Glas macht auch deutlich, welche Funktion das Dummy-Wort
|
|||
|
schieben außer einer besseren Lesbarkeit noch hat: Es löst die Schwierigkeit, daß
|
|||
|
6 möglichen Wurfergebnissen nur 4 mögliche Aktionen gegenüberstehen.
|
|||
|
|
|||
|
Die Art und Weise des Zugriffs in BEWEGEN entspricht dem Zugriff auf eine Zahl
|
|||
|
|
|||
|
“Sin einem eindimensionalen Feld, einem Vektor:
|
|||
|
|
|||
|
: bewegen ( addr n -- cfa )
|
|||
|
2%* + perform ;
|
|||
|
|
|||
|
se richtig (n -- O<k=n<=3)
|
|||
|
|
|||
|
swap
|
|||
|
|
|||
|
1 max 6 min
|
|||
|
|
|||
|
3 case? IF 2 1- exit THEN
|
|||
|
|
|||
|
5 case? IF 4 1- exit THEN
|
|||
|
|
|||
|
12.5
|
|||
|
Dieses Wort RICHTIG läßt zwar Werte kleiner als 1 und größer als 6 zu, justiert
|
|||
|
sie aber auf den Bereich zwischen 1 und 6 . Auch hier müßte eine Möglichkeit ge-
|
|||
|
schaffen werden, ein Wurfergebnis außerhalb der 6 Möglichkeiten als Betrugsversuch-.
|
|||
|
zurückzuweisen !
|
|||
|
Die Verbindung von Tabelle und Zugriffsprozedur wird von dem Wort :Does> vor-
|
|||
|
genommen:
|
|||
|
|
|||
|
\ :Does) für Create <name) :Does)> (action) ; ks 25 aug 88
|
|||
|
I 2 (does) here >r [compile) Does) ;
|
|||
|
|
|||
|
:Does) last @ 0= Abort" without reference"
|
|||
|
(does) current @ context ! hide 0 ] ;
|
|||
|
|
|||
|
En Dieses Wort :DOES> weist dem letzten über Create definierten Wort einen
|
|||
|
|
|||
|
Laufzeit-Teil zu. Dieses Wort wurde von Herrn K. Schleisiek-Kern programmiert ;
|
|||
|
auch hier gilt der Hinweis, nach dem Compilieren das mit ! als headerless
|
|||
|
deklarierte Wort durch clear zu löschen.
|
|||
|
|
|||
|
Create: Auswertung.8
|
|||
|
nehnen
|
|||
|
links schieben
|
|||
|
rechts schieben
|
|||
|
trinken ;
|
|||
|
:Does)
|
|||
|
richtig bewegen ;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen =TBBr-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ohne :DOES> sind die Tabelle und die Zugriffsprozeduren voneinander unabhängi-
|
|||
|
ge Worte:
|
|||
|
2 CRAPSI
|
|||
|
cr Anfrage cr
|
|||
|
input#
|
|||
|
Glas richtig bewegen
|
|||
|
er Glückwunsch ;
|
|||
|
|
|||
|
Entschließt man sich dagegen, sowohl Tabelle als auch Zugriffsprozedur in einem
|
|||
|
Wort zu definieren, so ergibt sich das gewohnte Erscheinungsbild:
|
|||
|
|
|||
|
: CRAPS
|
|||
|
cr Anfrage cr
|
|||
|
input#
|
|||
|
Auswertung
|
|||
|
|
|||
|
er Glückwunsch ;
|
|||
|
|
|||
|
Bei häufigerem Einsatz solcher Tabellen bietet sich der Einsatz von positional
|
|||
|
CASE defining words an. Auch hier wiederum zuerst die volks4TH-gemäße Lösung
|
|||
|
danach die traditionelle Variante:
|
|||
|
ı Case: (-)
|
|||
|
Create: Does) ( pfa -- ) swap 2* + perform ;
|
|||
|
|
|||
|
\ alternative Definition für CASE:
|
|||
|
: Case:
|
|||
|
: Does) ( pfa -- ) swap 2* + perform ;
|
|||
|
|
|||
|
Eine sehr elegante Möglichkeit, die Fehlerbehandlung im Falle eines unglaubwürdi-
|
|||
|
gen Fall-Indexes zu handhaben, bietet das Wort Associative: .
|
|||
|
Dieses Wort Associative: durchsucht eine Tabelle nach einer Übereinstimmung
|
|||
|
zwischen einem Zahlenwert auf dem Stack und den Zahlenwerten in der Tabelle
|
|||
|
und liefert den Index der gefundenen Zahl (match) zurück. Im Falle eines Mißer-
|
|||
|
folgs (mismatch) wird der größtmögliche Index +1 (out of range = maxIndex +1)
|
|||
|
übergeben:
|
|||
|
|
|||
|
: Associative: (n--)
|
|||
|
Constant Does) {n - index )
|
|||
|
dup @ -rot
|
|||
|
dup @ ®
|
|||
|
|
|||
|
DO 2+ 2dup @ = :
|
|||
|
IF 2drop drop I 9 © LEAVE THEN
|
|||
|
LOOP 2ärop ;
|
|||
|
|
|||
|
6 Associative: Auswerten
|
|||
|
|
|||
|
i
|
|||
|
|
|||
|
vw
|
|||
|
|
|||
|
4,
|
|||
|
6,
|
|||
|
|
|||
|
ww»
|
|||
|
|
|||
|
Case: Handeln \ besteht aus :
|
|||
|
|
|||
|
nehmen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 664° Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
links links
|
|||
|
rechts rechts
|
|||
|
trinken
|
|||
|
schinpfen ;
|
|||
|
Statt der Primitivabsicherung über MIN und MAX wird eine out of range Fehlerbe-
|
|||
|
handlung namens schimpfen an der Tabellenposition maxIndex +1 durchgeführt.
|
|||
|
|
|||
|
4.3.2.3 Einsatzmöglichkeiten
|
|||
|
|
|||
|
Dieser letzte Teil der Ausführungen über die Möglichkeiten, eine CASE-Situation zu
|
|||
|
handhaben, greift Anregungen aus der Literatur [5],[6] auf.
|
|||
|
|
|||
|
Dazu werden zwei Worte definiert:
|
|||
|
|
|||
|
CLS löscht den gesamten Bildschirm und
|
|||
|
CELLS macht die Berechnung des Tabellenzugriffs deutlicher:
|
|||
|
|
|||
|
: cls full page ;
|
|||
|
|
|||
|
ı cells 2” ;
|
|||
|
Das Inhaltliche und die tabellarische Struktur bleiben unverändert, lediglich die
|
|||
|
Behandlung einer out of range Situation wird diesmal mit min und max und zwei-
|
|||
|
maligem Eintragen der Fehler-Routine schimpfen verwirklicht.
|
|||
|
|
|||
|
Create: Handlung
|
|||
|
|
|||
|
schinpfen nehmen links links
|
|||
|
rechts rechts trinken schimpfen ;
|
|||
|
|
|||
|
\ Die Ausführung einer Liste nach Floegel 7/86
|
|||
|
|
|||
|
: auswählen ( addr n -- *cfa ) 2 arguments
|
|||
|
swap ® max \ out of range MIN
|
|||
|
7 nin \ out of range MAX
|
|||
|
cells + ;
|
|||
|
: auswerten (n-- ) 1 arguments
|
|||
|
|
|||
|
Handlung auswählen perform ;
|
|||
|
|
|||
|
_.ald (—-)
|
|||
|
806 DO cr I dup . auswerten 2 spaces LOOP ;
|
|||
|
AUSWÄHLEN übergibt bei gegebenem Vektor und gegebenem Index einen Zeiger auf
|
|||
|
die code field address des entsprechenden Wortes. AUSWERTEN führt das so
|
|||
|
ausgewählte Wort aus und .ALL diente nur zur Kontrolle. Solch ein Wort, das ange-
|
|||
|
legte Datenstrukturen auf dem Bildschirm darstellt, sollte in der Entwicklungs-
|
|||
|
phasen eines Programmes immer dabei sein.
|
|||
|
|
|||
|
Eine weitere Möglichkeit, Werte in einen Vektor einzutragen, hat Herr Floegel in
|
|||
|
seinem Buch [4] dargestellt:
|
|||
|
|
|||
|
Create Tabelle 8 cells allot
|
|||
|
|
|||
|
:Does> ( i -- addr ) swap cells +;
|
|||
|
' schimpfen ® Tabelle !
|
|||
|
nehmen 1 Tabelle !
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen = Bi -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
' links dup 2 Tabelle
|
|||
|
3 Tabelle
|
|||
|
' rechts dup 4 Tabelle
|
|||
|
5 Tabelle
|
|||
|
‘ trinken 6 Tabelle
|
|||
|
' schimpfen 7 Tabelle
|
|||
|
|
|||
|
: auswerten (i --) GO max 7 min Tabelle perform ;
|
|||
|
|
|||
|
: „action (i=®)
|
|||
|
Tabelle @ »>name bright .nane normal ;
|
|||
|
ı „Tabelle (--) cr 890DO cr I .action LOOP ;
|
|||
|
|
|||
|
Hier besteht mit .ACTION und .TABELLE die Möglichkeit, sich den Vektor darstellen
|
|||
|
zu lassen. In ähnlicher Weise werden auch im Kommandozeilen-Editor CED die
|
|||
|
neuen Aktionen in die Eingabe-Vektoren eingetragen.
|
|||
|
|
|||
|
Eine geringfügige Modifikation von [5] soll die Verknüpfung eines Vektors von Wor-
|
|||
|
ten und einer Menü-Option zeigen:
|
|||
|
|
|||
|
Create function
|
|||
|
] noop noop noop noop
|
|||
|
noop noop noop noop [
|
|||
|
:Does> ( i -- addr )
|
|||
|
swap ® max 7 min cells + ;
|
|||
|
|
|||
|
function ist ein execution vector , der mit NOOP vorbesetzt ist. Zur Laufzeit lie-
|
|||
|
fert er die Adresse des indizierten Elementes zurück.
|
|||
|
|
|||
|
: „action ( i addr -- }
|
|||
|
@ >name bright .name normal ;
|
|||
|
|
|||
|
.WORD gibt den Namen eines Wortes aus, dessen CFA in eine Adresse eingetragen
|
|||
|
wurde.
|
|||
|
|
|||
|
: option (i--)
|
|||
|
: r>
|
|||
|
dup 2+ >r \i *tw.adädr
|
|||
|
@ \iw.addr
|
|||
|
stash swap function ! \i w.addr i adär
|
|||
|
function .action ; \i addr
|
|||
|
|
|||
|
option holt die Adresse des auf option folgenden Wortes. Das Wort soll nicht
|
|||
|
ausgeführt werden, sondern das nachfolgende. Nur der Pointer auf das Wort soll
|
|||
|
|
|||
|
ausgewertet werden. Nach dem übergebenen Index wird der Pointer in function
|
|||
|
|
|||
|
eingetragen. Der Name des so eingetragenen Wortes wird angezeigt !
|
|||
|
|
|||
|
\ Menü jrg 66feb89
|
|||
|
: Menü
|
|||
|
|
|||
|
6 option schimpfen
|
|||
|
|
|||
|
1 option nehmen
|
|||
|
|
|||
|
option links
|
|||
|
option links
|
|||
|
option rechts
|
|||
|
option rechts
|
|||
|
option trinken
|
|||
|
7 option schirpfen ;
|
|||
|
|
|||
|
an wm
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 88 - Kontrollstrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Wenn das Wort MENÜ aufgerufen wird, werden nicht nur die Optionen in die Tabelle
|
|||
|
eingetragen, sondern auch namentlich auf dem Bildschirm dargestellt. Diese Technik
|
|||
|
bietet sich für eine Menüzeile an fester Bildschirmposition an, ähnlich der
|
|||
|
Statuszeile des volksFORTH. Zum Ändern solcher Menüpunkte bieten sich die
|
|||
|
Funktionstasten an:
|
|||
|
|
|||
|
: fkey ke)
|
|||
|
key &58 + abs function perform ;
|
|||
|
|
|||
|
FKEY liefert beim Druck einer Funktionstaste einen Wert von -59 bis -68 zu-
|
|||
|
rück. Dieser wird für 18 Funktionstasten in den Bereich von -1 bis -18 skaliert
|
|||
|
und der Absolutwert gebildet.
|
|||
|
|
|||
|
{1} Wil Baden Ultimate CASE-Statement
|
|||
|
(vVD2/87 S.48 ff.)
|
|||
|
|
|||
|
[2) Dr. Charles Eaker Just in CASE
|
|||
|
(FORTH DIM 11/3)
|
|||
|
|
|||
|
[3] R. Zech FORTH 83
|
|||
|
(S.98ff/S.318f.)
|
|||
|
|
|||
|
[4] E. Floegel FORTH Handbuch
|
|||
|
(S.189)
|
|||
|
|
|||
|
[5] W. Wejgaard Menus in FORTH
|
|||
|
|
|||
|
Elektroniker 9/88 (S.189 ff.)
|
|||
|
|
|||
|
4.4 Rekursion
|
|||
|
|
|||
|
Bevor die Technik der Rekursion für das volks4TH dargestellt wird, soll ein
|
|||
|
anderes Wort .LASTNAME zeigen, daß das Wort LAST mit dem in der Literatur
|
|||
|
oft anzutreffenden LATEST identisch ist:
|
|||
|
|
|||
|
Beide Worte liefern die name field address des zuletzt definierten Wortes im
|
|||
|
CURRENT-Vokabular. Das Wort LAST' dagegen liefert die cfa des zuletzt definier-
|
|||
|
ten Wortes.
|
|||
|
|
|||
|
: .lastname last @ .nane ;
|
|||
|
|
|||
|
Die Rekursion ist eine Technik, bei der ein Wort sich immer wieder selbst aufruft.
|
|||
|
Eines der bekannten Beispiele dafür ist die Berechnung der Fakultät einer posi-
|
|||
|
tiven ganzen Zahl. Hierbei ergibt sich n! aus dem Produkt aller ihrer Vorgänger.
|
|||
|
|
|||
|
Im volks4TH ist der Selbstaufruf eines Wortes durch RECURSIVE gekennzeichnet,
|
|||
|
so daß sich ein Programm zur Fakultätsberechnung wie folgt präsentiert:
|
|||
|
: fakultät (+n --n!)
|
|||
|
|
|||
|
recursive
|
|||
|
dup 6®< IF drop ." keine negativen Argumente! " exit
|
|||
|
THEN
|
|||
|
|
|||
|
?dup 0= IF 1 \ Spezialfall: ®
|
|||
|
ELSE dup 1- fakultät *
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kontrollstrukturen - BI -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
THEN ;
|
|||
|
|
|||
|
er 4 fakultät .
|
|||
|
|
|||
|
er 5 fakultät .
|
|||
|
|
|||
|
er 6 fakultät .
|
|||
|
Allerdings findet sich - vor allem in der figFORTH-Literatur - ein Wort MYSELF
|
|||
|
. das mit dem in FORTH83-Umgebungen anzutreffenden RECURSE identisch ist.
|
|||
|
Da auch diese Konstruktion, bei der MYSELF/RECURSE als Platzhalter für den
|
|||
|
Wortnamen dienen, gerne eingesetzt wird, werden die möglichen Definitionen und
|
|||
|
eine weitere Form von FAKULTÄT gezeigt:
|
|||
|
|
|||
|
. nyself last @ name) ,„ : immediate
|
|||
|
: myself last' ,„ : immediate
|
|||
|
|
|||
|
recurse [compile] myself ; immediate
|
|||
|
nyself Alias recurse immediate
|
|||
|
|
|||
|
: £fakultät (*+n--n!)
|
|||
|
dup 6< IF ." keine negativen Argumente erlaubt!
|
|||
|
ELSE ?dup 6= IF 1
|
|||
|
ELSE dup 1- myself *
|
|||
|
THEN
|
|||
|
|
|||
|
THEN ; .
|
|||
|
Bei der Verwendung von RECURSE wird lediglich MYSELF dadurch ersetzt:
|
|||
|
|
|||
|
...
|
|||
|
|
|||
|
?dup 0= IF 1 \ Spezialfall: ®
|
|||
|
ELSE dup 1- recurse *
|
|||
|
THEN
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 69: = Kontrolistrukturen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5. Ein- / Ausgabe im volksFORTH
|
|||
|
|
|||
|
5.1 Ein- / Ausgabebefehle im volksFORTH
|
|||
|
|
|||
|
Alle Eingabe- und Ausgabeworte (KEY EXPECT EMIT TYPE etc.) sind im volks-
|
|||
|
FORTH vektorisiert, d.h. bei ihrem Aufruf wird die Codefeldadresse des zugehörigen
|
|||
|
Befehls aus einer Tabelle entnommen und ausgeführt. So ist im System eine Tabelle
|
|||
|
mit Namen DISPLAY enthalten, die für die Ausgabe auf dem Bildschirmterminal
|
|||
|
sorgt.
|
|||
|
|
|||
|
Dieses Verfahren der Vektorisierung bietet entscheidende Vorteile:
|
|||
|
|
|||
|
= Mit der Input-Vektorisierung kann man z.B. mit einem Schlag die
|
|||
|
Eingabe von der Tastatur auf ein Modem umschalten.
|
|||
|
|
|||
|
= Durch die Output-Vektorisierung können mit einer neuen Tabelle
|
|||
|
alle Ausgaben auf ein anderes Gerät (z.B. einenDrucker) geleitet
|
|||
|
werden, ohne die Ausgabebefehle selbst ändern zu müssen.
|
|||
|
Mit einem Wort (DISPLAY, PRINT) kann das gesamte Ausgabeverhalten
|
|||
|
geändert werden. Gibt man z.B. ein:
|
|||
|
|
|||
|
print 1 list display
|
|||
|
|
|||
|
wird Screen 1 auf einen Drucker ausgegeben und anschließend wieder
|
|||
|
auf den Bildschirm zurückgeschaltet. Man braucht also kein neues
|
|||
|
Wort, etwa PRINTERLIST, zu definieren.
|
|||
|
|
|||
|
Eine neue Tabelle wird mit dem Wort OUTPUT: erzeugt. Die Definition können Sie
|
|||
|
mit view output: nachsehen. OUTPUT: erwartet eine Liste von Ausgabeworten,
|
|||
|
die mit ; abgeschlossen werden muß.
|
|||
|
|
|||
|
Beispiel: Output: >PRINTER
|
|||
|
pemit pcr ptype pdel ppage pat pat? ;
|
|||
|
|
|||
|
Damit wird eine neue Tabelle mit dem Namen >PRINTER angelegt. Beim späteren
|
|||
|
Aufruf von >PRINTER wird die Adresse dieser Tabelle in die Uservariable OUTPUT
|
|||
|
geschrieben. Ab sofort führt EMIT ein PEMIT aus, TYPE ein PTYPE usw.
|
|||
|
|
|||
|
Die Reihenfolge der Worte nach OUTPUT:
|
|||
|
userEMIT userCR userTYPE userDEL userPAGE userAT userAT?
|
|||
|
muß unbedingt eingehalten werden.
|
|||
|
|
|||
|
Entsprechend wird die Input-Vektorisierung gehandhabt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein- ; Ausgabe im volksFORTH ao
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5.2 Ein- / Ausgaben über Terminal
|
|||
|
|
|||
|
Das volks4th verfügt über eine Reihe von Konstanten, die der besseren Lesbarkeit
|
|||
|
dienen:
|
|||
|
|
|||
|
c/row ( -- Anzahl )
|
|||
|
ist die Konstante, die die Anzahl der Zeichen pro Zeile (&8®) angibt.
|
|||
|
|
|||
|
e/col ( -- Anzahl )
|
|||
|
ist die Konstante, die die Anzahl der Zeichen pro Spalte (&25) angibt.
|
|||
|
|
|||
|
e/dis ( -- Anzahl.Cells )
|
|||
|
ist die Konstante, die die Größe des Speichers für einen Ausgabeschirm
|
|||
|
angibt.
|
|||
|
|
|||
|
e/l (-- +#n) "characters-per-line"
|
|||
|
|
|||
|
+n ist die Anzahl der Zeichen pro Screenzeile. Aus historischen Gründen
|
|||
|
ist dieser Wert &64 bzw. $40 .
|
|||
|
|
|||
|
Vs ( -- +n) "lines-per-screen"
|
|||
|
+n ist die Anzahl der Zeilen pro Screen.
|
|||
|
|
|||
|
bl (--n "5
|
|||
|
n ist der ASCII-Wert für ein Leerzeichen.
|
|||
|
|
|||
|
#esc ( #=in) "number-escape"
|
|||
|
n ist der ASCII-Wert für Escape.
|
|||
|
|
|||
|
#er (--n "number-c-r
|
|||
|
n ist der Wert, den man durch KEY erhält, wenn die Return-Taste <cr>
|
|||
|
gedrückt wird.
|
|||
|
|
|||
|
#lf ( Sei) "number-linefeed"
|
|||
|
n ist der ASCII-Wert für Linefeed.
|
|||
|
|
|||
|
#bel (--n)
|
|||
|
n ist der ASCII-Wert für BELL.
|
|||
|
|
|||
|
#bs (== pn) "number-b-s"
|
|||
|
n ist der Wert, den man durch KEY erhält, wenn die Backspace-Taste ge-
|
|||
|
drückt wird.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
u Ein- / Ausgabe im volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3,81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
standardi/o (==) "standard-i-0"
|
|||
|
|
|||
|
inputkol
|
|||
|
|
|||
|
area
|
|||
|
|
|||
|
areakol
|
|||
|
|
|||
|
terminal
|
|||
|
|
|||
|
window
|
|||
|
|
|||
|
full
|
|||
|
|
|||
|
curat?
|
|||
|
|
|||
|
cur!
|
|||
|
|
|||
|
setpage
|
|||
|
|
|||
|
video@
|
|||
|
|
|||
|
stellt sicher, daß die beim letzten save bestimmten Ein- und Ausgabe-
|
|||
|
geräte wieder eingestellt sind.
|
|||
|
|
|||
|
und outputkol
|
|||
|
sind beides definierende Wörter, die eine festgelegte Anzahl von Zeigern
|
|||
|
auf Prozeduren erwarten.
|
|||
|
|
|||
|
( -- addr )
|
|||
|
ist eine Uservariable und zeigt auf den Zustandsvektor des aktiven Win-
|
|||
|
dows.
|
|||
|
|
|||
|
ist ein definierendes Wort, das zur Erzeugung eines Windows benutzt
|
|||
|
wird.
|
|||
|
|
|||
|
ist ein Window, das sich von Zeile @ - 23 erstreckt für das Terminal
|
|||
|
Output Window.
|
|||
|
|
|||
|
( topline bottomline -- )
|
|||
|
setzt die oberste und unterste Zeile des aktuellen Windows neu.
|
|||
|
|
|||
|
(=)
|
|||
|
setzt das aktuelle Window über den ganzen Bildschirm von der obersten
|
|||
|
bis zur untersten Zeile. Somit entspricht
|
|||
|
|
|||
|
: cla full page ;
|
|||
|
dem Befehl, der den gesamten Bildschirm löscht.
|
|||
|
|
|||
|
( -- row col )
|
|||
|
liefert die aktuelle Cursorposition im aktiven Fenster.
|
|||
|
|
|||
|
(a)
|
|||
|
setzt den Cursor in das Window, auf das AREA zeigt.
|
|||
|
|
|||
|
(R--)
|
|||
|
setzt aktive Bildschirmseite.
|
|||
|
|
|||
|
(--seg)
|
|||
|
liefert das Segment zurück, in dem der Speicher der Videokarte liegt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein- / Ausgabe im volksFORTH - 63 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
savevideo (--segı ff)
|
|||
|
rettet den Speicherbereich der Videoausgabe; wird bei dem Wort MSDOS
|
|||
|
eingesetzt.
|
|||
|
|
|||
|
restorevideo (seg -- )
|
|||
|
|
|||
|
restauriert die Bildschirmausgabe auf dem angegebenen Segment; wird bei
|
|||
|
dem Wort MSDOS eingesetzt.
|
|||
|
|
|||
|
catt ( -- addr )
|
|||
|
ist eine Variable, die das Attribut zur Zeichendarstellung enthält, z.B.
|
|||
|
das Zeichenattribut INVERS
|
|||
|
|
|||
|
list (u) 83
|
|||
|
zeigt den Inhalt des Screens u auf dem aktuellen Ausgabegerät an. SCR
|
|||
|
wird auf u gesetzt.
|
|||
|
Siehe BLOCK
|
|||
|
|
|||
|
(page ) "(page"
|
|||
|
löscht den Bildschirm und positioniert den Cursor in die linke obere Ecke.
|
|||
|
Vergleiche PAGE i
|
|||
|
|
|||
|
page ==)
|
|||
|
bewirkt, daß der Cursor des Ausgabegerätes auf eine leere neue Seite
|
|||
|
bewegt wird. Eines der OUTPUT-Worte.
|
|||
|
|
|||
|
(del (==) "(del"
|
|||
|
löscht ein Zeichen links vom Cursor.
|
|||
|
Vergleiche DEL
|
|||
|
|
|||
|
del (--)
|
|||
|
löscht das zuletzt ausgegebene Zeichen. Bei Druckern ist die korrekte
|
|||
|
Funktion nicht immer garantiert. Eines der OUTPUT-Worte
|
|||
|
|
|||
|
(er (ea) "(e-r"
|
|||
|
setzt den Cursor in die erste Spalte der nächsten Zeile. Ein PAUSE
|
|||
|
wird ausgeführt.
|
|||
|
|
|||
|
er . (==) 83 u
|
|||
|
bewirkt, daß die Schreibstelle des Ausgabegerätes an den Anfang der
|
|||
|
nächsten Zeile verlegt wird. Eines der OUTPUT-Worte.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
“64 » Ein- / Ausgabe im volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
?er
|
|||
|
|
|||
|
(at
|
|||
|
|
|||
|
(at?
|
|||
|
|
|||
|
at
|
|||
|
|
|||
|
j.at?
|
|||
|
|
|||
|
col
|
|||
|
|
|||
|
Tow
|
|||
|
|
|||
|
curoff
|
|||
|
|
|||
|
curon
|
|||
|
|
|||
|
curshape
|
|||
|
|
|||
|
(u) "question-c-r"
|
|||
|
prüft, ob in der aktuellen Zeile mehr als C/L Zeichen ausgegeben
|
|||
|
wurden und führt in diesem Fall CR aus.
|
|||
|
|
|||
|
( row col -- ) "at"
|
|||
|
setzt die aktuelle Cursorposition. (AT positioniert den Cursor in der Zeile
|
|||
|
row und der Spalte col . Ein Fehler liegt vor, wenn row > $18 (&24) oder
|
|||
|
col > $56 (&80) ist. Die fehlerhafte Ausgabe wird nicht unterdrückt!
|
|||
|
Vergleiche AT
|
|||
|
|
|||
|
( -- row col ) "(at-question"
|
|||
|
liefert die aktuelle Cursorposition. row ist die aktuelle Zeilennummer des
|
|||
|
Cursors, col die aktuelle Spaltennummer.
|
|||
|
|
|||
|
Vergleiche AT?
|
|||
|
|
|||
|
( row col -- )
|
|||
|
positioniert die Schreibstelle des Ausgabegerätes in die Zeile row und
|
|||
|
die Spalte col. AT ist eines der über OUTPUT vektorisierten Worte.
|
|||
|
Siehe AT?
|
|||
|
|
|||
|
( -- row col ) "at-question”
|
|||
|
ermittelt die aktuelle Position der Schreibstelle des Ausgabegerätes und
|
|||
|
legt Zeilen- und Spaltennummer auf den Stack. Eines der OUTPUT-Worte.
|
|||
|
|
|||
|
( -- #col ) "col"
|
|||
|
#col ist die Spalte, in der sich die Schreibstelle des Ausgabegerätes
|
|||
|
gerade befindet.
|
|||
|
Vergleiche ROW und AT?
|
|||
|
|
|||
|
( -- #row ) "row"
|
|||
|
#row ist die Zeile, in der sich die Schreibstelle des Ausgabegerätes be-
|
|||
|
findet.die Benutzung beschreiben-
|
|||
|
Vergleiche COL und AT?.
|
|||
|
|
|||
|
==)
|
|||
|
schaltet den Cursor aus.
|
|||
|
|
|||
|
)
|
|||
|
|
|||
|
schaltet den Cursor ein.
|
|||
|
|
|||
|
( topline bottomline -- )
|
|||
|
bestimmt das Aussehen des Cursors.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein- / Ausgabe im volksFORTH 65 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
printer
|
|||
|
|
|||
|
print
|
|||
|
|
|||
|
+print
|
|||
|
|
|||
|
lst!
|
|||
|
|
|||
|
5.3 Drucker-Ausgaben
|
|||
|
|
|||
|
(=)
|
|||
|
|
|||
|
ist das Vokabular mit den Worten zur Druckersteuerung.
|
|||
|
|
|||
|
(==
|
|||
|
schaltet die Ausgabe auf den Drucker um
|
|||
|
|
|||
|
(--)
|
|||
|
schaltet den Drucker zusätzlich zu.
|
|||
|
|
|||
|
(8b--)
|
|||
|
gibt ein Byte zum Drucker aus.
|
|||
|
|
|||
|
5.4 Ein- / Ausgabe von Zahlen
|
|||
|
|
|||
|
Die Eingabe von Zahlen erfolgt im interpretativen Modus über die Tastatur, wobei
|
|||
|
grundlegend Eingabeworte mit number number? und den verwandten Worten
|
|||
|
definiert werden.
|
|||
|
|
|||
|
Bei der Ausgabe von Zahlen ist wieder die fehlende Typisierung von FORTH zu be-
|
|||
|
achten - für ein bestimmtes Datenformat (integer, unsigned, double) ist jeweils der
|
|||
|
geeignete Operator auszuwählen.
|
|||
|
|
|||
|
(n--)
|
|||
|
gibt den obersten Stack-Werte als Zahl (integer) aus.
|
|||
|
Soll die Ausgabe des nachfolgenden Leerzeichens unterdrückt werden, so
|
|||
|
sind die Befehle für rechtsbündige Zahlenausgabe .r u.r d.r mit einer
|
|||
|
Feldlänge von ® zu benutzen.
|
|||
|
|
|||
|
(u--)
|
|||
|
gibt den obersten Stack-Wert als vorzeichenlose 16Bit-Zahl (unsigned)
|
|||
|
aus.
|
|||
|
|
|||
|
(d--)
|
|||
|
gibt die obersten beiden Stack-Werte als 32Bit-Zahl (double) aus.
|
|||
|
|
|||
|
(n Feldlänge -- )
|
|||
|
druckt eine 16Bit-Zahl in einem Feld mit angegebener Länge rechtsbündig
|
|||
|
aus.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 66 -
|
|||
|
|
|||
|
Ein- / Ausgabe im volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ur ( u Feidlänge -- )
|
|||
|
gibt den obersten Stack-Wert als vorzeichenlose 16Bit-Zahl in einem Feld
|
|||
|
rechtsbündig aus.
|
|||
|
|
|||
|
d.r ( d Feldlänge -- )
|
|||
|
gibt eine 32Bit-Zahl in einem Feld rechtsbündig aus.
|
|||
|
|
|||
|
5.5 Ein- / Ausgabe über einen Port
|
|||
|
|
|||
|
pc® ( port.addr -- 8b )
|
|||
|
holt ein Byte von port.addr aus einem Peripheriebaustein des 8986-
|
|||
|
Systems auf den Stack.
|
|||
|
|
|||
|
pe! ( 8b port.addr -- )
|
|||
|
speichert ein Byte in einen Peripheriebaustein des 8886-Systems bei
|
|||
|
port.addr.
|
|||
|
|
|||
|
5.6 Eingabe von Zeichen
|
|||
|
|
|||
|
In FORTH wird man immer einen Speicherbereich benennen, in dem Zeichen und
|
|||
|
Zeichenketten verarbeitet werden. Hierfür verwendet man meistens einen kleinen,
|
|||
|
88 Zeichen langen Speicherbereich namens PAD . Dieser Notizblock - so die
|
|||
|
deutsche Übersetzung von pad - belegt keinen festen Speicherbereich und steht
|
|||
|
sowohl dem FORTH-System als auch dem zur Verfügung.
|
|||
|
|
|||
|
Dann möchte ich Ihnen mit dem Texteingabe-Puffer tib einen weiteren wichtigen
|
|||
|
Speicherbereich vorstellen,der den vernünftigen Umgang mit den angeschlossenen
|
|||
|
Geräten sicherstellt. Weil die Texteingabe über die Tastatur relativ langsam vor
|
|||
|
sichgeht, werden die Zeichen hier erst in einem freien Speicherbereich, dem
|
|||
|
Pufferspeicher tib , gesammelt und dann abgearbeitet.
|
|||
|
|
|||
|
tib ( -- addr ) 83
|
|||
|
liefert die Adresse des Text-Eingabe-Puffers. Hier wird die Eingabe-Be-
|
|||
|
fehlszeile des aktuellen Eingabegerätes (meist KEYBOARD) gespeichert.
|
|||
|
Siehe >TIB
|
|||
|
|
|||
|
#tib ( -- addr ) 83 "number-t-i-b"
|
|||
|
addr ist die Adresse einer Variablen, die die Länge des aktuellen Textes
|
|||
|
(die Anzahl der Zeichen) im Text-Eingabe-Puffer enthält.
|
|||
|
Vergleiche TIB
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein- / Ausgabe im volksFORTH =bm =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
»tib ( -- addr ) "to-tib"
|
|||
|
addr ist die Adresse eines Zeigers auf den Text-Eingabe-Puffer.
|
|||
|
Siehe TIB
|
|||
|
|
|||
|
»in ( -- addr )
|
|||
|
ist eine Variable, die den Offset auf das gegenwärtige Zeichen im Quell-
|
|||
|
text enthält.
|
|||
|
>in indiziert relativ zum Beginn des Blockes, der durch die Variable bIk
|
|||
|
gekennzeichnet wird. Ist blk = 8 , so wird als Quelle der tib angenom-
|
|||
|
men.
|
|||
|
|
|||
|
Vergleiche word
|
|||
|
|
|||
|
pad ( -- addr )
|
|||
|
liefert die Adresse des temporären Speichers PAD . Die Adresse von
|
|||
|
PAD ändert sich, wenn der Dictionarypointer DP verändert wird, z.B.
|
|||
|
durch ALLOT oder ,„ (Komma).
|
|||
|
|
|||
|
input ( -- addr ) U
|
|||
|
addr ist die Adresse einer Uservariablen, die einen Zeiger auf ein Feld
|
|||
|
von vier Kompilationsadressen enthält, die für ein Eingabegerät die
|
|||
|
Funktionen KEY KEY? DECODE und EXPECT realisieren.
|
|||
|
|
|||
|
Vergleiche die Beschreibung der INPUT- und OUTPUT-Struktur.
|
|||
|
|
|||
|
keyboard ee)
|
|||
|
ein mit INPUT: definiertes Wort, das die Tastatur als Eingabegerät setzt.
|
|||
|
Die Worte KEY KEY? DECODE und EXPECT beziehen sich auf die
|
|||
|
Tastatur.
|
|||
|
|
|||
|
Siehe (KEY (KEY? (DECODE und (EXPECT
|
|||
|
|
|||
|
empty-keys (_ =)
|
|||
|
löscht den Tastaturpuffer über den Int.21h, Fct.dC, AL=B.
|
|||
|
|
|||
|
(key? ( -- flag ) "(key-question"
|
|||
|
Das Flag ist TRUE , wenn eine Taste gedrückt wurde, sonst FALSE .
|
|||
|
Vergleiche KEY? .
|
|||
|
|
|||
|
key? (-- flag ) "key-question"
|
|||
|
Das Flag ist TRUE , falls ein Zeichen zur Eingabe bereitsteht, sonst ist
|
|||
|
flag FALSE . Eines der INPUT-Worte.
|
|||
|
|
|||
|
- 88 - Ein- / Ausgabe im volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
(key (-- 16b ) "(key"
|
|||
|
wartet auf einen Tastendruck. Während der Wartezeit wird PAUSE
|
|||
|
ausgeführt.
|
|||
|
|
|||
|
Zeichen des erweiterten ASCII-Zeichensatzes werden in den unteren 8 Bit
|
|||
|
von 16b übergeben. Funktionstasten liefern negative Werte.Steuerzeichen
|
|||
|
werden nicht ausgewertet, sondern unverändert abgeliefert.
|
|||
|
|
|||
|
Vergleiche KEY.
|
|||
|
|
|||
|
key ( -- 16b ) 83
|
|||
|
empfängt ein Zeichen vom Eingabegerät. Es wird kein Echo ausgesandt.
|
|||
|
KEY wartet, bis tatsächlich ein Zeichen empfangen wurde.
|
|||
|
Die niederwertigen 8 Bit enthalten den ASCII-Code des zuletzt empfan-
|
|||
|
genen Zeichens. Alle gültigen ASCII-Codes können empfangen werden.
|
|||
|
Die oberen 8 Bit enthalten systemspezifische Informationen, den Tas-
|
|||
|
tatur-Scancode.
|
|||
|
Die Funktionstasten werden als negative Zahlenwerte zurückgegeben, so
|
|||
|
daß beispielsweise auf einer PC/XT-Tastatur folgende Tasten ent-
|
|||
|
sprechende 16Bit-Werte liefern :
|
|||
|
|
|||
|
Tasten Fl - F1ß: =59Eu268
|
|||
|
Cursorblock: -71 (home) - -81 (pgdn)
|
|||
|
Zahlen 8 - 9: 48 (6) - 57 (9)
|
|||
|
|
|||
|
KEY ist eines der INPUT-Worte.
|
|||
|
|
|||
|
(decode ( addr pos® key -—- addr posl ) "(decode"
|
|||
|
wertet key aus. key wird in der Speicherstelle addr+pos1 abgelegt
|
|||
|
und als Echo auf dem Bildschirm ausgegeben. Die Variable SPAN und
|
|||
|
pos werden inkrementiert. Backspace löscht das Zeichen links vom Cursor
|
|||
|
und dekrementiert posl und SPAN.
|
|||
|
|
|||
|
Vergleiche INPUT: und (expect ..
|
|||
|
|
|||
|
(expect ( addr len -- ) "(expect"
|
|||
|
erwartet len Zeichen vom Eingabegerät, die ab addr im Speicher abgelegt
|
|||
|
werden. Ein Echo der Zeichen wird ausgegeben. Return beendet die Ein-
|
|||
|
gabe vorzeitig. Ein abschließendes Leerzeichen wird statt des <CR> aus-
|
|||
|
gegeben. Die Länge der Zeichenkette wird in der Variablen SPAN über-
|
|||
|
geben.
|
|||
|
|
|||
|
Vergleiche EXPECT .
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein- / Ausgabe im volksFORTH =u69F =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
expect ( Zieladresse maxAnzahl -- ) 83
|
|||
|
empfängt maxAnzahl Zeichen und speichert sie ab der Zieladresse im
|
|||
|
Speicher, ohne ein count byte einzubauen. Der count wird statt dessen
|
|||
|
in der Variablen span abgelegt. Ist maxAnzahl = ® , so werden keine
|
|||
|
Zeichen übertragen.
|
|||
|
Die Übertragung wird beendet, wenn ein #CR erkannt oder maxAnzahl
|
|||
|
Zeichen übertragen wurden. Das #CR wird nicht mit abgespeichert.
|
|||
|
Alle Zeichen werden als Echo, statt des #CR wird ein Leerzeichen ausge-
|
|||
|
geben.
|
|||
|
Dies ist das expect aus der Literatur, mit dem man an beliebigen Stel-
|
|||
|
len im Speicher Eingabepuffer jeder Länge anlegen kann. Eines der
|
|||
|
INPUT-Worte.
|
|||
|
Vergleiche SPAN .
|
|||
|
|
|||
|
span ( -- addr ) 83
|
|||
|
Der Inhalt der Variablen SPAN gibt an, wieviele Zeichen vom letzten
|
|||
|
EXPECT übertragen wurden; in ihr ist die Anzahl der tatsächlich einge-
|
|||
|
gebenen Zeichen des zuletzt ausgeführten expect abgelegt.
|
|||
|
span wird ausgelesen, um zu sehen, ob die erwartete Zeichenzahl emp-
|
|||
|
fangen oder die Eingabe vorher mit <CR> abgebrochen wurde. Bei span
|
|||
|
ist zu beachten, daß es direkt nach einem expect benutzt werden muß,
|
|||
|
weil auch einige FORTH-Systemwörter span benutzen.
|
|||
|
|
|||
|
>expect ( Zieladresse maxAnzahl.Zeichen -- )
|
|||
|
legt ebenfalls einen zu erwartenden String an einer Zieladresse ab, aller-
|
|||
|
dings wird jetzt das count-byte eingebaut.
|
|||
|
|
|||
|
nullstring? ( addr -- addr ff ! addr tf )
|
|||
|
prüft, ob der counted String an der gegebenen Adresse die Länge NULL
|
|||
|
hat. Wenn dies der Fall ist, wird true hinterlegt, ansonsten bleibt addr
|
|||
|
erhalten und false wird übergeben.
|
|||
|
|
|||
|
stop? (-- flag ) "stop-question"
|
|||
|
Ein komfortables Wort, das es dem Benutzer gestattet, einen Programmab-
|
|||
|
lauf anzuhalten oder zu beenden.
|
|||
|
Steht vom Eingabegerät ein Zeichen zur Verfügung, so wird es eingelesen.
|
|||
|
Ist es #ESC oder CTRL-C , so ist Flag TRUE , sonst wird auf das
|
|||
|
nächste Zeichen gewartet. Ist dieses jetzt #ESC oder CTRL-C , so wird
|
|||
|
STOP? mit TRUE verlassen, sonst mit FALSE.
|
|||
|
Steht kein Zeichen zur Verfügung, so ist Flag FALSE.
|
|||
|
|
|||
|
- 10: Ein- / Ausgabe im volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
source
|
|||
|
|
|||
|
word
|
|||
|
|
|||
|
parse
|
|||
|
|
|||
|
name
|
|||
|
|
|||
|
find
|
|||
|
|
|||
|
( -- addr len )
|
|||
|
übergibt Adresse und Länge des Quelltextes; wenn die Blocknummer = 8
|
|||
|
ist, entsprechen diese Angaben denen des Text-Eingabe-Puffers TIB ;
|
|||
|
das ist der Grund, warum Block ® niemals geladen werden kann. Ist die
|
|||
|
Blocknummer nicht NULL, beziehen sich die Angaben auf den Massenspei-
|
|||
|
cher.
|
|||
|
|
|||
|
( delim -—- addr )
|
|||
|
durchsucht den Quelltext (siehe SOURCE) nach einem frei wählbaren Be-
|
|||
|
grenzer und legt den gefundenen String in der counted Form im Speicher
|
|||
|
an der Adresse here ab.
|
|||
|
Führende Zeichen vom Typ delim werden ignoriert. Deshalb erwartet word
|
|||
|
immer einen Delimiter und übernimmt nicht automatisch den üblichen Be-
|
|||
|
grenzer, das Leerzeichen. Daher typisch:
|
|||
|
|
|||
|
RO ER
|
|||
|
|
|||
|
( delim -- addr len )
|
|||
|
erwartet ebenfalls ein Zeichen als Begrenzer, liefert die nächste delim
|
|||
|
begrenzte Zeichenkette des Quelltextes aber schon in der üblichen Form
|
|||
|
addr count passend für type.
|
|||
|
Die Länge ist Null, falls der Quelltext erschöpft oder das erste Zeichen
|
|||
|
der delimiter ist. parse verändert die Variable >in.
|
|||
|
Typisches Auftreten: ;
|
|||
|
|
|||
|
: .( ASCII ) parse type ;
|
|||
|
|
|||
|
( -- string )
|
|||
|
holt den nächsten durch Leerzeichen abgeschlossenen String aus dem
|
|||
|
Quelltext, wandelt ihn in Großbuchstaben um und hinterläßt die Adresse,
|
|||
|
ab der der String im Speicher steht.
|
|||
|
Siehe word .
|
|||
|
|
|||
|
( string -- string ff I cfa tf )
|
|||
|
erwartet die Adresse eines counted Strings. Dieser String wird in der
|
|||
|
aktuellen Suchreihenfolge gesucht und das Resultat dieser Suche über-
|
|||
|
geben.
|
|||
|
Wird das Wort gefunden, so liegt die cfa und ein Pseudoflag tf bereit:
|
|||
|
- Ist das Wort immediate, so ist das flag positiv, sonst negativ.
|
|||
|
- Ist das Wort restrict, so hat das flag den Betrag 2, sonst Betrag 1.
|
|||
|
Typisch: ... (name) find ...
|
|||
|
was " RStein) Lin...
|
|||
|
.. name find ...
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein- / Ausgabe im volksFORTH I -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
execute
|
|||
|
|
|||
|
perform
|
|||
|
|
|||
|
query
|
|||
|
|
|||
|
interpret
|
|||
|
|
|||
|
( addr -- )
|
|||
|
Das durch addr gekennzeichnete Wort wird aufgerufen bzw. ausgeführt.
|
|||
|
Dabei kann es sich um ein beliebiges Wort handeln. Eine Fehlerbedingung
|
|||
|
existiert, falls addr nicht cfa eines Wortes ist.
|
|||
|
Typisch: ' (name) execute
|
|||
|
|
|||
|
( addr -- )
|
|||
|
ist ein execute für einen Vektor und entspricht ®@ execute . Typisch
|
|||
|
beim Einsatz einer Prozedurvariable:
|
|||
|
|
|||
|
Variable <(vector)
|
|||
|
|
|||
|
" noop <«vector) |!
|
|||
|
|
|||
|
(vector) perforn
|
|||
|
Hier wird zuerst eine Variable angelegt und anschließend dieser Variablen
|
|||
|
mit Hilfe des ' ("Tick") die CFA eines Wortes zugewiesen. Dieses Wort .
|
|||
|
kann nun über die Adresse der Prozedurvariablen und PERFORM ausge-
|
|||
|
führt werden. Allgemein wird diese Variable mit NOOP abgesichert.
|
|||
|
|
|||
|
( 83
|
|||
|
ist die allgemeine Texteingabe-Prozedur für den Texteingabe-Puffer.
|
|||
|
query stoppt die Programmausführung und liest eine Textzeile von max.
|
|||
|
88 Zeichen mit Hilfe von expect ein.
|
|||
|
Die Zeichen werden von einem Eingabegerät geholt und in den Text-Ein-
|
|||
|
gabe-Puffer übertragen, der bei TIB beginnt. Die Übertragung endet
|
|||
|
beim Empfang von #CR oder wenn die Länge des Text-Eingabe-Puffers
|
|||
|
erreicht wird. Der Inhalt von >IN und BLK wird zu ® gesetzt und
|
|||
|
#TIB enthält die Zahl der empfangenen Zeichen.
|
|||
|
Zu beachten ist, daß der Inhalt von TIB überschrieben wird. Damit
|
|||
|
werden auch alle Worte im TIB , die noch nicht ausgeführt wurden,
|
|||
|
ebenfalls überschrieben. Um Text aus dem Puffer zu lesen, kann WORD
|
|||
|
benutzt werden.
|
|||
|
Siehe EXPECT .
|
|||
|
|
|||
|
(„==,)
|
|||
|
ist der allgemeine Text-Interpreter des FORTH-Systems und beginnt die
|
|||
|
Interpretation des Quelltextes bei dem Zeichen, das durch den Inhalt der
|
|||
|
Variablen >in bezeichnet wird. >in indiziert relativ zum Beginn des
|
|||
|
Blockes, der durch die Variable blk gekennzeichnet wird. Ist bik =,
|
|||
|
so interpretiert interpret die max. 80 Zeichen im tib.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
w
|
|||
|
|
|||
|
Ein- / Ausgabe im volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
output
|
|||
|
|
|||
|
display
|
|||
|
|
|||
|
(emit
|
|||
|
|
|||
|
emit
|
|||
|
|
|||
|
charout
|
|||
|
|
|||
|
tipp
|
|||
|
|
|||
|
(type
|
|||
|
|
|||
|
type
|
|||
|
|
|||
|
5.7 Ausgabe von Zeichen
|
|||
|
|
|||
|
( -- addr ) U
|
|||
|
addr ist die Adresse einer Uservariablen, die einen Zeiger auf sieben
|
|||
|
Kompilationsadressen enthält, die für ein Ausgabegerät die Funktionen
|
|||
|
EMIT CR TYPE DEL PAGE AT und AT? realisieren.
|
|||
|
Vergleiche die gesonderte Beschreibung der Output-Struktur.
|
|||
|
|
|||
|
(.==)
|
|||
|
ist ein mit OUTPUT: definiertes Wort, das den Bildschirm als Ausgabe-
|
|||
|
gerät setzt, wenn es ausgeführt wird. Die Worte EMIT CR TYPE DEL
|
|||
|
PAGE AT und AT? beziehen sich dann auf den Bildschirm.
|
|||
|
|
|||
|
(8b -- ) "(emit"
|
|||
|
eibt 8b auf dem Bildschirm aus. Ein PAUSE wird ausgeführt. Alle Werte
|
|||
|
werden als Zeichen ausgegeben, Steuercodes sind nicht möglich, d.h. alle
|
|||
|
Werte < $28 werden als PC-spezifische Zeichen ausgegeben.
|
|||
|
|
|||
|
Vergleiche EMIT.
|
|||
|
|
|||
|
(16b --) 83
|
|||
|
gibt die unteren 8 Bit an das Ausgabegerät. Eines der OUTPUT-Worte.
|
|||
|
|
|||
|
(8 --)
|
|||
|
gibt 8b auf Standard-1/O-Gerät aus. Dazu wird die Fct.86 des Int21h be-
|
|||
|
nutzt. ASCII-Werte < $28 werden als Steuercodes interpretiert. CHAROUT
|
|||
|
ist ein Primitiv für die Ausgabe-routinen und sollte vermieden werden,
|
|||
|
da die Ausgabe dann nicht über die Videotreiber läuft.
|
|||
|
|
|||
|
( addr count -- )
|
|||
|
ist die Primitiv-Implementierung für TYPE über den MSDOS Character-
|
|||
|
Output.
|
|||
|
Siehe auch DISPLAY in KERNEL.SCR.
|
|||
|
|
|||
|
( addr len -- )
|
|||
|
gibt den String, der im Speicher bei addr beginnt und die Länge len hat,
|
|||
|
auf dem Bildschirm aus. Ein PAUSE wird ausgeführt.
|
|||
|
Vergleiche TYPE OUTPUT: und (EMIT.
|
|||
|
|
|||
|
( addr +n -- ) 83
|
|||
|
sendet +n Zeichen, die ab addr im Speicher abgelegt sind, an ein Aus-
|
|||
|
gabegerät. Ist +n = @ , so wird nichts ausgegeben.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ein- / Ausgabe im volksFORTH =>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ltype ( seg:addr Länge -- )
|
|||
|
ist ein segmentiertes TYPE.
|
|||
|
|
|||
|
space )
|
|||
|
gibt ein Leerzeichen aus.
|
|||
|
|
|||
|
spaces ( Anzahl -- )
|
|||
|
gibt eine bestimmte Anzahl von Leerzeichen aus.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 74 = Ein- / Ausgabe im volksFORTH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
6. Strings
|
|||
|
|
|||
|
Hier befinden sich grundlegende Routinen zur Stringverarbeitung.
|
|||
|
|
|||
|
Vor allem wurden auch Worte aufgenommen, die den Umgang mit den vom Betriebs-
|
|||
|
system geforderten ®-terminated Strings ermöglichen. FORTH hat hier gegenüber C
|
|||
|
den Nachteil, daß FORTH-Strings standardmäßig mit einem Count-Byte beginnen,
|
|||
|
das die Länge des Strings enthält. Ein abschließendes Zeichen (z.B. ein Null-Byte)
|
|||
|
ist daher unnötig. Da das Betriebssystem aber in C geschrieben wurde, müssen
|
|||
|
Strings entsprechend umgewandelt werden.
|
|||
|
|
|||
|
Standardmäßig arbeitet FORTH mit counted Strings, die lediglich durch eine Adresse
|
|||
|
gekennzeichnet werden. Das Byte an dieser Adresse enthält die Angabe, wie lang
|
|||
|
die Zeichenkette ist. Auf dieses count byte folgt dann die Zeichenkette selbst.
|
|||
|
Dadurch ist die Länge eines Standard-Strings in FORTH auf 255 Zeichen begrenzt.
|
|||
|
Die kürzeste Zeichenkette ist ein String der Länge NULL, für dessen Überprüfung
|
|||
|
der Befehl NULLSTRING? zur Verfügung steht.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5SfrfofrirgH
|
|||
|
|
|||
|
addr
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
So sieht der String FORTH an der Adresse addr im Speicher unter FORTH aus.
|
|||
|
|
|||
|
Es (==)
|
|||
|
ist nur während des Compilierens in Wörtern zu verwenden. Die ge-
|
|||
|
wünschte Zeichenkette wird von ." und " eingeschlossen, wobei das
|
|||
|
Leerzeichen nach ." nicht mitzählt. Wenn das Wort abgearbeitet wird,
|
|||
|
so wird der String zwischen ." und " ausgegeben:
|
|||
|
: Hallo ." Ich mache FORTH" ;
|
|||
|
|
|||
|
E ( -- addr ) GI "string"
|
|||
|
G=52) compiling
|
|||
|
liest den Text bis zum nächsten " und legt ihn als counted string im
|
|||
|
|
|||
|
Dictionary ab. Kann nur während der Kompilation ver-wendet werden. Zur
|
|||
|
Laufzeit wird die Startadresse des counted string auf den Stack gelegt.
|
|||
|
Das Leerzeichen, das auf das erste Anführungszeichen folgt, ist nicht
|
|||
|
Bestandteil des Strings. Wird in der folgenden Form benutzt:
|
|||
|
|
|||
|
: Hallo " Ich mache FORTH" count type ;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Strings er
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3,81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Fi (--) "string literal"
|
|||
|
speichert einen counted String ab HERE . Wird in der folgenden Form
|
|||
|
benutzt : Create Hallo ,„" Ich mache FORTH"
|
|||
|
|
|||
|
Hallo count type
|
|||
|
|
|||
|
nullstring? ( addr -- addr false } true )
|
|||
|
prüft, ob der counted String an der Adresse addr ein String der Länge
|
|||
|
NULL ist. Wenn dies zutrifft, wird TRUE übergeben. Anderenfalls bleibt
|
|||
|
addr erhalten und FALSE wird übergeben.
|
|||
|
|
|||
|
"lit ( -- addr )
|
|||
|
wird in compilierenden Worten benutzt, die auf INLINE-Strings zugreifen.
|
|||
|
Siehe auch ?" und ".
|
|||
|
|
|||
|
ah (sen)
|
|||
|
druckt den nachfolgenden String immer sofort aus. Der String wird von )
|
|||
|
beendet.
|
|||
|
Anwendung: .( Ich mache FORTH )
|
|||
|
|
|||
|
( (--)
|
|||
|
leitet einen Kommentar ein, d.h. Text, der vom Compiler ignoriert wird.
|
|||
|
|
|||
|
) beendet einen Kommentar. Dieses Wort ist aber selbst kein FORTH-Befehl,
|
|||
|
muß deshalb auch nicht mit Leerzeichen abgetrennt sein.
|
|||
|
|
|||
|
6.1 String-Manipulationen
|
|||
|
|
|||
|
Hier im Glossar bezeichnet der Stackkommentar ( string -- ) die Adresse eines
|
|||
|
counted Strings, dagegen ( addr len -- ) die Charakterisierung durch die
|
|||
|
Anfangsadresse der Zeichenkette und ihre Länge.
|
|||
|
|
|||
|
Keine Stringvariable - Benutze:
|
|||
|
: String: Create dup „ ® c, allot Does) 1+ count ;
|
|||
|
|
|||
|
caps ( -- addr )
|
|||
|
liefert die Adresse einer Variablen, die angibt, ob beim Stringvergleich
|
|||
|
auf Groß- und Kleinschreibung geachtet werden soll.
|
|||
|
|
|||
|
capital ( char -- char! )
|
|||
|
Die Zeichen im Bereich a bis z werden in die Großbuchstaben A bis 2
|
|||
|
umgewandelt, ebenso die Umlaute äöü . Andere Zeichen werden nicht
|
|||
|
verändert.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
N Strings
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
upper ( addr len -- )
|
|||
|
wandelt einen String in Großbuchstaben um. Es werden keine Parameter
|
|||
|
zurückgegeben.
|
|||
|
|
|||
|
capitalize ( string -- string )
|
|||
|
|
|||
|
ist durch UPPER ersetzt worden. Bei Bedarf kann es folgendermaßen
|
|||
|
definiert werden:
|
|||
|
|
|||
|
: capitalize ( string -- string ) dup count upper ;
|
|||
|
|
|||
|
/string ( addr® len index -- addri restlen ) "eut-string"
|
|||
|
verkürzt den durch addrd und len gekennzeichneten String an der mit
|
|||
|
index angegebenen Stelle und hinterläßt die Parameter des rechten Teil-
|
|||
|
strings.
|
|||
|
|
|||
|
-trailing ( addr® len® -- addrl leni ) "minus-trailing"
|
|||
|
kürzt einen String um die Leerzeichen, die sich am Ende des Strings be-
|
|||
|
finden. Anschließend liegen die neueen Parameter auf dem Stack, passend
|
|||
|
z.B. für TYPE.
|
|||
|
|
|||
|
scan ( addr® len char -- addrl restlen )
|
|||
|
durchsucht einen mit addr und len angegebenen String nach einem Zei-
|
|||
|
chen char.
|
|||
|
Wird das Zeichen gefunden, so wird die Adresse der Fundstelle und die
|
|||
|
Restlänge einschließlich des gefundenen Zeichens übergeben.
|
|||
|
Wird char nicht gefunden, so ist addri die Adresse des ersten Bytes
|
|||
|
hinter dem String und die Restlänge ist NULL.
|
|||
|
|
|||
|
skip ( addr® len char -- addri restlen )
|
|||
|
durchsucht einen mit addr® und len angegebenen String nach einer Ab-
|
|||
|
weichung von dem gegebenen Zeichen char.
|
|||
|
Beim ersten abweichenden Buchstaben wird die Adresse der Fundstelle
|
|||
|
und die Restlänge ohne das abweichende Zeichen übergeben.
|
|||
|
Besteht der gesamte String aus dem Zeichen char, so ist addri die
|
|||
|
Adresse des Bytes hinter dem String und die Restlänge ist NULL.
|
|||
|
|
|||
|
12 (ee)
|
|||
|
gibt die Position eines Zeichen in einem String an. Dieses ?" wird in
|
|||
|
Definitionen benutzt, um z.B. bei
|
|||
|
: vocal? ( char -- index ) capital ?" aeiou” ;
|
|||
|
Ascii ( char) vocal?
|
|||
|
festzustellen, ob es sich bei dem gegebenen Zeichen um einen Vokal
|
|||
|
handelt (index ungleich NULL) oder um welchen Vokal es sich handelt
|
|||
|
(a=1, e=2, i=3 etc.) ..
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Strings TUR
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
count ( string -- addr+1 len )
|
|||
|
wandelt eine String-Addresse in die Form addr len um, die für z.B. TYPE
|
|||
|
notwendig ist.
|
|||
|
bounds ( addr len -- limit start )
|
|||
|
ist definiert als
|
|||
|
: bounds over + swap ;
|
|||
|
und kann z.B. dazu benutzt werden, die Parameter einer Zeichenkette in
|
|||
|
DO..LOOP-gemäße Argumente umzurechnen:
|
|||
|
: upper ( addr len -- )
|
|||
|
bounds ?DO
|
|||
|
I c@ capital I c!
|
|||
|
LOOP ;
|
|||
|
type ( addr len -- )
|
|||
|
gibt eine Zeichenkette aus, die an addr beginnt und die angebene Länge
|
|||
|
hat.
|
|||
|
»type ( addr len -- )
|
|||
|
ist ein TYPE , das zuerst den String nach PAD kopiert. Dies ist in
|
|||
|
Multitasking-Systemen wichtig und wird folgendermaßen definiert:
|
|||
|
: >type ( addr count -- )
|
|||
|
pad place
|
|||
|
pad count type ;
|
|||
|
place ( addrö len dest.addr -- )
|
|||
|
legt eine Zeichenkette, die durch ihre Anfangsadresse und ihre Länge ge-
|
|||
|
kennzeichnet ist, an der Zieladresse als counted String ab.
|
|||
|
PLACE wird in der Regel benutzt, um Text einer bestimmten Länge als
|
|||
|
counted String abzuspeichern; dabei darf dest.addr gleich, größer oder
|
|||
|
kleiner als addrß sein.
|
|||
|
Die Wirkungsweise von PLACE wird in der Definition von >EXPECT
|
|||
|
deutlich, wo die Anzahl der von EXPECT eingelesenen Zeichen mit
|
|||
|
SPAN @ ausgelesen und von PLACE an der Zieladresse eingetragen wird:
|
|||
|
)expect ( addr len --)
|
|||
|
stash expect span @ over place ;
|
|||
|
attach ( addr len string --)
|
|||
|
fügt einen String an den durch addr und len gekennzeichneten String an,
|
|||
|
wobei der Count addiert wird.
|
|||
|
append ( char string -- )
|
|||
|
fügt ein Zeichen an den angegebenen String an und in-crementiert den
|
|||
|
Count.
|
|||
|
PBa- Strings
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
detract
|
|||
|
|
|||
|
— match
|
|||
|
|
|||
|
search
|
|||
|
|
|||
|
(find
|
|||
|
|
|||
|
( string -- char )
|
|||
|
|
|||
|
zieht das erste Zeichen aus einer Zeichenkette und de-crementiert den
|
|||
|
Count.
|
|||
|
|
|||
|
6.2 Suche nach Strings
|
|||
|
|
|||
|
6.2.1 In normalem Fließtext:
|
|||
|
|
|||
|
( buf.addr buf.len string -—- match.addr buf.rest )
|
|||
|
Der Pufferbereich an buf.addr mit der Länge buf.len wird nach einer
|
|||
|
vollständigen Übereinstimmung mit dem counted String überprüft. Die
|
|||
|
Adresse der Übereinstimmung und die Restlänge des Puffers wird über-
|
|||
|
geben. MATCH befindet sich im Vokabular EDITOR .
|
|||
|
|
|||
|
( buf len string -- offset flag )
|
|||
|
durchsucht einen Speicherbereich mit angegebener Länge nach einem
|
|||
|
counted string.
|
|||
|
Der Abstand vom Anfang des Speicherbereiches und ein Flag werden
|
|||
|
übergeben . Ist das Flag wahr, wurde der String gefunden, sonst nicht.
|
|||
|
Der Quelltext von SEARCH befindet sich im Editor und ist mit dessen
|
|||
|
Suchfunktion leicht aufzufinden.
|
|||
|
|
|||
|
6.2.2 Im Dictionary:
|
|||
|
|
|||
|
( string thread -- string ff Infa tf )
|
|||
|
erwartet die Adresse eines counted string und eine Suchreihe. Wird das
|
|||
|
Wort in dieser Reihe gefunden, so wird ein true flag und die nfa
|
|||
|
übergeben; wird es nicht gefunden, wird ein false flag übergeben und
|
|||
|
die Stringadresse bleibt erhalten.
|
|||
|
Typische Anwendung:
|
|||
|
|
|||
|
... last @ current @ (find...
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Strings
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
find
|
|||
|
|
|||
|
( string -- string.addr ff ! cfa tf )
|
|||
|
|
|||
|
erwartet die Adresse eines counted Strings. Dieser String wird in der
|
|||
|
|
|||
|
aktuellen Suchreihenfolge gesucht und das Resultat dieser Suche über-
|
|||
|
|
|||
|
geben.
|
|||
|
|
|||
|
Wird das Wort gefunden, so liegt die cfa und ein Pseudoflag tf bereit:
|
|||
|
- Ist das Wort immediate, so ist das Flag positiv, sonst negativ.
|
|||
|
- Ist das Wort restrict, so hat das Flag den Betrag 2, sonst Betrag 1.
|
|||
|
|
|||
|
Typische Anwendung:
|
|||
|
|
|||
|
.. (name ) find...
|
|||
|
" «string>" find ...
|
|||
|
. name find ...
|
|||
|
|
|||
|
6.3 @-terminated Strings
|
|||
|
|
|||
|
Es gibt noch eine andere Darstellungsform für Strings, die beispielsweise für MS-
|
|||
|
DOS geeigneter ist. Diese Strings werden zwar ebenfalls durch eine Adresse ge-
|
|||
|
kennzeichnet; diese Adresse enthält aber kein count byte . Statt dessen werden
|
|||
|
diese Zeichenketten mit einem Nullbyte abgeschlossen.
|
|||
|
|
|||
|
asciz
|
|||
|
|
|||
|
Yasciz
|
|||
|
|
|||
|
counted
|
|||
|
|
|||
|
( -- asciz )
|
|||
|
|
|||
|
(me) compiling
|
|||
|
holt das nächste Wort des Quelltextes ( TIB oder BLOCK ) in den Spei-
|
|||
|
cher und legt es als nullterminierten String (mit abschließendem Null-
|
|||
|
Byte) im Dictionary ab. Diese Adresse asciz im Dictionary wird zurückge-
|
|||
|
liefert.
|
|||
|
Wird in der folgenden Form benutzt :
|
|||
|
|
|||
|
asciz (string?
|
|||
|
Vergleiche ,".
|
|||
|
|
|||
|
( string addr.dest -- asciz )
|
|||
|
wandelt den counted String an der Adresse STRING um in einen null-
|
|||
|
terminierten String, der an der gegebenen Ziel-Adresse ADDR abgelegt
|
|||
|
wird. Die Länge des Strings im Speicher bleibt gleich.
|
|||
|
An der zurückgelieferten Adresse asciz liegt der neue String, wobei die
|
|||
|
übergebene Zieladresse und die zurückgelieferte ASCIZ-Adresse nicht
|
|||
|
gleich sein müssen.
|
|||
|
>ASCIZ ist das grundlegende Wort, um FORTH-Strings in MS-DOS-Strings
|
|||
|
umzuwandeln.
|
|||
|
|
|||
|
( asciz -— addr len )
|
|||
|
wird benutzt, um die Länge eines mit einem Nullbyte terminierten Strings
|
|||
|
zu bestimmen. asciz ist die Anfangsadresse dieses Strings, addr und len
|
|||
|
sind die Parameter. die z.B. von TYPE erwartet werden.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 89 -
|
|||
|
|
|||
|
Strings
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
digit?
|
|||
|
|
|||
|
6.4 Konvertierungen: Strings -— Zahlen
|
|||
|
|
|||
|
6.4.1 String in Zahlen wandeln
|
|||
|
|
|||
|
( char -- digit true )
|
|||
|
|
|||
|
( char -- false )
|
|||
|
prüft, ob das Zeichen char eine gültige Ziffer entsprechend der aktuellen
|
|||
|
Zahlenbasis in BASE ist. Ist das der Fall, so wird der Zahlenwert der
|
|||
|
Ziffer und TRUE auf den Stack gelegt. Ist char keine gültige Ziffer,
|
|||
|
wird FALSE übergeben.
|
|||
|
|
|||
|
accumulate ( +d® addr char -- +d1 addr )
|
|||
|
|
|||
|
convert
|
|||
|
|
|||
|
number?
|
|||
|
|
|||
|
dient der Umwandlung von Ziffern in Zahlen.
|
|||
|
|
|||
|
Multipliziert die Zahl +d® mit BASE , um sie eine Stelle in der aktu-
|
|||
|
ellen Zahlenbasis nach links zu rücken, und addiert den Zahlenwert von
|
|||
|
char. char muß eine in der Zahlenbasis gültige Ziffer darstellen, addr
|
|||
|
wird nicht verändert.
|
|||
|
|
|||
|
Wird z.B. in CONVERT benutzt. .
|
|||
|
|
|||
|
( +d® addr® -- +di addri )
|
|||
|
wandelt den Ascii-Text ab addr® +1 in eine Zahl entsprechend der
|
|||
|
Zahlenbasis BASE um. Der enstehende Zahlenwert und die Adresse des
|
|||
|
ersten nicht wandelbaren Zeichens im Text werden hinterlassen.
|
|||
|
|
|||
|
( addr -- d 8> I n @< I addr false )
|
|||
|
wandelt den counted String bei der Adresse addr in eine Zahl n um. Die
|
|||
|
Umwandlung erfolgt entsprechend der Zahlenbasis in BASE oder wird
|
|||
|
vom ersten Zeichen im String bestimmt.
|
|||
|
Enthält der String zwischen den Ziffer auch die Asciizeichen für Punkt
|
|||
|
oder Komma, so wird er als doppelt genaue Zahl interpretiert und 9>
|
|||
|
gibt die Zahl der Ziffern hinter dem Punkt einschließlich an.
|
|||
|
Sonst wird der String in eine einfach genaue Zahl n umgewandelt und
|
|||
|
eine Zahl kleiner als Null hinterlassen.
|
|||
|
Wenn die Ziffern des Strings nicht in eine Zahl umgewandelt werden kön-
|
|||
|
nen, bleibt die Adresse des Strings erhalten und FALSE wird auf den
|
|||
|
Stack gelegt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Strings
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Die Zeichen, die zur Bestimmung der- Zahlenbasis dem Ziffern-string vor-
|
|||
|
angestellt werden können, sind:
|
|||
|
|
|||
|
% (Basis 2 "binär")
|
|||
|
& (Basis 18 "dezimal")
|
|||
|
$ (Basis 16 "hexadezimal")
|
|||
|
|
|||
|
h «Basis 16 "hexadezimal")
|
|||
|
Der Wert in BASE wird dadurch nicht verändert.
|
|||
|
|
|||
|
number ( addr --d)
|
|||
|
wandelt den counted String bei der Adresse addr in eine Zahl d um. Die
|
|||
|
Umwandlung erfolgt entsprechend der Zahlenbasis in BASE . Eine Fehler-
|
|||
|
bedingung besteht, wenn die Ziffern des Strings nicht in eine Zahl
|
|||
|
verwandelt werden können. Durch Angabe eines Präfix (siehe NUMBER? )
|
|||
|
kann die Basis für diese Zahl modifiziert werden.
|
|||
|
|
|||
|
apl ( -- addr ) "decimal point location"
|
|||
|
ist eine Variable, die die Stellung des Dezimalpunktes angibt.
|
|||
|
|
|||
|
Ein Beispiel der Umwandlung von Zeichen in Zahlen:
|
|||
|
|
|||
|
In FORTH wird die Eingabe von Zahlen oft mit der allgemeinen Texteingabe und
|
|||
|
über die Befehle zur Umwandlung von Strings in Zahlen realisiert. In der Literatur
|
|||
|
wird dazu oft diese Lösung mit QUERY angeboten:
|
|||
|
|
|||
|
: in# ( <stringd -- dt£f nt£f addr ff)
|
|||
|
|
|||
|
query bl word number? ;
|
|||
|
|
|||
|
Diese Lösung ist ungünstig, da QUERY den TIB löscht. Zugleich stellt die Definition
|
|||
|
von NUMBER? eine unglückliche Stelle im volksFORTH dar.
|
|||
|
Es gibt im Laxen&Perry-F83 ein Wort gleichen Namens, das ganz anders (besser!)
|
|||
|
mit den Parametern umgeht. Hier folgt die Definition des F83-NUMBER?, aus dem
|
|||
|
volksFORTH NUMBER? aufgebaut:
|
|||
|
|
|||
|
: F83-NUMBER? ( string --df)
|
|||
|
|
|||
|
number? ?dup IF 9< IF extend THEN true exit THEN
|
|||
|
drop 0 6 false ;
|
|||
|
|
|||
|
Damit stellt das Wort INPUT# eine wenig aufwendige Zahleneingabemöglichkeit für
|
|||
|
16/32Bit-Zahlen dar:
|
|||
|
|
|||
|
\ input# jrg 29jul88
|
|||
|
: input# ( (string? --df)
|
|||
|
|
|||
|
pad c/1l 1- »expect \ get 63 char maximal
|
|||
|
|
|||
|
pad F83-number? ’ \ converts string > number
|
|||
|
|
|||
|
So kann der Anwender das übergebene Flag auswerten und die doppelt-genaue Zahl
|
|||
|
entsprechend seinen Vorstellungen einsetzen, im einfachsten Fall mit DROP zu
|
|||
|
einer einfach-genauen Zahl machen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 89 = Strings
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#Ss
|
|||
|
|
|||
|
hold
|
|||
|
|
|||
|
sign
|
|||
|
|
|||
|
#)
|
|||
|
|
|||
|
6.4.2 Zahlen in Strings wandeln
|
|||
|
|
|||
|
( +d8 -- +dl) 83 "sharp"
|
|||
|
Der Rest von +d® geteilt durch den Wert in BASE wird in ein Ascii-
|
|||
|
Zeichen umgewandelt und dem Ausgabestring in Richtung absteigender
|
|||
|
Adressen hinzugefügt. +d1 ist der Quotient und verbleibt auf dem Stack
|
|||
|
zur weiteren Bearbeitung. Üblicherweise zwischen {# und #> benutzt.
|
|||
|
|
|||
|
(+d--898) 83 "sharp-s"
|
|||
|
+d wird mit # umgewandelt, bis der Quotient zu Null geworden ist.
|
|||
|
Dabei wird jedes Zwischenergebnis in ein Ascii-Zeichen umgewandelt und
|
|||
|
dem String für die strukturierte Zahlenausgabe angefügt. Wenn +d von
|
|||
|
vornherein den Wert Null hatte, wird eine einzelne Null in den String
|
|||
|
gegeben. Wird üblichwerweise zwischen <# und #> benutzt.
|
|||
|
|
|||
|
( char -- ) 83
|
|||
|
Das Zeichen char wird in den Ausgabestring für die Zahlenausgabe ein-
|
|||
|
gefügt. Wird üblicherweise zwischen <# und #> benutzt.
|
|||
|
|
|||
|
(Gns==n) 83
|
|||
|
Wenn n negativ ist, wird ein Minuszeichen in den Ausgabestring für die
|
|||
|
Zahlenausgabe eingefügt. Wird üblicherweise zwischen <# und #> be-
|
|||
|
nutzt.
|
|||
|
|
|||
|
( 32b -- addr len ) 83 "sharp-greater"
|
|||
|
Am Ende der strukturierten Zahlenausgabe wird der 32b Wert vom Stack
|
|||
|
entfernt. Hinterlegt werden die Adresse des erzeugten Ausgabestrings und
|
|||
|
eine positive Zahl als die Anzahl der Zeichen im Ausgabestring, passend
|
|||
|
z.B. für TYPE.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Strings
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V, PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7. Umgang mit Dateien
|
|||
|
|
|||
|
Das File-Interface wurde grundlegend überarbeitet.
|
|||
|
|
|||
|
Auf der Benutzerebene stehen die gleichen Worte wie im volksFORTH 3.88 für den
|
|||
|
ATARI und für CP/M zur Verfügung; die darunterliegende Implementation wurde
|
|||
|
jedoch grundlegend geändert, so daß jetzt in FORTH auch sequentielle Files, die
|
|||
|
nicht die starre BLOCK-Struktur haben, manipuliert werden können.
|
|||
|
|
|||
|
Damit ist es endlich möglich, auch volksFORTH für kleine Hilfsprogramme zu ver-
|
|||
|
wenden, die mit anderen Programmen erstellte Files "bearbeiten" und durch den Be-
|
|||
|
fehl SAVESYSTEM als "standalone"-Programm abgespreichert wurden.
|
|||
|
|
|||
|
Besonders weitreichende Möglichkeiten erschließen sich dadurch, daß beim Aufruf
|
|||
|
von volksFORTH auf der Betriebssystemebene noch eine ganze Kommandozeile mit
|
|||
|
übergeben werden kann, die dann unmittelbar nach dem Booten von FORTH ausge-
|
|||
|
führt wird. Durch die Systemvariable RETURN_CODE kann nach Verlassen des
|
|||
|
FORTHProgramms ein Wert an MS-DOS zurückgegeben werden, der mit dem Batch-
|
|||
|
Befehl ERRORLEVEL abgefragt werden kann.
|
|||
|
|
|||
|
Darüberhinaus ist es auch möglich, mit dem Befehl MSDOS aus dem FORTH heraus
|
|||
|
eine weitere COMMAND.COM shell aufzurufen und später mit EXIT wieder ins
|
|||
|
FORTH zurückzukehren, wobei der Bildschirm, der zum Zeitpunkt des Aufrufs be-
|
|||
|
stand, wiederhergestellt wird.
|
|||
|
|
|||
|
Selbstverständlich kann neben MSDOS selber auch jedes andere beliebige An-
|
|||
|
wendungsprogramm aufgerufen werden - auch eine weitere Inkarnation des FORTH-
|
|||
|
Systems - so daß sich mit diesen Möglichkeiten die Begrenzungen überwinden
|
|||
|
lassen, die in dem beschränkten Adreßraum von 64k liegen. Auch komplizierte
|
|||
|
Overlaystrukturen sind nicht mehr notwendig, es werden einfach aus einem zen-
|
|||
|
tralen "Verwaltungsprogramm" heraus spezielle FORTH-Anwendungsprogramme aufge-
|
|||
|
rufen.
|
|||
|
|
|||
|
Das Fileinterface des volksFORTH benutzt die Dateien des MSDOS und dessen Sub-
|
|||
|
directories.
|
|||
|
|
|||
|
Dateien bestehen aus einem FORTH-Namen und einem MSDOS-Namen, die nicht
|
|||
|
übereinstimmen müssen.
|
|||
|
|
|||
|
Ist das FORTH-Wort, unter dem ein File zugreifbar ist, gemeint, so wird im
|
|||
|
folgenden vom (logischen) FORTH-File gesprochen. Dies entspricht einer
|
|||
|
Dateivariablen in den PASCAL-ähnlichen Sprachen. Der Zugriff auf eine Datei
|
|||
|
erfolgt daher in volksFORTH über den Namen eines Files ; dieser Namen ermöglicht
|
|||
|
dann den Zugriff entweder auf den Datei-Steuerblock (FCB) oder die MSDOS-
|
|||
|
Handle-Nummer.
|
|||
|
|
|||
|
Ist das File auf der Diskette gemeint, das vom MSDOS verwaltet wird, so wird vom
|
|||
|
(physikalischen) DOS-File gesprochen,
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 84 = Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Durch das Nennen des FORTH-Namens wird das FORTH-File (und das zugeordnete
|
|||
|
DOS-File) zum aktuellen File, auf das sich alle Operationen wie LIST , LOAD,
|
|||
|
CONVEY usw. beziehen.
|
|||
|
|
|||
|
Beim Öffnen eines Files wird die mit PATH angegebene Folge von Pfadnamen
|
|||
|
durchsucht. Dabei ist PATH ein von MSDOS völlig unabhängiger Pfad, so daß ver-
|
|||
|
schiedene Projekte auch mit verschiedenen FORTH-Systemen über ihren eigenen
|
|||
|
Pfad verwaltet werden können.
|
|||
|
|
|||
|
Der gültige MSDOS-Pfad wird davon nicht beeinflußt. Ist eine Datei einmal geöffnet,
|
|||
|
so kann diese Folge beliebig geändert werden, ohne daß der Zugriff auf das File
|
|||
|
behindert wird. Aus Sicherheitsgründen empfiehlt es sich aber, Files so oft und so
|
|||
|
lange wie irgend möglich geschlossen zu halten. Dann kann eine Änderung der
|
|||
|
Folge von Pfadnamen in PATH dazu führen, daß ein File nicht mehr gefunden
|
|||
|
wird.
|
|||
|
|
|||
|
volksFORTH bearbeitet seine Quelltexte in sogenannten Screen-Files, die üblicher-
|
|||
|
weise die Endung .SCR haben.
|
|||
|
|
|||
|
Dies sind Files, die in 1 KB große Screens aufgeteilt sind, jeweils in 16 Zeilen zu
|
|||
|
je 64 Zeichen strukturiert.
|
|||
|
|
|||
|
Üblicherweise enthält der Screen ® eines jeden Files eine kurze Erklärung über den
|
|||
|
Inhalt des Files - dies ist auch deshalb sinnvoll, da der Screen ® eines Files nie
|
|||
|
geladen werden kann.
|
|||
|
|
|||
|
Screen 1 enthält üblicherweise den sogenannten "loadscreen". Dieser steuert den
|
|||
|
Ladevorgang des gesamten Files. Ein Beispiel für einen solchen LOADSCREEN ist der
|
|||
|
|
|||
|
Scrl der Datei VOLKS4TH.SYS, der die aktuelle Arbeitsumgebung VOLKS4TH.COM
|
|||
|
zusammenstellt.
|
|||
|
|
|||
|
In Zeile ® eines jeden Screens ist ein Kommentar über den Inhalt des Screens und
|
|||
|
das Datum der letzten Änderung enthalten.
|
|||
|
|
|||
|
Um - vor allem auf Festplatten - Directories anzusprechen, gibt es verschiedene
|
|||
|
Methoden. Um beispielsweise Files in einem Directory "WORK" zu suchen oder an-
|
|||
|
zulegen, geben Sie ein :
|
|||
|
|
|||
|
cd work
|
|||
|
|
|||
|
Jetzt werden alle Files und Sub-Directories im Directory WORK gesucht oder neu
|
|||
|
geschaffen. Ist das Directory WORK noch nicht vorhanden, so erzeugen Sie es mit :
|
|||
|
md work
|
|||
|
|
|||
|
Wenn Sie Dateien auf einem bestimmten Laufwerk, z.B. A: , ansprechen wollen,
|
|||
|
geben Sie ein:
|
|||
|
|
|||
|
A:
|
|||
|
Hierbei wird A: zum aktuellen Laufwerk gemacht.
|
|||
|
Im einfachsten Fall existiert die zu benutzende Datei auf dem Massenspeicher und
|
|||
|
|
|||
|
der Datei-Name bereits im volksFORTH-Dictionary. Soiche Files sprechen Sie an,
|
|||
|
indem Sie einfach den Filenamen eingeben.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien = 85"-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Mit dem Wort files zeigt Ihnen voliksFORTH eine Liste dieser bereits im FORTH-
|
|||
|
System vorhandenen Dateien und Dateinamen, zusammen mit den zugeordneten DOS-
|
|||
|
Dateien und den Handle-Nummern.
|
|||
|
|
|||
|
Melden Sie irrtümlich eine Datei an, deren Name nicht im FORTH-Wörterbuch gefun-
|
|||
|
den wird, erscheint die übliche Fehlermeldung, das "?".
|
|||
|
|
|||
|
Um dagegen zu kontrollieren, ob eine Datei auf Disk existiert, benutzen Sie dir.
|
|||
|
Soll in einem solchen Fall ein File, das auf der Disk schon existiert, neu von
|
|||
|
volksFORTH bearbeitet werden, so wird es durch use <filename> zum sogenannten
|
|||
|
"aktuellen" File gemacht, in die Liste FILES und ins Wörterbuch eingetragen.
|
|||
|
|
|||
|
So macht use test.scr das MSDOS-File TEST.SCR zum aktuellen File, auf das
|
|||
|
sich solange alle weiteren File-Operationen beziehen, bis ein anderes File zum
|
|||
|
aktuellen File gemacht wird. Der Zugriff auf verschiedene Laufwerke ist für die
|
|||
|
Laufwerke A: bis H: vordefiniert.
|
|||
|
|
|||
|
Das Wort use erzeugt deshalb im FORTH-System das Wort TEST.SCR, falls es noch
|
|||
|
nicht vorhanden war. Wissen Sie also nicht mehr, ob Sie ein File schon benutzt
|
|||
|
haben, so können Sie das Wort use voranstellen, mit files nachsehen oder
|
|||
|
probehalber den Datei-Namen eingeben.
|
|||
|
|
|||
|
Möchten Sie ein neue Datei oder ein eigenes Screenfile anlegen, so wählen Sie
|
|||
|
einen Namen und benutzen:
|
|||
|
|
|||
|
makefile <filename)>
|
|||
|
|
|||
|
Danach erfolgen die Schreib/Lesezugriffe des DOS auf <filename>. Bei einem Block-
|
|||
|
file schätzen Sie die notwendige Größe nn in Blocks ab und geben ein:
|
|||
|
|
|||
|
makefile <filename®? nn more (z.B. 208 more)
|
|||
|
|
|||
|
Dabei ist der Name maximal 8 Buchstaben und die Extension maximal 3 Buchstaben
|
|||
|
lang. Diese Extension kann, muß aber nicht angegeben werden. Als Konvention wird
|
|||
|
vorgeschlagen, daß Files, die FORTH-Screens, also Quelltexte, enthalten, die
|
|||
|
Endung .SCR erhalten. Files, die Daten enthalten, die nicht unmittelbar lesbar sind,
|
|||
|
sollten auf .BLK enden.
|
|||
|
|
|||
|
Auf makefile hin legt das System eine neue Quelltext-Datei von beispielsweise
|
|||
|
26 KB Größe an. Das System geht bei 29KB davon aus, daß 1 KB Programmtexte in
|
|||
|
den ersten zehn Blöcken (8 - 9) und 1 KB Kommentare in den Shadow-Screens 19
|
|||
|
- 19 eingetragen werden. Das File wird nur logisch (!) in der Mitte geteilt. Wenn
|
|||
|
auf allen Screens nur Quelltexte eingetragen werden, so hat das keine negativen
|
|||
|
Konsequenzen, Sie bekommen dann nur im Editor mit SHIFT-F9 keinen Kommentar
|
|||
|
angezeigt.
|
|||
|
|
|||
|
Sie haben nun eine Datei, das die Screens 9..19 enthält. Geben Sie jetzt ein:
|
|||
|
11 oder 1 edit
|
|||
|
|
|||
|
Nach der Abfrage einer dreibuchstabigen Kennung, die Sie mit <CR> beantworten
|
|||
|
können, editieren Sie jetzt den Screen 1 Ihres neuen Files test.scr . Sie können,
|
|||
|
falls der Platz nicht ausreicht, Ihr File später einfach mit more verlängern. Ein
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 86 - Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
File kann leider nicht verkürzt werden.
|
|||
|
|
|||
|
Mit dem volksFORTH-Editor können Sie selbstverständlich auch stream files ohne
|
|||
|
die FORTH-typische Blockstruktur ansehen und editieren.
|
|||
|
|
|||
|
Drei wichtige Wörter für screen files sind:
|
|||
|
|
|||
|
Mit <nn> list wird Screen nn auf dem Bildschirm angezeigt - also zum Beispiel
|
|||
|
mit 1 list der Screen 1 des Files TEST.SCR.
|
|||
|
|
|||
|
Mit <nn> load wird ein Screen nn geladen, d.h. durch den FORTH-Compiler in das
|
|||
|
Wörterbuch compiliert.
|
|||
|
|
|||
|
Mit include <filename> kann man unkompliziert ein ganzes Screenfile laden. Diese
|
|||
|
Operation ist der Sequenz use <filename) 1 load äquivalent.
|
|||
|
|
|||
|
Beim Vergessen eines FORTH-Files mit Hilfe von FORGET , EMPTY usw. werden
|
|||
|
automatisch alle Blockpuffer, die aus diesem File stammen, gelöscht und, wenn sie
|
|||
|
geändert waren, auf die Diskette zurückgeschrieben. Das File wird anschließend ge-
|
|||
|
schlossen. Bei Verwendung von flush werden alle Files geschlossen. FLUSH sollte
|
|||
|
vor jedem Diskettenwechsel ausgeführt werden, und zwar nicht nur, um die ge-
|
|||
|
änderten Blöcke zurückzuschreiben, sondern auch damit alle Files geschlossen wer-
|
|||
|
den. Sind nämlich Files gleichen Namens auf der neuen Diskette vorhanden, so wird
|
|||
|
eine abweichende Länge des neuen Files vom FORTH nicht erkannt. Bei Verwendung
|
|||
|
von VIEW wird automatisch das richtige File geöffnet.
|
|||
|
|
|||
|
Sind bereits sehr viele Files geöffnet, kommt.es in der MSDOS-Grundeinstellung
|
|||
|
recht schnell zu der Fehlermeldung des Betriebssystems: too many open files . Da-
|
|||
|
gegen hilft die Änderung der Datei CONFIG.SYS:
|
|||
|
|
|||
|
FILES=16
|
|||
|
|
|||
|
Eine Besonderheit volksFORTH ist der Direktzugriff auf den Massenspeicher. Das
|
|||
|
Wort DIRECT schaltet das FileInterface ab und der Massenspeicher wird direkt
|
|||
|
physikalisch angesprochen ! j
|
|||
|
|
|||
|
Wenn nach dem Befehl EMPTY die Meldung F: direct auftaucht, ist das File-
|
|||
|
interface abgeschaltet. Solch ein Direktzugriff kann wieder auf das Fileinterface
|
|||
|
umgeschaltet werden, indem man einen Dateinamen aufruft. Bei den Dateinamen in
|
|||
|
der Liste der FILES ist also kein USE notwendig.
|
|||
|
|
|||
|
Wenn Sie als Beispiel direkt auf Drive A: zugreifen wollen, so ist die Syntax:
|
|||
|
|
|||
|
direct a:
|
|||
|
|
|||
|
Nun kann mit list , load , aber auch mit edit (!) auf die Disk zugegriffen
|
|||
|
werden! Deshalb ist bei Festplatten besondere Vorsicht geboten, da der Schreib-
|
|||
|
/Lesezeiger direkt auf dem Bootsektor der Platte stehen kann. Sollte Ihnen dies
|
|||
|
passieren, verlassen Sie den Editor mit CTRL-U (undo) und <ESC>.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien = 80 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 9.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Beim Direktzugriff muß allerdings beachtet werden, daß es für volksFORTH nur noch
|
|||
|
1 KB große Blöcke gibt, die hintereinander liegen und nur durch ihre Blocknummern
|
|||
|
identifiziert sind. Eine 360K DS/DD-Disk enthält dann für volksFORTH keine Files
|
|||
|
und kein Directory, sondern es steht lediglich Platz für 362 Blöcke zur Verfügung.
|
|||
|
|
|||
|
Es gibt zwar einige Leute, die diese direct-Funktion dazu benutzen, um mit dem
|
|||
|
FORTH-Editor die Systembereiche ihrer Festplatte zu editieren; aber normalerweise
|
|||
|
ermöglicht der Direct-Zugriff dem volksFORTH, ohne MSDOS auszukommen und den
|
|||
|
Massenspeicher sehr schnell und effizient zu bedienen.
|
|||
|
|
|||
|
Einige wichtige Worte:
|
|||
|
|
|||
|
call (==)
|
|||
|
ermöglicht den Aufruf von *,COM und *%.EXE-Files.
|
|||
|
call \park würde im Root-Directory Ihrer Harddisk ein Programm namens
|
|||
|
PARK aufrufen und ausführen.
|
|||
|
|
|||
|
msdos 0-2)
|
|||
|
verläßt das volksFORTH zur MSDOS-Ebene; mit exit kehren Sie ins
|
|||
|
FORTH zurück.
|
|||
|
|
|||
|
savesystem <name> (-=)
|
|||
|
|
|||
|
schreibt eine bootbare Form des jetzt laufenden FORTH-Systems unter
|
|||
|
dem Namen <name> auf den Massenspeicher. Dabei muß <name> die
|
|||
|
Endung .COM haben, wenn dieses System später wieder unter MSDOS ge-
|
|||
|
startet werden soll.
|
|||
|
Dieses Wort wird benutzt, um fertige Applikationen zu erzeugen. In
|
|||
|
diesem Fall sollte das Wort, daß die Applikation ausführt, in 'COLD
|
|||
|
gespeichert. Ein Beispiel:
|
|||
|
Sie haben ein Kopierprogramm geschrieben, das oberste ausführende Wort
|
|||
|
heißt COPYDISK . Mit der Befehlsfolge
|
|||
|
|
|||
|
' copydisk Is 'cold
|
|||
|
|
|||
|
savesystem copy.com
|
|||
|
erhalten Sie ein Progamm namens COPY.COM , das sofort beim Start
|
|||
|
COPYDISK ausführt.
|
|||
|
|
|||
|
direct ( ==)
|
|||
|
schaltet das MSDOS-Fileinterface aus und auf Direktzugriff um. Auf den
|
|||
|
Filezugriff schalten Sie durch das Nennen eines Filenamens um.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 88 - Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.1 Pfad-Unterstützung
|
|||
|
|
|||
|
volksFORTH besitzt eine eigene, vollständig von MSDOS unabhängige Pfadunter-
|
|||
|
stützung. Die Verwaltung von Directories entspricht in etwa der des MSDOS-
|
|||
|
Command-interpreters COMMAND.COM .
|
|||
|
|
|||
|
Beispiel: PATH A:\;B:\COPYALL\DEMO; \AUTO\
|
|||
|
|
|||
|
In diesem Beispiel wird zunächst die Diskstation A, dann das Directory
|
|||
|
COPYALL\DEMO auf Diskstation B und schließlich das Directory AUTO auf dem
|
|||
|
aktuellen Laufwerk gesucht.
|
|||
|
|
|||
|
Beachten Sie bitte das Zeichen "\" vor und hinter AUTO . Das vordere Zeichen "\"
|
|||
|
steht für das Hauptdirectory. Wird es weggelassen, so wird AUTO\ an das mit
|
|||
|
DIR gewählte Directory angehängt. Das hintere Zeichen "\" trennt den Filenamen
|
|||
|
vom Pfadnamen.
|
|||
|
|
|||
|
Durch die vollständige Unabhängigkeit kann z.B. volksFORTH mit dem Pfad
|
|||
|
C:\4TH; \4TH\WORK arbeiten, während MSDOS den Pfad C:\UTIL\TOOLS absucht.
|
|||
|
|
|||
|
path (--)
|
|||
|
Dieses Wort gestattet es, mehrere Directories nach einem zu Öffnenden
|
|||
|
File durchsuchen zu lassen. Das ist dann praktisch, wenn man mit
|
|||
|
mehreren Files arbeitet, die sich in verschiedenen Directories oder
|
|||
|
Diskstationen befinden. Es wird in den folgenden Formen benutzt:
|
|||
|
path dirl;\dir2\subdir2;\dir3
|
|||
|
|
|||
|
Hierbei sind <dirl>, <dir2> etc. Pfadnamen. Wird ein File auf dem Mas-
|
|||
|
“ senspeicher gesucht, so wird zunächst <diri>, dann <dir2> etc. durch-
|
|||
|
sucht. Zum Schluß wird das File dann im aktuellen Directory (siehe DIR)
|
|||
|
gesucht. Beachten Sie bitte, daß keine Leerzeichen in der Reihe der Pfad-
|
|||
|
namen auftreten dürfen.
|
|||
|
|
|||
|
path ohne Argument zeigt die aktuelle Pfadangabe und druckt
|
|||
|
die Reihe der Pfadnamen aus. Dieses Wort entspricht dem Kommando PATH
|
|||
|
des Kommandointerpreters.
|
|||
|
|
|||
|
path ; löscht die aktuelle Pfadangabe und es wird nur noch das
|
|||
|
aktuelle Directory durchsucht.
|
|||
|
|
|||
|
7.2 DOS-Befehle
|
|||
|
|
|||
|
dos
|
|||
|
|
|||
|
Viele Worte des Fileinterfaces, die normalerweise nicht benötigt werden,
|
|||
|
sind in diesem Vokabular enthalten.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien = 89I--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
dir
|
|||
|
zeigt das Inhaltsverzeichnis des Massenspeichers. Ohne weitere Eingaben
|
|||
|
wird der aktuelle Suchpfad einschließlich des Laufwerks angezeigt.
|
|||
|
|
|||
|
delete <filename>
|
|||
|
löscht eine Datei <filename> im aktuellen Directory .
|
|||
|
|
|||
|
ren <filename.alt> <filename.neu>
|
|||
|
benennt eine Datei nach üblicher MSDOS-Syntax um.
|
|||
|
|
|||
|
ftype <filename>
|
|||
|
gibt eine Text-Datei aus. FTYPE wurde so genannt, weil es ein FORTH-
|
|||
|
Wort type gibt.
|
|||
|
|
|||
|
md <dir>
|
|||
|
legt ein neues Directory an.
|
|||
|
|
|||
|
cd <dir>
|
|||
|
wechselt Directory (mit Pfadangabe).
|
|||
|
|
|||
|
rd <dir>
|
|||
|
löscht ein Directory.
|
|||
|
|
|||
|
dos: FORTH-Name DOS-Name "
|
|||
|
DOS: erwartet nach seinem Aufruf zwei Namen: Zuerst den FORTH-Namen,
|
|||
|
den der Befehl haben soll, dann den Namen der DOS-Funktion, die aus-
|
|||
|
geführt werden soll. Diese wird von einem Leerzeichen und einem quote "
|
|||
|
abgeschlossen. Ein Beispiel ist:
|
|||
|
dos: £ftype type "
|
|||
|
|
|||
|
Danach wird beim Aufruf des FORTH-Wortes FTYPE der MSDOS-Befehl
|
|||
|
TYPE ausgeführt.
|
|||
|
|
|||
|
7.3 Block-orientierte Dateien
|
|||
|
|
|||
|
Damit volksFORTH effizient auf den Massenspeicher zugreifen kann, bietet es -
|
|||
|
wie die meisten anderen FORTH-Systeme auch -— einen besonderen Puffermechanis-
|
|||
|
mus für den Diskzugriff. Dadurch wird der Geschwindigkeitsunterschied zwischen
|
|||
|
den langsamen Laufwerken und dem schnellen Hauptspeicher ausgeglichen.
|
|||
|
|
|||
|
Entgegen der Literatur [Brodie) ist im volkFORTH das Ende eines Screens nicht
|
|||
|
durch ein Doppel-Nullbyte 08 gekennzeichnet. volksFORTH arbeitet statt dessen mit
|
|||
|
SKIP und SCAN und wertet die Länge aus, die in >in bereits abgearbeitet ist.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 98 - Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3,81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
view
|
|||
|
|
|||
|
list
|
|||
|
|
|||
|
files
|
|||
|
|
|||
|
isfile
|
|||
|
|
|||
|
isfile@
|
|||
|
|
|||
|
fromfile
|
|||
|
|
|||
|
fswap
|
|||
|
|
|||
|
[FCB]
|
|||
|
|
|||
|
‚file
|
|||
|
|
|||
|
( <name) -- )
|
|||
|
wird in der Form view <name> benutzt.
|
|||
|
Wenn <name> im Wörterbuch gefunden wird, so wird das File geöffnet, in
|
|||
|
dem der Quelltext von <name> steht und der Block wird gelistet, auf dem
|
|||
|
<name> definiert ist.
|
|||
|
Siehe: LIST
|
|||
|
|
|||
|
C(bik# --)
|
|||
|
zeigt den block mit der angegebenen Nummer an.
|
|||
|
|
|||
|
==)
|
|||
|
zeigt alle FORTH-Dateien an. Diese müssen nicht mit den MSDOS-Files
|
|||
|
identisch sein. Dagegen zeigt dir die MSDOS-Files an.
|
|||
|
|
|||
|
( -- addr )
|
|||
|
ist die Adresse einer Variablen, die auf das aktuelle FORTH-File zeigt.
|
|||
|
Der Wert in dieser Variablen entspricht typisch der Adresse des File-
|
|||
|
ControlBlocks FCB. Ist der Wert in dieser Adresse gleich Null, so wird
|
|||
|
direkt ohne ein File auf den Massenspeicher zugegriffen.
|
|||
|
|
|||
|
(== fcb)
|
|||
|
holt den FCB des isfile. Die Sequenz
|
|||
|
isfile@ f.handle @
|
|||
|
liefert die DOS-Handlenummer.
|
|||
|
|
|||
|
( -- addr )
|
|||
|
ist die Adresse einer Variablen, die auf das FORTH-File zeigt, aus dem
|
|||
|
copy und convey die Blöcke lesen.
|
|||
|
fronfile @ liefert den FCB dieser Datei.
|
|||
|
|
|||
|
v==,)
|
|||
|
vertauscht isfile und fromfile .
|
|||
|
Vergleiche im Editor das Drücken der Taste F9.
|
|||
|
|
|||
|
(== fcb )
|
|||
|
ist eine Konstante des Typs FCB und dient für Vergleiche, ob ein Wort
|
|||
|
einen FCB darstellt. Es ist definiert als:
|
|||
|
|
|||
|
' kernel.scr @
|
|||
|
|
|||
|
( fceb --) DOS
|
|||
|
druckt den FORTH-Filenamen des Files aus, dessen FCB-Adresse auf dem
|
|||
|
Stack liegt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien - 9 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
filename ( -- addr ) Dos
|
|||
|
ist die Anfangsadresse eines 62-Byte großen Speicherbereichs, der zum
|
|||
|
Ablegen von Filenamen während DOS-File-Operationen dient.
|
|||
|
|
|||
|
fnamelen (-- N) DOS
|
|||
|
ist eine Konstante, die die maximale Länge von logischen Filenamen, be-
|
|||
|
stehend aus Drive, Path und Name, die in den FCB's abgespeichert werden
|
|||
|
können, bestimmt. Wird dieser Wert verändert, so kann die neue Länge
|
|||
|
erst in den FCB's verwendet werden, die nach der Änderung angelegt
|
|||
|
werden.
|
|||
|
|
|||
|
AUBiICHDHELE GH (=)
|
|||
|
|
|||
|
Entspricht MS-DOS, macht das dadurch bezeichnete logische Laufwerk zum =
|
|||
|
|
|||
|
aktuellen Laufwerk.
|
|||
|
|
|||
|
DTA ( -- 888 )
|
|||
|
ist als Konstante die Start-Adresse der DiskTransferArea.
|
|||
|
|
|||
|
capacities ( -- addr )
|
|||
|
ist die Adresse eines Vektors, der die Kapazitäten der angeschlossenen
|
|||
|
logischen Laufwerken in 1ikByte-Blöcken enthält. Dafür sind maximal 6
|
|||
|
Einträge (siehe: #DRIVES ) vorgesehen. Mit dem Hilfsprogramm DISKS.CFG
|
|||
|
können die Kapazitäten für die Diskettenlaufwerke eingestellt werden.
|
|||
|
|
|||
|
drv ( -- #drive )
|
|||
|
übergibt die Nummer des aktuellen Laufwerks.
|
|||
|
|
|||
|
drive ( #drive -- )
|
|||
|
macht das Laufwerk mit der angegebenen Nummerzum aktuellen Laufwerk.
|
|||
|
Hierbei entspricht n=®d dem Laufwerk A, n=1 dem Laufwerk B usw. . Auf
|
|||
|
|
|||
|
dem aktuellen Laufwerk werden Files und Directories erzeugt (und nach
|
|||
|
Durchsuchen von PATH gesucht).
|
|||
|
|
|||
|
8 block liefert die Adresse des ersten Blocks auf dem aktuellen Lauf-
|
|||
|
werk. ö
|
|||
|
Vergleiche »drive und offset..
|
|||
|
|
|||
|
file <name>
|
|||
|
erzeugt ein FORTH-Wort mit dem gleichen Namen. Wird dieses Wort später
|
|||
|
aufgerufen, so vermerkt es sich als aktuelles File isfile und als
|
|||
|
Hintergund-Datei fromfile . Diesem logischen FORTH-File kann man dann
|
|||
|
mit assign oder make eine MSDOS-Datei zuordnen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 92 = Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
make <name>
|
|||
|
|
|||
|
wird in der Form
|
|||
|
|
|||
|
make (Dateiname)
|
|||
|
benutzt. Es erzeugt ein MSDOS-File im aktuellen Directory und ordnet es
|
|||
|
dem aktuellen FORTH-File zu. Es hat die Länge Null (siehe more ),
|
|||
|
Beispiel: file test.scr test.scr make test.scr'
|
|||
|
|
|||
|
makefile (name>
|
|||
|
|
|||
|
assign
|
|||
|
|
|||
|
file?
|
|||
|
|
|||
|
file
|
|||
|
|
|||
|
load
|
|||
|
|
|||
|
bIk
|
|||
|
|
|||
|
erzeugt eine FORTH-Datei mit diesem Namen und ebenfalls eine MSDOS-
|
|||
|
Datei mit dem gleichen Namen. Dieses File wird auch sofort geöffnet, hat
|
|||
|
aber noch die Länge ®, wenn keine Größe mit nn more angegeben wurde.
|
|||
|
makefile ist ein Ersatz für die Prozedur in dem Beispiel, das bei make
|
|||
|
angegeben wurde.
|
|||
|
|
|||
|
)
|
|||
|
wird benutzt in der Form
|
|||
|
|
|||
|
assign (filename)
|
|||
|
und weist dem aktuellen logischen FORTH-File eine physikalische DOS-
|
|||
|
Datei zu.
|
|||
|
|
|||
|
(=)
|
|||
|
zeigt den FORTH-Filenamen des aktuellen Files an.
|
|||
|
|
|||
|
(==)
|
|||
|
zeigt den MSDOS-Namen, das Handle sowie Datum des letzten Zugriffs der
|
|||
|
aktuellen Datei.
|
|||
|
|
|||
|
Cbik# --)
|
|||
|
lädt/compiliert den block mit der angegebenen Nummer an.
|
|||
|
|
|||
|
( -- addr )
|
|||
|
ist die Adresse einer Variablen, die die Blocknummer des gerade inter-
|
|||
|
pretierten Blocks enthält. Wird TIB interpretiert, enthält BLK den
|
|||
|
Wert NULL ; d.h., auch wenn Sie den Inhalt interaktiv auslesen, so
|
|||
|
erhalten Sie immer den Wert 9 !
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien u Zum
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
loadfrom (bIk# --)
|
|||
|
|
|||
|
wird in folgender Form benutzt:
|
|||
|
( block# ) loadfrom “Dateiname>
|
|||
|
|
|||
|
Dies ist wichtig, wenn während des Compilierens Teile eines anderen
|
|||
|
Files geladen werden sollen. Damit kann die Funktion eines Linkers imi-
|
|||
|
tiert werden.
|
|||
|
Beispiel: 15 loadfrom tools.scr
|
|||
|
Dieses Wort benutzt use, um Files zu selektieren; das bedeutet, daß in
|
|||
|
diesem Beispiel automatisch eine Datei namens tools.scr erzeugt wird,
|
|||
|
falls dieses File noch nicht existierte.
|
|||
|
Dieses Wort hat nichts mit from oder fromfile zu tun, obwohl es
|
|||
|
ähnlich heißt.
|
|||
|
|
|||
|
include (==)
|
|||
|
wird in der Form benutzt:
|
|||
|
|
|||
|
include <Dateiname>
|
|||
|
|
|||
|
Hier wird ein File vollständig geladen. Voraussetzung ist, daß in Screen
|
|||
|
#1 Anweisungen stehen, die zum Laden aller Screens führen.
|
|||
|
|
|||
|
b/blk ( -- &1024 ) "bytes pro block"
|
|||
|
ist die Länge eines Blocks (bzw. Screens, immer 1 KByte) wird auf den
|
|||
|
Stack gelegt.
|
|||
|
Siehe B/BUF.
|
|||
|
|
|||
|
b/buf ( =n,;) "bytes pro buffer"
|
|||
|
n ist die Länge eines Blockpuffers incl. der Verwaltungs-informationen
|
|||
|
des Systems, in der Version 3.81 für den PC $%408 Byte, bestehend aus
|
|||
|
$408 Byte Puffer und $8 Byte Verwaltungsinformation.
|
|||
|
|
|||
|
bIk/drv -—-n) "blocks pro drive"
|
|||
|
n ist die Anzahl der auf dem aktuellen Laufwerk verfügbaren Blöcke.
|
|||
|
|
|||
|
(more Rs)
|
|||
|
wie MORE , jedoch wird das File nicht geschlossen.
|
|||
|
|
|||
|
more (n--)
|
|||
|
vergrößert die aktuelle Datei (isfile) um eine bestimmte Anzahl von
|
|||
|
Blöcken, die hinter angehängt werden. Anschließend wird die Datei ge-
|
|||
|
schlossen.
|
|||
|
|
|||
|
- 94. - Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
capacity (--n)
|
|||
|
n ist die Speicherkapazität einer Datei, wobei Block ® mitgezählt wird.
|
|||
|
Deshalb ist für Quelltexte nur capacity 1- (d.h. minus Block 9)
|
|||
|
nutzbar. Wenn shadow screens verwendet werden, steht nur capacity
|
|||
|
2/ 1- zur Verfügung.
|
|||
|
|
|||
|
block { u-- addr ) 83
|
|||
|
addr ist die Adresse des ersten Bytes des Blocks u in dessen Blockpuffer.
|
|||
|
Der Block u stammt aus dem File in ISFILE.
|
|||
|
BLOCK prüft den Pufferbereich auf die Existenz des Blocks Nummer u.
|
|||
|
Befindet sich der Block u in keinem der Blockpuffer, so wird er vom Mas-
|
|||
|
senspeicher in einen an ihn vergebenen Blockpuffer geladen. Falls der
|
|||
|
Block in diesem Puffer als UPDATEd markiert ist, wird er auf den Mas-
|
|||
|
senspeicher gesichert, bevor der Blockpuffer an den Block u vergeben
|
|||
|
wird.
|
|||
|
Nur die Daten im letzten Puffer, der über BLOCK oder BUFFER ange-
|
|||
|
sprochen wurde, sind sicher zugreifbar. Alle anderen Blockpuffer dürfen
|
|||
|
nicht mehr als gültig angenommen werden (möglicherweise existiert nur 1
|
|||
|
Blockpuffer).
|
|||
|
Vorsicht ist bei Benutzung des Multitaskers geboten, da eine andere Task
|
|||
|
block oder buffer ausführen kann. Der Inhalt eines Blockpuffers wird
|
|||
|
nur auf den Massenspeicher gesichert, wenn der Block mit update als
|
|||
|
verändert gekennzeichnet wurde.
|
|||
|
|
|||
|
(block ( bik file -- addr )
|
|||
|
liest den Block blk aus dem File, dessen FCB bei der Adresse file beginnt
|
|||
|
und legt diesen in einen Puffer bei der Adresse addr ab.
|
|||
|
|
|||
|
buffer ( block# -- addr )
|
|||
|
|
|||
|
weist dem block mit der angegebenen Nummer einen Blockpuffer im Spei-
|
|||
|
cher zu. Die Zuweisung wird von der internen Logik vorgenommen - an-
|
|||
|
schließend wird die Startadresse dieses Pufferbereiches übergeben. Dabei
|
|||
|
entspricht addr der Adresse des ersten Bytes des Blocks in seinem Puffer.
|
|||
|
Der große Unterschied zwischen block und buffer ist, daß block
|
|||
|
tatsächlich die Daten von Disk in den Puffer liest. buffer dagegen re-
|
|||
|
serviert nur den Puffer, initialisiert ihn nicht und liest keine Daten vom
|
|||
|
Massenspeicher. Daher ist der Inhalt dieses Blockpuffers undefiniert.
|
|||
|
|
|||
|
(buffer ( bIik file -- addr )
|
|||
|
reserviert einen 1kByte großen Puffer im Adreßbereich des FORTH-
|
|||
|
Systems für den Block biIk. file ist die Adresse des FCB's, in dem sich
|
|||
|
der Block befindet. Ist file = ®, dann handelt es sich um einen DIRECTen
|
|||
|
physikalischen Zugriff. addr ist die Anfangsadresse des Puffers.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien = 98.—
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
offset ( -- addr )
|
|||
|
liefert die Adresse einer UserVariablen, deren Inhalt zu der Blocknummer
|
|||
|
addiert wird, die sich beim Aufruf von block , buffer usw. auf dem
|
|||
|
Stack befindet.
|
|||
|
|
|||
|
fblock@ ( addr bik fcb -- ) DOS
|
|||
|
1024 Bytes, die im File fcb in Block blk stehen, werden ab der Adresse
|
|||
|
addr im FORTH-Adressbereich abgelegt.
|
|||
|
|
|||
|
fblockt Kkaddrı. bIK feb —— ) DOS
|
|||
|
1024 Bytes, die ab der Adresse addr innerhalb des FORTH-Adressbereichs
|
|||
|
stehen, werden auf den Block bik innerhalb des Files geschrieben, das
|
|||
|
durch fcb characterisiert ist.
|
|||
|
|
|||
|
*block C(bIik --d) DOS
|
|||
|
Die doppeltgenaue Zahl d ist die Byteadresse des ersten Bytes im 1924-
|
|||
|
Byte großen Block bIk.
|
|||
|
|
|||
|
/block (d-- rest bik ) DOS
|
|||
|
Die doppeltgenaue Zahl D wird umgerechnet in die REST-Anzahl von
|
|||
|
Bytes innerhalb des 1924-Byte großen Blocks bIk.
|
|||
|
|
|||
|
r/w ( addr bIk fcb r/w -- *f )
|
|||
|
ist ein deferred Wort, bei dessen Aufruf das systemabhängige Wort für
|
|||
|
den blockorientierten Massenspeicherzugriff ausgeführt wird.
|
|||
|
Dabei ist addr die Anfangsadresse des Speicherbereiches für den Block
|
|||
|
block, fcb die Addresse des Files, in dem sich der Block befindet. r/w ist
|
|||
|
gleich Null, wenn vom Speicherbereich auf den Massenspeicher geschrie-
|
|||
|
ben werden soll oder r/w =1, wenn der Block gelesen werden soll. *f ist
|
|||
|
nur im Fehlerfall wahr, sonst falsch.
|
|||
|
|
|||
|
(r/w ( addr bik fcb r/w -- *f )
|
|||
|
Die Standardroutine für das deferred Wort R/W.
|
|||
|
|
|||
|
eof ( -- true )
|
|||
|
entspricht der Konstanten TRUE = -1.
|
|||
|
|
|||
|
- 96 - Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4 Verwaltung der Block-Puffer
|
|||
|
|
|||
|
core? ( bIk# filename -- addr ! ff )
|
|||
|
prüft, ob sich der Block mit der angegebenen Nummer aus der genannten
|
|||
|
Datei bereits in einem der Block-Puffer befindet. Wenn das der Fall ist,
|
|||
|
wird die Anfangsadresse des Puffers übergeben, anderenfalls ein false
|
|||
|
flag . “
|
|||
|
Vergleiche BLOCK , BUFFER und ISFILE.
|
|||
|
|
|||
|
(core? ( blk# filename -- addr ! false )
|
|||
|
ist die Standardroutine für das Wort CORE? .
|
|||
|
|
|||
|
update (==)
|
|||
|
markiert den zur Zeit gültigen Pufferspeicher als verändert. Von dieser
|
|||
|
update-Kennzeichnung wird dann die Sicherung der Daten abhängig ge-
|
|||
|
macht, wenn dieser Blockpuffer für einen anderen Block benötigt oder
|
|||
|
wenn SAVE-BUFFERS ausgeführt wird.
|
|||
|
Vergleiche PREV .
|
|||
|
|
|||
|
save-buffers N)
|
|||
|
Das Alias sav im Editor heißt normalerweise save-buffers und rettet
|
|||
|
alle als UPDATEd markierten Pufferbereiche auf Disk und löscht die
|
|||
|
UPDATE-Kennzeichnungen. Hierbei bleibt die bestehende Zuweisung blk ->
|
|||
|
buffer erhalten, die Blöcke werden jedoch nicht verändert und bleiben für
|
|||
|
weitere Zugriffe im Speicher erhalten.
|
|||
|
|
|||
|
flush A)
|
|||
|
schreibt alle als UPDATEd markierten Pufferbereiche auf Disk und löscht
|
|||
|
die UPDATE-Markierung. Allerdings wird jetzt die Zuweisung BLK ->
|
|||
|
BUFFER zerstört. Zugleich wird die Datei geschlossen und das Inhaltsver-
|
|||
|
zeichnis aktualisiert.
|
|||
|
Vergleiche SAVE-BUFFERS und EMPTY-BUFFERS .
|
|||
|
|
|||
|
emptybuf ( buffer.addr -- )
|
|||
|
|
|||
|
empty-buffers GE)
|
|||
|
|
|||
|
löscht den Inhalt aller Blockpuffer, ohne die Daten von als UPDATEd4
|
|||
|
markierten Blockpuffern auf den Massenspeicher zurückzuschreiben. Es
|
|||
|
zerstört die Zuweisung BLK -> BUFFER und löscht die UPDATE-Mar-
|
|||
|
kierung.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien = Imre
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
freebuffer ("e=a)
|
|||
|
Entfernt den Blockpuffer mit der niedrigsten Adresse aus der Liste der
|
|||
|
Blockpuffer und gibt den dadurch belegten Speicherbereich frei. FIRST
|
|||
|
wird entsprechend um B/BUF erhöht. Ist der Inhalt des Puffers als
|
|||
|
UPDATEd markiert, so wird er zuvor auf den Massenspeicher gesichert.
|
|||
|
Gibt es im System nur noch einen Blockpuffer, so geschieht nichts.
|
|||
|
Vergleiche ALLOTBUFFER .
|
|||
|
|
|||
|
allotbuffer (=)
|
|||
|
Fügt der Liste der Blockpuffer noch einen weiteren hinzu, falls oberhalb
|
|||
|
vom Ende des Retunstacks dafür noch Platz ist. FIRST wird entspre-
|
|||
|
chend geändert.
|
|||
|
Vergleiche FREEBUFFER und ALL-BUFFERS .
|
|||
|
|
|||
|
all-buffers ==)
|
|||
|
Belegt den gesamten Speicherbereich von LIMIT abwärts bis zum oberen
|
|||
|
Ende des Returnstacks mit Blockpuffern.
|
|||
|
Siehe ALLOTBUFFER .
|
|||
|
|
|||
|
first ( -- addr )
|
|||
|
ist eine Variable, die einen Zeiger auf den Blockpuffer mit der niedrig-
|
|||
|
sten Adresse darstellt. So liefert Ihnen FIRST @ die Startadresse des
|
|||
|
Blockpufferbereiches.
|
|||
|
Vergleiche ALLOTBUFFER .
|
|||
|
|
|||
|
limit ( -- addr )
|
|||
|
ist im Gegensatz zu FIRST keine Variable, sondern liefert direkt die
|
|||
|
addr, unterhalb der sich die Blockpuffer befinden. Das letzte Byte des
|
|||
|
obersten Blockpuffers befindet sich in addr-1.
|
|||
|
Vergleiche ALL-BUFFERS und ALLOTBUFFER.
|
|||
|
|
|||
|
Die Anzahl der Blockpuffer im aktuellen System läßt sich so ausrechnen:
|
|||
|
:» #buf ( -- Anzahl )
|
|||
|
linit first@e- b/buf/ ;
|
|||
|
|
|||
|
prev ( -- addr )
|
|||
|
addr ist die Adresse einer Variablen, deren Wert der Anfang der Liste
|
|||
|
aller Blockpuffer ist. Der erste Blockpuffer in der Liste ist der zuletzt
|
|||
|
durch BLOCK oder BUFFER vergebene.
|
|||
|
|
|||
|
offset ( -- addr )
|
|||
|
addr ist die Adresse einer Uservariablen, deren Inhalt zu der Block-
|
|||
|
nummer addiert wird, die sich bei Aufruf von BLOCK , BUFFER usw.
|
|||
|
auf dem Stack befindet. OFFSET wird durch DRIVE verändert.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=, Ge Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
‚status (--)
|
|||
|
|
|||
|
ist ein defered Wort, das vor dem Laden eines Blockes oder vor dem Ab-
|
|||
|
arbeiten der Tastatureingabe ausgeführt wird. Normalerweise ist es mit
|
|||
|
NOOP vorbesetzt.
|
|||
|
|
|||
|
7.5 Index-, Verschiebe- und Kopierfunktionen für Block-Files
|
|||
|
|
|||
|
Die meisten FORTH-Systeme, die bevorzugt mit Block-Dateien arbeiten, verfügen
|
|||
|
über eine INDEX-Funktion, die die Zeile 8 eines jeden Screens anzeigt. Diese Zeile
|
|||
|
gibt üblicherweise den Inhalt des Screens an.
|
|||
|
|
|||
|
Allgemein ist die Syntax für Index: (start) <end) index
|
|||
|
|
|||
|
Das nachfolgend beschriebene INDEX erwartet dagegen nur die Angabe des Blockes,
|
|||
|
bei dem die INDEX-Anzeige beginnen soll ; wird kein Argument übergeben, so
|
|||
|
beginnt die INDEX-Anzeige mit Screen 1. Auch können nach dem Kompilieren die
|
|||
|
durch i als headerless gekennzeichneten Worte mit clear gelöscht werden.
|
|||
|
|
|||
|
| : range ( from to -- to+1 from )
|
|||
|
2dup u) IF swap THEN 1+ swap ;
|
|||
|
|
|||
|
i : .„£fnane isfile@ [ DOS ]J .file ;
|
|||
|
|
|||
|
: index ( from -- )
|
|||
|
depth 0= IF 1 THEN capacity 1- range
|
|||
|
." von " .fnane
|
|||
|
( range) DO cr I4 .r space
|
|||
|
I block c/l -trailing type
|
|||
|
stop? IF leave THEN
|
|||
|
LOOP ;
|
|||
|
|
|||
|
copy (ul u2--)
|
|||
|
Der Block ul wird in den Block u2 kopiert.
|
|||
|
Innerhalb einer Datei wird ein bereits beschriebener Zielblock überschrie-
|
|||
|
ben, der alte Inhalt des Blocks u2 ist verloren.
|
|||
|
Vergleiche auch CONVEY. j
|
|||
|
Ist ein FROMFILE angemeldet, so arbeitet COPY immer in Bezug auf
|
|||
|
das FROMFILE.. Der Befehl 3 4 copy kopiert dann den Block# 3 aus
|
|||
|
der Hintergrunddatei FROMFILE in die aktuelle Datei ISFILE und nicht
|
|||
|
innerhalb des ISFILE ! \ \
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien =#99 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
from <name>
|
|||
|
|
|||
|
gibt an, aus welchem File bei Datei-Operationen herauskopiert werden
|
|||
|
soll. Vergleiche auch die Datei STREAM.SCR .
|
|||
|
|
|||
|
from abc.scr 1 10 copy
|
|||
|
kopiert den Block 1 von File FROMFILE in den Block# 18 ins aktuelle
|
|||
|
ISFILE , wobei der Zielblock leer sein muß; soll nicht überschrieben, son-
|
|||
|
dern eingefügt werden, wird
|
|||
|
|
|||
|
from abc.scr 1 18 1 convey
|
|||
|
eingesetzt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
convey ( 1st.block last.block to.block -- )
|
|||
|
Verschiebt die Blöcke von I1st.block bis einschließlich last.block nach
|
|||
|
to.block. Die Bereiche dürfen sich überlappen. Eine Fehlerbehandlung wird
|
|||
|
eingeleitet, wenn last.block kleiner als 1st.block ist. —
|
|||
|
Die Blöcke werden aus dem File in FROMFILE ausgelesen und in das
|
|||
|
File in ISFILE geschrieben. FROMFILE und ISFILE dürfen gleich sein,
|
|||
|
Das Beispiel
|
|||
|
46 5 convey
|
|||
|
kopiert die Blöcke 4,5,6 nach 5,6,7. Der alte Inhalt des Blockes 7 ist
|
|||
|
verloren, der Inhalt der Blöcke 4 und 5 ist gleich.
|
|||
|
CONVEY wird auch benutzt, wenn man gerne einen freien Block in ein
|
|||
|
Blockfile einfügen möchte:
|
|||
|
(INSERT ( start# -- )
|
|||
|
fügt an der angegebenen Zielposition einen Block ein.
|
|||
|
: (insert ( start# -- )
|
|||
|
dup 1+ capacity 1- swap 1 more convey ;
|
|||
|
INSERT =)
|
|||
|
fügt vor dem aktuellen Block einen Block ein.
|
|||
|
: insert (==)
|
|||
|
scr @ dup (insert
|
|||
|
block b/blk blank update ;
|
|||
|
7.6 FCB-orientierte Dateien
|
|||
|
pushfile (==) c
|
|||
|
wird in :-Definitionen benutzt, um den aktuellen Zustand der File-
|
|||
|
variablen ISFILE und FROMFILE nach dem Ende der Colon-Definition
|
|||
|
wiederherzustellen.
|
|||
|
Vergleichen Sie bitte den Mechanismus der lokalen Variablen: PUSH
|
|||
|
- 100 - Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
open C-—)
|
|||
|
öffnet das aktuelle File zur Bearbeitung; ist aber in den meisten Fällen
|
|||
|
überflüssig, weil Files beim Zugriff automatisch geöffnet werden.
|
|||
|
|
|||
|
tmptyfile ==)
|
|||
|
|
|||
|
legt eine leere Datei zum aktuellen Dateinamen an. Wird z.B in MAKE
|
|||
|
benutzt.
|
|||
|
|
|||
|
killfile (==)
|
|||
|
löscht ohne weitere Rückfrage des aktuelle MSDOS-File; das aktuelle
|
|||
|
FORTH-File wird dabei nicht gelöscht, denn das FORTH-File ist wie eine
|
|||
|
Dateivariable in anderen Sprachen zu betrachten und dementsprechend als
|
|||
|
Variable mit forget <filename> zu löschen.
|
|||
|
|
|||
|
close (==)
|
|||
|
schließt das aktuelle File und aktualisiert das Inhaltsverzeichnis des
|
|||
|
Massenspeichers.
|
|||
|
|
|||
|
flush Ge)
|
|||
|
schließt alle geöffneten Dateien und aktualisiert das Inhaltsverzeichnis
|
|||
|
des Massenspeichers. Zugleich werden alle Zwischenpuffer auf die Disk
|
|||
|
zurückgeschrieben.
|
|||
|
|
|||
|
fopen (fcb -- )
|
|||
|
ist im volks4TH nicht vorhanden, weil die erwartete Funktion von
|
|||
|
FRESET erfüllt wird. Deshalb kann man dies so definieren:
|
|||
|
|
|||
|
' FRESET Alias FOPEN
|
|||
|
|
|||
|
freset (fcb--) DOS
|
|||
|
fcb ist die Adresse eines FileControlBlocks. Das dadurch charakterisierte
|
|||
|
File wird "zurückgesetzt", d.h. das File wird geöffnet (wenn es noch nicht
|
|||
|
geöffnet war) und der Schreib/Lesezeiger wird auf den Anfang des Files
|
|||
|
gesetzt.
|
|||
|
|
|||
|
felose (feb -= ) DOS
|
|||
|
Das File, dessen FCB-Adresse auf dem Stack liegt, wird geschlossen.
|
|||
|
|
|||
|
fgete ( fcb -- 8b I eof ) DOS
|
|||
|
|
|||
|
Aus dem File, dessen FCB-Adresse auf dem Stack liegt, wird das nächste
|
|||
|
Byte gelesen und der Schreib/Lesezeiger um eine Position weitergerückt.
|
|||
|
Wenn das letzte Byte bereits gelesen war, wird die End-Of-File-Mar-
|
|||
|
kierung -1 zurückgegeben.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien — Io >
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
fpute (8b fcb -- ) DOS
|
|||
|
Das Byte 8B wird an der aktuellen Position des Schreib/Lesezeigers in
|
|||
|
das File FCB geschrieben. Dabei wird der Zeiger um eine Position weiter
|
|||
|
gerückt.
|
|||
|
|
|||
|
file@ ( dfaddr fcb -- Sb | eof ) DOS
|
|||
|
Das Byte an der 32-bit Position dfaddr im File, daß durch fcb charak-
|
|||
|
terisiert ist, wird gelesen. Liegt dfaddr jenseits des letzten Bytes im File,
|
|||
|
so wird -1 zurückgegeben. Nach erfolgreichem Lesen steht der Lese-
|
|||
|
/Schreibzeiger hinter dem gelesenen Byte.
|
|||
|
|
|||
|
file! ( 8b dfaddr fcb -- ) DOS
|
|||
|
Das Byte 8B wird an die Position dfaddr des Files fcb geschrieben.
|
|||
|
|
|||
|
fseek ( dfaddr fcb -- ) DOS
|
|||
|
Der Schreib/Lesezeiger des Files, das durch fcb charakterisiert ist, wird
|
|||
|
auf die Position dfaddr gesetzt. Dabei ist dfaddr eine doppeltgenaue Zahl,
|
|||
|
so daß maximal Files von 4-GByte Größe verwaltet werden können.
|
|||
|
|
|||
|
savefile ( addr len -- )
|
|||
|
wird in der Form:
|
|||
|
savefile (name?
|
|||
|
benutzt und schreibt die Anzahl von len Bytes ab der Adresse addr in
|
|||
|
das neu erzeugte File mit dem Namen <name»>.
|
|||
|
|
|||
|
lfsave ( seg:addr quan string -- )
|
|||
|
erzeugt ein File mit dem Namen, der als gecounteter String an der
|
|||
|
Adresse string abgelegt ist und schreibt die Anzahl quan Bytes ab der
|
|||
|
erweiterten Adresse seg:addr in dieses neue File.
|
|||
|
|
|||
|
lfputs ( seg:addr quan fcb -- )
|
|||
|
quan Bytes ab der erweiterten Adresse seg:addr werden ab der aktuellen
|
|||
|
Position des Schreib/Lesezeigers in das File geschrieben, das durch fecb
|
|||
|
charakterisiert ist. Danach steht der Schreib/Lesezeiger hinter dem letz- —
|
|||
|
ten geschriebenen Byte. Um z.B. den Bildschirmspeicher in seinem aktu-
|
|||
|
ellen Zustand in eine Datei zu schreiben, wird es in der Form benutzt:
|
|||
|
. open video® O6 c/dis isfile@ lfputs close ...
|
|||
|
|
|||
|
Ifgets ( seg:addr quan fcb -- #read ) DOS
|
|||
|
siehe: ’READ . Lediglich wird statt der Handlenummer die Adresse des
|
|||
|
FCB's des gewünschten Files angegeben. Entsprechend dem Beispiel bei
|
|||
|
'LFPUTS lassen sich mit diesem Wort Bildschirmmasken direkt in den Bild-
|
|||
|
schirmspeicher laden. .
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 102» Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
asciz
|
|||
|
|
|||
|
‚asciz
|
|||
|
|
|||
|
counted
|
|||
|
|
|||
|
loadfile
|
|||
|
|
|||
|
file-link
|
|||
|
|
|||
|
"creat
|
|||
|
|
|||
|
"open
|
|||
|
|
|||
|
( -- asciz )
|
|||
|
holt das nächste Wort im Quelltext in den Speicher und legt es als null-
|
|||
|
terminierten String bei der Adresse asciz ab.
|
|||
|
|
|||
|
( string addr -- asciz )
|
|||
|
Mit diesem Operator wird der gecountete String an der Adresse string
|
|||
|
umgewandelt in einen nullterminierten String, der an der Adresse addr
|
|||
|
abgelegt wird. asciz ist die Adresse, an der der neue String liegt.
|
|||
|
|
|||
|
( asciz -- addr len )
|
|||
|
wird benutzt, um die Länge eines mit einer Null terminierten Strings zu
|
|||
|
bestimmen. asciz ist die Anfangsadresse dieses Strings (MS-DOS verwaltet
|
|||
|
Strings so), addr und len sind die Stringparameter, die z.B. von TYPE
|
|||
|
verarbeitet werden würden.
|
|||
|
|
|||
|
( -- addr )
|
|||
|
ist eine Variable als Pointer auf das File, das gerade geladen wird.
|
|||
|
|
|||
|
( -- addr )
|
|||
|
ist eine Variable, die den Anfang zur Verwaltung einer Liste der File-
|
|||
|
Control-Blöcke (FCB) enthält. Der Inhalt von FILE-LINK zeigt auf den
|
|||
|
Anfang des Parameterfeldes des zuletzt definierten FCB's - und an dieser
|
|||
|
Stelle steht dann die Adresse des davor definierten FCB's usw., so daß
|
|||
|
dadurch alle FCB's aufgefunden werden können. Diese Liste wird u.a. von
|
|||
|
forget und files benutzt.
|
|||
|
|
|||
|
7.7 HANDLE-orientierte Dateien
|
|||
|
|
|||
|
( asciz attribut -- handle ff ! err#) DOs
|
|||
|
Der MS-DOS Systemaufruf, um ein neues File zu erzeugen.
|
|||
|
|
|||
|
( asciz mode -- handle ff | err#) DOS
|
|||
|
Der MS-DOS Systemaufruf für das Öffnen eines Files. asciz ist die
|
|||
|
Adresse des vollen Namensstrings und mode bezeichnet die Art des File-
|
|||
|
Attributes. Dabei sind mögliche Attribute :
|
|||
|
|
|||
|
0 Constant read-only
|
|||
|
|
|||
|
1 Constant write-only
|
|||
|
|
|||
|
2 Constant read-write
|
|||
|
Bei Erfolg liegt eine HANDLE-Nummer unter einer Null auf dem Stack,
|
|||
|
ansonsten eine Fehlernummer.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien - 103 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
"read
|
|||
|
|
|||
|
"close
|
|||
|
|
|||
|
"unlink
|
|||
|
|
|||
|
"dir
|
|||
|
|
|||
|
"select
|
|||
|
|
|||
|
"disk?
|
|||
|
|
|||
|
attribut
|
|||
|
|
|||
|
(fsearch
|
|||
|
|
|||
|
fsearch
|
|||
|
|
|||
|
( seg:addr quan handle -- #read ) DOS
|
|||
|
quan Bytes werden aus dem File gelesen, daß durch die Kennummer
|
|||
|
handle charakterisiert ist. Sie werden im erweiterten Speicherbereich bei
|
|||
|
seg:addr abgelegt. Nach Ende der Leseoperation liegt die Anzahl der
|
|||
|
Bytes auf dem Stack, die tatsächlich bis zum Ende des Files gelesen
|
|||
|
werden konnten. Es können jedoch nur maximal 64kByte auf einmal ge-
|
|||
|
lesen werden.
|
|||
|
|
|||
|
( handle -- ) DOS
|
|||
|
Der MS-DOS Systemaufruf, um das File, das durch handle characterisiert
|
|||
|
ist, zu schließen. °
|
|||
|
|
|||
|
( asciz -- err# ) DOS
|
|||
|
Der MS-DOS Systemaufruf, um einen Fileeintrag zu löschen.
|
|||
|
|
|||
|
( addr drive -- err#) DOS
|
|||
|
Der MS-DOS Systemaufruf, mit dem das aktuelle Directory an der Adresse
|
|||
|
addr als nullterminierter String abgelegt wird.
|
|||
|
|
|||
|
(Mes) DOS
|
|||
|
Der MS-DOS Systemaufruf, mit dem das aktuelle Laufwerk selektiert wird.
|
|||
|
|
|||
|
(==) DOS
|
|||
|
Der MS-DOS Systemaufruf, mit dem das aktuelle Laufwerk abgefragt wird.
|
|||
|
|
|||
|
( -- addr ) DOS
|
|||
|
Eine Variable, die die File-Attribute enthält, die bei der Suche nach
|
|||
|
Files in einem Directory berücksichtigt werden. Standardmäßig mit 7 ini-
|
|||
|
tialisiert, so daß in die Suche read-only, hidden und system -Files ein-
|
|||
|
geschlossen sind.
|
|||
|
|
|||
|
( string -- asciz *#f ) DOS
|
|||
|
Das File, dessen Name als String ab Adresse string steht, wird in der
|
|||
|
Directory gesucht. Enthält der Filename keine Suchpfadinformation, dann
|
|||
|
wird im aktuellen Directory gesucht. Bei Erfolg liegt eine Null auf dem
|
|||
|
Stack, sonst eine Fehlernummer.
|
|||
|
|
|||
|
( string -- asciz *#f ) DOS
|
|||
|
Ein deferred Wort. Es enthält die Suchstrategie (siehe: (FSEARCH ), die
|
|||
|
beim Öffnen eines Files verwendet wird, um das File auf der Disk zu
|
|||
|
lokalisieren,
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 194 -
|
|||
|
|
|||
|
Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
_
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
"first
|
|||
|
|
|||
|
"next
|
|||
|
|
|||
|
direct
|
|||
|
|
|||
|
#drives
|
|||
|
|
|||
|
/drive
|
|||
|
|
|||
|
»drive
|
|||
|
|
|||
|
capacity
|
|||
|
|
|||
|
?diskerror
|
|||
|
|
|||
|
( asciz attr -- err#) DOS
|
|||
|
Der MS-DOS Systemaufruf, um erstmalig nach einem File zu suchen.
|
|||
|
|
|||
|
(--err#) DOS
|
|||
|
Der MS-DOS Systemaufruf, der nach FIRST benutzt wird, um weitere
|
|||
|
passende Filenamen aufzufinden.
|
|||
|
|
|||
|
7.8 Direkt-Zugriff auf Disketten
|
|||
|
|
|||
|
(==)
|
|||
|
Die Filevariablen werden auf Null gesetzt und damit beziehen sich die
|
|||
|
Diskzugriffe durch BLOCK auf physikalische Blocks.
|
|||
|
|
|||
|
(=--ä)
|
|||
|
ist eine Konstante, die die mögliche Anzahl von logischen Laufwerken im
|
|||
|
System definiert. Diese Anzahl ist nur im DIRECT-Modus von Bedeutung.
|
|||
|
So, wie der Kern compiliert ist, sind maximal 6 Laufwerke zugelassen.
|
|||
|
|
|||
|
( bIkl -- bIk2 drive )
|
|||
|
für den DIRECT-Modus beim Diskzugriff. Aus der absoluten Blocknummer
|
|||
|
bIkl wird (siehe: CAPACITIES ) die relative Blocknummer bIlk2 auf Lauf-
|
|||
|
werk DRIVE berechnet. Dabei entspricht Laufwerk A: dem Drive ® etc...
|
|||
|
|
|||
|
( bIkl #drv -- bIk2 ) "to-drive"
|
|||
|
dient zum "Umrechnen" von Blocknummern im DIRECT-Modus.
|
|||
|
blk2 ist die absolute Blocknummer, die dem relativen Block bikl auf
|
|||
|
Drive #drv entspricht. Beispiel
|
|||
|
|
|||
|
23 1 »drive block
|
|||
|
holt den Block mit der Nummer 21 vom Laufwerk 1, egal welches.
|
|||
|
Laufwerk gerade das aktuelle ist.
|
|||
|
|
|||
|
(--n)
|
|||
|
gibt die Kapazität in 1024-Byte Blöcken des aktuellen Files bzw. des
|
|||
|
aktuellen Laufwerks bei DIRECT-Zugriff.
|
|||
|
|
|||
|
7.9 Fehlerbehandlung
|
|||
|
|
|||
|
(==)
|
|||
|
Ein deferred Wort, daß die Fehlerbehandlungsroutine für Disk- und File-
|
|||
|
zugriffe enthält. Standardmäßig ist die Routine (DISKERROR zugewiesen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Umgang mit Dateien - 185 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
error# ( -- addr )
|
|||
|
Eine Variable, die die Fehlernummer des letzten Fehlers beim Zugriff auf
|
|||
|
ein File enthält.
|
|||
|
|
|||
|
(diskerror ( #err --) DOS
|
|||
|
Die Standard-System Fehlerbehandlungsroutine für Fehler beim Diskzu-
|
|||
|
griff. Hiermit ist das deferred Wort ?DISKERROR initialisiert.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=3106 - Umgang mit Dateien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
8. Speicheroperationen
|
|||
|
|
|||
|
Die INTEL-Prozessoren haben eine verkomplizierte Art, den Adreßraum jenseits von
|
|||
|
64kBytes zu adressieren - nämlich mit sogenannten "Segmentregistern".
|
|||
|
Am besten kommt man damit noch zurecht, wenn man diese Prozessoren als 16-bit
|
|||
|
Prozessoren betrachtet, die in der Lage sind, mehrere Programme, die jeweils höch-
|
|||
|
stens 64k Programmspeicherbereich haben, gleichzeitig im Speicher zu halten. Es ist
|
|||
|
deshalb auch unvernünftig, auf diesen Prozessoren ein FORTH-System mit 32-bit
|
|||
|
Adressen zu installieren - es handelt sich eben nicht um 32-bit Prozessoren.
|
|||
|
|
|||
|
Um in volksFORTH den gesamten 1 MB-Adreßraum zu nutzen, ist die Möglichkeit
|
|||
|
gegeben, aus dem FORTH heraus mit dem Wort call (im DOS-Vokabular) ein weiteres
|
|||
|
.COM- oder .EXE-Programm aufzurufen. Dies können natürlich ihrerseits FORTH-
|
|||
|
Programme sein, denen dann auch noch eine ganze Eingabezeile als Parameter mit
|
|||
|
"auf den Weg" gegeben werden kann.
|
|||
|
|
|||
|
Damit wäre es zum Beispiel möglich, den Full-Screen Editor aus dem System auszu-
|
|||
|
lagern und mit den Befehlen FIX, EDIT, ED usw. jeweils ein .COM-Programm
|
|||
|
aufzurufen, das den FORTH-Editor als "stand-alone" Programm enthält und damit
|
|||
|
keinen Adreßraum im Entwicklungssystem mehr verbraucht.
|
|||
|
|
|||
|
Über die Systemvariable RETURN_CODE ist es auch noch möglich, einen Fehlercode
|
|||
|
bei Beendigung des FORTH-Programms an MS-DOS zu übergeben, der dann in Batch-
|
|||
|
Files getestet werden kann.
|
|||
|
|
|||
|
Die Intel-Prozessoren setzen die Speicheradressen aus zwei Teilen zusammen, dem
|
|||
|
SEGMENT und dem OFFSET. Dies ist jedoch nicht mit "echten" 32Bit-Adressen zu
|
|||
|
verwechseln. Diese werden auf einem 16Bit-Stack in der Reihenfolge "low-word"
|
|||
|
unter dem "high-word" abgelegt. Überträgt man diese Philosophie auf die
|
|||
|
"seg:addr"-Adressen des 8986, dann blockiert dauernd die Segmentadresse den
|
|||
|
Stack. |
|
|||
|
|
|||
|
Deshalb wird bei den Operatoren, die im erweiterten Adreßraum des 8886 operieren,
|
|||
|
die Segmentadresse UNTER der Offsetadresse auf den Stack gelegt. Der
|
|||
|
Stackkommentar dafür lautet "seg:addr". Den Operatoren, die als Adreßargument
|
|||
|
eine "erweiterte" Adresse benötigen, wird ein "l" im Namen vorangestellt.
|
|||
|
|
|||
|
8.1 Speicheroperationen im 16-Bit-Adressraum
|
|||
|
|
|||
|
@ ( addr -- 16b ) 83 "fetch"
|
|||
|
Von der Adresse addr wird der Wert 16b aus dem Speicher geholt. Siehe
|
|||
|
auch !.
|
|||
|
volksFORTH enthält nicht das Wort ?.. Benutzen Sie:
|
|||
|
|
|||
|
2? Cadde-I) 8. ;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Speicheroperationen - 107 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
( 16b addr -- ) 83 "store"
|
|||
|
16b werden in den Speicher auf die Adresse addr geschrieben. In 8Bit-
|
|||
|
weise adressierten Speichern werden die zwei Bytes addr und addr+l
|
|||
|
überschrieben.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
+ {wi addr -- ) 83 "plus-store"
|
|||
|
wl wird zu dem Wert w in der Adresse addr addiert. Benutzt die plus-
|
|||
|
Operation. Die Summe wird in den Speicher in die Adresse addr geschrie-
|
|||
|
ben. Der alte Speicherinhalt wird überschrieben.
|
|||
|
|
|||
|
2! ( 32b addr -- ) 83 "two-store"
|
|||
|
32b werden in den Speicher ab Adresse addr geschrieben.
|
|||
|
|
|||
|
2@ ( addr -- 32b ) 83 "two-fetch"
|
|||
|
Von der Adresse addr wird der Wert 32b aus dem Speicher geholt.
|
|||
|
|
|||
|
c! ( 16b addr -- ) 83 "e-store"
|
|||
|
Von 16b werden die niederwertigsten 8 Bit in den Speicher an der
|
|||
|
Adresse addr geschrieben.
|
|||
|
|
|||
|
c@ ( addr -- 8b ) 83 "c-fetch"
|
|||
|
Von der Adresse addr wird der Wert 8b aus dem Speicher geholt.
|
|||
|
|
|||
|
move ( addrd addri u -- )
|
|||
|
|
|||
|
Beginnend bei addr6 werden u Bytes nach addri kopiert. Dabei ist es
|
|||
|
ohne Bedeutung, ob überlappende Speicherbereiche aufwärts oder abwärts
|
|||
|
kopiert werden, weil MOVE die passende Routine dazu auswählt. Hat u
|
|||
|
den Wert Null, passiert nichts.
|
|||
|
|
|||
|
Siehe auch CMOVE und CMOVE>.
|
|||
|
|
|||
|
cmove ( addr® addri u -- ) 83 "c-move"
|
|||
|
Beginnend bei addr® werden u Bytes zur Adresse addrl kopiert. Zuerst
|
|||
|
wird das Byte von addr® nach addri bewegt und dann aufsteigend fort-
|
|||
|
gefahren. Wenn u Null ist, wird nichts kopiert.
|
|||
|
|
|||
|
cmove> ( addr® addri u -- ) 83 "c-move-up"
|
|||
|
Beginnend bei adDr® werden u Bytes zur Adresse adDri kopiert. Zuerst
|
|||
|
wird das Byte von addrö +u -1 nach addrl +u -1 kopiert und dann
|
|||
|
absteigend fortgefahren. Wenn u Null ist, wird nichts kopiert. Das Wort
|
|||
|
wird benutzt, um Speicherinhalte auf höhere Adressen zu verschieben,
|
|||
|
wenn die Speicherbereiche sich überlappen.
|
|||
|
|
|||
|
= 1908 = Speicheroperationen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
fill
|
|||
|
|
|||
|
erase
|
|||
|
|
|||
|
blank
|
|||
|
|
|||
|
flip
|
|||
|
|
|||
|
ctoggle
|
|||
|
|
|||
|
off
|
|||
|
|
|||
|
on
|
|||
|
|
|||
|
here
|
|||
|
|
|||
|
align
|
|||
|
|
|||
|
( addr u 8b -- )
|
|||
|
|
|||
|
Von der Adresse addr an werden u Bytes des Speichers mit 8b über-
|
|||
|
schrieben. Hat u den Wert Null, passiert nichts.
|
|||
|
|
|||
|
(addru--)
|
|||
|
Von der Adresse addr an werden u Bytes im Speicher mit $08 überschrie-
|
|||
|
ben. Hat u den Wert Null, passiert nichts.
|
|||
|
|
|||
|
(add u--)
|
|||
|
Von der Adresse addr an werden u Bytes im Speicher mit Leerzeichen BL
|
|||
|
(828) überschrieben. Hat u den Wert Null, passiert nichts.
|
|||
|
|
|||
|
(ul -- u2)
|
|||
|
ist das Byteswap des obersten Stackelements.
|
|||
|
ul ist eine 16-bit Zahl mit den Bits B15..B8 und B7..B@, wobei man
|
|||
|
B15..B8 als das "high-Byte", B8..B®O als das "low-Byte" bezeichnet. Durch
|
|||
|
FLIP wird das High- mit dem Low-Byte ausgetauscht, so daß u2 als
|
|||
|
Ergebnis die Bits in der Reihenfolge B7..Bß® und B15..B8 angeordnet hat.
|
|||
|
Dieses FLIP entspricht der Definition:
|
|||
|
|
|||
|
: cswap ( 16b -- 16b' ) $100 um* or ;
|
|||
|
|
|||
|
( 8b addr -- ) 83 "e-toggle"
|
|||
|
Für jedes gesetzte Bit in 8b wird im Byte mit der Adresse addr das ent-
|
|||
|
sprechende Bit invertiert (d.h. ein zuvor gesetztes Bit ist danach ge-
|
|||
|
löscht und ein gelöschtes Bit ist danach gesetzt). Für alle gelöschten
|
|||
|
Bits in 8b bleiben die entsprechenden Bits im Byte mit der Adresse addr
|
|||
|
unverändert. Der Ausdruck dup c@ rot xor swap c! wirkt genauso.
|
|||
|
|
|||
|
( addr -- )
|
|||
|
schreibt den Wert FALSE in den Speicher mit der Adresse addr.
|
|||
|
|
|||
|
( addr -- )
|
|||
|
schreibt den Wert TRUE in den Speicher mit der Adresse addr.
|
|||
|
|
|||
|
( -- addr ) 83
|
|||
|
addr ist die Adresse des nächsten freien Dictionaryplatzes.
|
|||
|
|
|||
|
(--)
|
|||
|
rundet normalerweise den Dictionary-Pointer und damit auch HERE auf
|
|||
|
die nächste geraden Adresse auf. Ist HERE gerade, so geschieht nichts.
|
|||
|
Im volks4th für den 8088-Prozessor hat ALIGN keine Wirkung.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Speicheroperationen - 199 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
c
|
|||
|
|
|||
|
allot
|
|||
|
|
|||
|
dp
|
|||
|
|
|||
|
uallot
|
|||
|
|
|||
|
udp
|
|||
|
|
|||
|
pad
|
|||
|
|
|||
|
count
|
|||
|
|
|||
|
place
|
|||
|
|
|||
|
( 16b -- ) 83 "comma"
|
|||
|
ist ein 2 ALLOT für die gegebenen 16b und speichert diese 16b an
|
|||
|
HERE 2- ab.
|
|||
|
|
|||
|
(8 -- ) "c-comma"
|
|||
|
ist ein ALLOT für ein Byte und speichert 1 Byte in HERE 1- ab.
|
|||
|
|
|||
|
(w--) 83
|
|||
|
allokiert w Bytes im Dictionary. Die Adresse des nächsten freien Dic-
|
|||
|
|
|||
|
tionaryplatzes wird entsprechend verstellt.
|
|||
|
|
|||
|
( -- addr ) "d-p"
|
|||
|
|
|||
|
ist eine Uservariable, in der die Adresse des nächsten freien Dictionary-\._
|
|||
|
|
|||
|
platzes steht.
|
|||
|
|
|||
|
(nl --n2)
|
|||
|
allokiert bzw. deallokiert ni Bytes in der Userarea. n2 gibt den Anfang
|
|||
|
des allokierten Bereiches relativ zum Beginn der Userarea an. Eine
|
|||
|
Fehlerbehandlung wird eingeleitet, wenn die Userarea voll ist.
|
|||
|
|
|||
|
( -- addr ) "u-d-p"
|
|||
|
ist eine Uservariable, in dem das Ende der bisher allokierten Userarea
|
|||
|
vermerkt ist.
|
|||
|
|
|||
|
( -- addr ) 83
|
|||
|
addr ist die Startadresse einer "scratch area". In diesem Speicherbereich
|
|||
|
können Daten für Zwischenrechnungen abgelegt werden. Wenn die nächste
|
|||
|
verfügbare Stelle für das Dictionary verändert wird, ändert sich auch die
|
|||
|
Startadresse von PAD . Die vorherige Startadresse von PAD geht
|
|||
|
ebenso wie die Daten dort verloren.
|
|||
|
|
|||
|
( addri -- addr2 8b ) 83
|
|||
|
addr2 ist addri+l und 8b der Inhalt von addri. Das Byte mit der
|
|||
|
Adresse addrl enthält die Länge des Strings angegeben in Bytes. Die
|
|||
|
Zeichen des Strings beginnen bei addri+1. Die Länge eines Strings darf
|
|||
|
im Bereich (9..255) liegen.
|
|||
|
Vergleiche "counted String" .
|
|||
|
|
|||
|
( addri +n addr2 -- )
|
|||
|
bewegt +n Bytes von der Adresse addrl zur Adresse addr2+1 und
|
|||
|
schreibt den Wert +n in die Speicherstelle mit der Adresse addr2. Wird in
|
|||
|
der Regel benutzt, um Text einer bestimmten Länge als "counted string"
|
|||
|
abzuspeichern. addr2 darf gleich, größer und auch kleiner als addrl sein.
|
|||
|
|
|||
|
u
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 118 -
|
|||
|
|
|||
|
Speicheroperationen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
dump
|
|||
|
|
|||
|
b/seg
|
|||
|
|
|||
|
ds@
|
|||
|
|
|||
|
1@
|
|||
|
|
|||
|
lc@
|
|||
|
|
|||
|
le!
|
|||
|
|
|||
|
lmove
|
|||
|
|
|||
|
( addr Anzahl -- )
|
|||
|
Dieser wichtige Befehl zeigt ab einer gegebenen Adresse eine bestimmte
|
|||
|
Anzahl Bytes des Hauptspeichers an. Denn ist es sinnvoll, nachdem man
|
|||
|
im Speicher ganze Bereiche reserviert und dort Strukturen abgelegt hat,
|
|||
|
sich diese Bereiche auch anzusehen. Ebenso zeigt Ihnen der Befehl
|
|||
|
|
|||
|
(n)}) block b/blk dump
|
|||
|
einen Ihrer Quelltextblöcke an.
|
|||
|
|
|||
|
(ar)
|
|||
|
ist eine Konstante, die angibt, wieviele Bytes zwischen zwei Segmenten
|
|||
|
liegen. Dies sind beim 8086 16 Bytes, beim 89286 im 286-Modus jedoch
|
|||
|
64 Bytes. volksFORTH auf dem 89286 setzt zur Zeit voraus, daß der
|
|||
|
8086-Emulationsmodus eingeschaltet ist.
|
|||
|
|
|||
|
(--seg )
|
|||
|
legt die Segmentadresse des Segments auf den Stack, in dem sich das
|
|||
|
maximal 64kByte große FORTH-System gerade befindet. Das Daten-,
|
|||
|
Extra-, Stack- und Codesegment werden durch FORTH alle auf den
|
|||
|
gleichen Wert gesetzt.
|
|||
|
|
|||
|
8.2 Segmentierte Speicheroperationen
|
|||
|
|
|||
|
( seg:addr -- n )
|
|||
|
entspricht dem ® , jedoch im erweiterten Adreßraum.
|
|||
|
|
|||
|
m
|
|||
|
|
|||
|
n seg:addr -- )
|
|||
|
entspricht dem ! , jedoch im erweiterten Adreßraum.
|
|||
|
|
|||
|
( seg:addr -- 8b )
|
|||
|
entspricht dem C®@ , jedoch im erweiterten Adreßraum.
|
|||
|
|
|||
|
( 8b seg:addr -- )
|
|||
|
entspricht dem C! , jedoch im erweiterten Adreßraum.
|
|||
|
|
|||
|
‘( from.seg:addr to.seg:addr quan -- )
|
|||
|
entspricht dem. MOVE ,„ jedoch im erweiterten Adreßraum. Es können
|
|||
|
hiermit maximal 64KBytes auf einmal bewegt werden.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Speicheroperationen - tlul=
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Idump
|
|||
|
|
|||
|
lallocate
|
|||
|
|
|||
|
lfree
|
|||
|
|
|||
|
( seg:addr len -- )
|
|||
|
entspricht dem TYPE , jedoch im erweiterten Adreßraum. Es ist zu be-
|
|||
|
achten, daß TYPE in den Videodisplaytreibern BIOS.VID und MULTI.VID
|
|||
|
so implementiert ist, daß bei Erreichen des Zeilenendes nicht automatisch
|
|||
|
ein CR ausgeführt wird. Statt dessen werden alle Zeichen, die "jenseits"
|
|||
|
des rechten Rands liegen, nicht ausgegeben.
|
|||
|
|
|||
|
( seg:addr quan -- ) TOOLS
|
|||
|
entspricht dem DUMP , jedoch im erweiterten Adreßraum und zeigt ab
|
|||
|
einer angegebenen Adresse eine bestimmte Anzahl Bytes an.
|
|||
|
|
|||
|
( #pages -- seg ff | rest err# ) EXTEND
|
|||
|
Hiermit können im erweiterten Adreßraum die Anzahl #pages Speicher-
|
|||
|
platz angefordert werden.
|
|||
|
Die Größe einer "Page" in Bytes entspricht der Konstanten B/SEG . Wenn
|
|||
|
die Speicheranforderung erfüllt werden kann, dann wird unter einer NULL
|
|||
|
als Flag für den Erfolg der Operation die Segmentadresse des ersten Seg-
|
|||
|
ments innerhalb eines zusammenhängenden Speicherbereichs von #page
|
|||
|
Pages auf den Stack gelegt.
|
|||
|
Ansonsten liegt unter einem Fehlercode die maximale Anzahl von Pages,
|
|||
|
die noch als zusammenhängender Bereich verfügbar sind. Diese Funktion
|
|||
|
ist in dem Wort SAVEVIDEO benutzt, um den Bildschirminhalt in den
|
|||
|
Speicher zu kopieren.
|
|||
|
Die komplementären Funktionen sind LFREE und RESTOREVIDEO .
|
|||
|
|
|||
|
( seg -- err# )
|
|||
|
Der Speicherbereich, der an der Segmentadresse seg beginnt, wird wieder
|
|||
|
an das Betriebssystem zurückgegeben.
|
|||
|
Diese Operation ist nur definiert, wenn zu einem vorherigen Zeitpunkt
|
|||
|
eine LALLOCATE-Operation durchgeführt worden war, die als Ergebnis die
|
|||
|
Segmentadresse seg gehabt hatte.
|
|||
|
Es wird ein Fehlercode auf dem Stack übergeben, der im Erfolgsfall ® ist.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 112 =
|
|||
|
|
|||
|
Speicheroperationen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
9. Datentypen
|
|||
|
|
|||
|
Allgemein bestehen Programme aus einem Programm:Datenteil und einem An-
|
|||
|
weisungsteil. Dabei enthält der Befehlsteil die zu Algorithmen angeordneten
|
|||
|
Befehle, die sich wiederum aus Operanden und Operatoren zusammensetzen. Der
|
|||
|
Datenteil dagegen beschreibt eines Programmes den statischen Datenbereich, der die
|
|||
|
zu bearbeitenden Daten enthält.
|
|||
|
|
|||
|
Diese Datenbereiche sind durch die Interpretation ihres Inhaltes strukturiert, wobei
|
|||
|
Datenbereiche mit gleicher Strukturierung zum gleichen Datentyp gehören. Denn um
|
|||
|
mit einer Reihe von Bytes arbeiten zu können, muß man wissen, ob diese Bytes
|
|||
|
eine Zeichenkette, den Inhalt einer Variablen oder die Listenzellen einer :-Defini-
|
|||
|
tion darstellen.
|
|||
|
|
|||
|
Die Strukturierung und Verwaltung sowie die Interpretation des Dateninhaltes im
|
|||
|
Datenteil wird in den PASCAL-ähnlichen Sprachen am Programmanfang durch die
|
|||
|
Deklarationen der Datentypen, in FORTH dagegen erst im Befehlsteil eines Pro-
|
|||
|
grammes durch die eingesetzten Befehle bestimmt.
|
|||
|
|
|||
|
Da in FORTH die Typisierung über die Auswahl und den Einsatz von geeigneten
|
|||
|
Operatoren erfolgt, gehören in FORTH alle die Datenstrukturen dem gleichen Typ
|
|||
|
an, denen die Operatoren gemeinsam sind. In FORTH bestimmt also die jeweilige
|
|||
|
Operation den Datentyp des entsprechenden Bereiche - so interpretiert die Be-
|
|||
|
|
|||
|
fehlsfolge pad count type die im Speicherbereich PAD abgelegten Daten als Zei-
|
|||
|
chenkette !
|
|||
|
|
|||
|
Glossar
|
|||
|
|
|||
|
Create (==) 83
|
|||
|
|
|||
|
ist ein definierendes Wort, das in der Form:
|
|||
|
Create (name)
|
|||
|
|
|||
|
benutzt wird. CREATE erzeugt einen Kopf für <name».
|
|||
|
Die nächste freie Stelle im Dictionary (vergl. HERE und DP ) ist nach
|
|||
|
einem CREATE «name das erste Byte des Parameterfelds von <name>.
|
|||
|
Wenn <name> ausgeführt wird, legt es die Adresse seines Parameterfelds
|
|||
|
auf den Stack. CREATE reserviert keinen Speicherplatz im Parameterfeld
|
|||
|
von <name>.
|
|||
|
|
|||
|
Constant ( 16b -- ) 83
|
|||
|
ist ein definierendes Wort, das in der Form:
|
|||
|
16b Constant <name)>
|
|||
|
benutzt wird. Wird <name> später ausgeführt, so wird 16b auf den Stack
|
|||
|
gelegt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Datentypen ZERks, =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
2Constant
|
|||
|
|
|||
|
( 32b -- ) 83
|
|||
|
ist ein definierendes Wort, das in der Form:
|
|||
|
|
|||
|
32b 2Constant (name)
|
|||
|
benutzt wird. Erzeugt einen Kopf für <name> und legt 32b in dessen
|
|||
|
Parameterfeld so ab, daß bei Ausführung von <name> 32b wieder auf den
|
|||
|
Stack gelegt wird.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Variable (=) 83
|
|||
|
ist ein definierendes Wort, benutzt in der Form:
|
|||
|
Variable <name)
|
|||
|
VARIABLE erzeugt einen Kopf für <name> im Dictionary und hält 2 Byte
|
|||
|
in seinem Parameterfeld frei. Siehe ALLOT .
|
|||
|
Dieses Parameterfeld wird für den Inhalt der Variablen benutzt, jedoch
|
|||
|
nicht initialisiert. Wird <name> ausgeführt, so wird die Adresse des Para-
|
|||
|
meterfeldes von <name> auf den Stack gelegt. Mit @ und ! kann der
|
|||
|
Wert von <name> gelesen und geschrieben werden.
|
|||
|
Siehe auch +!.
|
|||
|
2Variable (a, 83
|
|||
|
ist ein definierendes Wort, das in der Form:
|
|||
|
2Variable (name)
|
|||
|
benutzt wird. Es erzeugt einen Kopf für <name> und hält 4 Byte in sei-
|
|||
|
nem Parameterfeld frei, die den Inhalt der doppelt-genauen Variablen
|
|||
|
aufnehmen. 2VARIABLE wird nicht initialisiert. Wenn <name> ausgeführt
|
|||
|
wird, wird die Adresse des Parameterfelds auf den Stack gelegt.
|
|||
|
Siehe VARIABLE .
|
|||
|
(--sys ) 83 "colon"
|
|||
|
ist ebenfalls ein definierendes Wort, das in der Form:
|
|||
|
: <name) <actions) ;
|
|||
|
benutzt wird.
|
|||
|
Es erzeugt die Wortdefinition für <name> im Kompilations-Vokabular,
|
|||
|
schaltet den Kompiler an und kompiliert anschließend den Quelltext wird.
|
|||
|
- 14 - Datentypen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Achtung:
|
|||
|
|
|||
|
Das erste Vokabular der Suchreihenfolge - das "transient" Vokabular -
|
|||
|
wird durch das Kompilations-Vokabular ersetzt! Das Kompilations-Voka-
|
|||
|
bular wird nicht geändert. .
|
|||
|
Soll also das CONTEXT-Vokabular für eine :-Definition geändert werden,
|
|||
|
so ist das gewünschte Vokabular entweder innerhalb einer Definition mit
|
|||
|
den eckigen Klammern
|
|||
|
|
|||
|
: <(nane) [ <vocabulary) ] ... ;
|
|||
|
zum CONTEXT zu machen oder außerhalb einer Definition zweimal in die
|
|||
|
Suchreihenfolge aufzunehmen ( also ) und später zu löschen ( toss ):
|
|||
|
|
|||
|
<vocabulary?> also
|
|||
|
: <colondefinition) ; toss
|
|||
|
<name> wird als "colon-definition" oder ":-Definition" bezeichnet. Die
|
|||
|
|
|||
|
neue Wortdefinition für <name> kann nicht im Dictionary gefunden wer-
|
|||
|
den, bis das zugehörige ; oder ;CODE erfolgreich ausgeführt wurde.
|
|||
|
RECURSIVE macht <name> jedoch sofort auffindbar.
|
|||
|
|
|||
|
Vergleiche HIDE und REVEAL .
|
|||
|
|
|||
|
Eine Fehlerbehandlung wird eingeleitet, wenn ein Wort während der
|
|||
|
Kompilation nicht gefunden bzw. nicht in eine Zahl (siehe auch BASE )
|
|||
|
gewandelt werden kann.
|
|||
|
|
|||
|
Der auf dem Stack hinterlassene Wert sys dient der Kompiler-Sicherheit
|
|||
|
und wird durch ; bzw. ;CODE abgebaut.
|
|||
|
|
|||
|
; e-=9) 83 1c "semi-colon"
|
|||
|
(sys --) compiling
|
|||
|
beendet die Kompilation einer :-Definition.
|
|||
|
; macht den Namen dieser colon definition im Dictionary auffindbar,
|
|||
|
schaltet den Kompiler aus, den Interpreter ein und kompiliert ein
|
|||
|
UNNEST (siehe auch EXIT ). Der Stackparameter sys, der in der Regel
|
|||
|
|
|||
|
von : hinterlassen wurde, wird geprüft und abgebaut. Eine Fehlerbe-
|
|||
|
handlung wird eingeleitet, wenn sys nicht dem erwarteten Wert ent-
|
|||
|
spricht.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Datentypen - ms =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-voiksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Defer
|
|||
|
|
|||
|
Alias
|
|||
|
|
|||
|
(sr
|
|||
|
ist ein definierendes Wort, das in der Form:
|
|||
|
|
|||
|
Defer <name)>
|
|||
|
benutzt wird. Erzeugt den Kopf für ein neues Wort <name> im Dictionary,
|
|||
|
hält 2 Byte in dessen Parameterfeld frei und speichert dort zunächst die
|
|||
|
Kompilationsadresse einer Fehlerroutine, Wird <name> nun ausgeführt, so
|
|||
|
wird eine Fehlerbehandlung eingeleitet.
|
|||
|
|
|||
|
Man kann dem Wort <name> jedoch zu jeder Zeit eine andere Funktion
|
|||
|
zuweisen mit der Sequenz:
|
|||
|
" «action) Is (name)
|
|||
|
Nach dieser Zuweisung verhält sich <name> wie <action>.
|
|||
|
Mit diesem Mechanismus kann man zwei Probleme elegant lösen:
|
|||
|
|
|||
|
1: Einerseits läßt sich <name> bereits kompilieren, bevor ihm “
|
|||
|
eine sinnvolle Aktion zugewiesen wurde.
|
|||
|
2; Andererseits ist die Veränderung des Verhaltens von
|
|||
|
|
|||
|
<name> für spezielle Zwecke auch nachträglich möglich,
|
|||
|
ohne neu kompilieren zu müssen.
|
|||
|
|
|||
|
Deferred Worte im System sind R/W "COLD 'RESTART 'ABORT 'QUIT
|
|||
|
NOTFOUND .STATUS und DISKERR . Diese Worte sind DEFERred, da-
|
|||
|
mit ihr Verhalten für die Anwendung geändert werden kann.
|
|||
|
|
|||
|
( <fä -- )
|
|||
|
ist ein Wort, mit dem das Verhalten eines deferred Wortes verändert
|
|||
|
werden kann. IS wird in der Form:
|
|||
|
|
|||
|
' «action? Is <name)
|
|||
|
benutzt. Wenn <name> kein deferred Wort ist, wird eine Fehlerbehandlung
|
|||
|
eingeleitet, sonst verhält sich <name> anschließend wie <action).
|
|||
|
Siehe DEFER .
|
|||
|
|
|||
|
«ierä,#- )
|
|||
|
ist ein definierendes Wort, das typisch in der Form:
|
|||
|
|
|||
|
'" <oldname)> Alias (newname)
|
|||
|
benutzt wird. ALIAS erzeugt einen Kopf für <newname> im Dictionary.
|
|||
|
Wird <newname> aufgerufen, so verhält es sich wie \cldname>. Insbeson-
|
|||
|
dere wird beim Kompilieren nicht <newname>, sondern <oldname> im Dic-
|
|||
|
tionary eingetragen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 116 =
|
|||
|
|
|||
|
Datentypen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Geseilschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Vocabulary (=>) 83
|
|||
|
|
|||
|
Input:
|
|||
|
|
|||
|
ist e . definierendes Wort, das in der Form:
|
|||
|
|
|||
|
: Vocabulary (name>
|
|||
|
benutzt wird. VOCABULARY erzeugt einen Kopf für <name>, das den
|
|||
|
Anfang einer neuen Liste von Worten bildet. Wird <name> ausgeführt, so
|
|||
|
werden bei der Suche im Dictionary zuerst die Worte in der Liste von
|
|||
|
<name> berücksichtigt. Wird das VOCABULARY (name) durch die Sequenz:
|
|||
|
|
|||
|
<name)> definitions
|
|||
|
|
|||
|
zum Kompilations-Vokabular, so werden neue Wort-Definitionen in die
|
|||
|
Liste von <name> gehängt.
|
|||
|
Vergleiche auch CONTEXT CURRENT ALSO TOSS ONLY FORTH und
|
|||
|
ONLYFORTH .
|
|||
|
|
|||
|
( ==n) "input-colon"
|
|||
|
ein definierendes Wort, benutzt in der Form:
|
|||
|
|
|||
|
Input: (name)
|
|||
|
|
|||
|
newKEY newKEY? newDECODE newEXPECT ;
|
|||
|
|
|||
|
INPUT: erzeugt einen Kopf für <name> im Dictionary und kompiliert einen
|
|||
|
Satz von Zeigern auf Worte, die für die Eingabe von Zeichen zuständig
|
|||
|
sind. Wird <name> ausgeführt, so wird ein Zeiger auf das Parameterfeld
|
|||
|
von <name> in die Uservariable INPUT geschrieben. Alle Eingaben wer-
|
|||
|
den jetzt über die neuen Eingabeworte abgewickelt.
|
|||
|
|
|||
|
Die Reihenfolge der Worte nach INPUT: <name> bis zum semi-colon muß
|
|||
|
eingehalten werden: ..key ..key? ..decode ..expect .
|
|||
|
|
|||
|
Im System ist das mit INPUT: definierte Wort keyboard enthalten,
|
|||
|
nach dessen Ausführung alle Eingaben von der Tastatur geholt werden.
|
|||
|
Siehe DECODE und EXPECT.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Datentypen 47 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Output: (==) "output-colon"
|
|||
|
|
|||
|
ist ein definierendes Wort, benutzt in der Form:
|
|||
|
Output: <name)>
|
|||
|
newEMIT newCR newTYPE newDEL newPAGE newAT newAT? ;
|
|||
|
|
|||
|
OUTPUT: erzeugt einen Kopf für <name> im Dictionary und kompiliert
|
|||
|
einen Satz von Zeigern auf Worte, die für die Ausgabe von Zeichen zu-
|
|||
|
ständig sind. Wird <name> ausgeführt, so wird ein Zeiger auf das Para-
|
|||
|
meterfeld von <name> in die Uservariable OUTPUT geschrieben. Alle
|
|||
|
Ausgaben werden jetzt über die neuen Ausgabeworte abgewickelt.
|
|||
|
|
|||
|
Die Reihenfolge der Worte nach OUTPUT: <name> bis zum semi-colon muß
|
|||
|
eingehalten werden: ..emit ..cr ..type ..del ..page ..at ..at?.
|
|||
|
|
|||
|
Im System ist das mit OUTPUT: definierte Wort display enthalten,
|
|||
|
nach dessen Ausführung alle Ausgaben auf den Bildschirm geleitet wer-
|
|||
|
den. Vergleiche auch das Wort PRINT aus dem Printer-Interface.
|
|||
|
|
|||
|
User (--') 83
|
|||
|
|
|||
|
ist ein definierendes Wort, benutzt in der Form:
|
|||
|
User (name)
|
|||
|
|
|||
|
USER erzeugt einen Kopf für <name> im Dictionary und hält 2 Byte in
|
|||
|
der Userarea frei (siehe UALLOT ). Diese 2 Byte werden für den Inhalt
|
|||
|
der Uservariablen benutzt und werden nicht initialisiert. Im Parameterfeld
|
|||
|
der Uservariablen im Dictionary wird nur ein Offset zum Beginn der
|
|||
|
Userarea abgelegt.
|
|||
|
Wird <name> ausgeführt, so wird die Adresse des Wertes der Uservariab-
|
|||
|
len in der Userarea auf den Stack gelegt.
|
|||
|
Uservariablen werden statt normaler Variablen z.B. dann benutzt, wenn
|
|||
|
der Einsatz des Multitaskers geplant ist und mindestens eine Task die
|
|||
|
Variable unbeeinflußt von anderen Tasks benötigt. Jede Task hat ihre
|
|||
|
eigene Userarea.
|
|||
|
|
|||
|
9.1 Ein- und zweidimensionale Felder
|
|||
|
|
|||
|
Wie in dem Buch "In FORTH denken" [S.192/193] diskutiert wird, stellen die meisten
|
|||
|
FORTH-Systeme aus gutem Grund kein Definitionswort für Arrays zur Verfügung.
|
|||
|
Weil aber der Aufbau dieser Definitionen nicht immer problemlos zu handhaben ist
|
|||
|
und die notwendigen Algorithmen in der Literatur manchmal falsch dargestellt wer-
|
|||
|
den, seien hier die Definitionen für eindimensionale Felder (Vektoren) und zwei-
|
|||
|
dimensionale Arrays angegeben.
|
|||
|
|
|||
|
Diese Datenstrukturen verbergen der zugrunde liegende Zellgröße in eigenen Defini-
|
|||
|
tionen, um die Worte ohne die typischen 2+ 2- 2% schreiben zu können. Die
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 118 - Datentypen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Basisgröße der /rressierung in einem 16bit-System ist das Byte, die Adressberech-
|
|||
|
nungen arbeiten * 16Bit-, also 2Byte-Adressen.
|
|||
|
1 Constant byte
|
|||
|
|
|||
|
2 Constant integer
|
|||
|
4 Constant double
|
|||
|
|
|||
|
I : bytes ; \ bytes ist 1*
|
|||
|
I : integers 2% ; \ Größe eines Bereiches
|
|||
|
tı : doubles 4%;
|
|||
|
|
|||
|
i : byte+t i# ; \ nächste byte-Adresse
|
|||
|
I x: integer+ 2+; \ nächste word-Adresse
|
|||
|
ı : double+t 4+;
|
|||
|
|
|||
|
Obwohl FORTH als Sprache keine Typisierung der Daten erwartet, arbeitet die hier
|
|||
|
vorgestellte PELD:-Definition mit einer Typübernahme:
|
|||
|
: Feld:
|
|||
|
Create ( #elements type - )
|
|||
|
dup c, *
|
|||
|
here over erase
|
|||
|
allot
|
|||
|
|
|||
|
Does) ( index <addr? - addr )
|
|||
|
eosnt BE # + 5;
|
|||
|
|
|||
|
Diese FELD:-Definition übergibt zur Laufzeit die Adresse des gegebenen Elementes,
|
|||
|
abhängig vom Typ der Variablen. Das Feld wird zur Compile-Zeit mit Nullen
|
|||
|
initialisiert.
|
|||
|
|
|||
|
In der möglichen Anwendung einer Meßdatenerfassung von Meßstellen wird die
|
|||
|
Handhabung von FELD: deutlich:
|
|||
|
|
|||
|
5 byte Feld: Bonn
|
|||
|
5 integer Feld: Köln
|
|||
|
5 double Feld: Moers
|
|||
|
|
|||
|
: Merte cr
|
|||
|
5020 IkKkölln @ T7Tu.r LOOP cr;
|
|||
|
|
|||
|
Der Zugriff auf eine solche Datenstruktur kann z.B. über eine Schleife erfolgen,
|
|||
|
wobei - wie immer in FORTH - die zum Datentyp passenden Operatoren einge-
|
|||
|
setzt werden müssen.
|
|||
|
|
|||
|
Die Arbeit mit einer Matrix ist ähnlich, nur wird hier der Zugriff über zwei ge-
|
|||
|
schachtelte Schleifen erfolgen. Bitte beachten Sie, daß beim Zugriff FORTH-un-
|
|||
|
typische Schleifenvariablen eingesetzt werden, die über dieSynonymdeklaration
|
|||
|
Alias definiert wurden.
|
|||
|
|
|||
|
Diese Definition von MATRIX: übernimmt ebenfalls eine Typangabe:
|
|||
|
|
|||
|
: Matrix: \ #zeilen #spalten range (double}integeribyte)
|
|||
|
\ #zeile #spalte -- element_addr )
|
|||
|
Create ’
|
|||
|
2dup swap \ integer!byte #zeile
|
|||
|
cr c% \ store #? and #?
|
|||
|
* *% dup \ amount bytes amount bytes
|
|||
|
here swap erase \ from here amount preset to ®
|
|||
|
allot \ amount allot
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Datentypen - #9. —
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V.
|
|||
|
|
|||
|
PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Does>
|
|||
|
|
|||
|
dup c@ 3 roll *
|
|||
|
2 roll +
|
|||
|
over bytet
|
|||
|
|
|||
|
c@ * +
|
|||
|
|
|||
|
integert
|
|||
|
|
|||
|
\ Drei Meßstationen haben je 4 Meßwerte erfaßt
|
|||
|
|
|||
|
\
|
|||
|
|
|||
|
3 Constant #Stationen
|
|||
|
|
|||
|
und gespeichert
|
|||
|
|
|||
|
4 Constant #Werte
|
|||
|
|
|||
|
'‘ I Alias Stationf
|
|||
|
' J Alias Wert#
|
|||
|
|
|||
|
#Stationen #Werte byte Matrix: Messung
|
|||
|
|
|||
|
\ Wert!#Stat.|#Wert}Feldname!Operation
|
|||
|
|
|||
|
10
|
|||
|
15
|
|||
|
10
|
|||
|
|
|||
|
#s
|
|||
|
|
|||
|
3 0 ® Messung
|
|||
|
6 0 1 Messung
|
|||
|
9 ® 2 Messung
|
|||
|
12 0 3 Messung
|
|||
|
10 Messung c! 72
|
|||
|
11 Messung c! % 2
|
|||
|
1 2 Messung c! 9 2
|
|||
|
1 3 Messung c! 1 2
|
|||
|
‚all ==)
|
|||
|
tationen ® DO cr
|
|||
|
#Werte 0 DO
|
|||
|
|
|||
|
LOOP ;
|
|||
|
|
|||
|
LOOP
|
|||
|
|
|||
|
vn”>, rmy,o©
|
|||
|
|
|||
|
ei
|
|||
|
ce!
|
|||
|
el
|
|||
|
ei
|
|||
|
|
|||
|
Messung c!
|
|||
|
Messung c!
|
|||
|
Messung c!
|
|||
|
Messung c!
|
|||
|
|
|||
|
Wert# Station# Messung c@ 3 .r
|
|||
|
|
|||
|
Den einzelnen Operationen zum Einspeichern der Werte steht das Auslesen der
|
|||
|
Werte über zwei geschachtelte Schleifen gegenüber.
|
|||
|
|
|||
|
Eine weitere, oft genutzte Datenstruktur ist ein Ringpuffer (queue), hier in der
|
|||
|
Form eines 255 Byte langen counted strings.
|
|||
|
hinten angehängt und vorne ausgelesen, so daß sich eine FIFO-Struktur ergibt:
|
|||
|
|
|||
|
Create QUEUE © c, 255 allot
|
|||
|
|
|||
|
more? ( addr -- n)
|
|||
|
|
|||
|
ce ;
|
|||
|
|
|||
|
q@ ( addr -- char)
|
|||
|
|
|||
|
dup more? IF detract exit
|
|||
|
|
|||
|
In diesen Puffer werden Zeichen
|
|||
|
|
|||
|
ELSE ." Ringpuffer leer! " drop
|
|||
|
THEN ;
|
|||
|
|
|||
|
a! ( addr char --) append ;
|
|||
|
|
|||
|
q- ( addr --) count type ;
|
|||
|
|
|||
|
: gfill ( addr --)
|
|||
|
|
|||
|
$FF )expect ;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Datentypen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
9.2 Methoden der objektorientierte Programmierung
|
|||
|
|
|||
|
Der METHODS>-A,.satz entbindet den Programmierer von der Pflicht, jedesmal den
|
|||
|
zum Datentyp passenden Operator auswählen zu müssen. Mit den generalisierten
|
|||
|
|
|||
|
Operatoren get put und show wird die jeweils notwendige Zugriffsmethode aus
|
|||
|
einer Tabelle von Methoden ausgeführt .
|
|||
|
|
|||
|
Mittlerweile bildet sich allerdings als Bezeichnung für generalisierte Operatoren
|
|||
|
auch die Syntax x@ x! xtype ein.
|
|||
|
|
|||
|
\ Terry Rayburn METHODS» euroFORML 87
|
|||
|
|
|||
|
: Methods) ([compile] Does)»
|
|||
|
compile exit ; immediate restrict
|
|||
|
|
|||
|
\ early binding
|
|||
|
[Method]: Create 2* „ immediate Does)
|
|||
|
here 2-@e @ 5 + svap@ +@, ;
|
|||
|
|
|||
|
0 [Method]: [get] 1 [Method]: [put] 2 [Method]: [show]
|
|||
|
|
|||
|
\ late binding
|
|||
|
: Method: Create 2* ,
|
|||
|
Does) @ over 2- @ 5 + + perform ;
|
|||
|
|
|||
|
6 Method: get 1 Method: put 2 Method: show
|
|||
|
|
|||
|
Der METHODS>-Ansatz wird in den Definitionen so eingesetzt:
|
|||
|
: Integer:
|
|||
|
Variable Methods) @ ! u? ;
|
|||
|
|
|||
|
12:2? 2@d.;
|
|||
|
: Double:
|
|||
|
2Variable Methods) 2@ 2! 2? ;
|
|||
|
|
|||
|
: Queue: Create B c, 255 allot
|
|||
|
Methods) q@ g!gq. ;
|
|||
|
|
|||
|
clear \ löscht die Namen der Worte auf dem Heap
|
|||
|
|
|||
|
Später im Programm wird dann mit den generalisierten Methoden auf die Daten-
|
|||
|
strukturen zugegriffen:
|
|||
|
|
|||
|
Integer: Konto 1000 Konto put Konto show
|
|||
|
Double: Moleküle 200.000 Moleküle put Moleküle get d.
|
|||
|
Queue: Puffer Puffer qfill
|
|||
|
|
|||
|
Ascii A Puffer put
|
|||
|
Puffer show
|
|||
|
|
|||
|
Die Methods>-Operatoren können mit den bekannten FORTH-Operatoren gemischt
|
|||
|
werden. Ebenso können die Tabelle belicbig geändert oder erweitert werden, so z.B.
|
|||
|
mit 4 Method: init .
|
|||
|
|
|||
|
Soll diese Methode des Initialisierens nur bei Integer: eingesetzt werden, sind die
|
|||
|
anderen Tabellen entsprechend an der vierten Position aufzufüllen:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Datentypen =, =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
: Integer:
|
|||
|
Variable Methods) @ ! u? off ;
|
|||
|
|
|||
|
i z 2init ( addr -- ) 0. 2swap 2! ;
|
|||
|
: Double:
|
|||
|
2Variable Methods) 2@ 2! 2? 2init ;
|
|||
|
|
|||
|
I : ginit GAS)
|
|||
|
." Pufferinitialisierung noch nicht definiert! " ;
|
|||
|
: Queue: Create ® c, 255 allot
|
|||
|
Methods) q@ q! q. qinit ;
|
|||
|
Der Zugriff erfolgt dann wie gezeigt mit Konto init oder Druckpuffer init . Die
|
|||
|
logische Konsequenz ist die Verbindung beider Möglichkeiten zu :METHODS> :
|
|||
|
|
|||
|
:Methods) [compile] :Does> compile exit ; immediate
|
|||
|
:Methods> erwartet eine Reihe von Operatoren und weist diese (Zugriffs-) —
|
|||
|
|
|||
|
Methoden dem zuletzt definierten Wort zu. Es wird analog zu :DOES> und
|
|||
|
METHODS> in dieser Form eingesetzt:
|
|||
|
|
|||
|
Create Puffer ® c, 255 allot
|
|||
|
:Methods) q@ da! q. qinit ;
|
|||
|
|
|||
|
Variable Zähler :Methods) @ ! u? off ;
|
|||
|
|
|||
|
Puffer show zähler init
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 122 - Datentypen
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
18. Manipulieren des Systemverhalten
|
|||
|
|
|||
|
Das grundlegende Systemverhalten ist bei den traditionellen Programmiersprachen in
|
|||
|
der Laufzeit-Bibliothek {runtime library) festgelegt.
|
|||
|
Diese runtime library enthält die grundlegenden Routinen, die bei der Ausführung
|
|||
|
|
|||
|
der Programme vorhanden sein müssen wie z.B. die Bildschirmansteuerung oder den
|
|||
|
Massenspeicherzugriff.
|
|||
|
|
|||
|
In FORTH entspricht das Programm KERNEL.COM dieser Laufzeit-Bibliothek. Auf
|
|||
|
diesen Systemkern wird dann die fertige Anwendung, also Ihr Programm, geladen.
|
|||
|
Ein Beispiel für eine solche Applikationserstellung ist das Erstellen des volks-
|
|||
|
FORTH-Arbeitssystems volks4th.com von der MS-DOS Kommandoebene aus:
|
|||
|
|
|||
|
A:>kernel include volks4th.sys
|
|||
|
|
|||
|
Im Gegensatz zu anderen Compilern, denen meist ein Assembler-Quelltext zugrunde
|
|||
|
liegt, ist KERNEL.COM aus einem FORTH-Quelltext durch METACOMPILATION erzeugt
|
|||
|
worden. Da sich ein FORTH-Quelltext besser pflegen und leichter ändern läßt als
|
|||
|
ein Assemblerprogramm, kann das grundlegende Systemverhalten in KERNEL.COM
|
|||
|
leicht neuen Erfordernissen anpassen.
|
|||
|
|
|||
|
18.1 Patchen von FORTH-Befehlen
|
|||
|
|
|||
|
Möchte man ohne MetaCompilation das Verhalten von Funktion in KERNEL.COM
|
|||
|
ändern, so "patcht" man dieses Programm - eine Vorgehensweise, die WordStar-
|
|||
|
Nutzern gut bekannt ist. Soll beispielsweise die Funktion des Wortes . (DOT) im
|
|||
|
Kern geändert werden, ist so vorzugehen:
|
|||
|
|
|||
|
\ "patchen" von :-Definitionen im Kern, z.B. ".":
|
|||
|
|
|||
|
". »body @ Constant altdot
|
|||
|
|
|||
|
. new. (n--)) RDROP <(new.action) ;
|
|||
|
"new. Tut »body ! \ nun läuft die neue Version
|
|||
|
altdot ” »body ! \ und nun wieder die alte Version
|
|||
|
Dabei ist es wichtig, die neue Arbeitsweise von . mit RDROP einzuleiten.
|
|||
|
|
|||
|
Im Gegensatz dazu können Sie die Eigenschaften Ihres volksFORTH-Arbeitssystems
|
|||
|
über den Inhalt von VOLKS4TH.SYS und durch direkte Änderung der Systemqauell-
|
|||
|
texte individuell anpassen werden.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Manipulieren des Systemverhalten =123. =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
18.2 Verwendung von DEFER-Wörtern
|
|||
|
|
|||
|
Eine weitere Möglichkeit, das Systemverhalten zur Laufzeit zu beeinflussen, wird in
|
|||
|
dem Wort name gezeigt:
|
|||
|
|
|||
|
Dort sorgt ein exit vor dem Definitions-abschließenden Semicolon für einen freien
|
|||
|
Platz im Wort. In diesen freien Platz kann später mit Hilfe des Wortes 'name ein
|
|||
|
weiteres Wort "eingehängt" werden, das dann beim Aufruf von name mit ausge-
|
|||
|
führt wird. Auf diese Weise wird das Gesamtverhalten nicht vollständig geändert,
|
|||
|
sondern um eine weitere Funktion ergänzt.
|
|||
|
|
|||
|
Oft möchte man auch das Verhalten einer Anwendung an bestimmten Punkten
|
|||
|
umschaltbar machen. Dies wird in volksFORTH erreicht durch:
|
|||
|
|
|||
|
Defer <name>
|
|||
|
|
|||
|
So kann man schon auf ein Wort Bezug nehmen, bevor es definiert zu wurde. Dazu
|
|||
|
reicht es, volks4TH den Namen bekannt zu geben. Später können immer wieder
|
|||
|
andere Routinen an Stelle dieses Wortes ausgeführt werden:
|
|||
|
|
|||
|
' <action> Is (name)
|
|||
|
|
|||
|
( bitte auf das Häkchen ' achten!)
|
|||
|
Wird allerdings <name> ausgeführt, bevor es mit IS initialisiert wurde, so er-
|
|||
|
scheint die Meldung "Crash" auf dem Bildschirm. Deshalb finden Sie oft diesen
|
|||
|
Ausdruck:
|
|||
|
|
|||
|
Defer (name) ' noop Is (name)
|
|||
|
|
|||
|
So simpel ist die vektorielle Programmausführung in FORTH implementiert. Damit
|
|||
|
kann man zwei Probleme elegant lösen:
|
|||
|
|
|||
|
1. Das Wort <name> läßt sich bereits kompilieren, ohne daß ihm eine
|
|||
|
sinnvolle Aktion zugewiesen wurde. Damit ist die Kompilation von
|
|||
|
Wörtern möglich, die erst später definiert werden (Vorwärts-Referen-
|
|||
|
zen).
|
|||
|
|
|||
|
2, Die nachträglich Veränderung von bereits kompilierten Wörtern ist
|
|||
|
damit möglich; vorausgesetzt, sie wurden als Defer-Wörter einge-
|
|||
|
tragen. Wörter, die mit der Defer-Anweisung erzeugt wurden, lassen
|
|||
|
sich also in ihrem Ablaufverhalten nachträglich ändern. Diese Wörter
|
|||
|
behalten also ihren Namen bei, verändern aber ihr Verhalten.
|
|||
|
|
|||
|
Als Beispiel betrachten Sie bitte folgendes:
|
|||
|
|
|||
|
: Versuch#1 ." erster Versuch" cr;
|
|||
|
: Versuch#2 ." zweiter Versuch" cr ;
|
|||
|
|
|||
|
Defer Beispiel
|
|||
|
‘ Versuch#1 Is Beispiel
|
|||
|
|
|||
|
Beispiel perform
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 124 - Manipulieren des Systemverhalten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
Damit haben Sie jetzt BEISPIEL ausgeführt. Schauen Sie sich die Meldung an und
|
|||
|
geben ein:
|
|||
|
|
|||
|
' Versuch#2 Is Beispiel
|
|||
|
|
|||
|
Führen Sie erneut Beispiel perforn aus - Sie bekommen nun die andere
|
|||
|
|
|||
|
Meldung! Auf diese Art und Weise können Sie dem Wort BEISPIEL beliebige
|
|||
|
Funktionen zuweisen.
|
|||
|
|
|||
|
Die Kombination DEFER/IS behält also den Namen bei, ändert aber das Verhalten
|
|||
|
eines Wortes. Damit ist die Kombination DEFER/IS inhaltlich das Gegenteil von
|
|||
|
ALIAS , das den Namen ändert, aber die Funktion beibehält.
|
|||
|
|
|||
|
Mit ALIAS können Sie in volksFORTH einem Wort recht einfach einen neuen
|
|||
|
Namen geben. Sollte Ihnen das V des Editors nicht gefallen, benennen Sie es um
|
|||
|
in WHERE ! Dieses Umbenennen läßt sich auf zwei Arten durchführen, entweder
|
|||
|
im traditionellen FORTH-Stil mit
|
|||
|
|
|||
|
: where v;
|
|||
|
|
|||
|
oder dem volksFORTH gemäß mit
|
|||
|
|
|||
|
' vw Alias where
|
|||
|
|
|||
|
10.3 Neudefinition von Befehlen
|
|||
|
|
|||
|
Sollen dagegen Worte des Compilers unter anderem Namen benutzt werden, so ist
|
|||
|
das in FORTH ebenfalls kein Thema:
|
|||
|
: NeuName AltNane ;
|
|||
|
|
|||
|
' THEN Alias ENDIF immediate restrict
|
|||
|
: ENDIF [compile]) THEN ; immediate restrict
|
|||
|
|
|||
|
Eine Anwendung dieser Synonym-Deklarationen besteht darin, einen sogenannten
|
|||
|
Standard-Prolog zu verwirklichen: Damit Programme auch Wörter benutzen können,
|
|||
|
die der jeweilige Compiler nicht zur Verfügung stellt, schreibt man für den je-
|
|||
|
weiligen Compiler einen kleinen Vorspann (prelude) in FORTH83-Code zum Pro-
|
|||
|
gramm, der die jeweilig benötigten Definitonen enthält.
|
|||
|
|
|||
|
Oft stellt ein anderer Compiler eine identische Funktion unter einem anderen
|
|||
|
Namen zur Verfügung. So verwenden viele FORTH-Systeme GOTOXY statt des AT
|
|||
|
zur Cursorpositionierung. Nun ändert man im Prolog den Namen über die Alias-
|
|||
|
Funktion und erspart sich das quälende Suchen/Ersetzen im Editor.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Manipulieren des Systemverhalten = 1238 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
18.4 DEFERed Wörter im volksFORTH83
|
|||
|
|
|||
|
Darüberhinaus besitzt das volksFORTH83 eine Reihe von Strukturen, die dazu die-
|
|||
|
nen, das Verhalten des Systems zu ändern. Im System sind bereits folgende
|
|||
|
DEFERred Worte vorhanden:
|
|||
|
|
|||
|
R/W 'cOLD 'RESTART 'ABORT 'QuIT NOTFOUND
|
|||
|
|
|||
|
‚STATUS DISKERR MAKEVIEW und CUSTOM-REMOVE .
|
|||
|
|
|||
|
Um sie zu ändern, benutzt man den Ausdruck:
|
|||
|
|
|||
|
' <«<action) Is (name)
|
|||
|
|
|||
|
Hierbei ist, wie oben besprochen, <name> ein durch DEFER erzeugtes Wort und
|
|||
|
<action> der Name des Wortes, das in Zukunft bei Aufruf von <name> ausgeführt
|
|||
|
wird.
|
|||
|
|
|||
|
Anwendungsmöglichkeiten dieser deferred Worte:
|
|||
|
|
|||
|
Durch Ändern von R/W kann man andere Floppies oder eine RAM-Disk betreiben.
|
|||
|
Es ist auch leicht möglich, Teile einer Disk gegen überschreiben zu schützen.
|
|||
|
|
|||
|
Durch Ändern von NOTFOUND kann man z.B. Worte, die nicht im Dictionary ge-
|
|||
|
funden wurden, anschließend in einer Disk-Directory suchen lassen oder auto-
|
|||
|
matisch als Vorwärtsreferenz vermerken.
|
|||
|
|
|||
|
Ändert man 'COLD , so kann man die Einschaltmeldung des volksFORTH83
|
|||
|
unterdrücken und stattdessen ein Anwenderprogramm starten, ohne daß Eingaben
|
|||
|
von der Tastatur aus erforderlich sind (siehe z.B. "Erstellen einer Applikation").
|
|||
|
|
|||
|
Ähnliches gilt für 'RESTART.
|
|||
|
|
|||
|
'ABORT ist z.B. dafür gedacht, eigene Stacks, z.B. für Fließkommazahlen, im
|
|||
|
Fehlerfall zu löschen. Die Verwendung dieses Wortes erfordert aber schon eine ge-
|
|||
|
wisse Systemkenntnis.
|
|||
|
|
|||
|
Das gilt auch für das Wort 'QUIT.. 'QUIT wird dazu benutzt, eigene Quitloops in
|
|||
|
den Compiler einzubetten. Wer sich für diese Materie interessiert, sollte sich den
|
|||
|
Quelltext des Tracer anschauen. Dort wird vorgeführt, wie man das macht.
|
|||
|
|
|||
|
‚STATUS schließlich wird vor Laden eines Blocks ausgeführt. Man kann sich damit
|
|||
|
anzeigen lassen, welchen Block einer längeren Sequenz das System gerade lädt und
|
|||
|
z.B. wieviel freier Speicher noch zur Verfügung steht.
|
|||
|
|
|||
|
CUSTOM-REMOVE kann vom fortgeschrittenen Programmierer dazu benutzt werden,
|
|||
|
eigene Datenstrukturen, die miteinander durch Zeiger verkettet sind, zu vergessen.
|
|||
|
Ein Beispiel dafür sind die File Control Blöcke des Fileinterfaces.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 126 - Manipulieren des Systemverhalten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
18.5 Vektoren im volksFORTH83
|
|||
|
|
|||
|
Es gibt im System die Uservariable ERRORHANDLER . Dabei handelt es sich um
|
|||
|
eine normale Variable, die als Inhalt die Kompilationsadresse eines Wortes hat. Der
|
|||
|
Inhalt der Variablen wird auf folgende Weise ausgeführt:
|
|||
|
|
|||
|
errorhandler perform
|
|||
|
|
|||
|
Zuweisen und Auslesen dieser Variablen geschieht mit @ und ! . Der Inhalt
|
|||
|
von ERRORHANDLER wird ausgeführt, wenn das System ABORT" oder ERROR"
|
|||
|
ausführt und das von diesen Worten verbrauchte Flag wahr ist. Die Adresse des
|
|||
|
Textes mit der Fehlermeldung befindet sich auf dem Stack.
|
|||
|
|
|||
|
Siehe z.B. (ERROR .
|
|||
|
|
|||
|
Das volksFORTH83 benutzt die indirekten Vektoren INPUT und OUTPUT . Die
|
|||
|
Funktionsweise der sich daraus ergebenden Strukturen soll am Beispiel von INPUT
|
|||
|
verdeutlicht werden:
|
|||
|
|
|||
|
INPUT ist eine Uservariable, die auf einen Vektor zeigt, in dem wiederum vier
|
|||
|
Kompilationsadressen abgelegt sind. Jedes der vier Inputworte KEY KEY?
|
|||
|
DECODE und EXPECT führt eine der Kompilationsadressen aus. Kompiliert wird
|
|||
|
solch ein Vektor in der folgenden Form:
|
|||
|
|
|||
|
Input: vector <namel) <(name2) (name3) <(name4) ;
|
|||
|
|
|||
|
Wird VECTOR ausgeführt, so schreibt er seine Parameterfeld-Adresse in die
|
|||
|
USERVariable INPUT. Von nun an führen die Inputworte die ihnen so zugewiese-
|
|||
|
nen Worte aus. KEY führt also <NAME1> aus usw...
|
|||
|
|
|||
|
Das Beispiel KEY? soll dieses Prinzip verdeutlichen:
|
|||
|
: key? (-- ce) input @ 2+ perform ;
|
|||
|
|
|||
|
Tatsächlich wurde KEY? im System ebenso wie die anderen Inputworte durch das
|
|||
|
nicht mehr sichtbare definierende Wort IN: erzeugt. Ein Beispiel für einen
|
|||
|
Inputvektor, der die Eingabe von der Tastatur holt:
|
|||
|
|
|||
|
Input: keyboard
|
|||
|
(key (key? (decode (expect ;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
keyboard
|
|||
|
ergibt:
|
|||
|
input pointer
|
|||
|
ln
|
|||
|
KEYBOARD code (key (key? (decode (expect
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Manipulieren des Systemverhalten 12a,
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Analog verhält es sich mit OUTPUT und den Outputworten EMIT CR TYPE DEL
|
|||
|
PAGE AT und AT? . Outputvektoren werden mit OUTPUT: genauso wie die
|
|||
|
Inputvektoren erzeugt.
|
|||
|
|
|||
|
Bitte beachten Sie, daß immer alle Worte in der richtigen Reihenfolge aufgeführt
|
|||
|
werden müssen! Soll nur ein Wort geändert werden, so müssen sie trotzdem die
|
|||
|
anderen mit hinschreiben.
|
|||
|
|
|||
|
18.6 Glossar
|
|||
|
|
|||
|
Defer (--)
|
|||
|
|
|||
|
ein definierendes Wort, das in der Form:
|
|||
|
|
|||
|
Defer (name)
|
|||
|
benutzt wird. Erzeugt den Kopf für ein neues Wort <name> im Dictionary,
|
|||
|
hält 2 Byte in dessen Parameterfeld frei und speichert dort zunächst die
|
|||
|
Kompilationsadresse einer Fehlerroutine.
|
|||
|
Wird <name> nun ausgeführt, so wird eine Fehlerbehandlung eingeleitet.
|
|||
|
Man kann dem Wort <name)> jedoch zu jeder Zeit eine andere Funktion
|
|||
|
zuweisen mit der Sequenz:
|
|||
|
|
|||
|
' «action)> Is (name)
|
|||
|
Nach dieser Zuweisung verhält sich <name> wie <action>.
|
|||
|
Mit diesem Mechanismus kann man zwei Probleme elegant lösen:
|
|||
|
Einerseits läßt sich <name> bereits kompilieren, bevor ihm eine sinnvolle
|
|||
|
Aktion zugewiesen wurde Damit ist die Kompilation erst später
|
|||
|
definierter Worte (Vorwärts-Referenzen) indirekt möglich.
|
|||
|
Andererseits ist die Veränderung des Verhaltens von <name> für spezielle
|
|||
|
Zwecke auch nachträglich möglich, ohne neu kompilieren zu müssen.
|
|||
|
Deferred Worte im System sind: R/W 'COLD 'RESTART 'ABORT 'QUIT
|
|||
|
NOTFOUND .STATUS und DISKERR . Diese Worte sind DEFERred, damit
|
|||
|
ihr Verhalten für die Anwendung geändert werden kann.
|
|||
|
|
|||
|
Is (cfa--)
|
|||
|
ist ein Wort, mit dem das Verhalten eines deferred Wortes verändert wer-
|
|||
|
den kann. IS wird in der Form:
|
|||
|
|
|||
|
' <action)> Is (name)
|
|||
|
|
|||
|
benutzt. Wenn <name> kein deferred Wort ist, wird eine Fehlerbehandlung
|
|||
|
eingeleitet, sonst verhält sich <name> anschließend wie <action?>. Das
|
|||
|
Wort IS des volksFORTH83 kann innerhalb von Definitionen benutzt
|
|||
|
werden.
|
|||
|
Siehe DEFER .
|
|||
|
|
|||
|
|
|||
|
|
|||
|
128 - Manipulieren des Systemverhalten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3,81
|
|||
|
|
|||
|
perform
|
|||
|
|
|||
|
noop
|
|||
|
|
|||
|
Alias
|
|||
|
|
|||
|
Input:
|
|||
|
|
|||
|
( addr --)
|
|||
|
erwartet eine Adresse, unter der sich ein Zeiger auf die Kompilations-
|
|||
|
adresse eines Wortes befindet. Dieses Wort wird dann ausgeführt.
|
|||
|
perform entspricht der Anweisungsfolge ®@ execute .
|
|||
|
|
|||
|
=)
|
|||
|
macht gar nichts.
|
|||
|
|
|||
|
(cfa --)
|
|||
|
ist ein definierendes Wort, das typisch in der Form:
|
|||
|
|
|||
|
' «oläname) Alias (newname)>
|
|||
|
benutzt wird. ALIAS erzeugt einen Kopf für <newname> im Dictionary.
|
|||
|
Wird <newname> aufgerufen, so verhält es sich wie <oldname)>. Insbeson-
|
|||
|
dere wird beim Kompilieren nicht <newname>, sondern <oldname> im Dic-
|
|||
|
tionary eingetragen.
|
|||
|
Im Unterschied zu : <(newname) <oldname> ; ist es mit ALIAS möglich,
|
|||
|
Worte, die den Returnstack beeinflussen (z.B. >r oder r> ), mit an-
|
|||
|
derem Namen zu definieren. Außer dem neuen Kopf für <newname> wird
|
|||
|
kein zusaetzlicher Speicherplatz verbraucht. Gegenwärtig wird bei Aus-
|
|||
|
führung von >name aus einer CFA in der Regel der letzte mit ALIAS
|
|||
|
erzeugte Name gefunden.
|
|||
|
|
|||
|
(42) "input-colon"
|
|||
|
ist ein definierendes Wort, benutzt in der Form:
|
|||
|
|
|||
|
Input: <name)> newKEY newKEY? newDECODE newEXPECT ;
|
|||
|
INPUT: erzeugt einen Kopf für <name> im Dictionary und kompiliert einen
|
|||
|
Satz von Zeigern auf Worte, die für die Eingabe von Zeichen zuständig
|
|||
|
sind. Wird <name> ausgeführt, so wird ein Zeiger auf das Parameterfeld
|
|||
|
von <name> in die Uservariable INPUT geschrieben. Alle Eingaben
|
|||
|
werden jetzt über die neuen Eingabeworte abgewickelt.
|
|||
|
Die Reihenfolge der Worte nach INPUT: <name> bis zum Semicolon muß
|
|||
|
eingehalten werden:
|
|||
|
|
|||
|
..kKey ..key? ..decode ..expect
|
|||
|
Im System ist das mit INPUT: definierte Wort keyboard enthalten,
|
|||
|
nach dessen Ausführung alle Eingaben von der Tastatur geholt werden.
|
|||
|
Siehe DECODE und EXPECT.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Manipulieren des Systemverhalten = 129 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Output:
|
|||
|
|
|||
|
'abort
|
|||
|
|
|||
|
'cold
|
|||
|
|
|||
|
'quit
|
|||
|
|
|||
|
'restart
|
|||
|
|
|||
|
(quit
|
|||
|
|
|||
|
==) "output-colon"
|
|||
|
|
|||
|
ist ein definierendes Wort, benutzt in der Form:
|
|||
|
Output: (name)
|
|||
|
newEMIT newCR newTYPE newDEL newPAGE newAT newAT? ;
|
|||
|
|
|||
|
OUTPUT: erzeugt einen Kopf für <name> im Dictionary und kompiliert
|
|||
|
einen Satz von Zeigern auf Worte, die für die Ausgabe von Zeichen zu-
|
|||
|
ständig sind. Wird <name> ausgeführt, so wird ein Zeiger auf das Para-
|
|||
|
meterfeld von <name> in die Uservariable OUTPUT geschrieben. Alle
|
|||
|
Ausgaben werden jetzt über die neuen Ausgabeworte abgewickelt.
|
|||
|
Die Reihenfolge der Worte nach OUTPUT: <name) muß eingehalten werden:
|
|||
|
|
|||
|
..emit ..cr ..type ..del ..page ..at ..at?
|
|||
|
Im System ist das mit OUTPUT: definierte Wort DISPLAY enthalten,
|
|||
|
nach dessen Ausführung alle Ausgaben auf den Bildschirm geleitet
|
|||
|
werden.
|
|||
|
Vergleiche auch das Wort PRINT aus dem Printer-Interface.
|
|||
|
|
|||
|
) "tick-abort"
|
|||
|
ist ein deferred Wort, das mit NOOP vorbesetzt ist. Es wird in ABORT
|
|||
|
ausgeführt, bevor QUIT aufgerufen wird. Es kann benutzt werden, um
|
|||
|
"automatisch" selbstdefinierte Stacks zu löschen.
|
|||
|
|
|||
|
Ge-) "tick-cold"
|
|||
|
ist ein deferred Wort, das mit NOOP vorbesetzt ist. Es wird in COLD
|
|||
|
aufgerufen, bevor die Einschaltmeldung ausgegeben wird. Es wird benutzt,
|
|||
|
um Geräte zu initialisieren oder Anwenderprogramme automatisch zu star-
|
|||
|
ten.
|
|||
|
|
|||
|
a=)) "tick-quit"
|
|||
|
ist ein deferred Wort, das normalerweise mit (QUIT besetzt ist. Es wird
|
|||
|
in QUIT aufgerufen, nachdem der Returnstack enleert und der interpre-
|
|||
|
tierende Zustand eingeschaltet wurde. Es wird benutzt, um spezielle
|
|||
|
Kommandointerpreter (wie z.B. im Tracer) aufzubauen.
|
|||
|
|
|||
|
(==) "tick-restart"
|
|||
|
Dies ist ein deferred Wort, das mit NOOP vorbesetzt ist. Es wird in
|
|||
|
RESTART aufgerufen, nachdem 'QUIT mit (QUIT besetzt wurde. Es
|
|||
|
wird benutzt, um Geräte nach einem Warmstart zu re-initialisieren.
|
|||
|
|
|||
|
(==) "paren-quit"
|
|||
|
Dieses Wort ist normalerweise der Inhalt von 'QUIT .. Es wird von QUIT
|
|||
|
benutzt. Es akzeptiert eine Zeile von der aktuellen Eingabeeinheit, führt
|
|||
|
sie aus und druckt "ok" bzw. "compiling".
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 130 -
|
|||
|
|
|||
|
Manipulieren des Systemverhalten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
‚status (--) "dot-status"
|
|||
|
Dieses Wort ist ein deferred Wort, das vor dem Einlesen einer Zeile bzw.
|
|||
|
dem Laden eines Blocks ausgeführt wird. Es ist mit NOOP vorbesetzt
|
|||
|
und kann dazu benutzt werden, Informationen über den Systemzustand
|
|||
|
oder den Quelltext auszugeben.
|
|||
|
|
|||
|
makeview ( -- 16b)
|
|||
|
ist ein deferred Wort, dem mit IS ein Wort zugewiesen wurde. Dieses
|
|||
|
Wort erzeugt aus dem gerade kompilierten Block eine 16b Zahl, die von
|
|||
|
Create in das Viewfeld eingetragen wird. Das deferred Wort wird benötigt,
|
|||
|
um das Fileinterface löschen zu können,
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Manipulieren des Systemverhalten 1831 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
1l. Vokabular-Struktur
|
|||
|
|
|||
|
Eine Liste von Worten ist ein Vokabular. Ein FORTH-System besteht im allgemeinen
|
|||
|
aus mehreren Vokabularen, die nebeneinander existieren. Neue Vokabulare werden
|
|||
|
durch das definierende Wort VOCABULARY erzeugt und haben ihrerseits einen
|
|||
|
Namen, der in einer Liste enthalten ist. Gewöhnlich kann von mehreren Worten mit
|
|||
|
gleichem Namen nur das zuletzt definierte erreicht werden. Befinden sich jedoch die
|
|||
|
einzelnen Worte in verschiedenen Vokabularen, so bleiben sie einzeln erreichbar.
|
|||
|
|
|||
|
11.1 Die Suchreihenfolge
|
|||
|
|
|||
|
Die Suchreihenfolge gibt an, in welcher Reihenfolge die verschiedenen Vokabulare
|
|||
|
nach einem Wort durchsucht werden.
|
|||
|
|
|||
|
Sie besteht aus zwei Teilen, dem auswechselbaren und dem festen Teil. Der aus-
|
|||
|
wechselbare Teil enthält genau ein Vokabular. Dies wird zuerst durchsucht. Wird
|
|||
|
ein Vokabular durch Eingeben seines Namens ausgeführt, so trägt es sich in den
|
|||
|
auswechselbaren Teil ein. Dabei wird der alte Inhalt überschrieben. Einige andere
|
|||
|
Worte ändern ebenfalls den auswechselbaren Teil. Soll ein Vokabular immer durch-
|
|||
|
sucht werden, so muß es in den festen Teil übertragen werden. Dieser enthält null
|
|||
|
bis sechs Vokabulare und wird nur vom Benutzer bzw. seinen Worten verändert. Zur
|
|||
|
Manipulation stehen u.a. die Worte ONLY ALSO TOSS zur Verfügung. Das Voka-
|
|||
|
bular, in das neue Worte einzutragen sind, wird durch das Wort DEFINITIONS an-
|
|||
|
gegeben. Die Suchreihenfolge kann man sich mit ORDER ansehen.
|
|||
|
|
|||
|
Ein Beispiele, das die Veränderung der Suchreihenfolge mit den eingegebenen Be-
|
|||
|
fehlen zeigt, wobei das Grundvokabular ROOT zwar in der Suchreihenfolge ent-
|
|||
|
halten ist, aber nicht von ORDER angezeigt wird, um die Statuszeile nicht mit
|
|||
|
obligatorischen Informationen zu blockieren:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Eingabe: ORDER ergibt dann:
|
|||
|
|
|||
|
Only£forth FORTH FORTH ROOT FORTH
|
|||
|
|
|||
|
Editor also EDITOR EDITOR FORTH ROOT FORTH
|
|||
|
Assembler ASSEMBLER EDITOR FORTH ROOT FORTH
|
|||
|
definitions Forth FORTH EDITOR FORTH ROOT ASSEMBLER
|
|||
|
|
|||
|
: test ; ASSEMBLER EDITOR FORTH ROOT ASSEMBLER
|
|||
|
|
|||
|
Hierbei ist vor allem auf colon (:) zu achten, das ebenfalls die Suchlaufpriorität
|
|||
|
ändert, indem es das Kompilationsvokabular current in den auswechselbaren Teil
|
|||
|
von context überträgt.
|
|||
|
|
|||
|
Der Inhalt eines Vokabulars besteht aus einer Liste von Worten, die durch ihre
|
|||
|
Linkfelder miteinander verbunden sind. Es gibt also genauso viele Listen wie
|
|||
|
Vokabulare. Alle Vokabulare sind selbst noch einmal über eine Liste verbunden,
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 182,0= Vokabular-Struktur
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
deren Anfang in VOC-LINK steht. Diese Verkettung ist nötig, um ein komfortables
|
|||
|
FORGET zu ermöglichen. Man bekommt beispielsweise folgendes Bild:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Voc-Link Assembler Only Forth }- Null
|
|||
|
| | |
|
|||
|
Wort | Wort | Wort
|
|||
|
| | |
|
|||
|
Wort | Wort Wort
|
|||
|
| | |
|
|||
|
Null Null Null
|
|||
|
|
|||
|
11.2 Glossar
|
|||
|
|
|||
|
Vocabulary (=) 83
|
|||
|
|
|||
|
ein definierendes Wort, das in der Form:
|
|||
|
|
|||
|
Vocabulary (name)
|
|||
|
benutzt wird.
|
|||
|
VOCABULARY erzeugt einen Kopf für <name>, das den Anfang einer
|
|||
|
neuen Liste von Worten bildet. Wird <name> ausgeführt, so werden bei
|
|||
|
der Suche im Dictionary zuerst die Worte in der Liste von <name>
|
|||
|
berücksichtigt. Wird das VOCABULARY <name> durch die Sequenz:
|
|||
|
|
|||
|
<name) definitions
|
|||
|
zum Kompilations-Vokabular, so werden neue Wort-Definitionen in die
|
|||
|
Liste von <name)> gehängt. Vergleiche auch CONTEXT CURRENT ALSO
|
|||
|
TOSS ONLY FORTH ONLYFORTH .
|
|||
|
|
|||
|
context ( -- addr )
|
|||
|
addr ist die Adresse des auswechselbaren Teils der Suchreihenfolge. Sie
|
|||
|
enthält einen Zeiger auf das erste zu durchsuchende Vokabular.
|
|||
|
|
|||
|
eurrent ( -- addr )
|
|||
|
|
|||
|
addr ist die Adresse eines Zeigers, der auf das Kompilationsvokabular
|
|||
|
zeigt, in das neue Worte eingefügt werden.
|
|||
|
|
|||
|
definitions (--)83
|
|||
|
ersetzt das gegenwärtige Kompilationsvokabular durch das Vokabular im
|
|||
|
auswechselbaren Teil der Suchreihenfolge, d.h. neue Worte werden in
|
|||
|
dieses Vokabular eingefügt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Vokabular-Struktur » I8Bim
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Only (=
|
|||
|
Das Nennen dieses Vokabular löscht die Suchreihenfolge vollständig und
|
|||
|
ersetzt sie durch das Vokabular ROOT im festen und auswechselbaren
|
|||
|
Teil der Suchreihenfolge. ROOT enthält nur wenige Worte, die für die
|
|||
|
Erzeugung einer Suchreihenfolge benötigt werden.
|
|||
|
|
|||
|
also ( = )
|
|||
|
Ein Wort, um die Suchreihenfolge zu spezifizieren. Das Vokabular im aus-
|
|||
|
wechselbarem Teil der Suchreihenfolge wird zum ersten Vokabular im
|
|||
|
festen Teil gemacht, wobei die anderen Vokabulare des festen Teils nach
|
|||
|
hinten rücken. Ein Fehler liegt vor, falls der feste Teil sechs Vokabulare
|
|||
|
enthält.
|
|||
|
|
|||
|
toss (--)
|
|||
|
entfernt das erste Vokabular des festen Teils der Suchreihenfolge. Inso-
|
|||
|
fern ist es das Gegenstück zu ALSO .
|
|||
|
|
|||
|
seal (me)
|
|||
|
löscht das Vokabular ROOT , so daß es nicht mehr durchsucht wird. Da-
|
|||
|
durch ist es möglich, nur die Vokabulare des Anwenderprogramms durch-
|
|||
|
suchen zu lassen.
|
|||
|
|
|||
|
Onlyforth Do)
|
|||
|
entspricht der häufig benötigten Sequenz:
|
|||
|
ONLY FORTH ALSO DEFINITIONS
|
|||
|
|
|||
|
Forth =) 83
|
|||
|
Das ursprüngliche Vokabular.
|
|||
|
|
|||
|
Assembler (--)
|
|||
|
Ein Vokabular, das Prozessor-spezifische Worte enthält, die für Code-
|
|||
|
Definitionen benötigt werden.
|
|||
|
|
|||
|
words (en)
|
|||
|
gibt die Namen der Worte des Vokabulars, das im auswechselbaren Teil
|
|||
|
der Suchreihenfolge steht, aus, beginnend mit dem zuletzt erzeugtem
|
|||
|
Namen.
|
|||
|
|
|||
|
forth-83 ==) 83
|
|||
|
Laut FORTH83-Standard soll dieses Wort sicherstellen, daß ein Standard-
|
|||
|
system benutzt wird. Im volksFORTH funktionslos.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 134 - Vokabular-Struktur
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
vp ( -- addr ) "v-p"
|
|||
|
Eine Variable, die das Ende der Suchreihenfolge markiert. Sie enthält
|
|||
|
ausserdem Informationen über die Länge der Suchreihenfolge.
|
|||
|
|
|||
|
voc-link ( -- addr )
|
|||
|
Eine Uservariable, die den Anfang einer Liste mit allen Vokabularen
|
|||
|
enthält. Diese Liste wird u.a. für FORGET benötigt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Vokabular-Struktur -196--
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V.
|
|||
|
|
|||
|
PC-voliksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
12. Dictionary -Struktur
|
|||
|
|
|||
|
Das FORTH-System besteht aus einem Dictionary von Worten. Die Struktur der
|
|||
|
Worte und des Dictionaries soll im folgenden erläutert werden.
|
|||
|
|
|||
|
12.1 Aufbau
|
|||
|
|
|||
|
Die FORTH-Worte sind in Listen angeordnet (s.a. Struktur der Vokabulare). Die vom
|
|||
|
Benutzer definierten Worte werden ebenfalls in diese Listen eingetragen.
|
|||
|
Jedes Wort besteht aus sechs Teilen. Es sind dies:
|
|||
|
|
|||
|
1. block
|
|||
|
|
|||
|
2. link
|
|||
|
|
|||
|
3. count
|
|||
|
|
|||
|
4. name
|
|||
|
|
|||
|
5. code
|
|||
|
|
|||
|
6. parameter
|
|||
|
|
|||
|
Der Nummer des Blocks, in dem das Wort definiert
|
|||
|
wurde (siehe auch VIEW).
|
|||
|
|
|||
|
Die Adresse (Zeiger) namens Ifa , die auf das "Link-
|
|||
|
feld" des nächsten Wortes zeigt.
|
|||
|
|
|||
|
Die Länge des Namens dieses Wortes und drei Mar-
|
|||
|
kierungsbits. Die Adresse nfa zeigt auf dieses Byte,
|
|||
|
ebenso last.
|
|||
|
|
|||
|
Der Name selbst.
|
|||
|
|
|||
|
Eine Adresse (Zeiger), die auf den Maschinencode
|
|||
|
zeigt, der bei Aufruf dieses Wortes ausgeführt wird.
|
|||
|
Die Adresse dieses Feldes heißt Kompilationsadresse
|
|||
|
cfa .
|
|||
|
|
|||
|
Das Parameterfeld; die Adresse dieses Feldes heißt pfa .
|
|||
|
|
|||
|
Ein Wort sieht dann so aus:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Wort
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
block
|
|||
|
|
|||
|
|
|||
|
|
|||
|
link
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
count | name code parameter ...
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Im folgenden sollen diese sechs Felder einzeln detalliert betrachtet werden.
|
|||
|
|
|||
|
Block
|
|||
|
|
|||
|
Das Blockfeld enthält in codierter Form die Nummer
|
|||
|
des Blocks und den Namen des Files, in dem das Wort
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 136 -
|
|||
|
|
|||
|
Dicetionary-Struktur
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V.
|
|||
|
|
|||
|
Link
|
|||
|
|
|||
|
— Countfeld
|
|||
|
|
|||
|
PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
definiert wurde. Wurde es von der Tastatur aus ein-
|
|||
|
gegeben, so enthält das Feld Null.
|
|||
|
|
|||
|
über das Linkfeld sind die Worte eines Vokabulars zu
|
|||
|
einer Liste verkettet. Jedes Link-Feld enthält die
|
|||
|
Adresse des vorherigen Link-Feldes. Jedes Wort zeigt
|
|||
|
also auf seinen Vorgänger. Das unterste Wort der
|
|||
|
Liste enthält im Link-Feld eine Null. Die Null zeigt
|
|||
|
das Ende der Liste an.
|
|||
|
|
|||
|
Das count field enthält die Länge des Namens (1..31
|
|||
|
Zeichen) und drei Markierungsbits :
|
|||
|
|
|||
|
|
|||
|
|
|||
|
restrict immediate indirect Länge
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Bit:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
6 5 4..0
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ist das immediate-Bit gesetzt, so wird das entspre-
|
|||
|
chende Wort im kompilierenden Zustand unmittelbar
|
|||
|
ausgeführt, und nicht ins Dictionary kompiliert (siehe
|
|||
|
auch IMMEDIATE ).
|
|||
|
|
|||
|
Ist das restrict-Bit gesetzt, so kann das Wort nicht
|
|||
|
durch Eingabe von der Tastatur ausgeführt, sondern
|
|||
|
nur in anderen Worten kompiliert werden. Gibt man es
|
|||
|
dennoch im interpretierenden Zustand ein, so er-
|
|||
|
scheint die Fehlermeldung "compile only" (siehe
|
|||
|
auch RESTRICT ).
|
|||
|
|
|||
|
Ist das indirect-Bit gesetzt, so folgt auf den Namen
|
|||
|
kein Codefeld, sondern ein Zeiger darauf. Damit kann
|
|||
|
der Name vom Rumpf ( Code- und Parameterfeld )
|
|||
|
getrennt werden. Die Trennung geschieht z.B. bei
|
|||
|
Verwendung der Worte ı oder ALIAS.
|
|||
|
|
|||
|
Beispiel: '‘ 1+ Alias addl
|
|||
|
ergibt folgende Struktur im Speicher (Dictionary) :
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Dicetionary-Struktur
|
|||
|
|
|||
|
= 1978 —
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Name
|
|||
|
|
|||
|
Code
|
|||
|
|
|||
|
Parameter
|
|||
|
|
|||
|
|
|||
|
|
|||
|
block | link | 524 addi pointer
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
andere Worte
|
|||
|
|
|||
|
|
|
|||
|
| Block’ | link' | $82 | 1+ | code | parameter
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Name besteht normalerweise aus ASCII-Zeichen.
|
|||
|
Bei der Eingabe werden Klein- in Großbuchstaben um-
|
|||
|
gewandelt. Daher druckt WORDS auch nur großge-
|
|||
|
schriebene Namen. \
|
|||
|
Da Namen sowohl groß als auch klein geschrieben
|
|||
|
eingegeben werden können, haben wir eine Konvention
|
|||
|
erarbeitet, die die Schreibweise von Namen festlegt:
|
|||
|
Bei Kontrollstrukturen wie DO LOOP etc. werden
|
|||
|
alle Buchstaben groß geschrieben.
|
|||
|
|
|||
|
Bei Namen von Vokabularen, immediate Worten und
|
|||
|
definierenden Worten, die CREATE ausführen, wird
|
|||
|
nur der erste Buchstabe groß geschrieben.
|
|||
|
|
|||
|
Beispiele sind: Is FORTH Constant
|
|||
|
|
|||
|
Alle anderen Worte werden klein geschrieben.
|
|||
|
Beispiele sind: dup cold base
|
|||
|
|
|||
|
Bestimmte Worte, die von immediate Worten kompiliert
|
|||
|
werden, beginnen mit der öffnenden Klammer "("
|
|||
|
gefolgt vom Namen des immediate Wortes.
|
|||
|
|
|||
|
Ein Beispiel: DO kompiliert (do.
|
|||
|
|
|||
|
Diese Schreibweise ist nicht zwingend; Sie sollten sich
|
|||
|
aber daran halten, um die Lesbarkeit Ihrer Quelltexte
|
|||
|
zu erhöhen.
|
|||
|
|
|||
|
Jedes Wort weist auf ein Stück Maschinencode. Die
|
|||
|
Adresse dieses Code-Stücks ist im Codefeld enthalten.
|
|||
|
Gleiche Worttypen weisen auf den gleichen Code. Es
|
|||
|
gibt verschiedene Worttypen, z.B. :-Definitionen,
|
|||
|
Variablen, Konstanten, Vokabulare usw. Sie haben je-
|
|||
|
weils ihren eigenen charakte- ristischen Code ge-
|
|||
|
meinsam. Die Adresse des Code-Feldes heißt Kompi-
|
|||
|
lationsadresse.
|
|||
|
|
|||
|
Das Parameterfeld enthält Daten, die vom Worttypen
|
|||
|
|
|||
|
abhängen. Beispiele :
|
|||
|
|
|||
|
a) Typ "Constant"
|
|||
|
Hier enthält das Parameterfeld des Wortes den Wert
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 198 —
|
|||
|
|
|||
|
Dictionary-Struktur
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V.
|
|||
|
|
|||
|
PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
der Konstanten. Der dem Wort zugeordnete Code liest
|
|||
|
den Inhalt des Parameterfeldes aus und legt ihn auf
|
|||
|
den Stack.
|
|||
|
|
|||
|
b) Typ "Variable"
|
|||
|
|
|||
|
Das Parameterfeid enthält den Wert der Variablen, der
|
|||
|
zugeordnete Code liest jedoch nicht das Parameterfeld
|
|||
|
aus, sondern legt dessen Adresse auf den Stack. Der
|
|||
|
Benutzer kann dann mit dem Wort @ den Wert holen
|
|||
|
und mit dem Wort ! überschreiben.
|
|||
|
|
|||
|
c) Typ ":-definition"
|
|||
|
Das ist ein mit : und ; gebildetes Wort. In diesem -
|
|||
|
Fall enthält das Parameterfeld hintereinander die
|
|||
|
Kompilationsadressen der Worte, die diese Definition
|
|||
|
bilden. Der zugeordnete Code sorgt dann dafür, daß
|
|||
|
diese Worte der Reihe nach ausgeführt werden.
|
|||
|
Beispiel :
|
|||
|
: test dup ;
|
|||
|
|
|||
|
ergibt:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
| TEST | code | pointer pointer |
|
|||
|
|
|||
|
rn
|
|||
|
|
|||
|
DUP code parameter
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
UNNEST code parameter
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Das Wort : hat den Namen TEST erzeugt. UNNEST
|
|||
|
wurde durch das Wort ; erzeugt
|
|||
|
|
|||
|
d) Typ "Code"
|
|||
|
|
|||
|
Worte vom Typ "Code" werden mit dem Assembler er-
|
|||
|
zeugt. Hier zeigt das Codefeld in der Regel auf das
|
|||
|
Parameterfeld. Dorthin wurde der Maschinencode
|
|||
|
assembliert.
|
|||
|
|
|||
|
Codeworte im volksFORTH können leicht "umgepatcht"
|
|||
|
werden, da lediglich die Adresse im Codefeld auf eine
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Dicetionary-Struktur
|
|||
|
|
|||
|
= 1396
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
here
|
|||
|
|
|||
|
dp
|
|||
|
|
|||
|
udp
|
|||
|
|
|||
|
allot
|
|||
|
|
|||
|
uallot
|
|||
|
|
|||
|
©
|
|||
|
|
|||
|
neue (andere) Maschinencodesequenz gesetzt werden
|
|||
|
muß.
|
|||
|
|
|||
|
12.2 Glossar
|
|||
|
|
|||
|
( -- addr ) 83
|
|||
|
addr ist die Adresse des nächsten freien Dictionaryplatzes.
|
|||
|
|
|||
|
( -- addr ) "d-p"
|
|||
|
Eine Uservariable, die die Adresse des nächsten freien Dicetionary-platzes
|
|||
|
enthält.
|
|||
|
|
|||
|
( -- addr ) "u-d-p"
|
|||
|
Eine Uservariable, in dem das Ende der bisher allokierten Userarea ver-
|
|||
|
merkt ist.
|
|||
|
|
|||
|
(w--) 83
|
|||
|
Allokiere w Bytes im Dictionary. Die Adresse des nächsten freien Dic-
|
|||
|
tionaryplatzes wird entsprechend verstellt.
|
|||
|
|
|||
|
(nl--n2)
|
|||
|
Allokiere bzw. deallokiere ni Bytes in der Userarea. n2 gibt den Anfang
|
|||
|
des allokierten Bereiches relativ zum Beginn der Userarea an. Eine
|
|||
|
Fehlerbehandlung wird eingeleitet, wenn die Userarea voll ist.
|
|||
|
|
|||
|
(16b --) "c-comma"
|
|||
|
ist ein ALLOT für ein Byte und speichert die unteren 8 Bit von 16b in
|
|||
|
HERE 1- .
|
|||
|
|
|||
|
( 16b --) 83 "comma"
|
|||
|
ist 2 ALLOT für 16b und speichere 16b ab HERE 2
|
|||
|
|
|||
|
( -- addr ) 83 "tick"
|
|||
|
Wird in der Form ' <«name)> benutzt.
|
|||
|
addr ist die Kompilationsadresse von <name>. Wird <name> nicht in der
|
|||
|
Suchreihenfolge gefunden, so wird eine Fehlerbehandlung eingeleitet.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 140 -
|
|||
|
|
|||
|
Dietionary-Struktur
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
name
|
|||
|
|
|||
|
'name
|
|||
|
|
|||
|
‚name
|
|||
|
|
|||
|
align
|
|||
|
|
|||
|
forget
|
|||
|
|
|||
|
(==)
|
|||
|
|
|||
|
Eine Besonderheit von name ist, daß dieses Wort über zwei EXITs
|
|||
|
verfügt. Zum einen das explizite exit und zum anderen das Semicolon,
|
|||
|
das ja auch ein exit ist. Die so einkompilierte Adresse kann dazu be-
|
|||
|
nutzt werden, beim Aufruf von name ein weiteres Wort ausführen zu
|
|||
|
lassen. Dieser Mechanismus kann als eine Variation von Deferred Worten
|
|||
|
aufgefaßt werden, weil auch hier das Wortverhalten geändert wird.
|
|||
|
|
|||
|
Siehe 'NAME und auch DEFER .
|
|||
|
|
|||
|
( -- addr )
|
|||
|
liefert die Bezugsadresse für das Einhängen eines Wortes, wie es bei
|
|||
|
name dargestellt wurde. Diese Möglichkeit, das Verhalten von Worten zu
|
|||
|
erweitern, wird bsp. im Editor eingesetzt. Dort wird im Wort showload
|
|||
|
ein Wort show über 'name in name eingehängt und dann in
|
|||
|
showoff durch das Eintragen von exit wieder überschrieben, d.h. aus-
|
|||
|
gehängt.
|
|||
|
|
|||
|
( addr -- ) "dot-name"
|
|||
|
addr ist die Adresse des Countfeldes eines Namens. Dieser Name wird
|
|||
|
ausgedruckt. Befindet er sich im Heap, so wird das Zeichen ı vorange-
|
|||
|
stellt. Ist addr Null, so wird "???" ausgegeben.
|
|||
|
|
|||
|
(=)
|
|||
|
macht nichts, weil der 8986/88 Prozessor auch von ungeraden Adressen
|
|||
|
Befehle holen kann, im Gegensatz zum 68®ß6der. Diese Worte sind vor-
|
|||
|
handen, damit Sourcecode zwischen den Systemen transportabel ist.
|
|||
|
Querverweis: HALIGN .
|
|||
|
|
|||
|
=) 83
|
|||
|
|
|||
|
Wird in der Form FORGET (name) benutzt. Falls <name> in der Such-
|
|||
|
reihenfolge gefunden wird, so werden <name> und alle danach definierten
|
|||
|
Worte aus dem Dictionary entfernt. Wird <name> nicht gefunden, so wird
|
|||
|
eine Fehlerbehandlung eingeleitet. Liegt <name> in dem durch SAVE ge-
|
|||
|
schützten Bereich, so wird ebenfalls eine Fehlerbehandlung eingeleitet. Es
|
|||
|
wurden Vorkehrungen getroffen, die es ermöglichen, aktive Tasks und
|
|||
|
Vokabulare, die in der Suchreihenfolge auftreten, zu vergessen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Dietionary-Struktur = 1996 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
remove
|
|||
|
|
|||
|
(forget
|
|||
|
|
|||
|
( die sym thread -- dic sym )
|
|||
|
|
|||
|
Dies ist ein Wort, das zusammen mit CUSTOM-REMOVE verwendet wird.
|
|||
|
dic ist die untere Grenze des Dictionarybereiches, der vergessen werden
|
|||
|
soll und sym die obere. Typisch zeigt sym in den Heap. thread ist der
|
|||
|
Anfang einer Kette von Zeigern, die durch einen Zeiger mit dem Wert Null
|
|||
|
abgeschlossen wird. Wird REMOVE dann ausgeführt, so werden alle Zei-
|
|||
|
ger (durch Umhängen der übrigen Zeiger) aus der Liste entfernt, die in
|
|||
|
dem zu vergessenden Dictionarybereich liegen. Dadurch ist es möglich,
|
|||
|
FORGET und ähnliche Worte auf Datenstrukturen anzuwenden.
|
|||
|
|
|||
|
( addr -- ) "paren-forget"
|
|||
|
Entfernt alle Worte, deren Kompilationsadresse oberhalb von addr liegt,
|
|||
|
aus dem Dictionary und setzt HERE auf addr. Ein Fehler liegt vor, falls
|
|||
|
addr im Heap liegt.
|
|||
|
|
|||
|
custom-remove ( die symb -- dic symb )
|
|||
|
|
|||
|
save
|
|||
|
|
|||
|
empty
|
|||
|
|
|||
|
last
|
|||
|
|
|||
|
Ein deferred Wort, daß von FORGET, CLEAR usw. aufgerufen wird. dic
|
|||
|
ist die untere Grenze des Dictonaryteils, der vergessen wird und symb
|
|||
|
die obere. Gewöhnlich zeigt symb in den Heap. :
|
|||
|
Dieses Wort kann dazu benutzt werden, eigene Datenstrukturen, die Zeiger
|
|||
|
enthalten, bei FORGET korrekt abzuabrbeiten. Es wird vom Fileinterface
|
|||
|
verwendet, daher darf es nicht einfach überschrieben werden. Man kann
|
|||
|
es z.B. in folgender Form benutzen :
|
|||
|
|
|||
|
: (name) [ ' custom-remove body @ , ]
|
|||
|
“liststart) @ remove ;
|
|||
|
(name) Is custom-remove
|
|||
|
Auf diese Weise stellt man sicher, daß das Wort, das vorher in CUSTOM-
|
|||
|
REMOVE eingetragen war, weiterhin ausgeführt wird.
|
|||
|
Siehe auch REMOVE .
|
|||
|
|
|||
|
WE)
|
|||
|
Kopiert den Wert aller Uservariablen in den Speicherbereich ab ORIGIN
|
|||
|
und sichert alle Vokabularlisten. Wird später COLD ausgeführt, so be-
|
|||
|
findet sich das System im gleichen Speicherzustand wie bei Ausführung
|
|||
|
von SAVE.
|
|||
|
|
|||
|
==)
|
|||
|
Löscht alle Worte, die nach der letzten Ausführung von SAVE oder dem
|
|||
|
letzten Kaltstart definiert wurden. DP (und damit HERE )wird auf sei-
|
|||
|
nen Kaltstartwert gesetzt und der Heap gelöscht.
|
|||
|
|
|||
|
( -- addr )
|
|||
|
Variable, die auf das Countfeld des zuletzt definierten Wortes zeigt.
|
|||
|
Siehe auch RECURSIVE und MYSELF .
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 142 -
|
|||
|
|
|||
|
Dietionary-Struktur
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
hide
|
|||
|
|
|||
|
reveal
|
|||
|
|
|||
|
origin
|
|||
|
|
|||
|
name)
|
|||
|
|
|||
|
>body
|
|||
|
|
|||
|
>name
|
|||
|
|
|||
|
==)
|
|||
|
Entfernt das zuletzt definierte Wort aus der Liste des Vokabulars, in das
|
|||
|
es eingetragen wurde. Dadurch kann es nicht gefunden werden. Es ist
|
|||
|
aber noch im Speicher vorhanden. (s.a. REVEAL LAST )
|
|||
|
|
|||
|
( ==)
|
|||
|
Trägt das zuletzt definierte Wort in die Liste des Vokabulars ein, in dem
|
|||
|
es definiert wurde.
|
|||
|
|
|||
|
( -- addr )
|
|||
|
addr ist die Adresse, ab der die Kaltstartwerte der Uservariablen abge-
|
|||
|
speichert sind.
|
|||
|
|
|||
|
( addri -- addr2 ) "name-from"
|
|||
|
addr2 ist die Kompilationsadresse, die mit dem Countfeld im addrı
|
|||
|
korrespondiert.
|
|||
|
|
|||
|
( addri -- addr2 ) "to-body"
|
|||
|
addr2 ist die Parameterfeldadresse, die mit der Kompilationsadresse addrl
|
|||
|
korrespondiert.
|
|||
|
|
|||
|
( addrli -- addr2 ) "to-name"
|
|||
|
addr2 ist die Adresse eines Countfeldes, das mit der Kompilationsadresse
|
|||
|
addri korrespondiert. Es ist möglich, daß es mehrere addr2 für ein addri
|
|||
|
gibt. In diesem Fall ist nicht definiert, welche ausgewählt wird.
|
|||
|
|
|||
|
In der Literatur finden Sie für die Umrechnung von Feld-Adressen auch oftmals
|
|||
|
folgende Worte:
|
|||
|
|
|||
|
»link »)name 2- ;
|
|||
|
link> 2+ name) ;
|
|||
|
n>link a
|
|||
|
l>name 2+ 5;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Dicetionary-Struktur - 133 +
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
13. Der HEAP
|
|||
|
|
|||
|
Eines der ungewöhnlichen und fortschrittlichen Konzepte des volksFORTH83 besteht
|
|||
|
in der Möglichkeit, Namen von Worten zu entfernen, ohne den Rumpf zu vernichten
|
|||
|
(headerless words).
|
|||
|
|
|||
|
Das ist insbesondere während der Kompilation nützlich, denn Namen von Worten,
|
|||
|
deren Benutzung von der Tastatur aus nicht sinnvoll wäre, tauchen am Ende der
|
|||
|
Kompilation auch nicht mehr im Dictionary auf. Man kann dem Quelltext sofort an-
|
|||
|
sehen, ob ein Wort für den Gebrauch außerhalb des Programmes bestimmt ist oder
|
|||
|
nicht.
|
|||
|
|
|||
|
Die Namen, die entfernt wurden, verbrauchen natürlich keinen Speicherplatz mehr.
|
|||
|
Damit wird die Verwendung von mehr und längeren Namen und dadurch auch die
|
|||
|
Lesbarkeit gefördert.
|
|||
|
|
|||
|
Namen, die später eliminiert werden sollen, werden durch das Wort ı gekenn-
|
|||
|
zeichnet. Das Wort ; muß unmittelbar vor dem Wort stehen, däs den zu elimi-
|
|||
|
nierenden Namen erzeugt. Der so erzeugte Name wird in einem besonderen Spei-
|
|||
|
cherbereich, dem Heap, abgelegt. Der Heap kann später mit dem Wort CLEAR ge-
|
|||
|
löscht werden. Dann sind natürlich auch alle Namen, die sich im Heap befanden,
|
|||
|
verschwunden. Das folgende Beispiel soll eine Art Taschenrechner darstellen:
|
|||
|
|
|||
|
ı Variable sum 1 sum !
|
|||
|
|
|||
|
Es werden weitere Worte definiert und dann CLEAR ausgeführt:
|
|||
|
|
|||
|
: clearsum (--) ®sun!;
|
|||
|
: add (n--) sun +! ;
|
|||
|
: show (-—-) suın®@.;
|
|||
|
clear
|
|||
|
|
|||
|
Diese Definitionen liefern die Worte CLEARSUM ADD und SHOW , während der
|
|||
|
Name der Variablen SUM durch CLEAR entfernt wurde. Das Codefeld und der
|
|||
|
Wert 0001 existieren jedoch noch. Man kann den Heap auch dazu "mißbrauchen",
|
|||
|
Code, der nur zeitweilig benötigt wird, nachher wieder zu entfernen. Der Assembler ‘
|
|||
|
wird auf diese Art geladen, so daß er nach Fertigstellen der Applikation mit
|
|||
|
CLEAR wieder entfernt werden kann und keinen Platz im Speicher mehr benötigt.
|
|||
|
|
|||
|
Glossar
|
|||
|
|
|||
|
I (=) "headerless"
|
|||
|
setzt bei Ausführung ?HEAD so, daß der nächste erzeugte Name nicht
|
|||
|
im normalen Dictionaryspeicher angelegt wird, sondern auf dem Heap.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 144 - Der HEAP
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
clear ,
|
|||
|
löscht alle Namen und Worte im Heap, so daß vorher mit |! definierte
|
|||
|
Worte nicht mehr benutzt werden können. Auf diese Weise kann der Gel-
|
|||
|
tungsbereich von Prozeduren eingeschränkt werden.
|
|||
|
|
|||
|
heap ( -- addr )
|
|||
|
|
|||
|
Hier ist addr der Anfang des Heap. Er wird z.B. durch HALLOT geändert.
|
|||
|
hallot GN)
|
|||
|
|
|||
|
allokiert bzw. deallokiert n Bytes auf dem Heap. Dabei wird der Stack
|
|||
|
|
|||
|
verschoben, ebenso wie der Beginn des Heap.
|
|||
|
|
|||
|
heap? ( addr -- flag ) "heap-question"
|
|||
|
übergibt ein wahres Flag, wenn addr ein Byte im Heap adressiert, an-
|
|||
|
sonsten FALSE.
|
|||
|
|
|||
|
?head ( -- addr ) "question-head"
|
|||
|
ist eine Variable, die angibt, ob und wieviele der nächsten zu erzeugen-
|
|||
|
den Namen im Heap angelegt werden sollen.
|
|||
|
|
|||
|
Siehe auch }.
|
|||
|
|
|||
|
halign (--) "h-align"
|
|||
|
dient nur der Softwarekompatibilität zu den anderen volks4TH-Systemen,
|
|||
|
da der 8886-Prozessor nicht align-ed werden braucht.
|
|||
|
|
|||
|
Querverweis: ALIGN.
|
|||
|
Der HEAP - 145 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
14. Die Ausführung von FORTH-Worten
|
|||
|
|
|||
|
Der geringe Platzbedarf übersetzter FORTH-Worte rührt wesentlich von der Existenz
|
|||
|
des Adressinterpreters her.
|
|||
|
|
|||
|
Wie im Kapitel über die Dictionary-Struktur beschrieben, besteht eine :-Definition
|
|||
|
aus dem Codefeld und dem Parameterfeld. Im Parameterfeld steht eine Folge von
|
|||
|
Adressen. Ein Wort wird kompiliert, indem seine Kompilationsadresse dem Para-
|
|||
|
meterfeld der :-Definition angefügt wird. Eine Ausnahme bilden die Immediate-
|
|||
|
Worte. Da sie während der Kompilation ausgeführt werden, können sie dem Para-
|
|||
|
meterfeld der :-Definition alles mögliche hinzufügen. Daraus wird klar, daß die
|
|||
|
meisten Worte innerhalb der :-Definition nur eine Adresse, also in einem 16-Bit-
|
|||
|
System genau 2 Bytes an Platz verbrauchen. Wird die :-Definition nun aufgerufen,
|
|||
|
so sollen alle Worte, deren Kompilationsadresse im Parameterfeld stehen, ausgeführt
|
|||
|
werden. Das besorgt der Adressinterpreter.
|
|||
|
|
|||
|
14.1 Der Aufbau des Adressinterpreters
|
|||
|
|
|||
|
Beim volksFORTH83 benutzt der Adressinterpreter einige Register der CPU, die im
|
|||
|
Kapitel über den Assembler aufgeführt werden. Es gibt aber mindestens die folgen-
|
|||
|
den Register :
|
|||
|
|
|||
|
IP ist der Instruktionszeiger (Instructionpointer ). Er zeigt auf die
|
|||
|
nächste auszuführende Instruktion. Das ist beim volks-FORTH83 die
|
|||
|
Speicherzelle, die die Kompilationsadresse des nächsten
|
|||
|
auszuführenden Wortes enthält.
|
|||
|
|
|||
|
W ist das Wortregister. Es zeigt auf die Kompilationsadresse des
|
|||
|
Wortes, das gerade ausgeführt wird.
|
|||
|
|
|||
|
sP ist der (Daten-) Stackpointer. Er zeigt auf das oberste Element des
|
|||
|
Stacks.
|
|||
|
|
|||
|
RP ist der Returnstackpointer. Er zeigt auf das oberste Element des
|
|||
|
Returnstacks.
|
|||
|
|
|||
|
14.2 Die Funktion des Adressinterpreters
|
|||
|
|
|||
|
NEXT ist die Anfangsadresse der Routine, die die Instruktion ausführt, auf die IP
|
|||
|
gerade zeigt. Die Routine NEXT ist ein Teil des Adressinterpreters. Zur Verdeut-
|
|||
|
lichung der Arbeitsweise ist dieser Teil hier in High Level geschrieben:
|
|||
|
|
|||
|
Variable IP
|
|||
|
Variable W
|
|||
|
|
|||
|
: Next
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 146 = Die Ausführung von FORTH-Worten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
IPee vv!
|
|||
|
2 Ip +!
|
|||
|
W perforn ;
|
|||
|
|
|||
|
Tatsächlich ist NEXT jedoch eine Maschinencoderoutine, weil dadurch die Aus-
|
|||
|
führungszeit von FORTH-Worten erheblich kürzer wird. NEXT ist somit ein Makro,
|
|||
|
die diejenige Instruktion ausführt, auf die das Register IP zeigt.
|
|||
|
|
|||
|
Ein Wort wird ausgeführt, indem der Code, auf den die Kompilations-adresse zeigt,
|
|||
|
als Maschinencode angesprungen wird. Der Code kann z.B. den alten Inhalt des IP
|
|||
|
auf den Returnstack bringen, die Adresse des Parameterfeldes im IP speichern und
|
|||
|
dann NEXT anspringen. Diese Routine gibt es wirklich, sie heißt "docol" und ihre
|
|||
|
Adresse steht im Codefeld jeder :-Definition.
|
|||
|
|
|||
|
Das Gegenstück zu dieser Routine ist ein FORTH-Wort mit dem Namen EXIT.
|
|||
|
Dabei handelt es sich um ein Wort, das das oberste Element des Returnstacks in
|
|||
|
den IP bringt und anschließend NEXT anspringt. Damit ist dann die Ausführung
|
|||
|
der Colon-Definition beendet.
|
|||
|
|
|||
|
Beipiel :
|
|||
|
ı 2* dup + ;
|
|||
|
Son ZAHL;
|
|||
|
a.) Ein Aufruf von
|
|||
|
|
|||
|
Brenn
|
|||
|
von der Tastatur aus führt zu folgenden Situationen :
|
|||
|
|
|||
|
FTerFrT® Fr]
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
IP Stack/Returnstack
|
|||
|
b.) Nach der ersten Ausführung von NEXT bekommt man :
|
|||
|
2. docol 2% . exit 5 system
|
|||
|
addri Stack/Returnstack
|
|||
|
system
|
|||
|
| 2% docol dup + exit 5 addri
|
|||
|
IP Stack/Returnstack
|
|||
|
€) Nochmalige Ausführung von NEXT ergibt:
|
|||
|
|
|||
|
( DUP ist ein Wort vom Typ "Code")
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 147 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
d.)
|
|||
|
|
|||
|
e.)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5 system
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
docol dup + exit 5 addri
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
IP Stack/Returnstack
|
|||
|
|
|||
|
Nach der nächsten Ausführung von NEXT zeigt der IP auf EXIT
|
|||
|
und nach dem darauf folgenden NEXT wird addri wieder in den
|
|||
|
|
|||
|
|
|||
|
|
|||
|
| 2% | docol | 2*
|
|||
|
|
|||
|
IP geladen:
|
|||
|
[e®
|
|||
|
|
|||
|
a
|
|||
|
|
|||
|
IP Stack/Returnstack
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Die Ausführung von . erfolgt analog zu den Schritten b,c und d.
|
|||
|
Anschließend zeigt IP auf EXIT in 2..
|
|||
|
|
|||
|
Nach Ausführung von NEXT kehrt das System wieder in den Text-
|
|||
|
interpreter zurück. Dessen Rückkehradresse wird durch system ange-
|
|||
|
deutet. Damit ist die Ausführung von 2. beendet .
|
|||
|
|
|||
|
14.3 Verschiedene IMMEDIATE-Worte
|
|||
|
|
|||
|
In diesem Abschnitt werden Beispiele für immediate Worte angegeben, die mehr als
|
|||
|
nur eine Adresse kompilieren.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
a.) Zeichenketten (strings), die durch " abgeschlossen werden, liegen
|
|||
|
|
|||
|
als counted strings im Dictionary vor.
|
|||
|
Beispiel: abort" Test"
|
|||
|
liefert: I (ABORT" 1 04 ı Tieisiıti
|
|||
|
|
|||
|
bi. Einige Kontrollstrukturen kompilieren ?BRANCH oder DBRANCH „,
|
|||
|
|
|||
|
denen ein Offset mit 16 Bit Länge folgt.
|
|||
|
|
|||
|
Beispiel: 0< IF swap THEN
|
|||
|
|
|||
|
liefert: 1 0< 1 ?BRANCH | 4 } SWAP I
|
|||
|
|
|||
|
Beispiel: BEGIN ?dup WHILE @ REPEAT
|
|||
|
|
|||
|
liefert: 1 ?DUP I ?BRANCH | 8 ! @ } BRANCH } -10 |!
|
|||
|
|
|||
|
c.) Ebenso fügen DO und ?DO einen Offset hinter das von ihnen
|
|||
|
kompilierte Wort (DO bzw. (?DO . Mit dem Dekompiler können Sie
|
|||
|
sich eigene Beispiele anschauen.
|
|||
|
|
|||
|
4.) Zahlen werden in das Wort LIT , gefolgt von einem 16-Bit-Wert,
|
|||
|
kompiliert.
|
|||
|
|
|||
|
- 148 - Die Ausführung von FORTH-Worten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Beispiel: [Ü hex ] 8 1000
|
|||
|
liefert: I CLIT ıi $08 } LIT } $1000 |}
|
|||
|
|
|||
|
14.4 Die Does>-Struktur
|
|||
|
|
|||
|
Die Struktur von Worten, die mit CREATE .. DOES> erzeugt wurden, soll anhand
|
|||
|
eines Beispiels erläutert werden.
|
|||
|
|
|||
|
Das Beispielprogramm lautet:
|
|||
|
: Constant ( <name) -- )
|
|||
|
(nn)
|
|||
|
Create , Does) @ ;
|
|||
|
3 Constant drei
|
|||
|
|
|||
|
Der erzeugte Code sieht folgendermaßen aus:
|
|||
|
|
|||
|
L
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
CONSTANT docol | Create | : | (;code | jmp dodoes> | @ | exit|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Das Wort (;CODE wurde durch DOES> erzeugt. Es setzt das Codefeld des durch
|
|||
|
CREATE erzeugten Wortes DREI und beendet dann die Ausführung von
|
|||
|
CONSTANT . Das Codefeld von DREI zeigt anschließend auf jmp dodoes> . Wird
|
|||
|
DREI später aufgerufen , so wird der zugeordnete Code ausgeführt. Das ist in
|
|||
|
diesem Fall jmp dodoes) .
|
|||
|
|
|||
|
dodoes> legt nun die Adresse des Parameterfeldes von DREI auf den Stack und
|
|||
|
führt die auf jmp dodoes) folgende Sequenz von Worten aus. ( Man beachte die
|
|||
|
Ähnlichkeit zu :-Definitionen). Diese Sequenz besteht aus @ und EXIT.
|
|||
|
|
|||
|
Der Inhalt des Parameterfeldes von DREI wird damit auf den Stack gebracht. Der
|
|||
|
Aufruf von DREI liefert also tatsächlich 9993.
|
|||
|
|
|||
|
Statt des jmp dodoes)> und der Sequenz von FORTH-Worten kann sich hinter
|
|||
|
(;CODE auch ausschließlich Maschinencode befinden. Das ist der Fall, wenn wir das
|
|||
|
Wort ;CODE statt DOES> benutzt hätten. Wird diese Maschinencodesequenz
|
|||
|
später ausgeführt, so zeigt das W-Register des Adressinterpreters auf das Codefeld
|
|||
|
des Wortes, dem dieser Code zugeordnet ist. Erhöht man also das W-Register um 2,
|
|||
|
so zeigt es auf das Parameterfeld des gerade auszuführenden Wortes.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 49 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V, PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
state
|
|||
|
|
|||
|
>in
|
|||
|
|
|||
|
source
|
|||
|
|
|||
|
bIk
|
|||
|
|
|||
|
load
|
|||
|
|
|||
|
14.5 Glossar
|
|||
|
|
|||
|
( -- addr ) 83
|
|||
|
Eine Variable, die den gegenwärtigen Zustand enthält. Der Wert Null zeigt
|
|||
|
den interpretierenden Zustand an, ein von Null verschiedener Wert den
|
|||
|
kompilierenden Zustand.
|
|||
|
|
|||
|
( -- addr ) 83 "to-in"
|
|||
|
Eine Variable, die den Offset auf das gegenwärtige Zeichen im Quelltext
|
|||
|
enthält.
|
|||
|
Siehe auch WORD .
|
|||
|
|
|||
|
( -- addr +n )
|
|||
|
liefert Anfang addr und maximale Länge +n des Quelltextes.
|
|||
|
Ist BLK Null, beziehen sich Anfang und Länge auf den Text-eingabe-
|
|||
|
puffer, sonst auf den Block, dessen Nummer in BLK steht und der in
|
|||
|
den Rechnerspeicher kopiert wurde.
|
|||
|
Siehe auch BLOCK und >IN.
|
|||
|
|
|||
|
( -- addr ) 83 "b-1-k"
|
|||
|
Eine Variable, die die Nummer des gerade als Quelltext interpretierten
|
|||
|
Blockes enthält. Ist der Wert von BLK Null, so wird der Quelltext vom
|
|||
|
Texteingabepuffer genommen.
|
|||
|
|
|||
|
(n--) 83
|
|||
|
Die Inhalte von >IN und BLK , die den gegenwärtigen Quelltext an-
|
|||
|
geben, werden gespeichert. Der Block mit der Nummer n wird dann zum
|
|||
|
Quelltext gemacht. Der Block wird interpretiert. Die Interpretation wird
|
|||
|
bei Ende des Blocks abgebrochen, sofern das nicht explizit geschieht.
|
|||
|
Dann wird der alte Inhalt nach BLK und >IN zurückgebracht.
|
|||
|
Siehe auch BLK, >IN und BLOCK.
|
|||
|
|
|||
|
(==) 83,1 "paren"
|
|||
|
|
|||
|
(==) compiling
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
|
|||
|
( cce)
|
|||
|
Die Zeichen ccc, abgeschlossen durch ) , werden als Kommentar betrach-
|
|||
|
tet. Kommentare werden ignoriert. Das Leerzeichen zwischen ( und ccc
|
|||
|
ist nicht Teil des Kommentars. ( kann im interpretierenden oder kompi-
|
|||
|
lierenden Zustand benutzt werden. Fehlt ) , so werden alle Zeichen im
|
|||
|
Quelltext als Kommentar betrachtet.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Die Ausführung von FORTH-Worten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
\\
|
|||
|
|
|||
|
\needs
|
|||
|
|
|||
|
+load
|
|||
|
|
|||
|
thru
|
|||
|
|
|||
|
+thru
|
|||
|
|
|||
|
(=) I "skip-line"
|
|||
|
Wer) compiling
|
|||
|
Ignoriere den auf dieses Wort folgenden Text bis zum Ende der Zeile.
|
|||
|
Siehe auch C/L.
|
|||
|
|
|||
|
(--) T "skip-screen"
|
|||
|
(==) compiling
|
|||
|
Ignoriere den auf dieses Wort folgenden Text bis zum Ende des Blockes.
|
|||
|
Siehe auch B/BLK .
|
|||
|
|
|||
|
==) "skip-needs"
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
|
|||
|
\needs <name)
|
|||
|
Wird <name> in der Suchreihenfolge gefunden, so wird der auf <name>
|
|||
|
folgende Text bis zum Ende der Zeile ignoriert. Wird <name> nicht ge-
|
|||
|
funden, so wird die Interpretation hinter <name> fortgesetzt.
|
|||
|
|
|||
|
Beispiel: \needs Editor 1+ load
|
|||
|
lädt den folgenden Block, falls EDITOR im Dictionary nicht vorhanden ist.
|
|||
|
|
|||
|
Ab der Version 3.81.3 wurde das Konzept um have eingeführt, so daß
|
|||
|
die bedingte Kompilation so eingesetzt wird:
|
|||
|
have Editor not .IF 1+ load .THEN
|
|||
|
|
|||
|
In anderen Quellen finden Sie auch exists? .
|
|||
|
|
|||
|
( Muse) "plus-load"
|
|||
|
ladet den Block, dessen Nummer um n höher ist, als die Nummer des
|
|||
|
gegenwärtig interpretierten Blockes.
|
|||
|
|
|||
|
(nn --)
|
|||
|
ladet die Blöcke von nl bis inklusive n2.
|
|||
|
|
|||
|
(ni -—-) ! "plus-thru"
|
|||
|
ladet hintereinander die Blöcke, die nl..n2 vom gegenwärtigen Block ent-
|
|||
|
fernt sind.
|
|||
|
|
|||
|
Beispiel 1 2 +thru lädt die nächsten beiden Blöcke.
|
|||
|
|
|||
|
==) I "next-block"
|
|||
|
(--) compiling
|
|||
|
Setze die Interpretation auf dem nächsten Block fort.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
sr >
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
loadfile ( -- addr)
|
|||
|
addr ist die Adresse einer Variablen, die auf das FORTH-File zeigt, das
|
|||
|
gerade geladen wird. Diese Variable wird bei Aufruf von LOAD , THRU
|
|||
|
usw. auf das aktuelle File gesetzt.
|
|||
|
|
|||
|
bye —)
|
|||
|
Dieses Wort führt FLUSH und EMPTY aus. Anschließend wird der
|
|||
|
Monitor des Rechners angesprungen oder eine andere implementationsab-
|
|||
|
hängige Funktion ausgeführt. Der Befehl dient zum Verlassen des
|
|||
|
volksFORTH.
|
|||
|
|
|||
|
cold ==)
|
|||
|
Bewirkt den Kaltstart des Systems. Dabei werden alle nach der letzter
|
|||
|
Ausführung von SAVE definierten Worte entfernt, die Uservariablen auf
|
|||
|
den Wert gesetzt, den sie bei SAVE hatten, die Blockpuffer neu initiali-
|
|||
|
siert, der Bildschirm gelöscht und die Einschaltmeldung
|
|||
|
"volksFORTH-83 rev..."
|
|||
|
ausgegeben. Anschliessend wird RESTART ausgeführt.
|
|||
|
|
|||
|
restart G==)
|
|||
|
Bewirkt den Warmstart des Systems. Es setzt 'QUIT, ERRORHANDLER
|
|||
|
und "'ABORT auf ihre normalen Werte und führt ABORT aus.
|
|||
|
|
|||
|
interpret )
|
|||
|
Beginnt die Interpretation des Quelltextes bei dem Zeichen, das durch
|
|||
|
den Inhalt von )IN indiziert wird. >IN indiziert relativ zum Anfang
|
|||
|
des Blockes, dessen Nummer in BLK steht. Ist BLK gleich Null, so
|
|||
|
werden Zeichen aus dem Texteingabepuffer interpretiert.
|
|||
|
|
|||
|
Auch INTERPRET benötigte bisher zur Implementation einen sehr
|
|||
|
mysteriösen Systempatch. Dank einer Idee von Mike Perry ist auch diese
|
|||
|
letzte Ecke nun abgeschliffen:
|
|||
|
|
|||
|
Das deferred Wort PARSER enthält entweder den Code für den Inter-
|
|||
|
preter oder den Compiler (durch [ und |] wumzuschalten) und Interpret
|
|||
|
ist nun eine BEGIN...REPEAT Schleife, in der das nächste Wort aus dem
|
|||
|
Quelltext geholt wird. Ist der Quelltext erschöpft, so wird die Schleife
|
|||
|
verlassen, andernfalls wird PARSER aufgerufen und dadurch das Wort
|
|||
|
entweder interpretiert oder compiliert.
|
|||
|
|
|||
|
Nun ist es auch sehr viel einfacher als vorher, selber eigene Worte zu
|
|||
|
definieren, die in PARSER eingehängt werden. Dies ist immer dann
|
|||
|
sinnvoll, wenn der Interpreter in einem Anwendungsprogramm anders als
|
|||
|
der übliche FORTH-Interpreter arbeiten soll.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
>292 = Die Ausführung von FORTH-Worten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 93,81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
prompt
|
|||
|
|
|||
|
parser
|
|||
|
|
|||
|
word
|
|||
|
|
|||
|
parse
|
|||
|
|
|||
|
name
|
|||
|
|
|||
|
(ee)
|
|||
|
ist ein deferred Wort, das für die Ausgabe des "ok" verantwortlich ist. Es
|
|||
|
wurde auch das Wort (QUIT implementiert.
|
|||
|
Nun ist es möglich, den FÖRTH-Interpreter auch wie ein "klassisches"
|
|||
|
Betriebssystem arbeiten zu lassen, in dem eine Meldung nicht nach jeder
|
|||
|
Aktion hinter der Eingabezeile ausgegeben wird, sondern vor einer Aktion
|
|||
|
am Anfang der Eingabezeile. Ein entsprechendes Beispiel befindet sich im
|
|||
|
Quelltext hinter der Definition von QUIT.
|
|||
|
|
|||
|
siehe INTERPRET.
|
|||
|
|
|||
|
(char --»addr-) 83
|
|||
|
|
|||
|
erzeugt einen counted String durch Lesen von Zeichen vom Quelltext, bis
|
|||
|
dieser erschöpft ist oder der Delimiter char auftritt.
|
|||
|
|
|||
|
Der Quelltext wird nicht zerstört. Führende Delimiter werden ignoriert.
|
|||
|
Der gesamte String wird im Speicher beginnend ab Adresse addr als eine
|
|||
|
Sequenz von Bytes abgelegt. Das erste Byte enthält die Länge des Strings
|
|||
|
(8..255). Der String wird durch ein Leerzeichen beendet, das nicht in der
|
|||
|
Längenangabe enthalten ist. Ist der String länger als 255 Zeichen, so ist
|
|||
|
die Länge undefiniert. War der Quelltext schon erschöpft, als WORD
|
|||
|
aufgerufen wurde, so wird ein String der Länge Null erzeugt. Wird der
|
|||
|
Delimiter nicht im Quelltext gefunden, so ist der Wert von >IN die
|
|||
|
Länge des Quelltextes. Wird der Delimiter gefunden, so wird >IN so
|
|||
|
verändert, dass >IN das Zeichen hinter dem Delimiter indiziert. #TIB
|
|||
|
wird nicht verändert. Der String kann sich oberhalb von HERE
|
|||
|
befinden.
|
|||
|
|
|||
|
( char -- addr +n )
|
|||
|
liefert die Adresse addr und Länge +n des nächsten Strings im Quelltext,
|
|||
|
der durch den Delimiter char abgeschlossen wird.
|
|||
|
+n ist Null, falls der Quelltext erschöpft oder das erste Zeichen char
|
|||
|
ist. >IN wird verändert.
|
|||
|
|
|||
|
(„u adärz7)
|
|||
|
holt den nächsten String, der durch Leerzeichen eingeschlossen wird, aus
|
|||
|
dem Quelltext, wandelt ihn in Grossbuchstaben um und hinterlässt die
|
|||
|
Adresse addr, ab der der String im Speicher steht.
|
|||
|
Siehe auch WORD .
|
|||
|
|
|||
|
|
|||
|
|
|||
|
-ı189 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
find ( addrl -- addr?2 n ) 83
|
|||
|
addr]l ist die Adresse eines counted string. Der String enthält einen
|
|||
|
Namen, der in der aktuellen Suchreihenfolge gesucht wird.
|
|||
|
wird das Wort nicht gefunden, so ist addr2 = addrl und n = Null.
|
|||
|
Wird das Wort gefunden, so ist addr2 dessen Kompilations-adresse und n
|
|||
|
erfüllt folgende Bedingungen:
|
|||
|
n ist positiv, wenn das Wort immediate ist, sonst negativ.
|
|||
|
n ist vom Betrag 2 , falls das Wort restrict ist, sonst vom Betrag 1.
|
|||
|
notfound ( addr -- )
|
|||
|
Ein deferred Wort, das aufgerufen wird, wenn der Text aus dem Quelltext
|
|||
|
weder als Name in der Suchreihenfolge gefunden wurde, noch als Zahl
|
|||
|
interpretiert werden kann.
|
|||
|
Kann benutzt werden, um eigene Zahl- oder Stringeingabeformate zu er-
|
|||
|
kennen. Ist mit NO.EXTENSIONS vorbesetzt. Dieses Wort bricht die
|
|||
|
Interpretation des Quelltextes ab und druckt die Fehlermeldung "?" aus.
|
|||
|
quit ( >=) 83
|
|||
|
Entleert den Returnstack, schaltet den interpretierenden Zustand ein,
|
|||
|
akzeptiert Eingaben von der aktuellen Eingabeeinheit und beginnt die
|
|||
|
Interpretation des eingegebenen Textes.
|
|||
|
' ( -- addr ) 83 "tick"
|
|||
|
wird in der Form benutzt:
|
|||
|
' <name)>
|
|||
|
addr ist die Kompilationsadresse von <name)>. Wird <name> nicht in der
|
|||
|
Suchreihenfolge gefunden, so wird eine Fehlerbehandlung eingeleitet.
|
|||
|
vl ( -- addr ) 83,1,C "bracket-tick"
|
|||
|
=) compiling
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
['J] <name)
|
|||
|
Kompiliert die Kompilationsadresse von <name> als eine Konstante. Wenn
|
|||
|
die :-definition später ausgeführt wird, so wird addr auf den Stack ge-
|
|||
|
bracht. Ein Fehler tritt auf, wenn <name> in der Suchreihenfolge nicht
|
|||
|
gefunden wird.
|
|||
|
compile (ee) 83,C
|
|||
|
Typischerweise in der folgenden Art benutzt:
|
|||
|
: <name) ... compile (namex) ... ;
|
|||
|
Wird <name> ausgeführt, so wird die Kompilationsadresse von <namex>
|
|||
|
zum Dictionary hinzugefügt und nicht ausgeführt. Typisch ist <name>
|
|||
|
immediate und <namex> nicht immediate.
|
|||
|
- 154 - Die Ausführung von FORTH-Worten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 9,81
|
|||
|
|
|||
|
[compile]
|
|||
|
|
|||
|
immediate
|
|||
|
|
|||
|
— restrict
|
|||
|
|
|||
|
Literal
|
|||
|
|
|||
|
(=) 83,1.C "bracket-compile"
|
|||
|
ee compiling
|
|||
|
Wird in der folgenden Art benutzt:
|
|||
|
[compile) <name>
|
|||
|
Erzwingt die Kompilation des folgenden Wortes <name>. Damit ist die
|
|||
|
Kompilation ven immediate-Worten möglich.
|
|||
|
|
|||
|
(a) 83
|
|||
|
Markiert das zuletzt definierte Wort als "immediate", d.h. dieses Wort wird
|
|||
|
auch im kompilierenden Zustand ausgeführt.
|
|||
|
|
|||
|
(Fan
|
|||
|
Markiert das zuletzt definierte Wort als "restrict", d.h. dieses Wort kann
|
|||
|
nicht vom Textinterpreter interpretiert, sondern ausschließlich in anderen
|
|||
|
Worten kompiliert werden.
|
|||
|
|
|||
|
() 83,1 "left-bracket”
|
|||
|
(=) compiling
|
|||
|
Schaltet den interpretierenden Zustand ein. Der Quelltext wird sukzessive
|
|||
|
ausgeführt. Typische Benutzung siehe LITERAL .
|
|||
|
|
|||
|
Sa) 83,1 "right-bracket"
|
|||
|
) compiling
|
|||
|
Schaltet den kompilierenden Zustand ein. Der Text vom Quelltext wird.
|
|||
|
sukzessive kompiliert. Typische Benutzung siehe LITERAL .
|
|||
|
|
|||
|
( -- 16b ) 83,1,C
|
|||
|
|
|||
|
( 16b -- ) compiling
|
|||
|
Typisch in der folgenden Art benutzt:
|
|||
|
|
|||
|
[ 16b ] Literal :
|
|||
|
Kompiliert ein systemabhängiges Wort, so daß bei Ausführung 16b auf den
|
|||
|
Stack gebracht wird.
|
|||
|
|
|||
|
(--) "comma-quote"
|
|||
|
Speichert einen counted String im Dictionary ab HERE . Dabei wird die
|
|||
|
Länge des Strings in dessen erstem Byte, das nicht zur Länge hin-
|
|||
|
zugezählt wird, vermerkt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 199, —
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Ascii (-- char ) 1
|
|||
|
(a) compiling
|
|||
|
wird in der folgenden Art benutzt:
|
|||
|
Ascii ccc
|
|||
|
wobei cce durch ein Leerzeichen beendet wird. char ist der Wert des
|
|||
|
ersten Zeichens von ccce im benutzten Zeichensatz (gewöhnlich ASCI).
|
|||
|
Falls sich das System im kompilierenden Zustand befindet, so wird char
|
|||
|
als Konstante compiliert. Wird die :-definition später ausgeführt, so liegt
|
|||
|
char auf dem Stack.
|
|||
|
Does> ( -- addr ) 83,1,C "does"
|
|||
|
(-) compiling
|
|||
|
Definiert das Verhalten des Wortes, das durch ein definierendes Wort er-
|
|||
|
zeugt wurde. Wird in der folgenden Art benutzt:
|
|||
|
: <typ.name)
|
|||
|
<defining time action)
|
|||
|
<create) <compiletime action)
|
|||
|
Does) <runtime action) ;
|
|||
|
und später:
|
|||
|
<typ.name) <instance.name)>
|
|||
|
wobei <create> CREATE ist oder ein anderes Wort, das CREATE
|
|||
|
ausführt. Zeigt das Ende des Wort-erzeugenden Teils des definierenden
|
|||
|
Wortes an. Beginnt die Kompilation des Codes, der ausgeführt wird, wenn
|
|||
|
<instance.name> aufgerufen wird. In diesem Fall ist addr die Parameter-
|
|||
|
feldadresse von <name>. addr wird auf den Stack gebracht und die
|
|||
|
Sequenz zwischen DOES> und ; wird ausgeführt.
|
|||
|
:Does>
|
|||
|
wird benutzt in der Form:
|
|||
|
Create (name) :Does) ... ;
|
|||
|
Folgende Definition liegt im volks4TH :DOES> zugrunde:
|
|||
|
I: (does) here >r [compile] Does) ;
|
|||
|
:Does)> last @ 0= Abort" without reference"
|
|||
|
(does) current @ context ! hide 6] ;
|
|||
|
:DOES> legt das Laufzeit-Verhalten des zuletzt definierten Wortes durch
|
|||
|
den bis zum ; nachfolgenden Code fest. Das betreffende Wort wurde mit
|
|||
|
Create oder einem Create benutzenden Wort definiert. Eine Anwendung
|
|||
|
finden Sie bei den Datentypen.
|
|||
|
= 186 Die Ausführung von FORTH-Worten
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
recursive =) LC
|
|||
|
(e=) compiling
|
|||
|
Erlaubt die rekursive Kompilation des gerade definierten Wortes in diesem
|
|||
|
Wort selbst. Ferner kann Code für Fehlerkontrolle erzeugt werden.
|
|||
|
Siehe auch MYSELF und RECURSE .
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
15. Der Assembler
|
|||
|
|
|||
|
Für das volksFORTH stehen zwei Assembler zur Verfügung:
|
|||
|
- Ein Assembler entsprechend dem Laxen&Perry F83
|
|||
|
- und der eigentliche volks4TH-Assembler.
|
|||
|
|
|||
|
15.1 Registerbelegung
|
|||
|
|
|||
|
Im Assembler sind FORTH-gemäße Namen für die Register gewählt worden. Dabei ist
|
|||
|
die Zuordnung zu den Intel-Namen folgendermassen:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
A- <=> AL
|
|||
|
A <=) AX
|
|||
|
|
|||
|
At <=> AH
|
|||
|
|
|||
|
C- <=) CL
|
|||
|
C <=> CcX
|
|||
|
|
|||
|
C+ <=> CH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Register A und C sind zur allgemeinen Benutzung frei.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
D- <=) DL
|
|||
|
D <=> DX
|
|||
|
|
|||
|
|
|||
|
|
|||
|
D+ <=> DH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Das D Register enthält das oberste Element des (Daten)-Stacks.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
R- <=> RL
|
|||
|
R <=> BX
|
|||
|
|
|||
|
|
|||
|
|
|||
|
R+ <=> RH
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Das B Register hält den Return_stack_pointer
|
|||
|
|
|||
|
Die weiteren Prozessor-Register werden wie folgt genutzt:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
“ja Der Assembler
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
U <=) BP User_area_pointer
|
|||
|
|
|||
|
S <=) SP Daten_stack_pointer
|
|||
|
|
|||
|
I <=) SI Instruction_pointer
|
|||
|
|
|||
|
W<«=> DI Word_pointer, im allgemeinen zur Benutzung frei.
|
|||
|
|
|||
|
D: <=} DS E: <=) ES S: <=) SS ©: <=) CS
|
|||
|
|
|||
|
Alle Segmentregister werden beim Booten auf den Wert des Codesegments C: gesetzt
|
|||
|
und muessen, wenn sie "verstellt" werden, wieder auf C: zurueckgesetzt werden.
|
|||
|
|
|||
|
Assemblerdefinitione werden in FORTH mit code eingeleitet und mit der Sequenz
|
|||
|
|
|||
|
Next end-code beendet:
|
|||
|
|
|||
|
Code sp! { addr -- ) DS mov D pop Next end-code
|
|||
|
|
|||
|
15.2 Registeroperationen
|
|||
|
|
|||
|
Returnstack
|
|||
|
|
|||
|
Code rp@ ( -- addr) Dpush RDmov Next end-code
|
|||
|
Code rp! ( addr -- } DR mov D pop Next end-code
|
|||
|
|
|||
|
Code rdrop Rine Rüince Next end-code restrict
|
|||
|
|
|||
|
Code ?>r (16b --) Rdec Rdec DR) mov D pop
|
|||
|
Next end-code restrict
|
|||
|
|
|||
|
Code rv (--16b) Dpush R)Dmov Rince Rinc
|
|||
|
Next end-code restrict
|
|||
|
|
|||
|
Code r@ ( -- 16b ) D push R) Dmov Next end-code
|
|||
|
|
|||
|
Code execute ( acf -- ) DW mov D pop
|
|||
|
W) jmp end-code
|
|||
|
|
|||
|
Code perform ( addr --) DW mov D pop
|
|||
|
W)Wmov W) jmp end-code
|
|||
|
|
|||
|
\ : perforn (addr --) ® execute ;
|
|||
|
Segmentregister
|
|||
|
|
|||
|
Code ds@ ( -- ddr) Dpush D:Dmov Next end-code
|
|||
|
|
|||
|
15.3 Besonderheiten im volksFORTH83
|
|||
|
|
|||
|
Nachfolgend sind einige interesante Besonderheiten beschrieben:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Assembler
|
|||
|
|
|||
|
FORTH-Geselischaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NEXT ist ein Makro, sog. in-line code; wenn NEXT kompiliert wird, werden die
|
|||
|
in NEXT enthaltenen Mnemnonics in die Definition eingetragen:
|
|||
|
Assembler also definitions
|
|||
|
|
|||
|
: Next lods AW xchg W) jmp
|
|||
|
there tnext-link @ T , H tnext-link ! ;
|
|||
|
|
|||
|
Das Wort EI hinterläßt durch here die Adresse von NEXT auf dem Stack. Diese
|
|||
|
Adresse wird in das Codefeld von NOOP geschrieben, so daß ein explizites NEXT
|
|||
|
unnötig wird.
|
|||
|
|
|||
|
t Code ei sti here Next end-code
|
|||
|
|
|||
|
Code noop here 2- ! end-code
|
|||
|
|
|||
|
Create recover Assembler
|
|||
|
Rdec Rdec IR) mov Ipop Next
|
|||
|
end-code
|
|||
|
|
|||
|
RECOVER soll nie ausgeführt werden, nur die Adresse dieser Routine ist für den
|
|||
|
TargetCompiler von Interesse:
|
|||
|
|
|||
|
se 6 T recover # call ] end-code H ;
|
|||
|
|
|||
|
In ähnlicher Form findet sich dann die endgültige Form von ;c: für das Target-
|
|||
|
System wieder:
|
|||
|
|
|||
|
ı ca recover # call last off end-code ® ] ;
|
|||
|
|
|||
|
15.4 Glossar
|
|||
|
|
|||
|
assembler ee)
|
|||
|
ist das Vokabular, das die Assembler-Worte enthält. Die Ausführung
|
|||
|
dieses Wortes nimmt ASSEMBLER als context in die Suchreihenfolge
|
|||
|
mit auf.
|
|||
|
|
|||
|
code <name> (==)
|
|||
|
leitet eine Assembler-Definiton ein und schaltet die Suchreihenfolge auf
|
|||
|
das Vokabular Assembler .
|
|||
|
Als Beispiel:
|
|||
|
Code sp® ( -- addr ) D push S D mov Next end-code
|
|||
|
|
|||
|
end-code We
|
|||
|
beendet eine Assembler-Definition.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 169 - Der Assembler
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V, PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Label <name> (ie)
|
|||
|
( -- addr )
|
|||
|
legt eine benannte Marke an und liefert eine Adresse zurück:
|
|||
|
|
|||
|
Code exit
|
|||
|
Label exit R)Imov Rince Rinc Next end-code
|
|||
|
|
|||
|
Code unnest exit here 2- ! end-code
|
|||
|
Code ?exit ( flag -- )
|
|||
|
|
|||
|
DDor D pop exit 0= ?] [Ü Next end-code
|
|||
|
Code Ö=exit ( flag -- )
|
|||
|
|
|||
|
DDor Dpop dexit 6= not ?] }] end-code
|
|||
|
|
|||
|
\: exit ( flag -- ) IF rärop THEN ;
|
|||
|
|
|||
|
»label <name> (=)
|
|||
|
( -- addr )
|
|||
|
kann als temporäre Konstante betrachtet werden, die sich mit clear
|
|||
|
löschen läßt. Ein von >label zurückgelieferter Wert wird als Literal
|
|||
|
|
|||
|
kompiliert.
|
|||
|
Beispiel: Assembler ö
|
|||
|
nop 5555 # jnp here 2- »label >cold
|
|||
|
nop 5555 # jmp here 2- >label >restart
|
|||
|
code, (==)
|
|||
|
|
|||
|
beendet den high level Teil eines defining words und leitet dessen
|
|||
|
Assembler-Teil ein. Wird benutzt in der Form:
|
|||
|
: (name) <Create) ... ;code ... end-code
|
|||
|
|
|||
|
‚c ==)
|
|||
|
leitet den high level Teil einer Assembler-Definition ein. Das Wort wird
|
|||
|
typisch im Handhaben einer Fehlersituation eingesetzt, da dann
|
|||
|
Geschwindigkeit keine Rolle mehr spielt. Als Beispiel:
|
|||
|
|
|||
|
I : stackfull ( -- ) depth $20 > Abort" tight stack"
|
|||
|
reveal last? IF dup heap? IF name) ELSE 4- THEN
|
|||
|
(forget
|
|||
|
THEN
|
|||
|
|
|||
|
true Abort" dictionary full" ;
|
|||
|
|
|||
|
Code ?stack u'dpUD) Amov SAsub CS
|
|||
|
?[ $100 # A add CS ?[ ;c: stack£full ; Assembler ]? ]?
|
|||
|
u'soUD) Amov Ainc Ainc SA sub
|
|||
|
CS not ?[ Next ])? ;c: true Abort" stack empty" ;
|
|||
|
|
|||
|
\: ?stack sp® here - $100 u< IF. stackfull THEN
|
|||
|
\ sp@ sO @ u> Abort" stack empty" ;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Assembler 1b.»
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
15.5 Kontrollstrukturen im Assembler
|
|||
|
|
|||
|
benutzt in der Form, wobei ce ein condition code ist:
|
|||
|
cc IF ... THEN
|
|||
|
Als Beispiel:
|
|||
|
Code dup ( 16b -- 16b 16b ) D push Next end-code
|
|||
|
Code ?dup ( 16b -- 16b 16b / false )
|
|||
|
DDor 0= not ?[ D push ]? Next end-code
|
|||
|
|
|||
|
a
|
|||
|
benutzt in der Form:
|
|||
|
cc IF ... ELSE ... THEN
|
|||
|
|
|||
|
benutzt in der Form:
|
|||
|
BEGIN ... REPEAT
|
|||
|
Als Beispiel:
|
|||
|
|
|||
|
Code 1+ (nl -- n2) [E Diünc Next
|
|||
|
Code 2+ (nl --n2) [ÜE Diänc swap ])
|
|||
|
Code 3+ (nl -- n2) [Ü Dinc .swap ]]
|
|||
|
Code 4+ (nl --n2) [E Diäine swap ]]
|
|||
|
I Code 6+ (nl -- n2) Dince Dinc 1] end-code
|
|||
|
|
|||
|
Code 1- (nl -- n2) [Ü Dodec Next
|
|||
|
Code 2- (nl -- n2) [Ü Ddec swap ]]
|
|||
|
|
|||
|
II ce ]]?
|
|||
|
benutzt in der Form:
|
|||
|
BEGIN ... cc UNTIL
|
|||
|
|
|||
|
I ce? 1%
|
|||
|
benutzt in der Form:
|
|||
|
BEGIN ... cc WHILE ... REPEAT
|
|||
|
|
|||
|
15.6 Beispiele aus dem volksFORTH
|
|||
|
|
|||
|
pop
|
|||
|
Code ärop {16b6-) D pop Next end-code
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=.162* Der Assembler
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaf:
|
|||
|
|
|||
|
t e.V,
|
|||
|
|
|||
|
PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Code ! (1
|
|||
|
Next
|
|||
|
|
|||
|
Code +!
|
|||
|
DW mov
|
|||
|
|
|||
|
6b addr -- )
|
|||
|
end-code
|
|||
|
|
|||
|
{ 16b addr --
|
|||
|
|
|||
|
A pop AW) add D pop Next
|
|||
|
|
|||
|
D W nov
|
|||
|
|
|||
|
)
|
|||
|
|
|||
|
push
|
|||
|
|
|||
|
Code 2dup ( 32b -- 32b 32b )
|
|||
|
|
|||
|
SW mov
|
|||
|
|
|||
|
Dpush W)
|
|||
|
|
|||
|
push Next
|
|||
|
|
|||
|
\ : 2dup ( 32b -- 32b 32b ) over over ;
|
|||
|
|
|||
|
Code over
|
|||
|
AD xchg
|
|||
|
|
|||
|
Code@ (a
|
|||
|
Next
|
|||
|
|
|||
|
Code c@ (
|
|||
|
DW mov
|
|||
|
|
|||
|
Code c! (
|
|||
|
DW mov
|
|||
|
|
|||
|
Code £flip
|
|||
|
|
|||
|
\ &_ £flin
|
|||
|
|
|||
|
Code negate
|
|||
|
\ : negate
|
|||
|
|
|||
|
Code and
|
|||
|
A pop
|
|||
|
|
|||
|
Code or
|
|||
|
A pop
|
|||
|
|
|||
|
Code ctoggl
|
|||
|
DW mov
|
|||
|
|
|||
|
( 16b1 16b2 -- 16b1 16b2 16bi )
|
|||
|
D pop D push
|
|||
|
|
|||
|
ddr -- 16b )
|
|||
|
end-code
|
|||
|
|
|||
|
addr -- &b )
|
|||
|
W) D- mov
|
|||
|
|
|||
|
16b addr -- )
|
|||
|
Apop A-W
|
|||
|
|
|||
|
{ 16b1 -- 16b1'
|
|||
|
|
|||
|
DW nov
|
|||
|
|
|||
|
mov
|
|||
|
|
|||
|
0 # D+ mov Next
|
|||
|
|
|||
|
) mov D pop
|
|||
|
|
|||
|
xchg
|
|||
|
) D- D+ xchg
|
|||
|
|
|||
|
( 16b1 -- 16b1' ) $100 um* or
|
|||
|
|
|||
|
(nl --n2)
|
|||
|
{nl --n2)
|
|||
|
( 16b1 16b2 --
|
|||
|
|
|||
|
AD and Next
|
|||
|
|
|||
|
( 16b1 16b2 --
|
|||
|
ADor Next
|
|||
|
( 16b1 16b2 --
|
|||
|
|
|||
|
neg
|
|||
|
|
|||
|
Dneg Next
|
|||
|
not 1+ ;
|
|||
|
|
|||
|
and
|
|||
|
|
|||
|
16b3 )
|
|||
|
end-code
|
|||
|
|
|||
|
or
|
|||
|
|
|||
|
16b3 )
|
|||
|
end-code
|
|||
|
|
|||
|
16b3 ) not swap not and not
|
|||
|
|
|||
|
xor
|
|||
|
|
|||
|
e (8b adär -- )
|
|||
|
|
|||
|
A pop A-W
|
|||
|
|
|||
|
) xor D pop
|
|||
|
|
|||
|
W) pop
|
|||
|
|
|||
|
end-code
|
|||
|
|
|||
|
A push Next
|
|||
|
|
|||
|
W) Dmov
|
|||
|
|
|||
|
end-code
|
|||
|
|
|||
|
end-code
|
|||
|
|
|||
|
end-code
|
|||
|
|
|||
|
r
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Assembler
|
|||
|
|
|||
|
= 1637 =
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V,
|
|||
|
|
|||
|
Code xeor
|
|||
|
|
|||
|
( 16b1 16b2 -- 1653
|
|||
|
A pop
|
|||
|
|
|||
|
ADxor Next
|
|||
|
|
|||
|
\ : etoggle ( 8b addr -- )
|
|||
|
|
|||
|
under c@ xor swap c!
|
|||
|
|
|||
|
PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
)
|
|||
|
|
|||
|
end-code
|
|||
|
|
|||
|
add
|
|||
|
Code + (n1in2 --n3) Apop AD add Next end-code
|
|||
|
sub
|
|||
|
Code - (nin2--n3)
|
|||
|
Apopp DAsub AD xchg Next end-code
|
|||
|
ar» {1m 13] negate + ;
|
|||
|
com
|
|||
|
Code not ( 16bl -- 16b2 ) D com Next end-code
|
|||
|
inc
|
|||
|
Code nip ( 16bl 16b2 -- 16b2 ) Sine Since Next end-code
|
|||
|
\:nip swap drop ; 5
|
|||
|
Code 2drop ( 32b -- ) S inc Sine Dpop Next end-code
|
|||
|
\ : 2drop ( 32b -- ) drop drop ;
|
|||
|
sal
|
|||
|
Code pick (n-- 16b.n )
|
|||
|
Dsall DWmov SWadd W) Dmov Next end-code
|
|||
|
\ : pick (n-- 16b.n ) 1+ 2% sp@ +@;
|
|||
|
std rep byte movs cld
|
|||
|
Code roll (n--)
|
|||
|
AIxcho Dsal DCmov DImov SIadd
|
|||
|
I)Dmov IWmov Idec Winc std
|
|||
|
rep byte movs cld A I xchg S inc S$S inc Next
|
|||
|
end-code u
|
|||
|
\: 261 - (nn =)
|
|||
|
\ dup >r pick sp@ dup 2+ r) 1+ 2* cmove> drop ;
|
|||
|
Code -roll (n -- ) Alxchog Dsal DC mov
|
|||
|
SW mov D pop S I mov $ dec S dec
|
|||
|
rep byte movs DW) mov D pop A I xchg Next
|
|||
|
end-code
|
|||
|
\.:-roll (n-- ) >r dup sp@ dup 2+
|
|||
|
\ dup 2+ swap r@ 2* cmove r) 1+ 2* + ! ;
|
|||
|
- 164 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Assembler
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
16. Der Multitasker
|
|||
|
|
|||
|
Ein wichtiger Aspekt der FORTH-Programmierung ist das Multitasking.
|
|||
|
|
|||
|
So wie man ein Programm in einzelne, unabhängige Module oder Worte aufteilt, so
|
|||
|
sollte man es auch in einzelne, unabhängige Prozesse aufteilen können. Das ist in
|
|||
|
den meisten Sprachen nicht möglich.
|
|||
|
|
|||
|
Das volksFORTH83 besitzt einen einfachen, aber leistungsfähigen Multitasker. Er
|
|||
|
ermöglicht die Konstruktion von Druckerspoolern, Uhren, Zählern und anderen
|
|||
|
einfachen Tasks, kann aber auch für Aufgaben eingesetzt werden, die über einen
|
|||
|
Druckerspooler hinausgehen.
|
|||
|
Als Beispiel soll gezeigt werden, wie man einen einfachen Druckerspooler kon-
|
|||
|
struiert. Das Programm für einen Druckerspooler lautet:
|
|||
|
|
|||
|
$FO $100 Task background
|
|||
|
|
|||
|
: spool background activate 1 160 pthru stop ;
|
|||
|
multitask spool
|
|||
|
|
|||
|
Normalerweise würde PTHRU den Rechner "lahmlegen", bis die Screens von 1 bis
|
|||
|
100 ausgedruckt worden sind. Bei Aufruf von SPOOL ist das nicht so; der Rech-
|
|||
|
ner kann sofort weitere Eingaben verarbeiten. Damit alles richtig funktioniert,
|
|||
|
|
|||
|
muß PTHRU allerdings einige Voraussetzungen erfüllen, die dieses Kapitel er-
|
|||
|
klären will.
|
|||
|
|
|||
|
Das Wort TASK ist ein definierendes Wort, das eine Task erzeugt. Eine Task be-
|
|||
|
sitzt übrigens Userarea, Stack, Returnstack und Dictionary unabhängig von der sog.
|
|||
|
Konsolen- oder Main-Task.
|
|||
|
|
|||
|
Im Beispiel ist $FO die Länge des reservierten Speicherbereichs für Returnstack und
|
|||
|
Userarea, $100 die Länge für Stack und Dictionary, jeweils in Bytes. Der Name der
|
|||
|
Task ist.in diesem Fall BACKGROUND .
|
|||
|
|
|||
|
MULTITASK sagt. dem Rechner,:.daß in Zukunft womöglich noch andere Tasks außer
|
|||
|
der Konsolentask auszuführen sind. Es schaltet also den Taskwechsler ein. Bei
|
|||
|
Ausführen von SINGLETASK wird der Taskwechsler ‚abgeschaltet. Dann wird nur
|
|||
|
noch die gerade aktive Task ausgeführt.
|
|||
|
|
|||
|
Der neue Task tut nichts, bis sie aufgeweckt wird. Das geschieht durch das Wort
|
|||
|
SPOOL .. Bei Ausführung von SPOOL geschieht. nun folgendes:
|
|||
|
|
|||
|
Die Task BACKGROUND wird aufgeweckt und ihr wird der Code hinter ACTIVATE
|
|||
|
(nämlich 1 100 PTHRU STOP ) zur Ausführung übergeben. Damit ist die Ausführung
|
|||
|
von SPOOL beendet, es können jetzt andere Worte eingetippt werden. Die Task
|
|||
|
jedoch führt unverdrossen 1 100 PTHRU aus, bis sie damit fertig ist. Dann stößt
|
|||
|
‚sie auf STOP und hält, an. Man sagt, die Task schläft. Will man die’ Task
|
|||
|
während des Druckvorganges anhalten, z.B. um Papier nachzufüllen, so tippt man
|
|||
|
BACKGROUND SLEEP ein. Dann wird BACKGROUND vom Taskwechsler übergangen.
|
|||
|
Soll es weitergehen. so tippt man BACKGROUND WAKE ein.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Multitasker - 165 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Häufig möchte man erst bei Aufruf von SPOOL den Bereich als Argument angeben,
|
|||
|
der ausgedruckt werden soll. Das geht wie folgt:
|
|||
|
|
|||
|
: newspool ( from to -- ) 2 background pass pthru stop ;
|
|||
|
|
|||
|
Die Phrase 2 BACKGROUND PASS funktioniert ähnlich wie BACKGROUND ACTIVATE ,
|
|||
|
jedoch werden der Task auf dem Stack zusätzlich die beiden obersten Werte ( hier
|
|||
|
from und to ) übergeben. Um die Screens 1 bis 188 auszudrucken, tippt man jetzt
|
|||
|
ein:
|
|||
|
|
|||
|
1 100 newspool
|
|||
|
|
|||
|
Somit entspricht BACKGROUND ACTIVATE gerade der Phrase ® BACKGROUND PASS .
|
|||
|
|
|||
|
16.1 Implementation
|
|||
|
|
|||
|
Der Unterschied dieses Multitaskers zu herkömmlichen liegt in seiner kooperativen
|
|||
|
Struktur begründet. Damit ist gemeint, daß jede Task explizit die Kontrolle über
|
|||
|
den Rechner und die Ein/Ausgabegeräte aufgeben und damit für andere Tasks ver-
|
|||
|
fügbar machen muß. Jede Task kann aber selbst "wählen", wann das geschieht. Es
|
|||
|
ist klar, daß das oft genug geschehen muß, damit alle Tasks. ihre Aufgaben
|
|||
|
wahrnehmen können.
|
|||
|
|
|||
|
Die Kontrolle über den Rechner wird durch das Wort PAUSE aufgegeben. PAUSE
|
|||
|
führt den Code aus, der den gegenwärtigen Zustand der gerade aktiven Task rettet
|
|||
|
und die Kontrolle des Rechners an den Taskwechsler übergibt. Der Zustand einer
|
|||
|
Task besteht aus den Werten des Interpreterpointers (IP) , des Returnstackpointers
|
|||
|
(RP) und des Stackpointers (SP).
|
|||
|
|
|||
|
Der Taskwechsler besteht aus einer geschlossenen Schleife. Jede Task enthält einen
|
|||
|
Maschinencodesprung auf die nächste Task, gefolgt von der Aufweckprozedur. Dort
|
|||
|
befindet sich die entsprechende Instruktion der nächsten Task. Ist die Task ge-
|
|||
|
stoppt, so wird dort ebenfalls ein Maschinencodesprung zur nächsten Task ausge-
|
|||
|
führt. Ist die Task dagegen aktiv, so ist der Sprung durch einen 1-Byte Call auf
|
|||
|
einen Vektor ersetzt worden, der die Aufweckprozedur auslöst. Diese Prozedur lädt
|
|||
|
den Zustand der Task (bestehend aus SP RP und IP} und setzt den Userpointer
|
|||
|
(UP), so daß er auf diese Task zeigt.
|
|||
|
|
|||
|
SINGLETASK ändert nun PAUSE so, daß überhaupt kein Taskwechsel stattfindet,
|
|||
|
wenn PAUSE aufgerufen wird. Das ist in dem Fall sinnvoll, wenn nur eine Task
|
|||
|
existiert, nämlich die Konsolentask, die beim Kaltstart des Systems "erzeugt"
|
|||
|
wurde. Dann würde PAUSE unnötig Zeit damit verbrauchen, einen Taskwechsel
|
|||
|
auszuführen, der sowieso wieder auf dieselbe Task führt.
|
|||
|
|
|||
|
Das System unterstützt den Multitasker, indem es während vieler Ein/Ausgabe-
|
|||
|
operationen wie KEY, TYPE und BLOCK usw. PAUSE ausführt. Häufig reicht
|
|||
|
das schon aus, damit eine Task (z.B. der Druckerspooler) gleichmäßig arbeitet.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 166 - Der Multitasker
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Tasks werden im ‚Dictionary der Konsolentask erzeugt. Jede besitzt ihre eigene
|
|||
|
Userarea mit: einer Kopie der Uservariablen. Die Implementation des Systems wird
|
|||
|
aber durch die Einschränkung vereinfacht, daß nur die Konsolentask Eingabetext
|
|||
|
interpretieren bzw. kompilieren kann. Es gibt z.B. nur eine Suchreihenfolge, die im
|
|||
|
|
|||
|
Prinzip für alle Tasks gilt. Da aber nur die Konsolentask von ihr Gebrauch macht,
|
|||
|
ist das nicht weiter störend.
|
|||
|
|
|||
|
Der Multitasker beim volksFORTH ist gegenüber z.B. dem des polyFORTH verein-
|
|||
|
facht, da volksFORTH ist kein Multiuser-System ist. So besitzen alle Terminal-Ein-
|
|||
|
heiten (wir nennen sie Tasks) gemeinsam nur ein Lexikon und einen Eingabepuffer.
|
|||
|
Es darf daher nur der OPERATOR (wir nennen ihn Main- oder Konsolen-Task)
|
|||
|
kompilieren.
|
|||
|
|
|||
|
Es ist übrigens möglich, aktive Tasks mit FORGET usw. zu vergessen. Das ist
|
|||
|
eine Eigenschaft, die nicht viele Systeme aufweisen! Allerdings geht das manchmal
|
|||
|
auch schief... Nämlich dann, wenn die vergessene Task einen "Semaphor" (s.u.)
|
|||
|
besaß. Der wird beim Vergessen nämlich nicht freigegeben und damit ist das zuge-
|
|||
|
hörige Gerät blockiert.
|
|||
|
|
|||
|
Schließlich sollte man noch erwähnen, daß beim Ausführen eines Tasknamens der
|
|||
|
Beginn der Userarea dieser Task auf dem Stack hinterlassen wird.
|
|||
|
|
|||
|
16.2 Semaphore und Lock
|
|||
|
|
|||
|
Ein Problem, daß bisher noch nicht erwähnt wurde, ist die Frage, was passiert,
|
|||
|
wenn zwei Tasks gleichzeitig drucken (oder Daten von der Diskette lesen) wollen?
|
|||
|
|
|||
|
Es ist klar: Um ein Durcheinander oder Fehler zu vermeiden, darf das immer nur
|
|||
|
eine Task zur Zeit. Programmtechnisch wird das Problem durch "Semaphore" gelöst:
|
|||
|
|
|||
|
Variable disp disp off
|
|||
|
: newtype disp lock type disp unlock ;
|
|||
|
|
|||
|
Der Effekt ist der folgende: Wenn zwei Tasks gleichzeitig NEWTYPE ausführen, so
|
|||
|
kann doch nur eine zur Zeit TYPE ausführen, unabhängig davon, wie viele
|
|||
|
PAUSE in TYPE enthalten sind. Die Phrase DISP LOCK schaltet nämlich hinter
|
|||
|
der ersten Task, die sie ausführt, die "Ampel auf rot" und läßt keine andere Task
|
|||
|
durch. Die anderen machen solange PAUSE ,„, bis die erste Task die Ampel mit
|
|||
|
DISP UNLOCK wieder auf grün umschaltet. Dann kann eine (!) andere Task die
|
|||
|
Ampel hinter sich umschalten usw. .
|
|||
|
|
|||
|
Übrigens wird die Task, die die Ampel auf rot schaltete, bei DISP LOCK nicht
|
|||
|
aufgehalten, sondern durchgelassen. Das ist notwendig, da ja TYPE ebenfalls
|
|||
|
|
|||
|
DISP LOCK enthalten könnte (Im obigen Beispiel natürlich nicht, aber es ist
|
|||
|
denkbar).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Multitasker = 187 +
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3,81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Die Implementation sieht nun folgendermaßen aus, wobei man sich noch vor Augen
|
|||
|
halten muß, daß jede Task eindeutig durch den Anfang ihrer Userarea identifizier-
|
|||
|
bar ist:
|
|||
|
|
|||
|
DISP ist ein sog. Semaphor; er muß den Anfangswert ® haben!
|
|||
|
|
|||
|
LOCK schaut sich nun den Semaphor an: Ist er Null, so wird die gerade
|
|||
|
aktive Task (bzw. der Anfang ihrer Userarea) in den Semaphor ein-
|
|||
|
getragen und die Task darf weitermarschieren.
|
|||
|
|
|||
|
Ist der Wert des Semaphors gerade die aktive Task, so darf sie natürlich auch
|
|||
|
weiter. Wenn aber der Wert des Semaphors von dem Anfang der Userarea der akti-
|
|||
|
ven Task abweicht, dann ist gerade eine andere Task hinter der Ampel aktiv und
|
|||
|
die Task muß solange PAUSE machen, bis die Ampel wieder grün, d.h. der
|
|||
|
Semaphor null ist. UNLOCK muß nun nichts anderes mehr tun, als den Wert des
|
|||
|
Semaphors wieder auf Null setzen. BLOCK und BUFFER sind übrigens auf diese
|
|||
|
Weise für die Benutzung durch mehrere Tasks gesichert: Es kann immer nur eine
|
|||
|
Task das Laden von Blöcken von der Diskette veranlassen.
|
|||
|
|
|||
|
Eine Bemerkung bzgl. BLOCK und anderer Dinge: °
|
|||
|
|
|||
|
Wie man dem Glossar entnehmen kann, ist immer nur die Adresse des zuletzt mit
|
|||
|
BLOCK oder BUFFER angeforderten Blockpuffers gültig, d.h. ältere Blöcke sind, je
|
|||
|
nach der Zahl der Blockpuffer, womöglich schon wieder auf die Diskette ausgelagert
|
|||
|
worden.
|
|||
|
|
|||
|
Auf der sicheren Seite liegt man, wenn man sich vorstellt, daß nur ein Blockpuffer
|
|||
|
im gesamten System existiert. Nun kann jede Task BLOCK ausführen und damit
|
|||
|
anderen Tasks die Blöcke "unter den Füßen" wegnehmen. Daher sollte man nicht die
|
|||
|
Adresse eines Blocks nach einem Wort, das PAUSE ausführt, weiter benutzen,
|
|||
|
sondern lieber neu mit BLOCK anfordern.
|
|||
|
|
|||
|
Das Beispiel
|
|||
|
‚line ( block -- )
|
|||
|
block c/l bounds DO I c@ emit LOOP ;
|
|||
|
ist falsch, denn nach EMIT stimmt der Adressbereich, den der Schleifenindex
|
|||
|
überstreicht, womöglich gar nicht mehr.
|
|||
|
|
|||
|
.line ( block -- )
|
|||
|
c/l1 0 DO dup block I + c®@ emit LOOP drop ;
|
|||
|
|
|||
|
ist richtig, denn es wird nur die Nummer des Blocks, nicht die Adresse seines
|
|||
|
Puffers aufbewahrt.
|
|||
|
|
|||
|
x .line ( block -- ) block c/l type ;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 168 - Der Multitasker
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ist falsch, da TYPE ja EMIT wiederholt ausführen kann und scemit die von
|
|||
|
BLOCK gelieferte Adresse in TYPE ungültig wird.
|
|||
|
|
|||
|
: >type ( addr len -- ) pad place pad count type ;
|
|||
|
|
|||
|
ist multitasking-sicher, wenn ein String vom BLOCK geholt wird.
|
|||
|
.line ( block -- ) block c/l >type ;
|
|||
|
|
|||
|
ist deshalb richtig, denn PAD ist für jeden Task verschieden.
|
|||
|
|
|||
|
16.3 Glossar
|
|||
|
|
|||
|
activate ( Taddr -- ) -tasker.scr-
|
|||
|
aktiviert die Task, die durch Taddr gekennzeichnet ist, und weckt sie
|
|||
|
auf.
|
|||
|
Vergleiche SLEEP , STOP, PASS, PAUSE, UP@, UP! und WAKE.
|
|||
|
|
|||
|
lock ( semaddr -- ) -kernel.scr-
|
|||
|
Der Semaphor (eine VARIABLE ), dessen Adresse auf dem Stack liegt,
|
|||
|
wird von der Task, die LOCK ausführt, blockiert.
|
|||
|
Dazu prüft LOCK den Inhalt des Semaphors. Zeigt der Inhalt an, daß
|
|||
|
eine andere Task den Semaphor blockiert hat, so wird PAUSE ausge-
|
|||
|
führt, bis der Semaphor freigegeben ist. Ist der Semaphor freigegeben, so
|
|||
|
schreibt LOCK das Kennzeichen der Task, die LOCK ausführt, in den
|
|||
|
Semaphor und sperrt ihn damit für alle anderen Tasks. Den FORTH-Code
|
|||
|
zwischen semaddr LOCK ... und ... semadär UNLOCK kann also immer nur
|
|||
|
eine Task zur Zeit ausführen.
|
|||
|
Semaphore schützen gemeinsame Ressourcen (z.B. den Drucker) vor dem
|
|||
|
gleichzeitigen Zugriff durch verschiedene Tasks.
|
|||
|
Vergleiche UNLOCK und RENDEZVOUS .
|
|||
|
|
|||
|
multitask O-=1) -tasker.scr-
|
|||
|
schaltet das Multitasking ein.
|
|||
|
Das Wort PAUSE ist dann keine NOOP-Funktion mehr, sondern gibt die
|
|||
|
Kontrolle über die FORTH-Maschine an eine andere Task weiter.
|
|||
|
|
|||
|
pass {n®.. nr-1 Taddr r -- ) -tasker.scr-
|
|||
|
|
|||
|
aktiviert die Task, die durch Taddr gekennzeichnet ist, und weckt sie
|
|||
|
auf. r gibt die Anzahl der Parameter n® bis nr-1 an, die vom Stack der
|
|||
|
PASS ausführenden Task auf den Stack der durch Taddr
|
|||
|
gekennzeichneten Task übergeben werden. Die Parameter n® bis nr-1
|
|||
|
stehen dieser Task dann in der gleichen Reihenfolge auf ihrem Stack zur
|
|||
|
weiteren Verarbeitung zur Verfügung.
|
|||
|
|
|||
|
Vergleiche ACTIVATE .
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Multitasker = 18891 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
pause 35) -kernel.ser-
|
|||
|
ist eine NOOP-Funktion, wenn der Singletask-Betrieb eingeschaltet ist;
|
|||
|
bewirkt jedoch, nach Ausführung von MULTITASK , daß die Task, die
|
|||
|
PAUSE ausführt, die Kontrolle über die FORTH-Maschine an eine andere
|
|||
|
Task abgibt.
|
|||
|
Existiert nur eine Task, oder schlafen alle anderen Tasks, so wird die
|
|||
|
Kontrolle unverzüglich an die Task zurückgegeben, die PAUSE aus-
|
|||
|
führte. Ist mindestens eine andere Task aktiv, so wird die Kontrolle von
|
|||
|
dieser übernommen und erst bei Ausführung von PAUSE oder STOP in
|
|||
|
dieser Task an eine andere Task weitergegeben. Da die Tasks ringförmig
|
|||
|
miteinander verkettet sind, erhält die Task, die zuerst PAUSE aus-
|
|||
|
führte, irgendwann die Kontrolle zurück. Eine Fehlerbedingung liegt vor,
|
|||
|
wenn eine Task weder PAUSE noch STOP ausführt.
|
|||
|
Vergleiche STOP , MULTITASK und SINGLETASK .
|
|||
|
|
|||
|
rendezvous ( semaddr -- ) -tasker.scr-
|
|||
|
gibt den Semaphor (die VARIABLE ) mit der Adresse semaddr frei (siehe
|
|||
|
UNLOCK ) und führt PAUSE aus, um anderen Tasks den Zugriff auf
|
|||
|
das, durch diesen Semaphor geschützte, Gerät zu ermöglichen. Anschlie-
|
|||
|
ßend wird LOCK ausgeführt, um das Gerät zurück zu erhalten. Dies ist
|
|||
|
eine Methode, eine zweite Task nur an einer genau benannten Stelle lau-
|
|||
|
fen zu lassen.
|
|||
|
|
|||
|
singletask (==) -tasker.scr-
|
|||
|
schaltet das Multitasking aus.
|
|||
|
PAUSE ist nach Ausführung von SINGLETASK eine NOOP-Funktion.
|
|||
|
Eine Fehlerbedingung besteht, wenn eine Hintergrund-Task SINGLETASK
|
|||
|
ohne anschließendes MULTITASK ausführt, da die Main- oder Terminal-
|
|||
|
Task dann nie mehr die Kontrolle bekommt.
|
|||
|
Vergleiche UP@ und UP!.
|
|||
|
|
|||
|
sleep ( Taddr -- ) -tasker.ser-
|
|||
|
|
|||
|
bringt die Task, die durch Taddr gekennzeichnet ist, zum Schlafen.
|
|||
|
|
|||
|
SLEEP hat den gleichen Effekt, wie die Ausführung von STOP durch
|
|||
|
die Task selbst. Der Unterschied ist, daß STOP in der Regel am Ende
|
|||
|
des Jobs der Task ausgeführt wird. SLEEP trifft die Task zu einem nicht
|
|||
|
vorhersehbaren Zeitpunkt, so daß die laufende Arbeit der Task abgebro-
|
|||
|
chen wird.
|
|||
|
|
|||
|
Vergleiche WAKE .
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Multitasker
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
stop
|
|||
|
|
|||
|
Task
|
|||
|
|
|||
|
unlock
|
|||
|
|
|||
|
==) -tasker.scr-
|
|||
|
bewirkt, daß die Task, die STOP ausführt, sich schlafen legt.
|
|||
|
Wichtige Zeiger der FORTH-Maschine, die den Zustand der Task kenn-
|
|||
|
zeichnen, werden gerettet, dann wird die Kontrolle an die nächste Task
|
|||
|
abgegeben, deren Zeiger wieder der FORTH-Maschine übergeben werden, so
|
|||
|
daß diese Task ihre Arbeit an der alten Stelle aufnehmen kann. PAUSE
|
|||
|
führt diese Aktionen ebenfalls aus, der Unterschied zu STOP ist, daß
|
|||
|
die ausführende Task bei PAUSE aktiv, bei STOP hingegen schlafend
|
|||
|
hinterlassen wird.
|
|||
|
Vergleiche PAUSE , WAKE und SLEEP.
|
|||
|
|
|||
|
( rlen slen <name> -- ) -tasker.scr-
|
|||
|
ist ein definierendes Wort, das in der Form:
|
|||
|
|
|||
|
rlen slen Task (name)
|
|||
|
benutzt wird. TASK erzeugt einen Arbeitsbereich für einen weiteren
|
|||
|
Job, der gleichzeitig zu schon laufenden Jobs ausgeführt werden soll.
|
|||
|
Die Task erhält den Namen <name>, hat einen Stack-Bereich der Länge
|
|||
|
slen und einen Returnstack-Bereich der Länge rlen.
|
|||
|
Im Stack Bereich liegen das Task-eigene Dictionary einschließlich PAD,
|
|||
|
das in Richtung zu höheren Adressen wächst, und der Daten-Stack, der
|
|||
|
zu niedrigen Adressen wächst. Im Returnstack-Bereich befinden sich die
|
|||
|
Task-eigene USER-Area (wächst zu höheren Adressen) und der Return-
|
|||
|
stack, der gegen kleinere Adressen wächst.
|
|||
|
Eine Task ist ein verkleinertes Abbild des FORTH-Systems, allerdings
|
|||
|
ohne den Blockpuffer-Bereich, der von allen Tasks gemeinsam benutzt
|
|||
|
wird.
|
|||
|
Zur Zeit ist es nicht zugelassen, daß Jobs einer Hintergrundtask kompi-
|
|||
|
lieren. Die Task ist nur der Arbeitsbereich für einen Hintergrund-Job,
|
|||
|
nicht jedoch der Job selbst.
|
|||
|
Die Ausführung von <name> in einer beliebigen Task hinterläßt die
|
|||
|
gleiche Adresse, die die Task “name selbst mit UP@ erzeugt und ist
|
|||
|
zugleich die typische Adresse, die von LOCK „, UNLOCK und
|
|||
|
RENDEZVOUS im Zusammenhang mit Semaphoren verwendet wird, bzw. von
|
|||
|
ACTIVATE , PASS , SLEEP und WAKE erwartet wird.
|
|||
|
|
|||
|
( semaddr -- ) -kernel.scr-
|
|||
|
gibt den Semaphor (die VARIABLE ), dessen Adresse auf dem Stack ist,
|
|||
|
für alle Tasks frei. Ist der Semaphor im Besitz einer anderen Task, so
|
|||
|
wartet UNLOCK mit PAUSE auf die Freigabe. Vergleiche LOCK und die
|
|||
|
Beschreibung des Taskers.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Multitasker = 17 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
up@
|
|||
|
|
|||
|
up!
|
|||
|
|
|||
|
wake
|
|||
|
|
|||
|
User
|
|||
|
|
|||
|
forge
|
|||
|
|
|||
|
t
|
|||
|
|
|||
|
( -- Taddr ) -kernel.scer- "u-p-fetch"
|
|||
|
liefert die Adresse Taddr des ersten Bytes der USER-Area der Task, die
|
|||
|
UP@ ausführt (siehe TASK ). In der USER-Area sind Variablen und
|
|||
|
andere Datenstrukturen hinterlegt, die jede Task für sich haben muß.
|
|||
|
Vergleiche UP! .
|
|||
|
|
|||
|
(addr -- ) -kernel.ser- "uU-p-store"
|
|||
|
richtet den UP (User Pointer) der FORTH-Maschine auf addr.
|
|||
|
Vorsicht ist bei der Verwendung von UP! in Hintergrund-Tasks geboten.
|
|||
|
Vergleiche UP@.
|
|||
|
|
|||
|
( Taddr -- ) -kernel.scr-
|
|||
|
weckt die Task, die durch Taddr gekennzeichnet ist, auf.
|
|||
|
Die Task führt ihren Job dort weiter aus, wo sie durch SLEEP angehal-
|
|||
|
ten wurde oder wo sie sich selbst durch STOP beendet hat (Vorsicht!).
|
|||
|
Vergleiche SLEEP , STOP, ACTIVATE und PASS.
|
|||
|
|
|||
|
) 83
|
|||
|
ist ein definierendes Wort, benutzt in der Form:
|
|||
|
|
|||
|
User <name> ;
|
|||
|
USER erzeugt einen Kopf für <name> im Dictionary und hält 2 Byte in
|
|||
|
der Userarea frei (siehe UALLOT).
|
|||
|
Diese 2 Byte werden für den Inhalt der Uservariablen benutzt und werden
|
|||
|
nicht initialisiert. Im Parameterfeld der Uservariablen im Dictionary wird
|
|||
|
nur ein Offset zum Beginn der Userarea abgelegt. Wird <name> ausgeführt,
|
|||
|
so wird die Adresse des Wertes der Uservariablen in der Userarea auf
|
|||
|
den Stack gegeben. Uservariablen werden statt normaler Variablen z.B.
|
|||
|
dann benutzt, wenn der Einsatz des Multitaskers geplant ist und mindes-
|
|||
|
tens eine Task die Variable unbeeinflußt von anderen Tasks benötigt
|
|||
|
(Jede Task hat ihre eigene Userarea).
|
|||
|
|
|||
|
(--) 83
|
|||
|
Wird in folgender Form benutzt:
|
|||
|
|
|||
|
FORGET <name)>
|
|||
|
Falls <name> in der Suchreihenfolge gefunden wird, so werden <name>
|
|||
|
und alle danach definierten Worte aus dem Dictionary entfernt. Wird
|
|||
|
<name> nicht gefunden, so wird eine Fehlerbehandlung eingeleitet. Liegt
|
|||
|
<name> in dem durch SAVE geschützten Bereich, so wird ebenfalls eine
|
|||
|
Fehlerbehandlung eingeleitet. Es wurden Vorkehrungen getroffen, die es
|
|||
|
ermöglichen. aktive Tasks und Vokabulare, die in der Suchreihenfolge
|
|||
|
auftreten, zu vergessen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Multitasker
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
block (u-- addr ) 83
|
|||
|
addr ist die Adresse des ersten Bytes des Blocks u in dessen Blockpuffer.
|
|||
|
Der Block u stammt aus dem File in ISFILE.
|
|||
|
BLOCK prüft den Pufferbereich auf die Existenz des Blocks Nummer u,
|
|||
|
Befindet sich der Block u in keinem der Blockpuffer, so wird er vom
|
|||
|
Massenspeicher in einen an ihn vergebenen Blockpuffer geladen. Falls der
|
|||
|
Block in diesem Puffer als UPDATEd markiert ist, wird er auf den Mas-
|
|||
|
senspeicher gesichert, bevor der Blockpuffer an den Block u vergeben
|
|||
|
wird. Nur die Daten im letzten Puffer, der über BLOCK oder BUFFER
|
|||
|
angesprochen wurde, sind sicher zugreifbar. Alle anderen Blockpuffer
|
|||
|
dürfen nicht mehr als gültig angenommen werden (möglicherweise exi-
|
|||
|
stiert nur 1 Blockpuffer).
|
|||
|
Vorsicht ist bei Benutzung des Multitaskers geboten, da eine andere Task
|
|||
|
BLOCK oder BUFFER ausführen kann. Der Inhalt eines Blockpuffers
|
|||
|
wird nur auf den Massenspeicher gesichert, wenn der Block mit UPDATE
|
|||
|
als verändert gekennzeichnet wurde.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Der Multitasker . . = 379,2
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
17. Debugging-Techniken
|
|||
|
|
|||
|
Fehlersuche ist in allen Programmiersprachen die aufwendigste Aufgabe des Pro-
|
|||
|
grammierers.
|
|||
|
|
|||
|
Für verschiedene Programme sind in der Regel auch verschiedene Hilfsmittel erfor-
|
|||
|
derlich. Daher kann dieses Kapitel die Fehler-suche nicht erschöpfend behandeln.
|
|||
|
Da aber Anfänger häufig typische Fehler machen, kann man gerade für diese
|
|||
|
Gruppe brauchbare Hilfsmittel angeben.
|
|||
|
|
|||
|
Voraussetzung für die Fehlersuche ist immer ein übersichtliches und verständliches
|
|||
|
Programm. In FORTH bedeutet das:
|
|||
|
|
|||
|
_ suggestive und prägnante Namen für Worte
|
|||
|
|
|||
|
sn starke Faktorisierung, d.h. sinnvoll zusammengehörende Teile eines
|
|||
|
Wortes sind zu einem eigenen Wort zusammengefaßt. Worte sollten
|
|||
|
durchschnittlich nicht mehr als 2 - 3 Zeilen lang sein !
|
|||
|
|
|||
|
- Übergabe von Parametern auf dem Stack statt in Variablen, wo
|
|||
|
immer es möglich ist.
|
|||
|
|
|||
|
Guter Stil in FORTH ist nicht schwer, erleichtert aber sehr die Fehlersuche. Ein
|
|||
|
Buch, das auch diesen Aspekt behandelt, sei unbedingt empfohlen : "In FORTH
|
|||
|
denken" von Leo Brodie, Hanser Verlag 1986.
|
|||
|
|
|||
|
Sind die genannten Bedingungen erfüllt, ist es meist möglich, die Worte interaktiv
|
|||
|
zu testen. Damit ist gemeint, daß man bestimmte Parameter auf den Stack legt und
|
|||
|
anschließend das zu testende Wort aufruft. Anhand der hinterlassenen Werte auf
|
|||
|
dem Stack kann man dann beurteilen, ob das Wort korrekt arbeitet.
|
|||
|
|
|||
|
Sinnvollerweise testet man natürlich die zuerst definierten Worte auch zuerst, denn
|
|||
|
ein Wort, das fehlerhafte Worte aufruft, funktioniert natürlich nicht korrekt. Wenn
|
|||
|
nun ein Wort auf diese Weise als fehlerhaft identifiziert wurde, muß man das Ge-
|
|||
|
schehen innerhalb des Wortes verfolgen. Das geschieht meist durch "tracen".
|
|||
|
|
|||
|
17.1 Der Tracer
|
|||
|
|
|||
|
Allgemein wird man zuerst das fehlerhafte Wort isoliert testen wollen. Dazu legt
|
|||
|
man ausgewählte Werte als Parameter für dieses Wort auf den Stack und beobachtet
|
|||
|
die Verarbeitung dieser Werte innerhablb des Wortes.
|
|||
|
|
|||
|
Angenommen, Sie wollen das Wort -TRAILING auf Fehler untersuchen. Die
|
|||
|
Funktion dieses Wortes ist das "Abschneiden" von Leerzeichen am Ende einer Zei-
|
|||
|
chenkette:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 174 = Debugging-Techniken
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Geseilschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
: -trailing ( addri nl -- addri n2 )
|
|||
|
|
|||
|
2dup bounds ?DO 2dup + 1- c@ bl =
|
|||
|
|
|||
|
IF leave THEN 1- LOOP ;
|
|||
|
Dabei könnten Sie dem Wort schon im Editor ein anderes Erscheinungsbild geben,
|
|||
|
indem Sie z.B. die Schleifenanweisungen ?DO und LOOP bündig untereinander
|
|||
|
schreiben, durch das Einfügen von Leerzeichen eine Gliederung schaffen oder die
|
|||
|
IF... THEN-Anweisung auf einer eigenen Zeile isolieren.
|
|||
|
|
|||
|
Zum Testen des Wortes wird ein String benötigt. Sie definieren bitte:
|
|||
|
Create teststring ,‚" Dies ist ein Test E
|
|||
|
|
|||
|
Dabei haben Sie absichtlich einige zusätzliche Leerzeichen eingefügt.
|
|||
|
|
|||
|
Um die Werte auf dem Stack, meist Adressen, besser interpretieren zu können,
|
|||
|
schalten Sie mit HEX die Zahlenbasis um und geben nun ein (Antwort des
|
|||
|
Computers unterstrichen) :
|
|||
|
|
|||
|
hex ok
|
|||
|
teststring .s 8686 ok
|
|||
|
count .s 1B 8687 ok
|
|||
|
|
|||
|
-trailing .s 1B 8687 ok
|
|||
|
|
|||
|
Der Aufruf von TESTSTRING liefert Ihnen die Stringadresse (hexadezimal) 8686 und
|
|||
|
das Wort COUNT berechnet Ihnen daraus die Länge der Zeichenkette und ihren
|
|||
|
Beginn.: 1B 8687 (auch hexadezimal)
|
|||
|
|
|||
|
Beim Aufruf von -TRAILING stellen Sie an Hand der unveränderten Adressen zu
|
|||
|
|
|||
|
Ihrem Erstaunen fest, daß -TRAILING kein einziges Leerzeichen abgeschnitten
|
|||
|
hat.
|
|||
|
|
|||
|
Spätestens jetzt sollten Sie am Rechner sitzen und den Tracer laden, wenn er noch
|
|||
|
nicht im System vorhanden ist. Prüfen Sie dazu, ob es das Wort TOOLS im
|
|||
|
FORTH-Vokabular gibt, dann ist der Tracer vorhanden. Denn der Tracer gehört zum
|
|||
|
Vokabular Tools , dessen Quelltexte Sie auf Ihrer Diskette finden.
|
|||
|
|
|||
|
Mit dem Tracer können Sie Worte, die mit dem : definiert wurden, schrittweise
|
|||
|
testen. Der Tracer läßt sich mit dem Wort TRACE starten, das seinerseits ein zu
|
|||
|
tracendes FORTH-Wort erwartet. TRACE schaltet im Gegensatz zu DEBUG nach
|
|||
|
Durchlauf des Wortes den Tracer automatisch mit END-TRACE wieder ab.
|
|||
|
|
|||
|
Um den Tracer zu benutzen, geben Sie nun folgendes ein:
|
|||
|
|
|||
|
teststring count
|
|||
|
.S. „IB 8687 ok
|
|||
|
tools trace -trailing
|
|||
|
|
|||
|
Es erscheint dieses Bild. wenn Sie nach dem Erscheinen einer jeden Zeile solange
|
|||
|
die <CR>Taste drücken, bis wieder ok erscheint:
|
|||
|
|
|||
|
8658 66A 2DUP 1B 8687
|
|||
|
865A AB2 BOUNDS 1B 8687 1B 8687
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Debugging-Techniken = a5 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V.
|
|||
|
|
|||
|
PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
865C A8O
|
|||
|
8660 66A
|
|||
|
8662 6E2
|
|||
|
8664 789
|
|||
|
8666 469
|
|||
|
8668 2224
|
|||
|
866A 91B
|
|||
|
866C B34
|
|||
|
8610 CFB
|
|||
|
8678 AOD
|
|||
|
|
|||
|
(?DO
|
|||
|
2DUP
|
|||
|
|
|||
|
+
|
|||
|
|
|||
|
1-
|
|||
|
|
|||
|
ce®
|
|||
|
|
|||
|
BL
|
|||
|
?BRANCH
|
|||
|
|
|||
|
LEAVE
|
|||
|
UNNEST
|
|||
|
|
|||
|
8687 86A2 1B 8687
|
|||
|
|
|||
|
1B 8687
|
|||
|
|
|||
|
1B 8687 1B 8687
|
|||
|
86A2 1B 8687
|
|||
|
86Al 1B 8687
|
|||
|
20 1B 8687
|
|||
|
|
|||
|
20 20 1B 8687
|
|||
|
|
|||
|
FFFF 1B 8687
|
|||
|
|
|||
|
1B 8687
|
|||
|
1B 8687
|
|||
|
|
|||
|
Betrachten Sie zuerst die Syntax von TRACE :
|
|||
|
|
|||
|
trace <(nanel)>
|
|||
|
|
|||
|
Hierbei ist <namel> das zu tracende Wort, wobei die vom Tracer zurückgelieferte
|
|||
|
Information so aussieht:
|
|||
|
|
|||
|
addri addr2 <name2)
|
|||
|
|
|||
|
addri
|
|||
|
|
|||
|
addr2
|
|||
|
<name2?>
|
|||
|
Werte
|
|||
|
|
|||
|
Werte
|
|||
|
|
|||
|
ist eine Adresse im Parameterfeld von <namel>, nämlich die, in der
|
|||
|
|
|||
|
addr2 steht.
|
|||
|
|
|||
|
ist die KompilationsAdresse von <name2).
|
|||
|
ist das Wort, das als nächstes ausgeführt werden soll !
|
|||
|
sind die Werte, die gerade auf dem Stack liegen.
|
|||
|
|
|||
|
Wie deuten Sie nun das eben erhaltene Bild ? In der ersten Zeile, die der Tracer
|
|||
|
beim Abarbeiten des zu untersuchenden Wortes
|
|||
|
|
|||
|
Sie:
|
|||
|
|
|||
|
8658 66A 2DUP
|
|||
|
|
|||
|
1B 8687
|
|||
|
|
|||
|
Hier ist 1B 8687 der Stackinhalt, wie er von
|
|||
|
nämlich Adresse und Länge des Strings TESTSTRING. Natürlich können die Zahlen
|
|||
|
|
|||
|
bei Ihnen anders aussehen,
|
|||
|
|
|||
|
kompiliert wurde.
|
|||
|
|
|||
|
66A ist die Kompilationsadresse von
|
|||
|
Auch diese Adressen können sich bei Ihnen geändert haben! Diese
|
|||
|
so daß auch im Falle mehrerer Worte mit gleichem
|
|||
|
|
|||
|
-TRAILING .
|
|||
|
Zahlen werden mit ausgegeben,
|
|||
|
|
|||
|
Namen eine Identifizierung möglich ist.
|
|||
|
|
|||
|
je nachdem, wohin
|
|||
|
|
|||
|
2DUP ,
|
|||
|
|
|||
|
-TRAILING angezeigt hat, finden
|
|||
|
|
|||
|
TESTSTRING COUNT geliefert wurde,
|
|||
|
|
|||
|
TESTSTRING und -TRAILING
|
|||
|
|
|||
|
8658 die Position von 2DUP in
|
|||
|
|
|||
|
Sehen wir uns die Ausgabe nun etwas genauer an.
|
|||
|
Bei den ersten beiden Zeilen wächst der Wert ganz links immer um 2. Es ist der
|
|||
|
Inhalt des Instructionpointers IP, der immer auf die nächste auszuführende Adresse
|
|||
|
zeigt. Der Inhalt dieser Adresse ist jeweils eine Kompilationsadresse 66A bei 2DUP
|
|||
|
usw.. Jede Kompilationsadresse benötigt zwei Bytes, daher muß der IP immer um 2
|
|||
|
|
|||
|
erhöht werden.
|
|||
|
|
|||
|
Immer? Nein, denn schon die nächste Zeile zeigt eine Ausnahme.
|
|||
|
|
|||
|
Das Wort
|
|||
|
|
|||
|
(?DO
|
|||
|
|
|||
|
finition von
|
|||
|
|
|||
|
-TRAILING
|
|||
|
|
|||
|
erhöht den IP um 4
|
|||
|
|
|||
|
stand doch nur
|
|||
|
|
|||
|
(?DO
|
|||
|
|
|||
|
! Woher kommt eigentlich (?DO , in der De-
|
|||
|
DO .
|
|||
|
|
|||
|
ist ein von ?DO kompi-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Debugging-Techniken
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
liertes Wort, das zusätzlich zur Kompilationsadresse noch einen l6Bit-Wert be-
|
|||
|
nötigt, nämlich für den Sprungoffset hinter LOOP , wenn die Schleife beendet ist.
|
|||
|
Zwei ähnliche Fälle treten noch auf. Das IF aus dem Quelltext hat ein ?BRANCH
|
|||
|
kompiliert. Es wird gesprungen, wenn der oberste Stackwert FALSE (=) ist. Auch
|
|||
|
?BRANCH benötigt einen zusätzlichen 16Bit-Wert für den Sprungoffset.
|
|||
|
|
|||
|
Nach LEAVE geht es hinter LOOP weiter, es wird UNNEST ausgeführt, das
|
|||
|
vom ; in -TRAILING kompiliert wurde und das gleiche wie EXIT bewirkt.
|
|||
|
Damit ist das Wort -TRAILING auch beendet. Das hier gelistete Wort UNNEST
|
|||
|
ist nicht zu verwechseln mit dem UNNEST des Tracers, siehe unten.m
|
|||
|
|
|||
|
Wo liegt nun der Fehler in unserer Definition von -TRAILING ?
|
|||
|
|
|||
|
Bevor Sie weiterlesen, sollten Sie die Fehlerbeschreibung, den Tracelauf und Ihre
|
|||
|
Vorstellung von der korrekten Arbeitsweise des Wortes noch einmal unter die Lupe
|
|||
|
nehmen.
|
|||
|
|
|||
|
Der Stack ist vor und nach -TRAILING gleich geblieben, die Länge des Strings
|
|||
|
also nicht verändert worden. Offensichtlich wird die Schleife gleich beim ersten Mal
|
|||
|
verlassen, obwohl das letzte Zeichen des Textes ein Leerzeichen war. Die Schleife
|
|||
|
hätte also eigentlich mit dem vorletzten Zeichen weiter machen müssen.
|
|||
|
|
|||
|
Mit anderen Worten: Die Abbruchbedingung in der Schleife ist falsch! Sie ist genau
|
|||
|
verkehrt herum gewählt. Ersetzt man = durch = NOT oder - ,so funktioniert
|
|||
|
das Wort korrekt. Überlegen Sie bitte, warum auch - statt = NOT eingesetzt
|
|||
|
werden kann. Tip: Der IF-Zweig wird nicht ausgeführt, wenn der oberste Stackwert
|
|||
|
FALSE , also gleich NULL ist.
|
|||
|
|
|||
|
Der volksFORTH83-Tracer gestattet es, jederzeit Befehle einzu-geben, die vor dem
|
|||
|
Abarbeiten des nächsten Trace-Kommandos ausgeführt werden. Das System wartet
|
|||
|
nach einem Step auf eine Eingabe von der Tastatur, bevor der nächste Step ausge-
|
|||
|
führt wird. .
|
|||
|
Endet eine Zeile mit einem Leerzeichen vor dem <CR> , so erlaubt der Tracer die
|
|||
|
Eingabe und Verarbeitung einer vollständigen Kommandozeile. Die Anforderung wird
|
|||
|
wiederholt, wenn in dieser Zeile ein Eingabe-Fehler auftauchen sollte. Damit ist
|
|||
|
__ jetzt ein etwas stressfreieres Ändern des Code bzw. des Stack während des Tracens
|
|||
|
möglich.
|
|||
|
So kann man z. B. Stack-Werte verändern oder das Tracen abbrechen. Ändern Sie
|
|||
|
probehalber beim nächsten Trace-Lauf von -TRAILING durch Eingabe von NOT
|
|||
|
das TRUE-Flag ($FFFF) auf dem Stack. bevor ?BRANCH ausgeführt wird und ver-
|
|||
|
folgen Sie den weiteren Trace-Lauf. Sie werden bemerken, daß die LOOP ein
|
|||
|
zweites Mal durchlaufen wird.
|
|||
|
|
|||
|
Wollen Sie das Tracen und die weitere Ausführung des getraceten Wortes ab-
|
|||
|
brechen, so geben Sie restart ein. RESTART führt einen Warm-Start des
|
|||
|
FORTHSystems aus und schaltet den Tracer ab. RESTART ist auch die Katastro-
|
|||
|
phen-Notbremse, die man einsetzt, wenn man sieht, daß das System mit dem näch-
|
|||
|
sten Befehl zwangsläufig im ComputerNirwana entschwinden wird.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Debusging-Techniken =
|
|||
|
|
|||
|
-ı
|
|||
|
=
|
|||
|
l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
17.2 Debug
|
|||
|
|
|||
|
Beim Tracen mit TRACE - nomen est omen - haben wir das fehlerhafte Wort
|
|||
|
isoliert zusammen mit ausgesuchten Parametern analysiert.
|
|||
|
|
|||
|
Im Gegensatz dazu bietet sich die Möglichkeit an, ein Wort in seiner Umgebung,
|
|||
|
|
|||
|
also in der Definition, in der es fehlerhaft arbeitet, zu untersuchen. Dazu dient
|
|||
|
der Befehl DEBUG :
|
|||
|
|
|||
|
debug (name)
|
|||
|
|
|||
|
Hierbei ist <name> das zu tracende Wort.
|
|||
|
|
|||
|
17.2.1 Beispiel: EXAMPLE
|
|||
|
|
|||
|
Bleiben wir bei unserem Beispiel, geben Sie bitte eine Definition mit -TRAILING
|
|||
|
ein. Dabei bietet sich zunächst die gleiche Sequenz wie oben an. Bitte definieren
|
|||
|
Sie dieses Beispiel :
|
|||
|
|
|||
|
: example ( --)
|
|||
|
|
|||
|
teststring count
|
|||
|
-trailing clearstack ;
|
|||
|
|
|||
|
Nun aktivieren Sie den Tracer mit :
|
|||
|
|
|||
|
debug -trailing
|
|||
|
Zunächst geschieht noch gar nichts. DEBUG hat nur den Tracer "scharf" gemacht.
|
|||
|
Rufen Sie nun mit EXAMPLE ein Wort auf, das <name> enthält, unterbricht der
|
|||
|
|
|||
|
Tracer die Ausführung, wenn er auf <name> stößt. Es erscheint folgendes, Ihnen
|
|||
|
schon bekanntes Bild:
|
|||
|
|
|||
|
example
|
|||
|
|
|||
|
8658 66A 2DUP 1B 8687
|
|||
|
|
|||
|
865A AB2 BOUNDS 1B 8687 1B 8687
|
|||
|
865C A80 (?DO 8687 86A2 1B 8687
|
|||
|
8660 66A 2DUP 1B 8687
|
|||
|
|
|||
|
8662 6E2 + 1B 8687 1B 8687
|
|||
|
8664 789 1- 86A2 1B 8687
|
|||
|
|
|||
|
Die Parameter sind unter diesen Bedingungen natürlich wieder die, die von
|
|||
|
TESTSTRING und COUNT auf den Stack gelegt werden. Interessant ist aber hier
|
|||
|
die Kontrolle, ob -TRAILING vielleicht falsche Parameter übergeben bekommt.
|
|||
|
|
|||
|
17.2.2 NEST und UNNEST
|
|||
|
|
|||
|
Nützlich ist auch die Möglichkeit, das Wort, das als nächstes zur Ausführung an-
|
|||
|
steht, seinerseits zu tracen, bis es ins aufrufende Wort zurückkehrt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 178, - Debugging-Techniken
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Dafür ist das Wort nest vorgesehen. Allerdings beschränkt sich dieses Möglichkeit
|
|||
|
|
|||
|
auf Worte, die in Highlevel-FORTH geschrieben sind. Assemblercode läßt sich damit
|
|||
|
nicht debuggen und Sie erhalten eine Meldung;
|
|||
|
|
|||
|
name) can't be debugged
|
|||
|
|
|||
|
Bitte tracen Sie unser Beispiel wieder mit TRACE EXANFLE :
|
|||
|
|
|||
|
Wenn Sie nun wissen wollen, was -TRAILING innerhalb des Beispiels macht, so
|
|||
|
geben Sie bitte NEST ein, wenn -TRAILING als nächstes auszuführendes Wort
|
|||
|
angezeigt wird.
|
|||
|
|
|||
|
Sie erhalten dann:
|
|||
|
|
|||
|
trace example
|
|||
|
|
|||
|
8669 8684 TESTSTRING
|
|||
|
|
|||
|
86B2 EEF COUNT 8686
|
|||
|
|
|||
|
86B4 8656 -TRAILING 1B 8687 nest
|
|||
|
8653 66A 2DUP 1B 8687
|
|||
|
|
|||
|
865A AB2 BOUNDS 1B 8687 1B 8687
|
|||
|
865C A8O ?DO 8687 86A2 1B 8687
|
|||
|
8660 66A 2DUP 1iB 8687
|
|||
|
|
|||
|
8662 6E2 + 1B 8687 1B 8687
|
|||
|
8664 789 1- 86A2 1B 8687
|
|||
|
8666 469 Ce 86A1l 1B 8687
|
|||
|
8668 2224 BL 20 1B 8687
|
|||
|
|
|||
|
866A 91B = 20 20 1B 8687
|
|||
|
866C B34A ?BRANCH FFFF 1B 8687
|
|||
|
8670 CFB LEAVE 1B 8687
|
|||
|
|
|||
|
8678 AOD UNNEST ı1B 8687
|
|||
|
|
|||
|
86B6 162E CLEARSTACK 1B 8687
|
|||
|
|
|||
|
8658 AOD UNNEST ok
|
|||
|
|
|||
|
Beachten Sie bitte, daß die Zeilen jetzt eingerückt dargestellt werden, bis der
|
|||
|
Tracer automatisch in das aufrufende Wort zurückkehrt. .Der Gebrauch von NEST
|
|||
|
ist nur dadurch eingeschränkt, daß sich einige Worte, die den ReturnStack mani--
|
|||
|
pulieren, mit NEST nicht tracen lassen, da der Tracer selbst Gebrauch vom
|
|||
|
ReturnStack macht. Auf solche Worte muß man den Tracer mit DEBUG ansetzen.
|
|||
|
|
|||
|
Wollen Sie das Tracen eines Wortes beenden, ohne die Ausführung des Wortes ab-
|
|||
|
zubrechen, so benutzen Sie unnest .
|
|||
|
|
|||
|
Ist der Tracer geladen, so kommen Sie an das tief im System steckende UNNEST ,
|
|||
|
einem Synonym für EXIT , das ausschließlich vom ; kompiliert wird, nicht mehr
|
|||
|
heran und benutzen statt dessen das Tracer-UNNEST, das Sie eine Ebene im
|
|||
|
Tracelauf zurückbringt.
|
|||
|
|
|||
|
Manchmal hat man in einem Wort vorkommende Schleifen beim ersten Durchlauf als
|
|||
|
korrekt erkannt und möchte diese nicht weiter tracen. Das kann sowohl bei
|
|||
|
DO...LOOPs der Fall sein als auch bei Konstruktionen mit BEGIN...WHILE...REPEAT
|
|||
|
oder BEGIN...UNTIL. In diesen Fällen gibt man am Ende der Schleife das Wort
|
|||
|
endloop ein. Die Schleife wird dann in Echtzeit abgearbeitet und der Tracer mel-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Debugging-Techniken - 199 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Geseilschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
det sich erst wieder, wenn er nach dem Wort angekommen ist, bei dem ENDLOOP
|
|||
|
eingegeben wurde.
|
|||
|
|
|||
|
Sollte statt dessen die Meldung: ENDLOOP COMPILE ONLY zu sehen sein, so ist das
|
|||
|
Vokabular TOOLS nicht in der Suchreihenfolge . Haben Sie den Fehler gefunden
|
|||
|
und wollen deshalb nicht mehr tracen, so müssen Sie nach dem Ende des Tracens
|
|||
|
END-TRACE oder jederzeit RESTART eingeben, ansonsten bleibt der Tracer
|
|||
|
"scharf", was zu merkwürdigen Erscheinungen führen kann; außer dem verringert
|
|||
|
sich bei eingeschaltetem Tracer die Geschwindigkeit des Systems.
|
|||
|
|
|||
|
Beachten Sie bitte auch, daß Sie für die Worte DEBUG und TRACE das Voka-
|
|||
|
bular TOOLS mit in die Suchreihenfolge aufgenommen haben. Sie sollten also nach
|
|||
|
hoffentlich erfolgreichen Tracelauf die Suchordnung wieder umschalten, weil der
|
|||
|
Befehl RESTART zwar den Tracer abschaltet, aber die Suchreihenfolge nicht zu-
|
|||
|
rückschaltet.
|
|||
|
|
|||
|
Wenn man sich eingearbeitet hat, ist der Tracer ein wirklich verblüffendes Werk-
|
|||
|
zeug, mit dem man sehr viele Fehler schnell finden kann. Er ist gleichsam ein
|
|||
|
Mikroskop, mit dem man sehr tief ins Innere von FORTH schauen kann.
|
|||
|
|
|||
|
17.3 Stacksicherheit
|
|||
|
|
|||
|
Anfänger neigen häufig dazu, Fehler bei der Stackmanipulation zu machen. Er-
|
|||
|
schwerend kommt häufig hinzu, daß sie viel zu lange Worte schreiben, in denen es
|
|||
|
dann von unübersichtlichen Stackmanipulationen nur so wimmelt. Es gibt einige
|
|||
|
Worte, die sehr einfach sind und Fehler bei der Stackmanipulation früh erkennen
|
|||
|
helfen. Denn leider führen schwerwiegende Stackfehler zu "mysteriösen" System-
|
|||
|
crashs.
|
|||
|
|
|||
|
In Schleifen führt ein nicht ausgeglichener Stack oft zu solchen Fehlern. Während
|
|||
|
der Testphase eines Programms oder Wortes sollte man daher bei jedem Schleifen-
|
|||
|
durchlauf prüfen, ob der Stack evtl. über- oder leerläuft. Das geschieht durch
|
|||
|
Eintippen von :
|
|||
|
: LOOP compile ?stack [compile] LOOP
|
|||
|
: +LOOP compile ?stack [compile) +LOOP
|
|||
|
: UNTIL compile ?stack [compile] UNTIL
|
|||
|
|
|||
|
: REPEAT compile ?stack [compile) REPEAT
|
|||
|
: compile ?stack ;
|
|||
|
|
|||
|
immediate restrict
|
|||
|
immediate restrict
|
|||
|
immediate restrict
|
|||
|
immediate restrict
|
|||
|
|
|||
|
Versuchen Sie ruhig, herauszufinden wie die letzte Definition funktioniert. Es ist
|
|||
|
nicht kompliziert. Durch diese Worte bekommt man sehr schnell mitgeteilt, wann ein
|
|||
|
Fehler auftrat. Es erscheint dann die Fehlermeldung
|
|||
|
|
|||
|
<name) stack full
|
|||
|
|
|||
|
‚ wobei <name> der zuletzt vom Terminal eingegebene Name ist.Wenn man nun
|
|||
|
überhaupt keine Ahnung hat. wo der Fehler auftrat, so gebe man ein:
|
|||
|
|
|||
|
: unravel
|
|||
|
rdrop rdrcp rdrop \ delete errorhandlernest
|
|||
|
cr ." trace dump on abort is :" cr
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- FOR - Debugging-Techniken
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BEGIN rp@ rö @ - \ until stack empty
|
|||
|
WHILE r? dup 8 u.r space
|
|||
|
|
|||
|
2- @ >name .name cr
|
|||
|
REPEAT (error ;
|
|||
|
|
|||
|
unravel errorhandler !
|
|||
|
|
|||
|
Sie bekommen dann bei Eingabe von 1 2 6 */ ungefähr folgenden Ausdruck :
|
|||
|
|
|||
|
trace dump on abort is:
|
|||
|
|
|||
|
E32 */MOD 1D8A EXECUTE
|
|||
|
|
|||
|
1E24 PARSER
|
|||
|
|
|||
|
20CD INTERPRET
|
|||
|
|
|||
|
20FA 'QUIT / division over£flow
|
|||
|
|
|||
|
__ 'QUIT INTERPRET PARSER und EXECUTE rühren vom Textinterpreter her.
|
|||
|
Interessant wird es bei */MOD . Wir wissen, daß */MOD von */ aufgerufen
|
|||
|
wird. */MOD ruft nun wieder M/MOD auf, in M/MOD gehts weiter nach
|
|||
|
UM/MOD . Dieses Wort ist in Code geschrieben und "verursachte" den Fehler, indem
|
|||
|
es eine Division durch Null ausführte.
|
|||
|
|
|||
|
Nicht immer treten Fehler in Schleifen auf. Es kann auch der Fall sein, daß ein
|
|||
|
Wort zu wenig Argumente auf dem Stack vorfindet, weniger nämlich, als Sie für
|
|||
|
dieses Wort vorgesehen haben. Diesen Fall sichert ARGUMENTS . Die Definition
|
|||
|
dieses Wortes ist:
|
|||
|
|
|||
|
: arguments (n--)
|
|||
|
depth 1- < abort" not enough arguments" ;
|
|||
|
Es wird folgendermaßen benutzt:
|
|||
|
: -trailing ( addr len) 2 arguments ... ;
|
|||
|
|
|||
|
wobei die drei Punkte den Rest des Quelltextes andeuten sollen.
|
|||
|
|
|||
|
Findet -TRAILING nun weniger als zwei Werte auf dem Stack vor, so wird eine
|
|||
|
Fehlermeldung ausgegeben. Natürlich kann man damit nicht prüfen, ob die Werte
|
|||
|
auf dem Stack wirklich für -TRAILING bestimmt waren.
|
|||
|
|
|||
|
Sind Sie als Programmierer sicher, daß an einer bestimmten Stelle im Programm eine
|
|||
|
bestimmte Anzahl von Werten auf dem Stack liegt, so können Sie das ebenfalls
|
|||
|
sicherstellen:
|
|||
|
: isdepth (n--) depth 1- - abort" wrong depth" ;
|
|||
|
|
|||
|
ISDEPTH bricht das Programm ab, wenn die Zahl der Werte auf dem Stack nicht
|
|||
|
gleich n ist, wobei n natürlich nicht mitgezählt wird. Es wird analog zu
|
|||
|
ARGUMENTS benutzt. Mit diesen Worten lassen sich Stackfehler oft feststellen und
|
|||
|
lokalisieren.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Debugging-Techniken = 1a >
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
17.4 Aufrufgeschichte
|
|||
|
|
|||
|
Möchte man wissen, was geschah, bevor ein Fehler auftrat und nicht nur, wo er
|
|||
|
auftrat.- denn nur diese Information liefert UNRAVEL - so kann man einen
|
|||
|
modifizierten Tracer verwenden, bei dem man nicht nach jeder Zeile <CR> drücken
|
|||
|
muß:
|
|||
|
|
|||
|
> ==)
|
|||
|
|
|||
|
Does)» cr rdepth 2* spaces
|
|||
|
dup 2- >name .name )r ;
|
|||
|
|
|||
|
Hierbei wird ein neues Wort mit dem Namen : definiert, das zunächst das alte
|
|||
|
Wort : aufruft und so ein Wort im Dictionary erzeugt. Das Laufzeitverhalten die-
|
|||
|
ses Wortes wird aber so geändert, daß es sich jedesmal wieder ausdruckt, wenn es
|
|||
|
aufgerufen wird. Alle Worte, die nach der Redefinition, so nennt man das erneute
|
|||
|
Definieren eines schon bekannten Wortes, des : definiert wurden, weisen dieses
|
|||
|
Verhalten auf.
|
|||
|
|
|||
|
Beispiel:
|
|||
|
|
|||
|
Sa
|
|||
|
» rechhe (--n) 123//;
|
|||
|
RECHNE / / RECHNE division overflow
|
|||
|
|
|||
|
Wir sehen also, daß erst bei der zweiten Division der Fehler auftrat. Das ist auch
|
|||
|
logisch, denn 2 3 / ergibt ©.
|
|||
|
|
|||
|
Sie sind sicher in der Lage, die Grundidee dieses zweiten Tracers zu verfeinern.
|
|||
|
Ideen wären z.B.:
|
|||
|
|
|||
|
- Ausgabe der Werte auf dem Stack bei Aufruf eines Wortes
|
|||
|
|
|||
|
- Die Möglichkeit, Teile eines Tracelaufs komfortabel zu unterdrücken.
|
|||
|
|
|||
|
17.5 Dump
|
|||
|
|
|||
|
Einen Speicherdump benötigt man beim Programmieren sehr oft, mindestens dann,
|
|||
|
wenn man eigene Datenstrukturen anschauen will. Oft ist es dann hinderlich,
|
|||
|
eigene Worte zur womöglich gar formatierten Ausgabe der Datenstrukturen schreiben
|
|||
|
zu müssen. In diesen Fällen benötigt man ein Wort, das einen Speicherdump aus-
|
|||
|
gibt. Das volksFORTH besitzt zwei Worte zum Dumpen von Speicherblöcken sowie
|
|||
|
einen Dekompiler, der auch für Datenstrukturen verwendet werden kann.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 182 - Debugging-Techniken
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
dump
|
|||
|
|
|||
|
(addrn -- )
|
|||
|
Ab addr werden n Bytes formatiert ausgegeben. Dabei steht am Anfang
|
|||
|
einer Zeile die Adresse, dann folgen 16 Byte, die in der Mitte zur bes-
|
|||
|
seren Übersicht getrennt sind und dann die Ascii-Darstellung. Dabei wer-
|
|||
|
den nur Zeichen im Bereich zwischen $2® und $7F ausgegeben. Die Aus-
|
|||
|
gabe läßt sich jederzeit mit einer beliebigen Taste unterbrechen oder mit
|
|||
|
<Esc> abbrechen.
|
|||
|
Mit PRINT läßt sich die Ausgabe auf einen Drucker umleiten.
|
|||
|
Beispiel: print pad 40 dump display
|
|||
|
Das abschließende DISPLAY sorgt dafür, daß wieder der Bild-schirm als
|
|||
|
Ausgabegerät gesetzt wird.
|
|||
|
|
|||
|
— Möchte man Speicherbereich außerhalb des .FORTH-Systems dumpen, gibt es dafür
|
|||
|
|
|||
|
das Wort:
|
|||
|
|
|||
|
ldump
|
|||
|
|
|||
|
(laddrn --)
|
|||
|
erwartet eine - doppelt lange - absolute Speicheradresse und wie oben
|
|||
|
die Anzahl der auszugebenden Bytes. Die Ausgabe auf einen Drucker ge-
|
|||
|
schieht genau so wie oben beschrieben.
|
|||
|
|
|||
|
17.6 Dekompiler
|
|||
|
|
|||
|
Ein Dekompiler gehört so zu sagen zum guten Ton eines FORTH Systems, war er
|
|||
|
bisher-doch die einzige Möglichkeit, wenigstens. ungefähr den Aufbau eines Systems
|
|||
|
zu durchschauen. Bei volks FORTH83 ist das anders, und zwar aus zwei Gründen:
|
|||
|
Sie haben sämtliche Quelltexte vorliegen, und es gibt die VIEW-Funktion. Letztere
|
|||
|
ist normalerweise sinn voller als der beste Dekompiler, da kein Dekompiler in der
|
|||
|
Lage ist, z.B. Stackkommentare zu rekonstruieren.
|
|||
|
|
|||
|
Der Tracer ist beim Debugging sehr viel hilfreicher als ein Dekompiler, da er auch
|
|||
|
die Verarbeitung von Stackwerten erkennen läßt. Damit sind Fehler leichter aufzu-
|
|||
|
|
|||
|
finden. r
|
|||
|
Dennoch gibt es natürlich auch im volksFORTH einen Dekompiler, zum einen als zu-
|
|||
|
|
|||
|
ladbares Werkzeug und zum anderen in einfacher von Hand zu bedienender Form.
|
|||
|
|
|||
|
Der zuladbare Dekompiler SEE wird mit
|
|||
|
|
|||
|
include see.scr
|
|||
|
|
|||
|
geladen und in der Form
|
|||
|
|
|||
|
see (name)
|
|||
|
|
|||
|
benutzt. Daraufhin wird das Wort dekompilert.
|
|||
|
|
|||
|
Als ständig verfügbares Dekompiler-Werkzeug stehen im Vokabular TOOLS folgende
|
|||
|
Worte zur Verfügung:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Debugging-Techniken - 183 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
N name ( addr -- addr' )
|
|||
|
druckt den Namen des bei addr kompilierten Wortes aus und setzt addr
|
|||
|
auf das nächste Wort,
|
|||
|
|
|||
|
L literal ( addr -- addr' )
|
|||
|
wird nach LIT benutzt und druckt den Inhalt von addr als Zahl aus. Es
|
|||
|
wird also nicht versucht, den Inhalt, wie bei N, als FORTH-Wort zu
|
|||
|
interpretieren.
|
|||
|
|
|||
|
S string ( addr -- addr' )
|
|||
|
wird nach ABORT" , ", ." und allen anderen Worten benutzt, auf die
|
|||
|
ein String folgt. Der String wird ausgedruckt und addr entsprechend er-
|
|||
|
höht, sodaß sie hinter den String zeigt.
|
|||
|
|
|||
|
C character ( addr -- addr' )
|
|||
|
druckt den Inhalt von addr als Ascii-Zeichen aus und geht ein Byte
|
|||
|
weiter. Damit kann man eigene Datenstrukturen ansehen.
|
|||
|
|
|||
|
B branch ( addr -- addr')
|
|||
|
wird nach BRANCH oder ?BRANCH benutzt und druckt den Inhalt einer
|
|||
|
Adresse als Sprungoffset und Sprungziel aus.
|
|||
|
|
|||
|
D dump ( addr n -- addr' )
|
|||
|
dumped n Bytes. Wird benutzt, um selbstdefinierte Daten strukturen an-
|
|||
|
zusehen.
|
|||
|
Siehe auch DUMP und LDUMP.
|
|||
|
|
|||
|
Sehen wir uns nun ein Beispiel zur Benutzung des Dekompilers an. Geben Sie bitte
|
|||
|
folgende Definition ein:
|
|||
|
|
|||
|
: test (n--)
|
|||
|
12 = IF cr ." Die Zahl ist zwölf !" THEN ;
|
|||
|
|
|||
|
Rufen Sie das Vokabular TOOLS durch Nennen seines Namens auf und ermitteln
|
|||
|
Sie die Adresse des ersten in TEST kompilierten Wortes:
|
|||
|
|
|||
|
' test >body
|
|||
|
|
|||
|
Jetzt können Sie TEST nach folgendem Muster dekompilieren:
|
|||
|
|
|||
|
n 80B0: 856 CLIT
|
|||
|
|
|||
|
c 80B2: 12
|
|||
|
|
|||
|
n 80B3: 92A =
|
|||
|
|
|||
|
n 80B5: B43 ?BRANCH
|
|||
|
|
|||
|
b 80B7: 1B 80D2
|
|||
|
|
|||
|
n 8059: ZBEI CR
|
|||
|
|
|||
|
n 80BB: 127E (."
|
|||
|
|
|||
|
s 80BD: 14 Die Zahl ist zwölf !
|
|||
|
n 8002: 41C UNNEST
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 18 = Debugging-Techniken
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Die erste Adresse ist die, an der im Wort TEST die anderen Worte kompiliert
|
|||
|
sind. Die zweite ist jeweils die Kompilationsadresse der Worte, danach folgen die
|
|||
|
sonstigen Ausgaben des Dekompilers.
|
|||
|
Probieren Sie dieses Beispiel auch mit dem Tracer aus: 29 trace test und achten
|
|||
|
Sie auf die Unterschiede. Sie werden sehen, daß der Tracer aussagefähiger und
|
|||
|
dazu noch einfacher zu bedienen ist.
|
|||
|
|
|||
|
Wenn Sie sich die Ratschläge und Tips zu Herzen genommen haben und noch etwas
|
|||
|
den Umgang mit den Hilfsmitteln üben, werden Sie sich sicher nicht mehr vorstellen
|
|||
|
können, wie Sie jemals in anderen Sprachen ohne diese Hilfsmittel ausgekommen
|
|||
|
sind. Bedenken Sie bitte auch: Diese Mittel sind kein Heiligtum - oft wird Sie eine
|
|||
|
Modifikation schneller zum Ziel führen. Scheuen Sie sich nicht, sich vor dem Be-
|
|||
|
arbeiten einer umfangreichen Aufgabe erst die geeigneten Hilfsmittel zu pro-
|
|||
|
grammieren.
|
|||
|
|
|||
|
17.7 Glossar
|
|||
|
|
|||
|
restart (==)
|
|||
|
ermöglicht gegenüber den Versionen auf dem ATARI und dem C64 auf
|
|||
|
Grund der Konstruktion ausschließlich den Ausstieg aus dem Single-Step-
|
|||
|
Trace-Modus .
|
|||
|
|
|||
|
end-trace ai
|
|||
|
dient lediglich dazu, um einen DEBUG-Befehl rückgängig zu machen.
|
|||
|
|
|||
|
Schaltet den Tracer ab, der durch "patchen" der Next-Routine arbeitet.
|
|||
|
Die Ausführung des aufrufenden Wortes wird fortgesetzt.
|
|||
|
|
|||
|
next-link ( -- addr.)
|
|||
|
addr ist die Adresse einer Uservariablen, die auf die Liste aller Next-
|
|||
|
routinen zeigt. Der Assembler erzeugt bei Verwendung des Wortes NEXT
|
|||
|
Code, für den ein Zeiger in diese Liste eingetragen wird. Die so ent-
|
|||
|
standene Liste wird vom Tracer benutzt, um alle im System vorhandenen
|
|||
|
Kopien des Codes für NEXT zu modifizieren.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Debugging-Techniken j85-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
18. Begriffe
|
|||
|
|
|||
|
18.1 Entscheidungskriterien
|
|||
|
|
|||
|
Bei Konflikten läßt sich das Standardteam von folgenden Kriterien in Reihenfolge
|
|||
|
ihrer Wichtigkeit leiten:
|
|||
|
|
|||
|
1; Korrekte Funktion - bekannte Einschränkungen, Eindeutigkeit.
|
|||
|
|
|||
|
g, Transportabilität — wiederholbare Ergebnisse, wenn Programme zwi-
|
|||
|
schen Standardsystemen portiert werden.
|
|||
|
|
|||
|
3. Einfachheit
|
|||
|
Klare, eindeutige Namen - die Benutzung beschreiben - der statt
|
|||
|
funktionaler Namen, z.B. [COMPILE] statt 'c, und ALLOT statt
|
|||
|
dp+!..
|
|||
|
|
|||
|
5, Allgemeinheit
|
|||
|
|
|||
|
6 Ausführungsgeschwindigkeit
|
|||
|
|
|||
|
Ts Kompaktheit
|
|||
|
|
|||
|
8. Kompilationsgeschwindigkeit
|
|||
|
|
|||
|
9, Historische Kontinuität
|
|||
|
|
|||
|
10. Aussprechbarkeit
|
|||
|
|
|||
|
il; Verständlichkeit -— es muß einfach gelehrt werden können
|
|||
|
|
|||
|
18.2 Definition der Begriffe
|
|||
|
|
|||
|
Es werden im allgemeinen die amerikanischen Begriffe beibehalten, es sei denn, der
|
|||
|
Begriff ist bereits im Deutschen geläufig. Wird ein deutscher Begriff verwendet, so
|
|||
|
wird in Klammern der engl. Originalbegriff beigefügt; wird der Originalbegriff bei-
|
|||
|
behalten, so wird in Klammern eine möglichst treffende Übersetzung angegeben.
|
|||
|
|
|||
|
Adresse, Byte (address, byte)
|
|||
|
Eine 16bit Zahl ohne Vorzeichen, die den Ort eines 8bit Bytes im Bereich
|
|||
|
<0...65.535> angibt. Adressen werden wie Zahlen ohne Vorzeichen mani-
|
|||
|
puliert.
|
|||
|
Siehe: "Arithmetik, 2er-komplement"
|
|||
|
|
|||
|
Adresse, Kompilation (address, compilation)
|
|||
|
Der Zahlenwert, der zur Identifikation eines FORTH Wortes kompiliert
|
|||
|
wird. Der Adressinterpreter benutzt diesen Wert, um den zu jedem Wort
|
|||
|
gehörigen Maschinencode aufzufinden.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 186 - Begriffe
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V, PC-vclksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Adresse, Natürliche (address, native machine)
|
|||
|
|
|||
|
Die vorgegebene Adressdarstellung der Computerhardware.
|
|||
|
|
|||
|
Adresse, Parameterfeld (address, parameter field) "pfa"
|
|||
|
|
|||
|
anzeigen
|
|||
|
|
|||
|
Die Adresse des ersten Bytes jedes Wortes, das für das Ablegen von
|
|||
|
Kompilationsadressen ( bei :-definitionen ) oder numerischen Daten bzw.
|
|||
|
Textstrings usw. benutzt wird.
|
|||
|
|
|||
|
(display)
|
|||
|
|
|||
|
Der Prozess, ein oder mehrere Zeichen zum aktuellen Ausgabegerät zu
|
|||
|
senden. Diese Zeichen werden normalerweise auf einem Monitor angezeigt
|
|||
|
bzw. auf einem Drucker gedruckt.
|
|||
|
|
|||
|
Arithmetik, 2er-komplement (arithmetic, two's complement)
|
|||
|
|
|||
|
Block
|
|||
|
|
|||
|
Die Arithmetik arbeitet mit Zahlen in 2er-Komplementdarstellung; diese
|
|||
|
Zahlen sind, je nach Operation, 16bit oder 32bit weit. Addition und
|
|||
|
Subtraktion von 2er-Komplementzahlen ignorieren Überlaufsituationen.
|
|||
|
Dadurch ist es möglich, daß die gleichen Operatoren benutzt werden kön-
|
|||
|
nen, gleichgültig, ob man die Zahl mit Vorzeichen ( -32.768...32,767 bei
|
|||
|
16-Bit ) oder ohne Vorzeichen ( 8...65,535 bei 16-Bit) benutzt.
|
|||
|
|
|||
|
(block)
|
|||
|
Die 1024 Byte Daten des Massenspeichers, auf die über Blocknummern im
|
|||
|
Bereich 9...Anzahl_existenter_Blöcke-1 zugegriffen wird. Die exakte
|
|||
|
Anzahl der Bytes, die je Zugriff auf den Massenspeicher übertragen wer-
|
|||
|
den, und die Übersetzung von Blocknummern in die zugehörige Adresse
|
|||
|
des Laufwerks und des physikalischen Satzes, sind rechnerabhängig.
|
|||
|
Siehe: "Blockpuffer" und "Massenspeicher"
|
|||
|
|
|||
|
Blockpuffer (block buffer)
|
|||
|
|
|||
|
Ein 1824 Byte langer Hauptspeicherbereich, in dem ein Block vorüber-
|
|||
|
gehend benutzbar ist. Ein Block ist in höchstens einem Blockpuffer ent-
|
|||
|
halten.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Byte (byte)
|
|||
|
Eine Einheit von 8bit. Bei Speichern ist es die Speicherkapazität von
|
|||
|
8bits.
|
|||
|
|
|||
|
Begriffe
|
|||
|
|
|||
|
= 187,
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Kompilation (compilation)
|
|||
|
|
|||
|
Der Prozess, den Quelltext in eine interne Form umzuwandeln, die später
|
|||
|
ausgeführt werden kann. Wenn sich das System im Kompilationszustand
|
|||
|
befindet, werden die Kompilationsadressen von Worten im Dictionary ab-
|
|||
|
gelegt, so daß sie später vom Adresseninterpreter ausgeführt werden
|
|||
|
können. Zahlen werden so kompiliert, daß sie bei Ausführung auf den
|
|||
|
Stack gelegt werden. Zahlen werden aus dem Quelltext ohne oder mit
|
|||
|
negativem Vorzeichen akzeptiert und gemäß dem Wert von BASE umge-
|
|||
|
wandelt.
|
|||
|
|
|||
|
Siehe: "Zahl", "Zahlenumwandlung", "Interpreter, Text" und "Zustand"
|
|||
|
|
|||
|
Definition (Definition)
|
|||
|
|
|||
|
Siehe: "Wortdefinition"
|
|||
|
|
|||
|
Dictionary (Wörterbuch)
|
|||
|
|
|||
|
Division,
|
|||
|
|
|||
|
Eine Struktur von Wortdefinitionen, die im Hauptspeicher des Rechners
|
|||
|
angelegt ist. Sie ist erweiterbar und wächst in Richtung höherer Spei-
|
|||
|
cheradressen. Einträge sind in Vokabularen organisiert, so daß die Be-
|
|||
|
nutzung von Synonymen möglich ist, d.h. gleiche Namen können, in ver-
|
|||
|
schiedenen Vokabularen enthalten, vollkommen verschiedene Funktionen
|
|||
|
auslösen.
|
|||
|
|
|||
|
Siehe; "Suchreihenfolge"
|
|||
|
|
|||
|
floored (division, floored)
|
|||
|
|
|||
|
Ganzzahlige Division, bei der der Rest das gleiche Vorzeichen hat wie der
|
|||
|
Divisor oder gleich Null ist; der Quotient wird gegen die nächstkleinere
|
|||
|
ganze Zahl gerundet. Bemerkung: Ausgenommen von Fehlern durch Über-
|
|||
|
lauf gilt: Ni N2 SWAP OVER /MOD ROT * + ist identisch mit Ni.
|
|||
|
|
|||
|
Siehe: "floor, arithmetisch"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Beispiele: Dividend Divisor Rest Quotient
|
|||
|
10 7 3 1
|
|||
|
-10 7 4 2
|
|||
|
10 -1 -4 -2
|
|||
|
-18 -2 -3 1.
|
|||
|
|
|||
|
Empfangen receive)
|
|||
|
|
|||
|
Falsch
|
|||
|
|
|||
|
Der Prozess, der darin besteht, ein Zeichen von der aktuellen Eingabe-
|
|||
|
einheit zu empfangen. Die Anwahl einer Einheit ist rechnerabhängieg.
|
|||
|
|
|||
|
(false)
|
|||
|
Die Zahl Null repräsentiert den "Falschzustand" eines Flags.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 188 -
|
|||
|
|
|||
|
Begriffe
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Fehlerbedingung (error condition)
|
|||
|
|
|||
|
Eine Ausnahmesituation, in der ein Systemverhalten erfolgt, das nicht mit
|
|||
|
der erwarteten Funktion übereinstimmt. Im der Beschreibung der einzelnen
|
|||
|
Worte sind die möglichen Fehlerbedingungen und das dazugehörige Sys-
|
|||
|
temverhalten beschrieben.
|
|||
|
|
|||
|
Flag (logischer Wert)
|
|||
|
|
|||
|
Eine Zahl, die eine von zwei möglichen Werten hat, falsch oder wahr.
|
|||
|
Siehe: "Falsch" , "Wahr"
|
|||
|
|
|||
|
Floor, arithmetic
|
|||
|
|
|||
|
Glossar
|
|||
|
|
|||
|
Z sei eine reelle Zahl. Dann. ist der Floor von Z die größte ganze Zahl,
|
|||
|
die kleiner oder gleich Z ist.
|
|||
|
|
|||
|
Der Floor von +9,6 ist ®
|
|||
|
|
|||
|
Der Floor von -9,4 ist -1
|
|||
|
|
|||
|
(glossary)
|
|||
|
|
|||
|
Eine umgangssprachliche Beschreibung, die die zu einer Wortdefinition ge-
|
|||
|
hörende Aktion des Computers beschreibt - die Beschreibung der Seman-
|
|||
|
tik des Wortes.
|
|||
|
|
|||
|
Interpreter, Adressen (interpreter, address)
|
|||
|
|
|||
|
Die Maschinencodeinstruktionen, die die kompilierten Wort-definitionen
|
|||
|
ausführen, die aus Kompilationsadressen bestehen.
|
|||
|
|
|||
|
Interpreter, Text (interpreter, text)
|
|||
|
|
|||
|
Eine Wortdefinition, die immer wieder einen Wortnamen aus dem Quelltext
|
|||
|
holt, die zugehörige Kompilationsadresse bestimmt und diese durch den
|
|||
|
Adressinterpreter ausführen läßt. Quelltext, der als Zahl interpretiert
|
|||
|
wird, hinter-läßt den entsprechenden Wert auf dem Stack.
|
|||
|
|
|||
|
Siehe: "Zahlenumwandlung"
|
|||
|
|
|||
|
“»Kontrollstrukturen (structure, control)
|
|||
|
|
|||
|
Eine Gruppe von Worten, die, wenn sie ausgeführt werden, den Programm-
|
|||
|
fluß verändern. Beispiele von Kontrollstrukturen sind:
|
|||
|
|
|||
|
DO ... LOOP
|
|||
|
|
|||
|
BEGIN ... WHILE ... REPEAT
|
|||
|
|
|||
|
IF .. ELSE ... THEN
|
|||
|
|
|||
|
|
|||
|
|
|||
|
laden (load)
|
|||
|
Das Umschalten des Quelltextes zum Massenspeicher. Dies ist die übliche
|
|||
|
Methode, dem Dictionary neue Definitionen hinzuzufügen.
|
|||
|
|
|||
|
Begriffe - 7898-
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Massenspeicher (mass storage)
|
|||
|
Speicher, der ausserhalb des durch FORTH adressierbaren Bereiches liegen
|
|||
|
kann. Auf den Massenspeicher wird in Form von 1924 Byte großen Blök-
|
|||
|
ken zugegriffen. Auf einen Block kann innerhalb des FORTH-Adressbe-
|
|||
|
reichs in einem Blockpuffer zugegriffen werden. Wenn ein Block als ver-
|
|||
|
ändert ( UPDATE ) gekennzeichnet ist, wird er letztendlich wieder auf
|
|||
|
den Massenspeicher zurückgeschrieben.
|
|||
|
|
|||
|
Programm (program)
|
|||
|
Eine vollständige Ablaufbeschreibung in FORTH-Quelltext, um eine be-
|
|||
|
stimmte Funktion zu realisieren.
|
|||
|
|
|||
|
Quelltext (input stream)
|
|||
|
|
|||
|
Eine Folge von Zeichen, die dem System zur Bearbeitung durch den Text-
|
|||
|
interpreter zugeführt wird. Der Quelltext kommt üblicherweise von der
|
|||
|
aktuellen Eingabeeinheit (über den Texteingabepuffer) oder dem Massen-
|
|||
|
speicher (über einen Blockpuffer). BLK , IN , TIB und #TIB
|
|||
|
charakterisieren den Quelltext. Worte, die BLK ‚,„ >»IN ,„ TIB oder
|
|||
|
#TIB benutzen und/oder verändern, sind dafür verantwortlich, die Kon-
|
|||
|
trolle des Quelltextes aufrechtzuerhalten oder wiederherzustellen. Der
|
|||
|
Quelltext reicht von der Stelle, die durch den Relativzeiger >IN ange-
|
|||
|
geben wird, bis zum Ende. Wenn BLK Null ist, so befindet sich der
|
|||
|
Quelltext an der Stelle, die durch TIB adressiert wird, und er ist #TIB
|
|||
|
Bytes lang. Wenn BLK ungleich Null ist, so ist der Quelltext der Inhalt
|
|||
|
des Blockpuffers, der durch BLK angegeben ist, und er ist 1024 Byte
|
|||
|
lang.
|
|||
|
|
|||
|
Rekursion (recursion)
|
|||
|
Der Prozess der direkten oder indirekten Selbstreferenz.
|
|||
|
|
|||
|
Screen (Bildschirm)
|
|||
|
|
|||
|
Ein Screen sind Textdaten, die zum Editieren aufbereitet sind. Nach Kon-
|
|||
|
vention besteht ein Screen aus 16 Zeilen zu je 64 Zeichen. Die Zeilen
|
|||
|
werden von ® bis 15 durchnumeriert. Screens enthalten normalerweise
|
|||
|
Quelltext. können jedoch auch dazu benutzt werden, um Massenspeicher-
|
|||
|
daten zu betrachten. Das erste Byte eines Screens ist gleichzeitig das
|
|||
|
erste Byte eines Massenspeicherblocks; dies ist auch der Anfangspunkt
|
|||
|
für Quelltextinterpretation während des Ladens eines Blocks.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
= 199 = Begriffe
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Suchreihenfolge (search order)
|
|||
|
|
|||
|
Eine Spezifikation der Reihenfolge, in der ausgewählte Vokabulare im
|
|||
|
Dietionary durchsucht werden. Die Suchreihenfolge besteht aus einem
|
|||
|
auswechselbaren und einem festen Teil, wobei der auswechselbare Teil
|
|||
|
immer als erstes durchsucht wird. Die Ausführung eines Vokabularnamens
|
|||
|
macht es zum ersten Vokabular in der Suchreihenfolge, wobei das Voka-
|
|||
|
bular, das vorher als erstes durchsucht worden war, verdrängt wird. Auf
|
|||
|
dieses erste Vokabular folgt, soweit spezifiziert, der feste Teil der Such-
|
|||
|
reihen-folge, der danach durchsucht wird. Die Ausführung von ALSO
|
|||
|
übernimmt das Vokabular im auswechselbaren Teil in den festen Teil der
|
|||
|
Suchreihenfolge. Das Dictionary wird immer dann durchsucht, wenn ein
|
|||
|
Wort durch seinen Namen aufge-funden werden soll.
|
|||
|
|
|||
|
stack, data (Datenstapel)
|
|||
|
|
|||
|
Eine "Zuletzt-rein, Zuerst-raus" (last-in, first-out) Struktur, die aus
|
|||
|
einzelnen 16bit Daten besteht. Dieser Stack wird hauptsächlich zum Ab-
|
|||
|
legen von Zwischenergebnissen während des Ausführens von Wortdefini-
|
|||
|
tionen benutzt. Daten auf dem Stack können Zahlen, Zeichen, Adressen,
|
|||
|
Boole'sche Werte usw. sein. Wenn der Begriff "Stapel" oder "Stack" ohne
|
|||
|
Zusatz benutzt wird, so ist immer der Datenstack gemeint.
|
|||
|
|
|||
|
stack, return (Rücksprungstapel)
|
|||
|
|
|||
|
Eine "Zuletzt-rein, Zuerst-raus" Struktur, die hauptsächlich Adressen von
|
|||
|
Wortdefinitionen enthält, deren Ausführung durch den Adressinterpreter
|
|||
|
noch nicht beendet ist. Wenn eine Wortdefinition eine andere Wortdefini-
|
|||
|
tion aufruft, so wird die Rücksprungadresse auf dem Returnstack abge-
|
|||
|
legt. Der Returnstack kann zeitweise auch für die Ablage anderer Daten-
|
|||
|
benutzt werden.
|
|||
|
|
|||
|
String, counted (abgezählte Zeichenkette)
|
|||
|
|
|||
|
Eine Hintereinanderfolge von 8bit Daten, die im Speicher durch ihre
|
|||
|
niedrigste Adresse charakterisiert wird. Das Byte an dieser Adresse
|
|||
|
enthält einen Zahlenwert im Bereich <®...255>, der die Anzahl der zu
|
|||
|
diesem String gehörigen Bytes angibt, die unmittelbar auf das Countbyte-
|
|||
|
folgen. Die Anzahl beinhaltet nicht das Countbyte selber. Counted Strings
|
|||
|
enthalten normalerweise ASCII-Zeichen.
|
|||
|
|
|||
|
String, Text (Zeichenkette)
|
|||
|
|
|||
|
Eine Hintereirıanderfolge von 8bit Daten, die im Speicher durch ihre
|
|||
|
niedrigste Adresse und ihre Länge in Bytes charakterisiert ist. Strings
|
|||
|
enthalten normalerweise ASCII-Zeichen. Wenn der Begriff "String" alleine
|
|||
|
oder in Verbindung mit anderen Begriffen benutzt wird, so sind Text-
|
|||
|
strings gemeint.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Begriffe
|
|||
|
|
|||
|
- 19er
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Userarea (Benutzerbereich)
|
|||
|
Ein Gebiet im Speicher, das zum Ablegen der Uservariablen benutzt wird
|
|||
|
und für jeden einzelnen Prozeß/Benutzer getrennt vorhanden ist.
|
|||
|
|
|||
|
Uservariable (Benutzervariable)
|
|||
|
Eine Variable, deren Datenbereich sich in der Userarea befindet. Einige
|
|||
|
Systemvariablen werden in der Userarea gehalten, sodaß die Worte, die
|
|||
|
diese benutzen, für mehrere Prozesse/Benutzer gleichzeitig verwendbar
|
|||
|
sind.
|
|||
|
|
|||
|
Vokabular (vocabulary)
|
|||
|
Eine geordnete Liste von Wortdefinitionen. Vokabulare werden vorteilhaft
|
|||
|
benutzt, um Worte voneinander zu unterscheiden, die gleiche Namen
|
|||
|
haben (Synonyme). In einem Vokabular können mehrere Definitionen mit
|
|||
|
dem gleichen Namen existieren; diesen Vorgang nennt man redefinieren.
|
|||
|
Wird das Vokabular nach einem Namen durchsucht, so wird die jüngste
|
|||
|
Redefinition gefunden.
|
|||
|
|
|||
|
Vokabular, Kompilation (vocabulary, compilation)
|
|||
|
Das Vokabular, in das neue Wortdefinitionen eingetragen werden.
|
|||
|
|
|||
|
Wahr (true)
|
|||
|
Ein Wert, der nicht Null ist, wird als "wahr" interpre-tiert. Wahrheits-
|
|||
|
werte, die von Standard-FORTH-Worten errechnet werden, sind 16bit
|
|||
|
Zahlen, bei denen alle 16 Stellen auf "1" gesetzt sind, so daß diese zum
|
|||
|
Maskieren benutzt werden können.
|
|||
|
|
|||
|
Wort, Definierendes (defining word)
|
|||
|
Ein Wort, das bei Ausführung einen neuen Dictionary-Eintrag im Kompi-
|
|||
|
lationsvokabular erzeugt. Der Name des neuen Wortes wird dem Quelltext
|
|||
|
entnommen. Wenn der Quelltext erschöpft ist, bevor der neue Name er-
|
|||
|
zeugt wurde, so wird die Fehlermeldung "ungültiger Name" ausgegeben.
|
|||
|
Beispiele von definierenden Worten sind: : CONSTANT CREATE
|
|||
|
|
|||
|
Wort, immediate (immediate word)
|
|||
|
Ein Wort, das ausgeführt wird, wenn es während der Kompilation oder
|
|||
|
Interpretation aufgefunden wird. Immediate Worte behandeln Sondersitua-
|
|||
|
tionen während der Kompilation.
|
|||
|
Siehe z.B. IF LITERAL ." usw.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
— 1I2M- Begriffe
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
Wortdefinition (word definition)
|
|||
|
|
|||
|
Wortname
|
|||
|
|
|||
|
Eine mit einem Namen versehene, ausführbare FORTH-Proze-dur, die ins
|
|||
|
Dictionary kompiliert wurde. Sie kann durch Maschinencode, als eine
|
|||
|
Folge von Kompilationsadressen oder durch sonstige kompilierte Worte
|
|||
|
spezifiziert sein. Wenn der Begriff "Wort" ohne Zusatz benutzt wird, so ist
|
|||
|
im allgemeinen eine Wortdefinition gemeint.
|
|||
|
|
|||
|
(word name)
|
|||
|
Der Name einer Wortdefinition. Wortnamen sind maximal 31 Zeichen lang
|
|||
|
und enthalten kein Leerzeichen. Haben zwei Definitionen verschiedene
|
|||
|
Namen innerhalb desselben Voka-bulars, so sind sie eindeutig auffind-
|
|||
|
bar, wenn das Vokabular durchsucht wird.
|
|||
|
Siehe: "Vokabular"
|
|||
|
|
|||
|
Zahl (number)
|
|||
|
|
|||
|
Wenn Werte innerhalb eines größeren Feldes existieren, so sind die
|
|||
|
höherwertigen Bits auf Null gesetzt. 16bit Zahlen sind im Speicher so ab-
|
|||
|
gelegt, dass sie in zwei benachbar-ten Byteadressen enthalten sind. Die
|
|||
|
Bytereihenfolge ist rechnerabhängig. Doppeltgenaue Zahlen (32bit) werden
|
|||
|
auf dem Stack so abgelegt, daß die höherwertigen 16bit (mit dem Vor-
|
|||
|
zeichenbit) oben liegen. Die Adresse der niederwer-tigen 16bit ist um
|
|||
|
zwei größer als die Adresse der höherwertigen 16bit, wenn die Zahl im
|
|||
|
Speicher abgelegt ist.
|
|||
|
|
|||
|
Siehe: "Arithmetik, 2er-komplement" und "Zahlentypen"
|
|||
|
|
|||
|
Zahlenausgabe, bildhaft (pictured numeric output)
|
|||
|
|
|||
|
Durch die Benutzung elementarer Worte für die Zahlenaus-gabe ( z.B. <#
|
|||
|
# #5 #)> ) werden Zahlenwerte in Textstrings umgewandelt. Diese De-
|
|||
|
finitionen werden in einer Folge benutzt, die ein symbolisches Bild des
|
|||
|
gewünschten Ausga-beformates darstellen. Die Umwandlung schreitet von
|
|||
|
der niedrigstwertigen zur höchstwertigen Ziffer fort und die umgewandel-
|
|||
|
|
|||
|
ten Zeichen werden von höheren gegen niedrigere Speicheradressen abge-
|
|||
|
legt.
|
|||
|
|
|||
|
Zahlenausgabe, freiformatiert (free field format)
|
|||
|
|
|||
|
Zahlen werden in Abhängigkeit von BASE umgewandelt und ohne füh-
|
|||
|
rende Nullen, aber mit einem folgenden Leerzei-chen, angezeigt. Die An-
|
|||
|
zahl von Stellen, die angezeigt werden, ist die Minimalanzahl von Stellen
|
|||
|
- mindestens eine - die notwendig sind, um die Zahl eindeutig darzu-
|
|||
|
stellen.
|
|||
|
|
|||
|
Siehe: "Zahlenumwandlung"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Begriffe
|
|||
|
|
|||
|
= 119355
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Zahlentypen (number types)
|
|||
|
|
|||
|
Alle Zahlentypen bestehen aus einer spezifischen Anzahl von Bits. Zahlen
|
|||
|
mit oder ohne Vorzeichen bestehen aus bewerteten Bits. Bewertete Bits
|
|||
|
innerhalb einer Zahl haben den Zahlenwert einer Zweierpotenz, wobei das
|
|||
|
am weitesten rechts stehende Bit (das niedrigstwertige) einen Wert von
|
|||
|
zwei hoch null hat. Diese Bewertung setzt sich bis zum am weitesten
|
|||
|
links stehenden Bit fort, wobei sich die Bewertung für jedes Bit um eine
|
|||
|
Zweierpotenz erhöht. Für eine Zahl ohne Vorzeichen ist das am weitesten
|
|||
|
links stehende Bit in diese Bewertung eingeschlossen, sodaß für eine
|
|||
|
solche 16bit Zahl das ganz linke Bit den Wert 32768 hat. Für Zahlen mit
|
|||
|
Vorzeichen wird die Bewertung des ganz linken Bits negiert, sodaß es bei
|
|||
|
einer 16bit Zahl den Wert -32768 hat. Diese Art der Wertung für Zahlen
|
|||
|
mit Vorzeichen wird 2er-komplementdarstellung genannt.Nicht spezifi-
|
|||
|
zierte, bewertete Zahlen sind mit oder ohne Vorzeichen; der Programm-
|
|||
|
kontext bestimmt, wie die Zahl zu interpretieren ist.
|
|||
|
|
|||
|
Zahlenumwandlung (number conversion)
|
|||
|
|
|||
|
Zeichen
|
|||
|
|
|||
|
Zahlen werden intern als Binärzahlen geführt und extern durch graphi-
|
|||
|
sche Zeichen des ASCII Zeichensatzes darge-stellt. Die Umwandlung zwi-
|
|||
|
schen der internen und externen Form wird unter Beachtung des Wertes
|
|||
|
von BASE durchge-führt, um die Ziffern einer Zahl zu bestimmen. Eine
|
|||
|
Ziffer liegt im Bereich von Null bis BASE-1. Die Ziffer mit dem Wert Null
|
|||
|
wird durch das ASCII-zeichen "8" (Position 3/0, dezimalwert 48) darge-
|
|||
|
stellt. Diese Zifferndarstellung geht den ASCII-code weiter aufwärts bis
|
|||
|
zum Zeichen "9", das dem dezimalen Wert neun entspricht. Werte, die jen-
|
|||
|
seits von neun liegen, werden durch die ASCII-zeichen beginnend mit "A",
|
|||
|
entsprechend dem Wert zehn usw. bis zum ASCII-zeichen """, entsprechend
|
|||
|
einundsiebzig, dargestellt.Bei einer negativen Zahl wird das ASCII-Zeichen
|
|||
|
"-" den Ziffern vorangestellt. Bei der Zahleneingabe kann der aktuelle
|
|||
|
Wert von BASE für die gerade umzuwandelnde Zahl dadurch umgangen
|
|||
|
werden, daß den Ziffern ein "Zahlenbasisprefix" vorangesteilt wird. Dabei
|
|||
|
wird durch das Zeichen "%" die Basis vorübergehend auf den Wert zwei
|
|||
|
gesetzt, durch "&" auf den Wert zehn und durch "$" oder "h" auf den
|
|||
|
Wert sechzehn. Bei negativen Zahlen folgt das Zahlenbasisprefix dem
|
|||
|
Minuszeichen. Enthält die Zahl ein Komma oder einen Punkt, so wird sie
|
|||
|
als 32bit Zahl umgewandelt.
|
|||
|
|
|||
|
(character)
|
|||
|
|
|||
|
Eine 8bit Zahl, deren Bedeutung durch den ASCII-Standard festgelegt ist.
|
|||
|
Wenn es in einem größeren Feld gespeichert ist, so sind die höherwerti-
|
|||
|
gen Bits auf Null gesetzt.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 194 -
|
|||
|
|
|||
|
Begriffe
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
Zustand
|
|||
|
|
|||
|
(mode)
|
|||
|
|
|||
|
Der Textinterpreter kann sich in zwei möglichen Zuständen befinden: dem
|
|||
|
interpretierenden oder dem kompilierenden Zustand. Die Variable STATUS
|
|||
|
wird vom System entsprechend gesetzt, und zwar enthält sie bei der
|
|||
|
Interpretation eine False-flag, bei der Kompilation eine True-flag.
|
|||
|
|
|||
|
Siehe: "Interpreter, Text" und "Kompilation”
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Begriffe
|
|||
|
|
|||
|
= 195 —
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.\V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis
|
|||
|
|
|||
|
DABEI Eee nennen rer ern eaneeT 110, 140
|
|||
|
|
|||
|
(decode.
|
|||
|
|
|||
|
(diskerror
|
|||
|
|
|||
|
(error ...
|
|||
|
(expect..
|
|||
|
|
|||
|
(fsearch
|
|||
|
(key...
|
|||
|
(key? ..
|
|||
|
(more...
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 196 - Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
MI nenn een kumn: 151
|
|||
|
+LOOP ... er 43
|
|||
|
+print
|
|||
|
|
|||
|
|
|||
|
|
|||
|
a uvcse ..6, 114, 182
|
|||
|
..55, 57, 156
|
|||
|
|
|||
|
»asciz.
|
|||
|
DDOG Yen innen een ee ee
|
|||
|
|
|||
|
»expect.
|
|||
|
|
|||
|
Ylabel...
|
|||
|
|
|||
|
»mark ...
|
|||
|
|
|||
|
DL EEE RE EL 68
|
|||
|
|
|||
|
FAISKERLOR nme HERE fänlree\ ee yrehteeeegee
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis = IRA
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
[FCB]
|
|||
|
[Method]
|
|||
|
\
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
-— j58 Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Anne era ef 29
|
|||
|
Abbruchbedingung ..
|
|||
|
|
|||
|
DOT a ee RENTE ee ee
|
|||
|
RT ende neun iunurheteeiitgek
|
|||
|
abSsimkeunr
|
|||
|
|
|||
|
accumulate ...
|
|||
|
|
|||
|
activate ......
|
|||
|
|
|||
|
address...
|
|||
|
|
|||
|
Adressinterpreter .. ah
|
|||
|
AGREBTAUTDI ne en ehe ehe ...107
|
|||
|
AGAIN ee eeriinaebles 45
|
|||
|
Alias
|
|||
|
|
|||
|
align
|
|||
|
|
|||
|
all-buffers
|
|||
|
|
|||
|
allot
|
|||
|
|
|||
|
allotbuffer...
|
|||
|
|
|||
|
DIES ER ne
|
|||
|
|
|||
|
and
|
|||
|
SPIDER rn ren BIN I TTURTERTER TI
|
|||
|
APPUKAUON: re Te ne 88
|
|||
|
Team ...63
|
|||
|
areakol....... +68
|
|||
|
arguments .. .181
|
|||
|
ASCHSGOGER. Sesam tan rn Te essen. een teen 69
|
|||
|
ISChZ a rn TR ETT E 80, 103
|
|||
|
ASSEMmbIlen. een er ren Rn Zn ....194, 144, 168
|
|||
|
SESIene. Mana een nn 93
|
|||
|
Associative: ...56
|
|||
|
DRS anna 65
|
|||
|
attächt... >78
|
|||
|
attribut. 104
|
|||
|
b/bik ..... .94
|
|||
|
b/buf..... .94
|
|||
|
b/seg ..... SE ae een ee een TI Tee Eee ıll
|
|||
|
BERKER. een REN 62
|
|||
|
BALICHSBlle, nennen „107
|
|||
|
BedingtesKoMpPIIENUN 8, ee elemente 4
|
|||
|
BELCH In een mann nennen ee Ia#6
|
|||
|
BEGIN .... ..44
|
|||
|
BELL nenn 1.262
|
|||
|
BEtrIC HEs väter ern 153
|
|||
|
BERWEENL nasse nn ea tee erneuern 49
|
|||
|
Bildschirm ............ ..63, 73
|
|||
|
BilASchirtmausgabern an energie er ee 64
|
|||
|
Bildschirmseite... enaseennenn eneegeaehenennen Re 63
|
|||
|
DIE neun Ererheeteneinheenee 62
|
|||
|
DEREK nenne Tenen e eneeeeeeee 109
|
|||
|
Dann .93, 150
|
|||
|
DURING ae ernennen een En Manage ee 94
|
|||
|
DIOCKS et .95, 136, 173, 187
|
|||
|
DIOCKSbÜT er... ernennen ee ee Eee 187
|
|||
|
BlOCKBEId... een een .... 136
|
|||
|
BIOSCK AD): mine tg een ER TETETTeITeTAI TE 7ı
|
|||
|
bounds .... ..44, 78
|
|||
|
BÜMER.. adsense Re ee NR Tee“ 95
|
|||
|
DI ee ae TIERE RE 152
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis 7938 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
187
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
capacities
|
|||
|
capacity ..
|
|||
|
COPA 4... nennen ernennen en ee
|
|||
|
capitalize
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
character.
|
|||
|
charout..
|
|||
|
BlöBT „un
|
|||
|
clearstack
|
|||
|
|
|||
|
Colon-Definition .. de ;
|
|||
|
Solondefinition. enunnanneuzunn nee mm 41
|
|||
|
|
|||
|
compilation. ..188, 192
|
|||
|
BORD enge euere e en 154
|
|||
|
Constant .. „113
|
|||
|
conteXt.... ..133
|
|||
|
convert. +
|
|||
|
convey .. .100
|
|||
|
|
|||
|
|
|||
|
|
|||
|
EOUNTFBITE: un nn
|
|||
|
|
|||
|
COUuNted nun nennseeeweenennneneenneenee een ennenenns
|
|||
|
counted String ... ei
|
|||
|
counted StFINBS .....ueesesensesesenensnsnsnsnnnnsensnnnensenensestsnnsnsnensnnennnnnnnsnnusnennennnnnen
|
|||
|
Countfeld, as am am 1110001010111 Be U un
|
|||
|
|
|||
|
CSWaP .... BETRETEN eretereleu ital 109
|
|||
|
ctoggle .. i
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=.200 ,- Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.8]
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
CHTOTEN Yan ansehen enneeeneeeereeeeeneeeeTeeeeeTg en eELE 65
|
|||
|
CUTOIK nennen 65
|
|||
|
GUN ON ee een een heine rturne nr RER ee een eine 133
|
|||
|
TURSDADE, nennen sun nenne ee were TTLTITERIEE 65
|
|||
|
GUTS OT er RA ansehen einatmen r rer eee aeeeesehn erregen 65
|
|||
|
CURSORHOSILIONL....nnenununnenuenen nen «69,68
|
|||
|
custom-remove. ‚r42
|
|||
|
One ecnessienunseininnniehmnneiessiegtenhieee nee rege u
|
|||
|
IR Mae unseeeeiende ...34
|
|||
|
d= ..34
|
|||
|
d.... ...66
|
|||
|
d.r 67
|
|||
|
d< .34
|
|||
|
= .34
|
|||
|
GO eiennailasenaneninnenennei ee een 34
|
|||
|
GRDSER nee en ee a esse antrae use 34
|
|||
|
Datei
|
|||
|
Anlegen. nem en 15
|
|||
|
EN RER RERREE cc 15
|
|||
|
Datei-Steuerblock . 84
|
|||
|
Dateivariable ........ 84
|
|||
|
Datenformat ....... «0
|
|||
|
Datenstrukturen.
|
|||
|
Datentyp ............
|
|||
|
debug .......
|
|||
|
decode...
|
|||
|
Dalai
|
|||
|
defining word
|
|||
|
Definition
|
|||
|
definitions ....
|
|||
|
DeKompiler ...en.a. een en en ea EN.
|
|||
|
UT ten nase ers enleei rapie en een Eee ee EEE
|
|||
|
delete...
|
|||
|
GERINE Te anne eneinene sense
|
|||
|
GELRACH nannten
|
|||
|
DictHonary u... &5
|
|||
|
DIEVIONANSDOIDLER, „moment seen EEE EEE ae 68
|
|||
|
digit? .... „81
|
|||
|
ÜRTGR ea ner anne nnlannaiae sanierte ernennen ERIET ES SEE Tee 99
|
|||
|
direct .... say ‚195
|
|||
|
DITEEROTY rpineieannnin see ee ee ee 85
|
|||
|
DIREKEZUSTIFT. nennen nenne ea 87
|
|||
|
USDIAY „ou N 187
|
|||
|
DIVISION... umnassenernegene nennen ein ee een EEE ER EEE ern ee ee 188
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DOESN near nenasanuneinuseh seine Teer ee EEE EERETETE 121, 156
|
|||
|
|
|||
|
drop
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DRUCRENSPOBLER anna nennen nennen 165
|
|||
|
Druckersteuerung
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Start des Compilers.....
|
|||
|
Tastenbelegung ...........
|
|||
|
|
|||
|
Smit are
|
|||
|
|
|||
|
empty-buffers. ei
|
|||
|
enipty-kKeysunue ungen
|
|||
|
emptybuf
|
|||
|
end-code
|
|||
|
|
|||
|
endloop En 5
|
|||
|
Entwieklungssysten... oo un
|
|||
|
OR 9 na III III FERN.
|
|||
|
ETASE ann
|
|||
|
error condition..
|
|||
|
ELLI ia
|
|||
|
EITOr# en
|
|||
|
errorhandler .......rnen se
|
|||
|
erweiterten Adreßraum....neenee.
|
|||
|
Escape aan Bereien
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ERTL Een ei aan anna ns
|
|||
|
BREcUTLIon VER nn
|
|||
|
ERISTET iin
|
|||
|
|
|||
|
extend.......
|
|||
|
|
|||
|
F83-NUMBER?.
|
|||
|
Faktorisierung
|
|||
|
Fakultäten
|
|||
|
Fallunterscheidung.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
fblock@....
|
|||
|
EFGB ss sie
|
|||
|
felose ...........
|
|||
|
Fehlercode.... u
|
|||
|
PERTETSUCHE nein en anne ent esse
|
|||
|
FELD
|
|||
|
|
|||
|
TRBEE una aaa ker aa IH 10H 15T aIdTkEkNSc UI. CE
|
|||
|
EIER erde Te er Te EEE Tee
|
|||
|
figFORTH. . nie
|
|||
|
DIIORR Rn rennen En ERTL TITTEN
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
12021 Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Eile-Interfäce res serien ae 84
|
|||
|
file ink u.
|
|||
|
file? cc...
|
|||
|
|
|||
|
FORTH-Screen ..
|
|||
|
|
|||
|
Er LEERE TEETSOT ERLERNTE TERENN 192
|
|||
|
TTEEHUNTET. 200 een nee een erarbeiten nalen een reines enejeelsge zeige 98
|
|||
|
freset ........ „181
|
|||
|
DEOINS er EEE a EEE EEE eh an eo ern te kennen an e khnceiuggeiye 189
|
|||
|
fromfile ... 116,91
|
|||
|
TSEARERE. re ennumnneenae ten ennee anne Pennes se TEL T ER ETaE Eee naerRe Sas een rende 194
|
|||
|
fseek .... .182
|
|||
|
fswap ... url
|
|||
|
DEI DER raenieeinn mn ee TEE TEN EEE REES Ha nee namen arrkeenia ne 98
|
|||
|
SOLE nee
|
|||
|
Fünkblonstaste as. mean enenae nennen een TREE EER TER EEET TREE 59
|
|||
|
dee 69
|
|||
|
gets „121
|
|||
|
SIODa N ee ee en u sedtnsnch seta ehe sehegehsussseeen 35
|
|||
|
Glossar
|
|||
|
BOBIT=S WORTEN. een el ee RE Tears uiesnnaeraune nee 33
|
|||
|
Arithmetischer Eunktionen 7... ee edenereeeanedenseneennesnedseenen ernennen 29
|
|||
|
ASSEMDIEL.....sereeoslemeenen nenne ...168
|
|||
|
MUSATUCKEN! VON ISOTEENS uni nenee haste sun enuenun ensure nenne 25
|
|||
|
DEDUEEINSR een een nalen ten nen sera he seen sen Sehen Se Fer eeeee 185
|
|||
|
KONDROLSTROKLURENE ee ee nen ee seems esemenubeeenneraiieenenengenwegiee 41
|
|||
|
Logik-undr Vergleichen. m er ee 32
|
|||
|
Multitasker.................. ...169
|
|||
|
Speicheroperationen .. et
|
|||
|
Stackoperationen ....... 36
|
|||
|
Derminal-VO nen anne san n denen eneenneen nennen een 62
|
|||
|
VEKtOLISTEHUNE- Bene hauen he ende ern see een ae een yo Tea EER Es 128
|
|||
|
VOKaDUWAar.. nennen samen nase ane en nee ann nalen eier en eeeironte 133
|
|||
|
SIOSSATY „ucuccuies
|
|||
|
GOTOXY..
|
|||
|
Na ee ee nee ee he ene tee ee
|
|||
|
Da Ole nn eenn eiEn SRTERRENET RT EHI Rh afarelıhanesiie
|
|||
|
Handle-Nummer
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis = 208 =
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Handlenummer .............
|
|||
|
|
|||
|
have. a Ai
|
|||
|
|
|||
|
headerless words.
|
|||
|
|
|||
|
Heap...
|
|||
|
|
|||
|
heap?
|
|||
|
|
|||
|
help
|
|||
|
|
|||
|
here
|
|||
|
|
|||
|
hide, su
|
|||
|
|
|||
|
high-Byte..
|
|||
|
|
|||
|
high-word uns:
|
|||
|
|
|||
|
KIA. „unannemnenemennene
|
|||
|
|
|||
|
Usa
|
|||
|
|
|||
|
De nme aeeufänete
|
|||
|
|
|||
|
immediate ............
|
|||
|
|
|||
|
immediate word...
|
|||
|
|
|||
|
immediate-BE uses; ...137
|
|||
|
INNE" CHAR nennen nannten nennen 169
|
|||
|
include .......... 27, 94
|
|||
|
INGEX neuere 26,
|
|||
|
INAITECL BIT. 137
|
|||
|
INPUT ame au 68, 127
|
|||
|
input stream .. nennen Taeie 198
|
|||
|
INT DU nennt ee ERTEILT EL IRDIT TEN TEL TEE ETTILTTELRER 48, 82
|
|||
|
Input: a. u 127, 129
|
|||
|
inputkol .....eccn... ER ERERETIERE ER 63
|
|||
|
Instructionpointer .. ae 146, 176
|
|||
|
Instruktionszeiger .. Kenssnssssunensensersnnennne 146
|
|||
|
INTEL-Prozessor..... RENTEN DEUNER 197
|
|||
|
INTELDIEN anna en 12, 152
|
|||
|
Interpreter ......cceessesennsssenseensnenensnrennnn nee aan 153, 189
|
|||
|
IP sen: ee 146, 176
|
|||
|
BE ne ET EEE EEE LEITERN 128
|
|||
|
IS-FEPEH resaun nam eann a a 01 II DL. 46
|
|||
|
|
|||
|
isdepth ....
|
|||
|
isfile ....
|
|||
|
isfile®@..
|
|||
|
|
|||
|
ee nmeseisgealee
|
|||
|
|
|||
|
Kaltstartwerte == y
|
|||
|
kernel .. nenn ee ee 123
|
|||
|
key..... 69, 117
|
|||
|
KENNE. Dennsis ninendereenemennsim nass arte UT BRETT TRETEN ET TEE 117
|
|||
|
keyboard.
|
|||
|
|
|||
|
KIIENE,. nennen 101
|
|||
|
Kommandozeile 177
|
|||
|
|
|||
|
Kommentare „sauer
|
|||
|
|
|||
|
Kompilationsadresse .............. Kaiser e 185
|
|||
|
Kompilationsvokabular Een nase SET 133
|
|||
|
Konsolentask .....uuresnsesenenennensenennnennensnnensenenensnsenenensnensnensssesnensenene era aa 165
|
|||
|
|
|||
|
lallocate..
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 204 .- Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Linefeed ..
|
|||
|
INK en
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Linkfeld .. 137
|
|||
|
TO hrs oezenlees 143
|
|||
|
a SEN
|
|||
|
IST RN ee selektieren 132
|
|||
|
listing ... 25
|
|||
|
BIER ln ee Te en eisernen ee 155
|
|||
|
Literatur
|
|||
|
Allgemeines über FORTH ... mir
|
|||
|
Kontrollstrukturen.......... 59
|
|||
|
NO ee rleährkeserstetene 111
|
|||
|
VO er esteniäte 93, 150, 189
|
|||
|
sa 103, 152
|
|||
|
leadfrom .....
|
|||
|
loadscreen ..
|
|||
|
JOCHMr ee et een
|
|||
|
ION ns ren
|
|||
|
LOOR Aus
|
|||
|
Low-Byte ...
|
|||
|
low-word
|
|||
|
ST er a ee tere 66
|
|||
|
ltype 74, 112
|
|||
|
einen las ee 34
|
|||
|
TE On ee 34
|
|||
|
MARER. en ee TE ET TETE SETI ehaer nee enssne une see 93
|
|||
|
makefile .... ..86, 93
|
|||
|
MAREVIEWAR Dee ENTE TEN su feeneeelnneeneete 131
|
|||
|
N KO ee ee een 160
|
|||
|
mass storage... „190
|
|||
|
MALEN rs TO:
|
|||
|
a RR ee ee N Teenie 119
|
|||
|
TR Eee ae reed EN ReIE Neschinatn.en scale ne ereumneninerelelen 30
|
|||
|
PA en hama ..85, 90
|
|||
|
MELACO DIA ae 123
|
|||
|
MONO TER ene eigen 21
|
|||
|
Methodsiu. 22... mm ehren 121
|
|||
|
a 90
|
|||
|
Mod el
|
|||
|
Module.. ..165
|
|||
|
More ..... „86, 94
|
|||
|
TON TS 108
|
|||
|
MSAOS rer eat 88
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis - 205 -
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
MSDOS-Fileinterface............ecnsssensseesesssenenssnnessnnnssnnenssnensaenunnansnnnsennnnnnnnnnen 88
|
|||
|
mülbtask seen ..165, 169
|
|||
|
Multitasking .......... nn +78, 165
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
notfound .. een kenn
|
|||
|
NUDEBYEE =nsstesentunuartersa areas BraENteTRE TEL EETEEETTETTTTERLETÄTTERE TEE TETTET ER TEIRE 808
|
|||
|
nullstring? .. 78, 76
|
|||
|
|
|||
|
|
|||
|
|
|||
|
number ......
|
|||
|
number? 81, 82
|
|||
|
Of ren 122
|
|||
|
DIE nn
|
|||
|
|
|||
|
„197
|
|||
|
OT uukeskaresreenautendiein ...189
|
|||
|
ON 134
|
|||
|
Onlyforthynsesseense „134
|
|||
|
OBEN nee ..101
|
|||
|
Operator...... ....66
|
|||
|
OPENATONEN euere Ben a III 121
|
|||
|
origin
|
|||
|
OUt Of range .eeeeeeenaesenenenensnsnnunensnensnsensnsesensnensenenensnsnsnsestsensnssnsansessssnsnssnnnen
|
|||
|
output ......... > RER, 73
|
|||
|
Output: ....... 130
|
|||
|
outputkol .... zur . u
|
|||
|
OVERn..n..r Er mise nenn hueersieire ee 37
|
|||
|
PADsncs „67, 68, 118
|
|||
|
Page ....... as = 20, 26, 64
|
|||
|
Parameter ee mnsienenwrrnimasemanaen ...96, 196, 138
|
|||
|
|
|||
|
Parameterfeld ‚ 138, 139, 146
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
path er 15, 26, 89
|
|||
|
PAUSE eeeennennseesssssensnnennnnnnnennsnersennenennnnnunnnnnnnnneseneenennnnnnnnnnnn 64, 69, 73, 179
|
|||
|
DON nice rTeansITrEe eure 67
|
|||
|
PC®@ .......
|
|||
|
|
|||
|
perform
|
|||
|
|
|||
|
Peripheriebaustein „ss... ana 67
|
|||
|
|
|||
|
Pfad ..
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
- 286-— Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3,81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DIACE. rat nt en rn ee NET T 110
|
|||
|
DEE nenn 25
|
|||
|
DOT ee ee en ee 67
|
|||
|
positional CASE ... &
|
|||
|
|
|||
|
POSENKSNOBATLIOND ne 7
|
|||
|
BREV an nett KERN IE I Rn 98
|
|||
|
PEINE ..66
|
|||
|
DRINLET zitieren 66
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Prorrstn aeun Er 113, 199
|
|||
|
Befehlsteil. ee Basen 213
|
|||
|
Datenteil... a er
|
|||
|
|
|||
|
prompt..... Er 158
|
|||
|
|
|||
|
Prozesur sn air 6
|
|||
|
Prozedurvariable.. 2
|
|||
|
PROZESSEN et nen re ulaieshinirisekimee een 165
|
|||
|
pthru....
|
|||
|
|
|||
|
Puffer 128
|
|||
|
DE ensure 39
|
|||
|
PUSTIR On ee ee 109
|
|||
|
DHUAIa. are
|
|||
|
|
|||
|
GIET aukaeerenn 1 72,82
|
|||
|
|
|||
|
BEQUTSO. ana 69
|
|||
|
recursive
|
|||
|
|
|||
|
Register... .. ...158
|
|||
|
Registerbelegung ... u ...158
|
|||
|
Registeroperationen er ee erinnern 159
|
|||
|
|
|||
|
Rekursion. nme FR „59, 190
|
|||
|
TE VE een 142
|
|||
|
|
|||
|
rendezvous ..
|
|||
|
|
|||
|
RERBEAT ...
|
|||
|
|
|||
|
TESLAT Lin
|
|||
|
|
|||
|
BESTOLENAGEO) variieren 64
|
|||
|
BESTrICH nee Di ne een 155
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOWIENSTOLCANET An er hen een ben nee bee ne nee 41
|
|||
|
REBUEN= Bastei een Tee 62
|
|||
|
REIEURNBCODELSE AM anne 107
|
|||
|
RE BBEMSIKRG Ki neuen ee ee me Re. warnen .39, 47, 191
|
|||
|
Retunnstackpolnter.niee nt en ...146
|
|||
|
TR aan ...143
|
|||
|
RINSDURLETAI IE een enge Men Rare ‚126
|
|||
|
roll.. OT
|
|||
|
TODE EN
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis ER
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ROW: nenne BETT EEE Er ETTLINGEN. 65
|
|||
|
RP. .146
|
|||
|
ED mn nahe engen near mean Bd
|
|||
|
PD: aa 1111111 a a aa 100 5) aaa hl ı1k 5Ä SICH. 39
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
runtime library
|
|||
|
|
|||
|
Dinner IE
|
|||
|
ee ale Fr ann Een ne ee ine nee ren
|
|||
|
save
|
|||
|
|
|||
|
save-buffers
|
|||
|
|
|||
|
SAVERLE. aneeaneneernTeRUmmEnSERmTIRRTE En Rn en 102
|
|||
|
savesystem. ....88
|
|||
|
SaVEeVided...unsmemernenennanenenennemenennnneenennennenenen nennen 64
|
|||
|
Scan III 71
|
|||
|
Scancode ......uescessenasensnunsennsnnnennnensnennssensennssnennenssnnsnessenssnnsnnssenansssnensersensnennn 69
|
|||
|
Schleifenindex su 0 42, 43
|
|||
|
Schleifenrumpf .......zcesesesensesenenennennsnnenennenen en ersehen 42
|
|||
|
Schleifenvariable . „119
|
|||
|
Schrittweite ....... PR IH. 43
|
|||
|
STE nstunnaiiieiseieienenigeeenihezungnern 25, 47
|
|||
|
Seren. ..198
|
|||
|
screen files... rl
|
|||
|
Screen-Files
|
|||
|
|
|||
|
BERN Denkens sangen
|
|||
|
|
|||
|
SEATch,.n
|
|||
|
|
|||
|
search order
|
|||
|
|
|||
|
SER eeeeaennensnnnnnnnenunsnennunsnensennssnnennneunsennsnennensseennennenennnsnennensnennsnnnennen en
|
|||
|
SEGMENT aan 3
|
|||
|
Segmentäadresse ......ncuesnensusnsussnnennsnensnenennnensnnennnnennenenennensnensnnesnnnnnnnnensnne nen 107
|
|||
|
Segmentrezistar nun a dl 9dkUiCCC——— 197
|
|||
|
Semaphore ........ ..167
|
|||
|
SETPABE nee Br 63
|
|||
|
Shadow-Konzept.......... za .16
|
|||
|
Shadow-Screens .........
|
|||
|
|
|||
|
SHOW. rasen
|
|||
|
|
|||
|
SHOWLOEER nn be IT LIU
|
|||
|
N een ran Äeen
|
|||
|
singletask &
|
|||
|
SKID. Minen Teer nr aheeen
|
|||
|
Brenn er erreE
|
|||
|
source.
|
|||
|
|
|||
|
SDAGES umschauen
|
|||
|
Spaltennummer..
|
|||
|
SPAN .ncccneneneeenenenn
|
|||
|
Speicheradressen ...
|
|||
|
Stack...
|
|||
|
Stacknotation ........
|
|||
|
Stackoperationen...
|
|||
|
Stackpointer ...........
|
|||
|
Standard-Prolog ....
|
|||
|
standard! „une
|
|||
|
|
|||
|
|
|||
|
|
|||
|
-.208 - Indexverzeichnis
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev, 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
SteVEranWeIsUNngeNn ans een er reaeeeeee
|
|||
|
Steuerzeichen .........
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
string literal.....
|
|||
|
Stringvariable ...
|
|||
|
Stringvergleich ... N:
|
|||
|
BIEDFEINBRTBIER ne nn nennen
|
|||
|
SIWAD, Messer seen ns ea ee na ae nrene
|
|||
|
Synonymdeklaration .
|
|||
|
DIE EIER. en errieen EReaimuaäaRe nen
|
|||
|
Systemverhalten
|
|||
|
|
|||
|
ANDPASSEHR nee Eee nn 123
|
|||
|
|
|||
|
beeinflussen
|
|||
|
|
|||
|
Taskwechsler..
|
|||
|
Tastendruck ...
|
|||
|
Teilstrings ..
|
|||
|
TENMINAL nun en Men Tresen irre tekeikegen insg testen
|
|||
|
MOXtZMienpreterensnue enter nung garten enter Eee Eee
|
|||
|
THEN er... szene
|
|||
|
|
|||
|
unnest.
|
|||
|
unravel ..
|
|||
|
UNTIL...
|
|||
|
|
|||
|
up®........
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Indexverzeichnis =m2093#=
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
FORTH-Gesellschaft e.V. PC-volksFORTH83 rev. 3.81
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ÜSERANER anne EEE 192
|
|||
|
Uservariable.... is ‚ 142,-192
|
|||
|
DU essen] 33
|
|||
|
VAarIabIa uncut ka a Ta alt CKICECEn 114
|
|||
|
Vektor ya:
|
|||
|
vektorielle Programmausführung sen een 124
|
|||
|
Vektorisierfüng..usssesnensenenenennenaneneennenennnen nennen mean nennen een een
|
|||
|
Verlassen des volksFORTH ..
|
|||
|
|
|||
|
WAGe0d. san. En
|
|||
|
Videokarte....neneuusesssnenensennenunnennrnnnenensununnnennnernesenennsnssnnnesenannsnsnsnsnnnsenenennnnnn
|
|||
|
VIEW anmnan
|
|||
|
|
|||
|
voc-iNkK..
|
|||
|
|
|||
|
Vocabularvy ses nn
|
|||
|
|
|||
|
WORS ummnssceineeenteiinteunnscemeeinn nenne een 15, 26
|
|||
|
Vokabular 132
|
|||
|
VokabMET-KONZEdE.. nennen nennen ee een 8
|
|||
|
|
|||
|
Vorwärts-Referenzen.
|
|||
|
|
|||
|
WOLTTEZISTET uruauussnaanan anna ran aa a0 1 ıctkaıuUrT RL LUAAI
|
|||
|
WOTLLYDEN .eeeceenenasessensnnnnsnnnsannnnennennensennennensnnnnnennennensensensnenssnnsnnenn ze
|
|||
|
KOT name
|
|||
|
Zahleneingabe .
|
|||
|
Zähler .............
|
|||
|
Zeichenattribut
|
|||
|
Zeichenkette....... ae ä
|
|||
|
Zeichenketten. u.
|
|||
|
|
|||
|
ZENENENGEL nen eier
|
|||
|
|
|||
|
Zeilennummer ....
|
|||
|
Zugriffsmethode
|
|||
|
|
|||
|
|
|||
|
|
|||
|
=. 210r® Indexverzeichnis
|
|||
|
|
|||
|
|