commit 412a71a7c0d604919046c788820f1d264cf31af7 Author: Max Rottenkolber Date: Sun Jul 26 20:44:19 2015 +0200 Add MicroLisp documentation. diff --git a/software/microlisp/microlisp-bedienungsanleitung.mk2 b/software/microlisp/microlisp-bedienungsanleitung.mk2 new file mode 100644 index 0000000..361dc54 --- /dev/null +++ b/software/microlisp/microlisp-bedienungsanleitung.mk2 @@ -0,0 +1,210 @@ +< Die _MicroLisp_-Sprache + + Die _MicroLisp_-Sprache ist ein klassischer Lisp-Dialekt. + MicroLisp-Quelltext besteht aus Ausdrücken und Kommentaren. Ein + Kommentar beginnt mit einem Semikolon ({;}) und wird durch einen + Zeilenumbruch beendet. Kommentare werden ignoriert. Ein Ausdruck ist + eine so genannte _S-Expression_ die speziell interpretiert wird. + + Der Begriff _S-Expression_ bezeichnet eine einfache Sprache zum + ausdrücken von Datenliteralen. Sie wird in den meisten Lisp-Dialekten, + so wie auch in _MicroLisp_, als Repräsentation für Daten und Quelltext + benutzt. + + Eine _S-Expression_ ist entweder ein Atom oder eine Liste. Atome sind + Literale für Symbole, Zahlen, Zeichen und Zeichenketten. Eine Liste + ist eine Folge von _S-Expressions_ umschlossen von Klammerzeichen, {(} + und {)}. + + #code 7.4 Beispielhafte _S-Expressions_ mit Kommentaren.# + ;; Atome: + banane ; Das Symbol banane + 12 ; Die Zahl 12 + 1/2 ; Die Zahl 0.5 + #\A ; Das Zeichen 'A' + "Hallo, Welt!" ; Die Zeichenkette 'Hallo, Welt!' + + ;; Listen: + (1 2 3) ; Eine Liste die die Zahlen 1, 2 und 3 beinhaltet + () ; Die leere Liste, äquivalent zum Symbol nil + (name ("Joe" "Peng") ; Eine Liste die das Symbol name, eine weitere + alter 37) ; Liste aus zwei Zeichenketten, noch ein Symbol + ; alter und die Zahl 37 enthält + # + + Quelltextbeispiel 7.4 veranschaulicht den Syntax von _S-Expressions_ + und verdeutlicht wie atomare Datentypen mithilfe von Listen kombiniert + werden können um Datensätze darzustellen. _MicroLisp_-Ausdrücke sind + Datensätze die nach folgenden Regeln interpretiert werden. + + Jeder Ausdruck hat einen Wert. Alle atomaren Datentypen bis auf + Symbole, also Zahlen, Zeichen und Zeichenketten, werden als Literale + interpretiert. Sie haben also sich selbst als Wert. Symbole werden als + Bezeichner interpretiert. Sie haben den Wert an den sie gebunden + wurden. Listen werden als Prozeduraufrufe interpretiert. Der Wert des + ersten Ausdrucks in der Liste ist die Prozedur und die Werte der + restlichen Ausdrücke sind die Argumente, die der Prozedur übergeben + werden. Prozeduraufrufe haben ihr Ergebnis als Rückgabewert. + + Bezeichner können mithilfe von zwei Axiomen an Werte gebunden werden. + Das {define}-Axiom bindet Bezeichner global an Werte. Ein + _MicroLisp_-Programm kann beliebig viele {define}-Ausdrücke haben, + diese müssen jedoch zusammen am Anfang des Programms stehen. Das + {lambda}-Axiom ermöglicht die Konstruktion von anonymen Prozeduren mit + Parametern und einem Rückgabewert. Innerhalb einer Prozedur werden die + Bezeichner der Parameter an die übergebenen Werte gebunden. + + #code 7.5 Beispielprogramm zu {define} und {lambda}.# + ;;; define-Ausdrücke am Anfang des Programms + ;; Syntax von define: (define SYMBOL WERT) + (define globaler-bezeichner 1) + ;; Syntax von lambda: (lambda (SYMBOLE...) AUSDRÜCKE...) + (define prozedur (lambda (x) (add x globaler-bezeichner))) + + ;;; Restliche Ausdrücke + 3 ; hat den Wert 3 + globaler-bezeichner ; hat den Wert 1 + prozedur ; hat eine Prozedur als Wert + (prozedur globaler-bezeichner) ; hat den Wert 2 + # + + {define} übernimmt ein Symbol, das nicht ausgewertet wird, und einen + Wert als Parameter. {lambda} übernimmt eine Liste von Symbolen, die + ebenfalls unausgewertet bleiben, und eine beliebige Anzahl von + Ausdrücken, die zur Zeit des Prozeduraufrufs ausgewertet werden. Der + Wert des letzten Ausdrucks ist der Rückgabewert der Prozedur. + + Es gibt zwei weitere Axiome die ihre Parameter nicht wie Prozeduren + auswerten. Das primitive Kontrollkonstrukt {cond} und {quote}. {cond} + verhält sich wie das klassisch verkettete {IF-ELSE}-Statement. Es + übernimmt eine beliebige Anzahl von Listen die Ausdrücke beinhalten als + Parameter. Jede Liste stellt einen Fall dar. {cond} durchläuft die + Fälle und wertet dabei die Bedingung, den Ersten Ausdruck des Falls, + aus. Wenn der Wert der Bedingung nicht das Symbol {nil} ist werden die + restlichen Ausdrücke des Falls ausgewertet und der Wert des letzten + Ausdrucks ist der Rückgabewert von {cond}. Falls kein Fall zutrifft ist + der Rückgabewert von {cond} das Symbol {nil}. + + Das {quote}-Axiom verhält sich wie die Quotation in natürlicher + Sprache. Es übernimmt einen Ausdruck und verhindert dessen + Auswertung. Es ermöglicht die Darstellung von literalen Listen und + Symbolen innerhalb Ausdrücken. + + #code 7.6 Beispiele zu {cond} und {quote}. Das Symbol wird {t} + konventionell als positiver Wahrheitswert benutzt. Tatsächlich ist aber + nur ein Wert "falsch" und zwar das Symbol {nil}, beziehungsweise die + leere Liste.# + ;; Beispiele zu cond + (cond (nil "Falsch") ; gibt "Wahr zurück" + (t "Wahr")) + (cond (12 "Nicht nil") ; gibt "Nicht nil" zurück + (t "Wahr")) + (cond (nil "Falsch")) ; gibt nil zurück + + ;; Beispiele zu quote + (quote banane) ; gibt das Symbol banane zurück + (quote (1 2 3)) ; gibt eine Liste die die Zahlen 1, 2 und 3 beinhaltet + ; zurück + # + + Die {cond}-Ausdrücke in Beispielquelltext 7.6 funktionieren, weil die + Bezeichner {nil} und {t} standardmäßig an die Symbole {nil} und {t} + gebunden sind. Alternativ hätte auch {(quote nil)} und {(quote t)} + geschrieben werden können. + + Zur dynamischen Erzeugung von Listen werden drei Axiome {cell}, {first} + und {rest} zur Verfügung gestellt. {cell} übernimmt einen beliebigen + Wert und eine Liste als Parameter und gibt eine Liste zurück. Die + resultierende Liste besteht aus dem übergebenen Wert und dem Inhalt + der übergebenen Liste. {first} und {rest} übernehmen eine Liste als + Parameter und geben jeweils das erste Element und die restlichen + Elemente der Liste zurück. + + #code 7.7 Beispiele zu {cell}, {first} und {rest}. Die letzten beiden + Beispiele funktionieren weil Literale Zeichenkette tatsächlich nur eine + Schreibweise für Listen von Zeichen ist. {"Joe"} ist also äquivalent zu + {(quote (\#\J \#\o \#\e))} und {(cell \#\J (cell \#\o (cell \#\e nil)))}.# + (define liste1 (cell 1 nil)) ; liste1 bezeichnet die Liste (1) + (define liste2 + (cell 1 (quote (2 3)))) ; liste2 bezeichnet die Liste (1 2 3) + (first nil) ; gibt nil zurück + (rest nil) ; gibt nil zurück + (first liste1) ; gibt die Zahl 1 zurück + (rest liste1) ; gibt das Symbol nil zurück + (rest liste2) ; gibt die Liste (2 3) zurück + (first (rest liste2)) ; gibt die Zahl 2 zurück + (first "Joe") ; gibt das Zeichen 'J' zurück + (rest "Joe") ; gibt die Zeichenkette "oe" zurück, + ; bzw. eine Liste die die Zeichen 'o' + ; und 'e' enthält + # + + Für die Datentypen der Sprache sind primitive Prädikate vordefiniert. + {procedure?}, {cell?}, {symbol?}, {number?} und {character?} übernehmen + jeweils einen Wert und geben das Symbol {nil} zurück wenn der + entsprechende Typ nicht mit dem Typ des Wertes übereinstimmt. + {symbolic=}, {numeric=} und {character=} übernehmen jeweils zwei + Werte des entsprechenden Typs und geben das Symbol {nil} zurück wenn + die übergebenen Werte nicht äquivalent sind. + + Für Zahlen gibt es zusätzlich das Vergleichsprädikat {numeric>} welches + zwei Zahlen übernimmt und das Symbol {nil} zurück gibt wenn die erste + übergebene Zahl nicht größer ist als die zweite übergebene Zahl. + Außerdem können zwei Zahlen mit den Axiomen {add}, {subtract}, + {multiply} und {divide} jeweils addiert, subtrahiert, multipliziert und + dividiert werden. {modulo} dividiert zwei Zahlen mit Rest und gibt den + Rest zurück. + + Für Ein- und Ausgabe werden die Axiome {read}, {write} und {delete} + zur Verfügung gestellt. {read} übernimmt eine Quelle und gibt einen + Wert zurück. Eine Quelle ist eine Liste die Zeichenketten beinhaltet + und designiert einen Dateipfad oder die Standardein- oder Ausgabe im + Fall der leeren Liste ({nil}). {read} liest einen Wert aus der + angegebenen Quelle und gibt es zurück. Im Falle eines Fehlers wird das + Symbol {nil} zurückgegeben. {write} übernimmt einen Wert und eine + Quelle und schreibt den Wert in die angegebene Quelle. Wenn ein Fehler + beim Schreiben auftritt gibt {write} das Symbol {nil} zurück. {delete} + übernimmt eine Quelle und löscht den dort persistierten Wert. Wenn der + Löschvorgang nicht erfolgreich war gibt {delete} das Symbol {nil} + zurück. + + Damit sind alle Regeln und Axiome der _MicroLisp_-Sprache definiert. + Alles andere wird durch Kombination der Erkärten Axiome definiert. + +> + +< Die _MicroLisp_-Entwicklungsumgebung + + Die _MicroLisp_-Entwicklungsumgebung stellt zwei Befehle für die + interaktive Auswertung von Ausdrücken zur Verfügung. {evaluate} + übernimmt einen Ausdruck als Parameter und gibt seinen Wert zurück und + {include} übernimmt eine Quelltextdatei und wertet sie aus. + + Für die Kompilation von Quelltextdateien nach _ANSI C_ gibt es den + {compile-files}-Befehl. Er übernimmt eine beliebige Anzahl von + Quelltextdateien und generiert ein entsprechendes _C_-Programm. Das + resultierende _C_-Programm hat den Namen der letzten Quelltextdatei mit + der Endung {.c}. + + Der {define-macro} Befehl dient zur Definition von Makros. Makros + müssen in _Common Lisp_ Kodiert werden. {define-macro} übernimmt ein + Symbol, eine Lambda-Liste und einen Prozedurkörper. Das Symbol dient + als Name unter dem die Makroprozedur, die durch die Lambda-Liste und + den Prozedurkörper definiert wird, registriert wird. Bevor Ausdrücke + Ausgewertet oder Kompiliert werden, werden gegebenenfalls + Makroausdrücke mit Ausdrücken ersetzt, die von den entsprechenden + Makroprozeduren generiert wurden. + + #code 7.7 Beispielhafte Makrodefinition von {if}.# + ;; if: Wenn CONDITION nicht nil ist wird THEN ausgewertet, ansonsten + ;; wird ELSE ausgewertet. + (define-macro if (condition then &optional else) + `(cond (,condition ,then) + (t ,else))) + + ;; Wenn das if-Makro definiert ist würde beispielsweise der Ausdruck + ;; (if (numeric> 2 1) 3 4) zu (cond ((numeric> 2 1) 3) (t 4)) + ;; ausgedehnt werden. + # + +>