FORTH für den NASCOM
Teil 5 von Günter Kreidl
1) Fehlerkorrektur
Leider hat sich beim Abtippen der FORTH-Erweiterungen im
Oktoberheft
ein Fehler bei der Funktion MESSAGE eingeschlichen, Richtig lautet sie:
: MESSAGE GETWORD ENTER VARBL CMPLW
CODEADR PEEKW
REPEAT CIN DUP COUT DUP 34 EQ UNTIL
DUP 8 EQ IF
POP DEC ELSE OVER POKEB INC THEN
LOOP
POP ZERO OVER POKEB INC CODEADR POKEW ;
Ich hoffe, der Fehler hat nicht zuviel Frust verursacht, und bedanke
mich bei Herrn Waltenberger, der ihn entdeckt hat.
2) Verbesserung der Initialisierungsroutine
Wer sich bei den
Erweiterungen bis zum Editor-Modus hindurchgearbeitet hat, der wird
eine unangenehme Erfahrung machen, wenn er den Editor-Modus einmal mit
RESET verlassen mußte; der Interpreter läßt sich nicht mehr starten - es
hilft nur neues Laden von Cassette. Hier läßt sich leicht Abhilfe
schaffen, da sich in der Initialisierungsroutine der erweiterten
Fassung einige "NOP's" befinden (von 1003H bis 100EH), Hier
kann man nun zwei Befehle eintragen, die den Interpreter auch nach
RESET im Editor-Modus wieder neu starten lassen. Da die jeweiligen
Adressen der Variablen INVAR und der Konstanten BLADR bei verschiedenen
Benutzern je nach Reihenfolge der Eingabe unterschiedlich sein mögen,
wollen wir sie durch den Interpreter suchen lassen:
BLADR PRINTHEX SPACE INVAR PRINTHEX
1747 1774 (Antwort des Interpreters)
Nun können wir bei 1003H eintragen:
1003 21 47 17 22 74 17.
Dadurch wird bei jedem Start als Einleseroutine
BLINK aufgerufen. (Der Editor-Modus arbeitet
mit BLINK und READSCR. Der Interpreter-Modus
hingegen kann nicht mit READSCR arbeiten.)
3) Compilererweiterungen
Die folgende Funktion " :: " ermöglicht es, neue
Compiler-Funktionen zu definieren. Zunächst wird eine
Interpreter-Funktion compiliert, dann wird deren Name an das Compiler-
| |
Dictionary angehängt und aus dem Dictionary des Interpreters wieder
gelöscht, Das Compiler-Dictionary wächst also "nach oben",
das Interpreter-Dictionary dagegen "nach unten",
: :: : NAMES PEEKW DUP PEEKB 3 + OVER OVER
MEMORY PEEKW SWAP MOVEBYTES SWAP
OVER + NAMES POKEW MEMORY PEEKW +
DUP MEMORY POKEW ZERO SWAP POKEB ;
Um die folgenden Funktionen zu verstehen,
die dem Compiler hinzugefügt werden, muß man
sich noch einmal die Arbeitsweise des Compilers
vergegenwärtigen: Außer Zahlen erkennt
er Interpreterfunktionen, die dann compiliert
werden, und Compilerfunktionen, die
sofort ausgeführt werden. Manchmal ist es
aber wünschenswert, im Compiler-Modus eine
Interpreterfunktion direkt ausführen zu lassen,
bzw. im "::"-Modus eine Compilerfunktion
eben nicht ausführen, sondern compilieren
zu lassen. Dies geschieht durch Voranstellen
der Zeichen ( ! , " ).
:: ! GETWORD NAMES PEEKW LOOKUP
IF EXECUTE
ELSE ERROR TYPE PRINTS THEN ;
4759 CONSTANT CNAMES zeigt auf variable
:: " GETWORD CNAMES PEEKW LOOKUP
IF CMPLW
ELSE ERROR TYPE PRINTS THEN ;
Nicht als bleibende Erweiterung des Systems,
sondern als ein Beispiel für die Anwendung
der oben definierten Funktionen sei eine
Kommentarfunktion mit "(" und ")" definiert:
:: ( REPEAT GETWORD INC PEEKB 41 EQ UNTIL
LOOP ;
Innerhalb der Klammern kann man nun beliebibigen Text in die Funktion
einfügen, der vom Compiler ignoriert wird (Vergl. "REM" in
BASIC!), Ich persönlich ziehe aber die Funktion MISCHTEXT vor, die
Kommentare in Kleinschrift erlaubt.
Ein zweites Beispiel (ebenfalls nicht als bleibende Erweiterung
gedacht) verwendet die Klammern als Wiederholungsfunktion:
:: ( ONE 4302 adresse der funktion tpush
CMPLW CMPLW " FOR ;
: : ) " LOOP ;
Beispiel für die Anwendung:
: COUNT ( I = SPACE ) ;
Auf die Eingabe "5 COUNT" antwortet der Interpreter mit:
1 2 3 4 5
|