Hallo,
vielleicht erinnert sich noch einer an meinen ersten Versuch eine eigene kleine Programmiersprache zu entwickeln: Das Ergebnis war dann mein Bot-Simulator. Damals noch sehr einfach gehalten und in Delphi geschrieben war diese einfache Skriptsprache damals recht faszinierend.
Da ich im Moment nicht allzuviel zu tun habe ich deshalb mal wieder Lust bekommen mich an einem derartigen Projekt zu versuchen. Das Ergebnis ist XQYZi (XQYZ's Interpreter [wobei XQYZ nur einer meiner 50 Nicks ist die ich gelegentlich mal hier und da verwende, ersetzt es also nach belieben durch Crash, Crash-Override, WordsBG, B.G., HChKn oder Patrick).
Das einfachste Beispiel fuer ein Programm in meiner Sprache waere: Screenshot
dafuer muesste man das allerdings ueber die Konsole xqyzi.exe -emain ausfuehren. Standardmaessig ist der Einstiegspunkt des Programmes die Funktion "main" in der Klasse Program, also etwa so wie hier:
Das besondere an XQYZi (bzw. der Sprache die er interpretiert) ist das es keine Zuweisungen im Klassischen Sinne gibt, also etwa a = b, sondern alles mehr oder weniger als Funktion geschrieben wird (Prefix Artig) wie in a ( b ). Ein anderes Beispiel waere eine Addition: a ( + ( 2 3 ) ). In Delphi waere es so geschrieben: a := (3 + 2);, wobei a noch deklariert werden muss, was hier (wie bei vielen Skriptprachen) nicht noetig ist. Ein komplexeres Beispiel was man bereits machen kann:
Math ist dabei eine kleine Bibliothek im inc-Verzeichnis des Interpreters.
Der Quellcode des Interpreters ist in C# verfasst (auch wenn die erste Version in Delphi geschrieben ist) und hat um die 1000 Zeilen Quellcode.
Der Quelltext ist halbwegs gut kommentiert, falls sich einer Tatsaechlich das Teil ansehen will.
Freigegeben ist das ganze unter der GPL (v3) und funktioniert unter Vista/.NET 3.5.
Bezueglich des Syntaxes noch ein kleiner Hinweis: Der 100% korrekte Weg ist jedes "Wort", also jeder Token des Quelltextes durch ein Whitespace zu separieren. Der Interpreter ist aber zumindest ein wenig tolerant, so laeft auch der folgende Quelltext:
Es gibt aber auch ne Menge Sachen die einfach nicht gehen, etwa main(){. Also wenn *irgendwas* schief geht und das Programm abstuerzt, mit ziemlicher Wahrscheinlich ein Syntax-Fehler.
Download (Source ist das mit Source im Namen, das andere ist Binaries und Beispielprogramm).
PS (keine Ahnung wo ich das noch anmerken koennte, aber faellt mit grad noch ein): Alle Variablen sind nur in der Momentanen Funktion gueltig, auch wenn man theoretisch Klassen-globale Funktionen verwenden kann wenn sie schon deklariert worden waeren. Steht aber recht weit oben auf meiner ToDo-Liste. Aber zunaechst brauche ich noch Bedingungen, auch wenn ich mir noch nicht ganz sicher ueber den Syntax bin.
Hmm... An sich eine Wunderbare Idee!
Und bisher scheint es auch wunderbar zu funktionieren.
ABER:
2+3
a ( + ( 2 3 ) ) 'ist ja noch einfach zu verstehen.
2+5*4+7 wäre dann ja:
Zwischen ( * ( 5 4 ) )
result ( + ( 2 Zwischen 7 ) )
Ok, das Funktioniert... Ist aber wenig viel...
Aber ich habe weiter probiert:
result ( + ( 2 Zwischen ( * ( 5 4 ) ) 7 ) )
müsste normal gehen. Nicht so in diesem Fall... (Programm muss beendet werden^^)
Naja, worum es mir geht ist, das ich das ganze wirklich extremst Interessant finde... Dich aber auch gleich auf ein paar Fehler hinweisen möchte, die das Coden unnötig erschweren...
Wenn ich jetzt nen Brett vor dem Kopf hatte, und das ganze sich auch besser lösen lassen würde, dann immer her damit =D
Ich habe deine Lösung mal ausprobiert, und gesehen das es zwar keinen Absurz verursacht, wie meine erste Funktionierende Möglichkeit, aber dennoch kein Ergebnis liefert.
Selbst wenn es eines geliefert hätte wäre es IMO falsch. Es brücksichtigt die "Punkt-vor-Strich"-Regel nicht.
Ich vermute mal, korrekt wäre result (*((+(2,4)),(+(4,7))). Das hat irgendwie was von LISP, oder?
...
So wie ich die Syntax jetzt verstanden habe, sind doch die Kommata nicht als Parameter-Separierer gedacht, sondern die Leerzeichen. Also wäre der Code eigentlich falsch. Aber naja, wenn's keinen Fehler wirft~
@Topic: Finde das ganze doch recht interessant. Die Syntax sieht lustig und ganz cool aus. Aber Calis hat ja schon ein paar Schwächen aufgezeigt. Bei einer recht simplen Berechnung alà 2+5*4+7 muss man sich den Kopf zerbrechen über die Platzierung der Funktionsaufrufe, Klammern, Leerzeichen, ...
Bin aber auch mal gespannt, wie sich das Projekt entwickelt. Hab auch schon einen kurzen Blick in den Quellcode des Interpreters geworfen, sah aber soweit gut aus, auch wenn ich's mir nur flüchtig angeguckt hab.
Wie gesagt, bleib am Ball. Ist auf jeden Fall 'ne coole Sache.
Geändert von The Best Isaac (05.03.2009 um 23:47 Uhr)
Sorry, konnte nicht frueher antworten, bin die ganze Woche schon irgendwie krank.
Zitat von Calis
result ( + ( 2 Zwischen ( * ( 5 4 ) ) 7 ) )
müsste normal gehen. Nicht so in diesem Fall... (Programm muss beendet werden^^)
...
Keine Klammern um das * Konstrukt herum, sonst nimmt er den Aufrug vor der Klammer nicht als Variable wahr sondern als Aufruf einer Funktion. Das Teil ist nicht besonders fehlertolerant.
result ( + ( 2 Zwischen * ( 5 4 ) 7 ) )
Zitat von DFYX
Das hat irgendwie was von LISP, oder?
...
Ein wenig vom Syntax angelehnt, aber es hat ja nicht wirklich Listen und in Lisp schreibt man afair Operatoren mit in die Liste, also (+ 2 3) statt + (2 3)
Zitat von Calis
result ( + ( ( * ( 5 4 ) ) 2 7 ) )
...
Unnoetige, bzw. verbotene Klammernutzung halt:
result ( + ( * ( 5 4 ) 2 7 ) )
Geht!
Ich hab mal die neue Version hochgeladen die auch if und = != <= < und so einen Kram enthaelt. Download-Link ist immernoch der gleiche. Als Beispiel hier nur anzufuehren:
(Ausschnitt)
und ein kleines Input/If Test Programm was auch beiliegt:
Hab letztens sogar mal versucht die erste Aufgabe von Project Euler damit zu loesen, was im Prinzip sehr einfach geht, aber bei der Mul3 Funktion haengt sich das Teil irgendwann auf (ganz knapp, da wenn ich bei ner hoeheren Zahl starten lasse geht es normalerweise noch), hatte aber wegen besagter Krankheit noch keine Zeit fuer weitere Versuche:
Ich liebe dieses Teil, da kann man richtig schön mit rumprobieren...
Warum funktioniert folgendes nicht?
Ich habe vorher auch probiert die Ask Funktion nicht auszulagern und den Code in der Main zu lassen. Sie funktionierte dann zwar, gab aber am ende folgendes aus: