EVAL (SBX)

Aus C64-Wiki
Zur Navigation springenZur Suche springen
EVAL (SBX)
Syntax: EVAL <string>
Parameter
<string>: Zeichenkette (Variable oder Konstante)
Einordnung
Typ: Anweisung
Kontext: Auswertung, numerische Berechnung
Aufgabe: Ausführen von BASIC-Anweisungen, die in einer Zeichenkette übergeben werden
Abkürzung:
Token: $65 $18 (101 24)
Verwandte Befehle
BACK


Dieser Artikel beschreibt das Simons'-Basic-Extension-Schlüsselwort EVAL.


Die Anweisung EVAL führt die mit einer String-Variablen bzw. Zeichenkette übergebenen BASIC-Befehle aus.

Der Parameter kann ein zusammengesetzter String-Ausdruck sein. Er muss aber immer als letzten Befehl BACK enthalten, also mit ":BACK" enden.

Eine typische Anwendung ist die Berechnung eines mit der Zeichenkette übergebenen mathematischen Ausdrucks, etwa einer Gleichung. Da <string> wie eine BASIC-Zeile ausgewertet wird, können beliebige Anweisungen im Parameter enthalten sein, auch mehrere durch ":" getrennte Befehle sind möglich. Die im EVAL-String enthaltenen Variablen werden im normalen Bereich des BASIC verwaltet, d.h. außerhalb geänderte Werte wirken auch innerhalb und umgekehrt.

Ein leerer <string> erzeugt einen ?NULL STRING ERROR. Ist der Parameter keine Zeichenkette, wird ?TYPE MISMATCH ERROR und fehlt er, wird ?SYNTAX ERROR ausgegeben.

Implementierung[Bearbeiten | Quelltext bearbeiten]

Die EVAL-Routine liest den übergebenen String-Ausdruck ein, schreibt seinen Inhalt in den Eingabepuffer ab $0200 (512) und schließt diesen mit dem Wert 0 ab. Der Programmzeiger ($7A/$7B) wird gesichert in $C88A/$C88B und dann auf den Eingabepufferbeginn ($0200=512) gesetzt. Anschließend werden die enthaltenen BASIC-Befehle in Token umgewandelt und der Puffer dem BASIC-Interpreter zur Ausführung übergeben.

Der BACK-Befehl am Ende holt die gesicherten Werte des Programmzeigers zurück, so dass das Programm an der gespeicherten Stelle fortgesetzt wird. Wird kein BACK-Befehl gefunden, beendet EVAL das Programm.

Fehler[Bearbeiten | Quelltext bearbeiten]

Die EVAL-Routine von Simons Basic Extension enthält zwei Fehler:

  • Die Länge von <string> wird nicht auf den maximal zulässigen Wert (87) überprüft.
Der Benutzer muss hier selbst darauf achten, das sie nicht zu groß wird.
  • Die Länge der Zeichenkette <string> wird intern nicht korrekt ermittelt. Statt dessen wird das High-Byte der String-Adresse übergeben. Dieses ist normalerweise $08 = 8, wenn die Zeichenkette im Programm liegt, und $76 = 118, wenn sie auf dem String-Heap liegt. Im ersten Fall wird die Auswertung nach 8 Zeichen abgebrochen, was oft zu einem SYNTAX ERROR führt. Im zweiten Fall werden 118 Bytes ausgewertet, wodurch die auf den Eingabepuffer (88 Bytes groß) folgenden Bereiche in der erweiterten Zeropage bis $0276 überschrieben werden. Die Ausführung des Befehls dauert dabei spürbar lange.
Fehlerkorrektur: Dieses Problem lässt sich zum Glück einfach mit zwei POKEs beheben: POKE $8E52,105: POKE $8E53,0. Dadurch prüft das Y-Register nun auf die korrekte Länge aus der Zeropage-Adresse $69 = 105. Siehe dazu auch die Analyse in Simons Basic Extension Tipps.

Beispiele[Bearbeiten | Quelltext bearbeiten]

Fehlertest[Bearbeiten | Quelltext bearbeiten]

Das folgende Programmbeispiel dokumentiert einige Auswirkungen des Fehlers.

10 EVAL":BACK":L=PEEK($C888)
20 Q$=CHR$(34)
30 A$="?64:BACK"
40 B$="Y=64*100:BACK"
50 C$="X=4:Y=X*X:BACK"
60 A=LEN(A$):B=LEN(B$):C=LEN(C$)
70 PRINT "A":PRINTQ$A$Q$,A
75 PRINT Q$LEFT$(A$,L)Q$,L:PRINT
80 PRINT "B":PRINTQ$B$Q$,B
85 PRINT Q$LEFT$(B$,L)Q$,L:PRINT
90 PRINT "C":PRINTQ$C$Q$,C
95 PRINT Q$LEFT$(C$,L)Q$,L:PRINT
100 PRINT "A:";:EVAL A$
110 PRINT "B:";:EVAL B$:PRINT Y
120 PRINT "C:";:EVAL C$:PRINT Y

RUN
A
"?64:BACK"           8
"?64:BACK"           8

B
"Y=64*100:BACK"      13
"Y=64*100"           8

C
"X=4:Y=X*X:BACK"     14
"X=4:Y=X*"           8

A: 64
B:
READY.
BACK
 6400
C:
?SYNTAX  ERROR
READY.

Der falsche Wert für die String-Länge wird der Speicherstelle $C888 übergeben. Diese wird daher in Zeile 10 durch ein Dummy-EVAL initialisiert.

  • A: die Zeichenkette ist genau 8 Byte lang und wird daher korrekt ausgeführt.
  • B: von der Zeichenkette mit der Länge 13 werden 8 Zeichen verarbeitet. BACK ist nicht dabei.
  • C: wird nicht ausgeführt, da EVAL nach B das Programmende angenommen hat.
  • Durch die Eingabe von BACK im Direktmodus wird der Rest des Programms in Zeile 110 hinter EVAL B$ beginnend mit PRINT Y ausgeführt und Teil C führt zu einem SYNTAX ERROR.

Anwendung[Bearbeiten | Quelltext bearbeiten]

100 K$="Z=SQR(X*X+Y*Y)": REM EINGELESEN
110 PRINT CHR$(147):CSET1:B$=":BACK"
120 PRINT "X/Y-PUNKTE NAHE Z=1 FINDEN.":PRINT
130 PRINT "BITTE KOORDINATEN X UND Y EINGEBEN:"
140 X=0:Y=0:INPUT X,Y
150 IF X=0 AND Y=0 THEN END
160 EVAL K$+B$
170 Z1=ABS(Z-1)
180 IF Z<1 THEN Z$="KLEINER"
190 IF Z>1 THEN Z$="GROESSER"
200 IF Z1<0.01 THEN Z$="TREFFER"
210 PRINT Z;Z$
220 PRINT:GOTO140