Zaphod / Narcissus
JavaScript VM in JavaScript

von Philipp Hirch


Seminar Zaphod / Narcissus | Inhaltsverzeichnis | Einleitung | Interpreter | Narcissus | Beispiel | Fazit | Quellenverzeichnis

Interpreter


Interpreter == VM ?

Ein Interpreter definiert mit seiner Sprache immer eine VM, deshalb wird sich im folgenden immer auf ein Interpreter bezogen.


Allgemeiner Aufbau

Den Aufbau eines Interpreters kann man in Zwei Funktionen und einer Umgebungsvariable herunterbrechen, die sich gegenseitig wieder Aufrufen.
Kreislauf eines Interpreters

Die Erste Funktion dient zum Auswerten (evaluate,eval) eines Ausdrucks, sie teilt den Ausdruck in seine Bestandsteile auf (sie „parst“ den Ausdruck).

Sie besteht aus Zwei Parametern, einen Ausdruck und der Umgebungsvariable und gibt als Baumstruktur die Einzelteile des Statements zurück.

Beispiel:
eval( „1 + 6“, env ) → Addition der Operanden „1“ und „6“.

Die Zweite Funktion die zum Anwenden eines Ausdrucks.

Sie besteht aus einer Funktion und ihren Parametern und gibt ein Ergebnis zurück.

Beispiel:
apply( addition, [1,6]) → 7

Lässt man diese beiden Funktionen sich nun gegenseitig aufrufen, besitzt mein ein Interpreter.

Beispiel für den verschachtelten Aufruf: 4 * (1 + 6);

Eval( 4 * (1 + 6) ) → Multiplikation der Operanden „4“ und „(1+6)“
Apply( * , [ 4, (1+6)]) → 2 ter Operand kann nicht angewendet werden → eval
Eval( 1+6 ) → Addition der Operanden „1“ und „6“
Apply( + , [1,6]) → 1 + 6 = 7
Apply( * , [ 4 , 7 ]) → 28

Self-Interpreter

Eine spezielle Art von Interpretern sind Self-Interpreter.

Dies sind Interpreter die in jener Sprache geschrieben sind, welche sie später interpretieren sollen.

Daraus ergeben sich einige Vor- und Nachteile:

-
Die Definition der Self-Interpreter Sprache ist nicht wohlgeformt
z.B kann nicht dazu benutzt werden eine Sprache zu definieren
+


Meta-Circular Interpreter

Ein meta-circular interpreter, ist eine Sonderform eines Self-Interpreters, wo das Programm ein Primitiver Datentyp der Hostsprache ist. Dies wird Homoikonizität genannt.

Das bekannteste Beispiel eines MCI ist LISP und die meisten anderen Sprachen der Lisp-Familie.

In Lisp werden die grundlegenden Datenstrukturen (Listen,Symbole …) extern als S-Expressions repräsentiert, in welche auch Lisp-Programme abgebildet werden.

Ein Vorteil dieser Art der Implementierung ist das meiste Funktionalität aus dem Hostsystem übernommen werden kann.

The difference between self-interpreters and meta-circular interpreters is that the latter restate language features in terms of the features themselves, instead of actually implementing them. (Circular definitions, in other words; hence the name). They depend on their host environment to give the features meaning.
--Reginald Braithwaite, "The significance of the meta-circular interpreter".


Das Huhn oder Ei -Problem

Was im ersten Moment an einem Self-Interpreter komisch klingt, ist meist die Huhn oder Ei Frage, was war zuerst da. Oder in diesem Fall, wie kann ein Interpreter sich selbst interpretieren bevor er überhaupt existiert?

Das Geheimnis dahinter ist einfach.
Wie bei Self-Hosting Kompilierer, besteht auch hier der erste Interpreter aus einer anderen Sprache. Wie zum Beispiel:


Seminar Zaphod / Narcissus | Inhaltsverzeichnis | Einleitung | Interpreter | Narcissus | Beispiel | Fazit | Quellenverzeichnis