Programmiersprachen
LVA 185.208, VU, 3 Ects, 2012 S
1 2+eine Anwendung des Operators
+auf 1 und 2, die als Ergebnis 3 liefert. Der Ausdruck
1 2 3 4+*-wird zu 1-(2*(3+4)) = -13 ausgewertet: Der erste Operator addiert die direkt davor stehenden Argumente 3 und 4 zu 7, der Operator
*wird auf die nach der Addition direkt davor stehenden Argumente 2 und 7 angewandt, und schließlich
-auf 1 und 14.
Neben Zahlen sind auch Zeichen als Daten verwendbar (am besten als ASCII-Zeichen, aber andere Codierungen sind ebenso erlaubt).
So stehen a
und b
einfach nur für die entsprechenden Zeichen, und \n
steht für Newline, \t
für den Tabulator und so weiter.
Durch Voranstellen von \
verlieren Operatoren, eckige Klammern (siehe unten) und Ziffern ihre üblichen Bedeutungen und werden als Zeichen betrachtet.
Jedoch wird intern nicht zwischen Zahlen und Zeichen unterschieden.
Beispielsweise sind A
und 65
unterschiedliche externe Darstellungen derselben Zahl.
Ausdrücke in eckigen Klammern werden nicht gleich ausgewertet.
Einige Operatoren verarbeiten geklammerte Ausdrücke als Argumente.
Zum Beispiel wird [2*]
als Argument des Operators @
selbst als Operator gesehen, der ein Argument mit 2 multipliziert.
Der Ausdruck 3[2*]@
wird zu 3 2*
bzw. 6 ausgewertet.
@Eingaben in diese Liste geschrieben.
Zur Vereinfachung können für den Stack, die Eingabeliste, geklammerte Ausdrücke, Zahlen, etc. (vernünftig gewählte) Maximalgrößen festgelegt werden, bei deren Überschreitung eine Fehlermeldung ausgegeben wird. Nach einer Fehlermeldung kann die Programmausführung abgebrochen werden.
\...:
\folgenden Zeichens wird auf den Stack gelegt. Für
\n,
\t, etc. wird jedoch der Code für Newline, Tabulator, etc. auf den Stack gelegt.
0bis
9:
[und
]:
\davor):
+,
-,
*,
/,
%,
&,
|,
=,
<,
>):
%zur Berechnung des Divisionsrestes) und einfachen Vergleichen, wobei & bzw. | das logische UND bzw. ODER darstellen. Diese Operatoren nehmen die zwei obersten Elemente vom Stack und legen das Ergebnis auf den Stack. Wenn ein Argument keine Zahl sondern ein geklammerter Ausdruck ist, soll ein Fehler gemeldet werden, ebenso wenn ein Argument von & bzw. | kein Wahrheitswert (0 steht für
wahrund 1 für
falsch) ist. Ausgenommen hiervon ist nur
=: Wenn
=auf zwei gleiche geklammerte Ausdrücke oder zwei gleiche Zahlen angewandt wird, soll als Ergebnis 0 (wahr) zurückgegeben werden, sonst 1 (falsch). Bei nichtassoziativen Operationen ist auf die Reihenfolge der Argumente zu achten:
4 2-und
4 2/und
2 4%sollen jeweils 2 ergeben, und
4 2>und
2 4<sollen
wahrliefern. Ein Fehler soll gemeldet werden, wenn das zweite Argument von / oder % gleich 0 ist.
~:
!:
#:
@:
@keinerlei Auswirkung; das Argument wird wieder unverändert auf den Stack gelegt.
":
':
?:
^, Top-of-Stack direkt neben
^, Einträge durch Leerzeichen getrennt) und die Eingabeliste (rechts von
^, nächstes zu verarbeitendes Zeichen direkt neben
^). Pfeile zwischen solchen Zustandsbeschreibungen zeigen Zustandsänderungen durch Ausführung von Operationen an.
Das erste Beispiel zeigt eine bedingte Anweisung:
Auf dem Stack wird 0 (wahr) oder 1 (falsch) erwartet.
Abhängig davon soll der eine oder andere geklammerte Ausdruck ausgewertet werden.
Wir legen zuerst den Ausdruck für den wahr-Zweig [9]
und dann den für den falsch-Zweig [9~]
auf den Stack und führen einen Ausdruck [4!5#2+#@]
aus, der die eigentliche bedingte Anweisung darstellt.
Die folgenden Abarbeitungsschritte zeigen, was passiert, wenn am Stack zuvor 0 gelegen ist:
0 ^[9][9~][4!5#2+#@]@
--> 0 [9] ^[9~][4!5#2+#@]@
--> 0 [9] [9~] ^[4!5#2+#@]@
--> 0 [9] [9~] [4!5#2+#@] ^@
--> 0 [9] [9~] ^4!5#2+#@
--> 0 [9] [9~] 4 ^!5#2+#@
--> 0 [9] [9~] 0 ^5#2+#@
--> 0 [9] [9~] 0 5 ^#2+#@
--> [9] [9~] 0 ^2+#@
--> [9] [9~] 0 2 ^+#@
--> [9] [9~] 2 ^#@
--> [9] ^@
--> ^ 9
--> 9 ^
Das nächste Beispiel zeigt anhand der Berechnung von 3 Faktorielle, wie man rekursive Routinen realisieren kann. Zur Vereinfachung kürzen wir den Ausdruck [3!3!1-2!1=[]5!C@3#*] durch A ab, wobei C für den Ausdruck [4!5#2+#@] aus dem vorigen Beispiel steht. Beachten Sie, dass A und C hier nur zur Vereinfachung der Lesbarkeit dient. Im Taschenrechner sollte statt A und C jeweils der entsprechende geklammerte Ausdruck vorkommen.
3 ^A3!4#3!@3#
--> 3 A ^3!4#3!@3#
--> 3 A 3 ^!4#3!@3#
--> 3 A 3 ^4#3!@3#
--> 3 A 3 4 ^#3!@3#
--> A 3 ^3!@3#
--> A 3 3 ^!@3#
--> A 3 A ^@3#
--> A 3 ^ 3!3!1-2!1=[]5!C@3#* 3#
--> A 3 3 ^!3!1-2!1=[]5!C@3#* 3#
--> A 3 A ^3!1-2!1=[]5!C@3#* 3#
--> A 3 A 3 ^!1-2!1=[]5!C@3#* 3#
--> A 3 A 3 ^1-2!1=[]5!C@3#* 3#
--> A 3 A 3 1 ^-2!1=[]5!C@3#* 3#
--> A 3 A 2 ^2!1=[]5!C@3#* 3#
--> A 3 A 2 2 ^!1=[]5!C@3#* 3#
--> A 3 A 2 2 ^1=[]5!C@3#* 3#
--> A 3 A 2 2 1 ^=[]5!C@3#* 3#
--> A 3 A 2 1 ^[]5!C@3#* 3#
--> A 3 A 2 1 [] ^5!C@3#* 3#
--> A 3 A 2 1 [] 5 ^!C@3#* 3#
--> A 3 A 2 1 [] A ^C@3#* 3#
--> A 3 A 2 1 [] A C ^@3#* 3#
...
--> A 3 A 2 A ^@ 3#* 3#
--> A 3 A 2 ^ 3!3!1-2!1=[]5!C@3#* 3#* 3#
--> A 3 A 2 3 ^!3!1-2!1=[]5!C@3#* 3#* 3#
--> A 3 A 2 A ^3!1-2!1=[]5!C@3#* 3#* 3#
--> A 3 A 2 A 3 ^!1-2!1=[]5!C@3#* 3#* 3#
--> A 3 A 2 A 2 ^1-2!1=[]5!C@3#* 3#* 3#
--> A 3 A 2 A 2 1 ^-2!1=[]5!C@3#* 3#* 3#
--> A 3 A 2 A 1 ^2!1=[]5!C@3#* 3#* 3#
--> A 3 A 2 A 1 2 ^!1=[]5!C@3#* 3#* 3#
--> A 3 A 2 A 1 1 ^1=[]5!C@3#* 3#* 3#
--> A 3 A 2 A 1 1 1 ^=[]5!C@3#* 3#* 3#
--> A 3 A 2 A 1 0 ^[]5!C@3#* 3#* 3#
--> A 3 A 2 A 1 0 [] ^5!C@3#* 3#* 3#
--> A 3 A 2 A 1 0 [] 5 ^!C@3#* 3#* 3#
--> A 3 A 2 A 1 0 [] A ^C@3#* 3#* 3#
--> A 3 A 2 A 1 0 [] A C ^@3#* 3#* 3#
...
--> A 3 A 2 A 1 [] ^@ 3#* 3#* 3#
--> A 3 A 2 A 1 ^ 3#* 3#* 3#
--> A 3 A 2 A 1 3 ^#* 3#* 3#
--> A 3 A 2 1 ^* 3#* 3#
--> A 3 A 2 ^ 3#* 3#
--> A 3 A 2 3 ^#* 3#
--> A 3 2 ^* 3#
--> A 6 ^ 3#
--> A 6 3 ^#
--> 6 ^
Die Ein- und Ausgabe sollte keine allzugroßen Schwierigkeiten bereiten.
Beispielsweise soll der Ausdruck [\n"E"i"n"g"a"b"e":"\ "?@'] zunächst in einer neuen Zeile am Display Eingabe:
anzeigen, auf eine Eingabe warten, den eingelesenen Ausdruck ausführen und schließlich das Ergebnis (oberstes Stackelement) ausgeben.
Der Ausdruck [[\nEingabe:\ ]"?@'] sollte genau dasselbe machen.
Praktischer Hinweis: Zum Programmieren bzw. Starten des Taschenrechners sind lange und komplizierte Ausdrücke einzugeben. Am einfachsten ist dies zu erledigen, wenn als Display und zur Eingabe eine einfache Textkonsole verwendet wird. Dann kann man Programme rasch durch Copy-and-Paste eingeben.