Ein einfacher Lisp-Dolmetscher in Umka

Die Entwicklung meiner statisch typisierten Skriptsprache Umka ist in die Phase eingetreten, in der die Sprachfunktionen anhand komplexerer Beispiele als Skripte in ein paar Dutzend Zeilen getestet werden mussten. Dafür habe ich mich entschieden, den Lisp-Interpreter in meiner Sprache zu implementieren . Ich wurde von einem pädagogischen Experiment von Rob Pike inspiriert, einem der Schöpfer der Go-Sprache. Pike hat kürzlich einen kleinen Lisp-Dolmetscher in Go veröffentlicht . Ich war besonders beeindruckt von Pikes Bemerkung, dass sich die Beschreibung des Dolmetschers auf einer Seite 13 des alten Lisp 1.5-Handbuchs befand.... Angesichts der syntaktischen Affinität von Umka und Go war es schwierig, der Versuchung zu widerstehen, einen solchen Interpreter in Umka zu erstellen, und zwar nicht durch buchstäbliche Übertragung von Pikes Code, sondern vollständig von Grund auf neu. Ich hoffe, dass die Kenner von Lisp und funktionalen Sprachen mir das naive Erstaunen verzeihen, mit Schönheit in Kontakt zu sein.

Für den Uneingeweihten kann Lisp dem Schock so nahe kommen. Wo ist die Grenze zwischen Code und Daten? Wo sind die Schleifen? Wo ist der Stapel? Die einzige Datenstruktur ist ein Baum. Es kann auch eine Liste darstellen. Es wird auch zu einem abstrakten Syntaxbaum, wenn das Programm analysiert wird. Es ersetzt auch den Stapel bei der Auswertung von Ausdrücken. Jeder Baum kann versucht werden, als Code ausgeführt oder als Daten verwendet zu werden. Anstelle von Schleifen - Rekursion. Es gibt nicht einmal Arithmetik im Kern der Sprache. Dennoch ist es eine vollständige Turing-Sprache, die unendlich erweitert und mit syntaktischem Zucker bestreut werden kann.

Das Definieren eines minimalen Lisp-Interpreters dauert weniger als eine Seite. Auf einer Strecke natürlich: Es verwendet Funktionen, die auf mehreren vorherigen Seiten definiert wurden. Der Lisp-Schöpfer John McCarthy scheint alles getan zu haben , um sich im Lakonismus zu übertreffen, und veröffentlichte schließlich ein Lisp- Mikrohandbuch, das die Sprachdefinition zusammen mit der Dolmetscherquelle enthielt - insgesamt zwei Magazinseiten. Richtig, er fügte der Überschrift hinzu: " Nicht die ganze Wahrheit ".

Der Kern der Sprache (hier geht es um die ältesten und einfachsten Dialekte) erfordert fünf Elementarfunktionen, vier Schlüsselwörter und zwei Konstanten, die nicht mit der Sprache selbst ausgedrückt werden können.

Grundlegende Sprachkonstrukte für diejenigen, die mit ihnen nicht vertraut sind
  • (car x) - Markieren Sie den Kopf der Liste x

  • (cdr x)x

  • (cons x y)x y

  • (atom x)x

  • (eq x y)x y

  • (cond (a x) (b y))x y a b

  • (quote x)x ,

  • ((lambda (x) a) y)a, x y

  • ((label ff (lambda (x) a)) y)ff

  • t

  • nil

, . , , , 6:

((label fac (lambda (n) (cond ((eq n 0) 1) ((quote t) (mul n (fac (sub n 1))))))) 6)

Lisp, . Lisp 1.5 13 , . . , REPL . , , , label defn, , . Lisp .

Da der gesamte Interpreter mit Rekursion und Baumverarbeitung durchsetzt ist, diente er als hervorragender Test für viele Funktionen der Umka-Sprache, vom Stapeln bis zur Speicherbereinigung. Ich denke, Umka hat den Test gut gemacht. Wir mussten nur zwei oder drei kleinere Fehler im Zusammenhang mit dem Export von Namen und erweiterten Typdeklarationen beheben. Der gesamte Interpretercode war weniger als 400 Zeilen lang.

Für diejenigen, die mit meinem Dolmetscher spielen und sich von Rob Pike über das Relais inspirieren lassen möchten, empfehle ich, den Ordner mit Beispielen aus dem Hauptzweig und nicht aus der neuesten Version zu nehmen .




All Articles