Um einen Computer zu programmieren, erteilt man ihm Anweisungen. Ein Computerprogramm ist daher eine Folge von Anweisungen. Eine Anweisung teilr dem Computer mit, was er tun soll: z.B. eine Berechnung durchführen, Daten einlesen oder Daten ausgeben.
Eins solches, menschenlesbares Computerprogramm nennt man auch einen Quelltext. Zum Erstellen eines Quelltextes kann man im Prinzip jeden beliebigen Editor verwenden. Achtung: Ein Textverarbeitungsprogramm ist völlig ungeignet!
Nachstehend ein ganz einfaches Beispielprogramm, das nur aus eine einzige Anweisung enthält:
#!/usr/bin/env sim writeln "Hallo Welt!"
(Quelltexte stehen in diesem Text stets in einem gelblich hinterlegten Kasten.)
Die erste Zeile eines jeden Simplicity-Programms ist die sogenannte Shebang-Zeile.
Die Shebang-Zeile teilt dem Linux-Betriebssystem mit, dass zur Ausführung des Programms der Simplicity-Compiler (sim) benötigt wird (der dazu natürlich installiert sein muss).
Um das Programm tatsächlich ausführen zu können, müssen wir den Quelltext zuerst abspeichern, z.B. unter dem Namen "hallo" (im aktuellen Arbeitsverzeichnis). Unter Linux müssen wir das Programm noch ausführbar machen, z.B. mit dem Konsolenbefehl
chmod a+x hallo
(Konsoleneingaben stehen in diesem Text stets in einem grünlich hinterlegten Kasten.)
Um das Programm auszuführen, brauchen wir nun nur noch seinen Namen auf der Konsole einzugeben
hallo
und schon erscheint die nachstehende Ausgabe auf der Konsole:
Hallo Welt!
(Programmausgaben stehen in diesem Text stets in einem bläulich hinterlegten Kasten.)
In diesem Beispiel ist "writeln" (write line) der Name der Anweisung. Der write-Anweisung kann man beliebig viele sogenannte Argumente übergeben. In unserem Beispiel gibt es nur ein einziges Argument, nämlich "Hallo Welt!"
Neben Texten können auch Zahlen und Rechenausdrücke als Argumente verwendet werden. Die Operatoren "+" und "-" sollten selbsterklärend sein; "*" ist der Multiplikationsoperator und "/" der Divisionsoperator.
Ein ganz einfaches Beispiel:
#!/usr/bin/env sim writeln 2+2
Nachdem wir das Programm abgespeichert und ausführbar gemacht haben, können wir es ausführen:
4
#!/usr/bin/env sim writeln 3*2+5 writeln 3*(2+5)
Wiederum abspeichern, ausführbar machen und ausführen:
#!/usr/bin/env sim writeln 3*2+5 writeln 3*(2+5)
Das vorangehende Beispiel zeigt uns, dass auch in Simplicity die üblichen, aus dem Mathematikunterricht bekannten Rechenregeln gelten und die Reihenfolge der Rechenoperationen durch Klammerung von Ausdrücken geändert werden kann.
Neben Operatoren ("+", "-", "*", "/") kann man auch mathematische Funktionen verwenden:
#!/usr/bin/env sim writeln sqrt(9) writeln cos(0)
Die Funktion sqrt berechnet die Quadratwurzel (engl. square root) und die Funktion cos den Cosinus seines Arguments.
Alle Argumente einer Funktion müssen stets in Klammern stehen. Die öffnende Klammer muss in Simplicity unmittelbar, also ohne Abstand, auf den Funktionsnamen folgen.
Wie man ein Programm ausführt, sollte nun bereits klar sein.
3 1
Um unsere Programme leichter lesbar zu machen, können wir für beliebige Ausdrücke (Zahlen, Texte, Berechnungen) symbolische Namen vergeben.
Im nachstehenden Programm sind dies "Länge" (mit dem Wert 20), "Breite" (mit dem Wert 10) und "Fläche" (mit dem Produkt aus "Länge" und "Breite").
Die Definition eines solchen symbolischen Namens ist selbst eine Anweisung. Diese besteht aus einem Dollarzeichen ("$") unmittelbar gefolgt vom gewünschten Namen. Das Argument der Anweisung legt den Wert fest, der an den symbolischen Namen gebunden wird. Da dieser Wert später nicht mehr geändert werden kann, spricht man auch von einer Konstanten.
Man kann einen so definierten symbolische Namen auch als Argument oder in einem Ausdruck verwenden. Er steht dann für den an den Namen gebunden Wert.
#!/usr/bin/env sim $Länge 20 $Breite 10 $Fläche Länge*Breite writeln Fläche
200
In diesem Kapitel werden wir ein größeres Anwendungsbeispiel implementieren, das eine für Schüler sehr wichtige Frage beantwortet: "Wie lange muss ich heute noch in der Schule hocken?"
Ein Scope oder Block ist eine Gruppe zusammengehöriger Anweisungen. Im Quelltext wird ein Scope durch einen Doppelpunkt eingeleitet. Der Doppelpunkt steht in der Regel am Ende einer Zeile. Die Anweisungen des Scopes stehen dann in den nachfolgenden Zeilen. Diese sind allesamt gegenüber der Zeile, die den Doppelpunkt enthält, eingerückt.
Scopes können nach Belieben geschachtelt werden, d.h. ein Scope kann beliebige Unterscopes enthalten.
Für den Sonderfall, dass ein Scope nur eine einzige Anweisung enthalten soll, kann man dies auch rechts neben den Doppelpunkt (allerdings nach einem Abstand) schreiben, z.B.:
if a > 10: writeln "a ist zu groß"
Alle Symbole die mittels $ oder $$ deklariert werden haben sogenannten lexikalischen Scope. D.h., sie sind nur innerhalb des Scopes, in dem sie deklariert wurden bekannt und auch dort erst ab der Stelle ihrer Deklaration.
Man kann das Wort Scope auch als Geltungsbereich übersetzen.
Neben den mittels $ bzw. $$ deklarierten lexikalischen Symbolen, gibt es noch die sogenannten dynamischen Symbole. Diese müssen (und können) nicht deklariert werden. Solange ein Symbol nicht als lexikalisch (mittels $ bzw. $$) deklariert wurde, ist es ein dynamisches Symbol.
Die Zuweisung an ein dynamisches Symbol erfolgt wie gewohnt mit Hilfe des !-Operators.
Das Haupteinsatzgebiet dynamischer Symbole ist die Definition von globalen Funktionen und Prozedure in Bibliotheken.
Im Gegensatz zu lexikalischen Symbolen, sind dynamische Symbole auch außerhalb des Scopes, in dem sie definiert wurden bekannt, falls sie aus diesem Scope heraus aufgerufen wurden.
Ein Beispiel:
$p: writeln f(2) writeln f(4) do: !f: [x] [x*x] p !f: [x] [3*x/2]
4 16
if x >= 10 & x <= 20:
write "
x liegt im Bereich von 10 bis 20
if
x >= 10 & x <= 20:
write "
x liegt im Bereich von 10 bis 20
:
write "
x ist entweder kleiner als 10 oder größer als 20
unless x < 10 || x > 20:
write "
x liegt im Bereich von 10 bis 20
cond
[x >= 10 & x < 20]:
write "
x liegt im Bereich von 10 bis 20
[x >= 20 & x <= 30]:
write "
x liegt im Bereich von 20 bis 30
:
write "
x ist entweder kleiner als 10 oder größer als 30
case x
10 .. 19:
write "
x liegt im Bereich von 10 bis 19
20 .. 30:
write "
x liegt im Bereich von 20 bis 30
:
write "
x ist entweder kleiner als 10 oder größer als 30
$$i 1 while [i <= 10]: writeln i " x " i " = " i*i !i i+1
1 x 1 = 1 2 x 2 = 4 3 x 3 = 9 4 x 4 = 16 5 x 5 = 25 6 x 6 = 36 7 x 7 = 49 8 x 8 = 64 9 x 9 = 81 10 x 10 = 100
$$i 1 until [i > 10]: writeln i " x " i " = " i*i !i i+1
1 x 1 = 1 2 x 2 = 4 3 x 3 = 9 4 x 4 = 16 5 x 5 = 25 6 x 6 = 36 7 x 7 = 49 8 x 8 = 64 9 x 9 = 81 10 x 10 = 100
$$i 1 10->times: writeln i " x " i " = " i*i !i i+1
1 x 1 = 1 2 x 2 = 4 3 x 3 = 9 4 x 4 = 16 5 x 5 = 25 6 x 6 = 36 7 x 7 = 49 8 x 8 = 64 9 x 9 = 81 10 x 10 = 100
1->to 10: [i] writeln i " x " i " = " i*i
1 x 1 = 1 2 x 2 = 4 3 x 3 = 9 4 x 4 = 16 5 x 5 = 25 6 x 6 = 36 7 x 7 = 49 8 x 8 = 64 9 x 9 = 81 10 x 10 = 100