|
![]() |
Hallo liebe DP'ler
Ich meld mich mal wieder mit ner neuen Komponente ![]() Einleitung Nach dem Release meines ![]() Allgemeines Sysygy Script Engine ist eine Skript-Sprache die den Dialekt Pascal benutzt. Es werden bei weitem nicht alle Features der Delphi-Sprache unterstützt, aber immerhin ein kleiner Teil. Beim kompilieren erstellt der Parser Byte-Code, denn dann von einem Interpreter ausgeführt wird. Durch die Einbindung einer Script-Sprache ist es Möglich, ein Programm von Benutzern erweiterbar zu machen, ohne dass das Hauptprogramm neu kompiliert werden muss. Dadurch wird ein enormes Spektrum an neuen Möglichkeiten eröffnet. Man kann mit der Script-Sprache z.B. aufwendige, mathematische Funktionen berechnen, die einen einfachen Matheparser überfordern würden. Denn dadurch, dass Ergebnisse in Variablen zwischengespeichert werden können und diese dann mit if-Anweisungen verschieden weiterbearbeitet werden können, kann man z.B. verschachtelte Funktionen erstellen, die nicht an das Programm gebunden sind sondern vom Benutzer während der Laufzeit des Programms geändert werden können (z.B. ein Funktionszeichner). Ebenfalls ist es möglich, dass sich ein Programm selbst dynamisch anpasst: bei manchen Gelegenheiten ist es extrem schwer, bestimmte Situationen im Code zu verarbeiten. Möglich ist es zwar immer, doch manchmal kann der Aufwand extrem groß sein. An dieser Stelle könnte das Programm z.B. dynamisch neuen Quelltext erstellen, der dann von der Script-Sprache ausgeführt wird. Sehr hilfreich wird eine Script-Sprache, wenn man z.B. ein Programm per "Fernwartung" erweitern oder ausbessern möchte und man nicht so einfach an die Datei herankommt. Dann kann es z.B. ausreichen, ein neues/verbessertes Script einfach an das Programm zu schicken und somit die Funktionalität erweitern/ausbessern. Das mag jetzt zwar so klingen, als könnte man ganz einfach in einen PC eindringen - doch man sollte bedenken: das Script kann nur Funktionen ausführen, welche das Programm der ScriptEngine bereits zur Verfügung stellt. (Übertrieben) gesagt kann man nicht aus einer 2 KB-Exe ein Monsterprogramm machen. Ein kleines Beispiel wäre: ich habe eine StringListe, die sortiert werden soll. Die Vergleichsfunktion der einzelnen Zeilen lager ich in ein Script aus, das den Vergleich übernimmt. Das Script kann dann nur die Vergleichsfunktion beeinträchtigen aber z.B. nicht die Liste leeren. Was unterstützt die Script-Sprache
Was wird noch nicht unterstützt Hier mal eine kurze Liste mit Featuren, die ich noch plane einzubauen:
Sysygy "Klassen" vs Delphi Klassen ![]() In der Script Engine ist es möglich, externe procedures und functions zu deklarieren. Um diese besser und übersichtlicher zusammenzubringen und den OOP-Gedanken nachzugehen hab ich mich dazu entschlossen, externe Methoden in Klassen zusammenfassen zu können. Dabei unterstützten diese "Pseudo"-Klassen auch Vererbung. An einem Beispiel kann man das ganz gut erklären: Nehmen wir an, ich habe in Delphi folgende Komponente, die ich in der Script-Sprache verfügbar machen will:
Delphi-Quellcode:
Jetzt kann man in der Script-Sprache eine Pseudo-Klasse erstellen, mit deren Hilfe man auf diese Klasse zugreifen kann.
type
TMyClass = class(TComponent) private FSomeThing : string; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; function GetSomeThing: string; end; Script-Code
Delphi-Quellcode:
Diese Klasse speist man jetzt in einen Exporter, der daraus eine Delphi-Unit erstellt (ist mit dabei). Diese Delphi-Unit bindet man dann in das Delphi-Projekt ein - den Rest übernimmt die Script-Sprache. Ein Script könnte jetzt z.B. so aussehen:
unit myClassUnit;
uses Classes; // für TComponent type TMyClass = class(TComponent) public function Create(AOwner: TComponent): TMyClass; function GetSomeThing; end;
Delphi-Quellcode:
Die Klassen in der Script-Engine sind also sozusaggen nur eine Zusammenfassung von externen Methoden. Es können keine Variablen oder Script-Interne Methoden hinzugefügt werden. Das will ich aber noch ändern, jedoch dauert das eine ganze weile.
program Test;
uses myClassUnit; var p: TMyClass; s: string; begin p := p.Create; // hier ist ein großer Unterschied zu Delphi s := p.GetSomeThing; if p.ComponentCount = 0 then // da die Klasse von TComponent abgeleitet ist exit; end; Bisherige Einschränkungen
So, genug der negativen Sachen ![]() Was muss ich zusätzlich noch an Komponenten installieren? Die Script-Sprache an sich braucht keine zusätzlichen Komponenten - es werden nur die Klassen benutzt, die bereits bei Delphi mit dabei sind. Auch die mitgelieferten Demos (bis auf eine) kommen mit den Komponenten aus. Jedoch werden für die Kompilierung der Haupt-GUI zwei große Sachen benötigt:
Wie installiere ich die Sysygy Script Engine? Der Parser sowie der Interpretor sind Komponenten mit relativ wenig properties. Von daher ist eine Installation eigentlich nicht vorgesehen. Am besten, ihr kopiert die Quelltexte in einen beliebigen Ordner und fügt diesen in den Suchpfad von Delphi dazu. Ein fertiges Package wird jedoch nicht mitgeliefert. Welche Delphi-Version muss ich haben? Also garantieren kann ich für nichts. Ich hab die Script-Sprache mit Delphi 7 erstellt, von daher sollte alles, was neuer als D7 ist, damit klar kommt. Ich weiß nicht, wie weit runter man mit den Delphi-Versionen gehen kann. Jedoch sollte es schon möglich sein, Funktionen als overloaded zu deklarieren. Sysygy Script Engine + FreePascal Mit Version 0.99e hab ich es geschafft, die Script-Engine FreePascal-kompatibel zu machen. Ich habe (bis auf ein paar einzelne Scripts) nicht viel ausprobiert, aber es hat alles bisher geklappt. Da ja FPC auf sehr vielen Plattformen funktioniert, weiß ich nicht, ob wirklich alles unterstützt wird. x86-CPUs sollten ziemlich sicher funktionieren, bei x86-64Bit-Systemen weiß ich nicht, ob alles funktioniert. Die die LCL ja nicht 100%ig kompatibel mit der VCL ist, sind einige Funktionen der Include-Dateien uSygInc*.pas nicht mit eingebunden. Zwar erscheinen diese Funktionen noch im Script, jedoch führt ein Aufruf zu einer Exception. Ich werde aber noch die neuen Includes {$IFDEF FPC} und {$IFDEF DELPHI} in die Header mit einbauen und somit die nicht verfügbaren Funktionen für das Script unsichtbar machen - jedoch dauert das noch etwas. Bisher gibt es noch Probleme mit den Units uSygIncGraphics und uSygIncWinCRT, die anderen sollten aber funktionieren. Wie benutze ich die Komponenten? Ich habe ein paar Demoprogramme in den Download mit hinein gepackt, an denen man (hoffentlich) gut sehen kann, wie man die Komponenten am einfachsten benutzt. Hier ist aber mal der grundlegende Aufbau zur Benutzung
Delphi-Quellcode:
Was ist in den Download dabei?
uses
uSygParser, // für TSygScript_Parser uSygRunTime; // für TSygScript_RunTime var Compiler : TSygScript_Parser; // das Objekt muss natürlich vorher erstellt werden Executor : TSygScript_RunTime; // ... und das Objekt sollte auch vorher erstellt werden function CompileAndExecute(ScriptSource: string): boolean; begin // Ergebniss vorinitalisieren result := False; // Script kompilieren if Compiler.ParseScript(ScriptSource) then begin // ByteCode im Executor speichern Executor.FillData(Compiler.OutputData); // Script ausführen Executor.Run; result := True; end; end;
Lizenz: Das "Hauptprogramm" sowie die Komponente ist unter der BSD-Lizenz lizenziert. Der Lizenztext liegt ebenfalls nochmal im Hauptordner der zip-Datei sowie als Header in jeder .pas-Datei. Falls jemand eine andere Lizenz haben will, bin ich gerne bereit, eine einzelne, personengebundene Lizenz nach Absprache zu erstellen. Und nun ... ... wünsch ich viel Spaß beim ausprobieren ![]() Change-Log Version: 0.99h (15.10.2008)
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0 |
Delphi 7 Professional |
#71
![]() Die Script engine ist für mich immer noch interessant. Du schreibst aber, dass du an einer Neuen Scriptengine dran bist. Hast du schon einen Zeitpunkt für das erste Release und macht es dann besser wenn man auf diese neue Engine wartet?
![]() Bzw wie kompatibel wird die neue zu der (schon hervorragenden) "alten" Engine sein?
Generell wird die Script-Engine nicht sehr kompatibel zu der alten sein. Die Virtual Machine ist komplett neu geschrieben und ist somit nicht von den Daten kompatibel. Jedoch wird die Syntax ebenfalls wieder Pascal sein, somit ist die Sprache an sich sehr kompatibel. Jedoch hab ich die Syntax auch schon erweitert und die Funktionen werden in virtuellen statischen Klassen in der Script-Engine zusammengefasst. Hier mal ein Beispiel
Delphi-Quellcode:
Jedoch wird man Projekte an die neue Script-Engine etwas anpassen müssen. Die grundlegenden Funktionen bleiben in etwa gleich, jedoch mit etwas anderen Parametern:
//alte Script-Sprache
var i: integer; begin i := StrToInt('123'); WriteLn(IntToStr(i)); end; // Neue Script-Sprache var i: integer; begin i := Convert.StrToInt('123'); Console.WriteLine(Convert.IntToStr(i)); // Entweder so Console.WriteLine(i); // oder so - overloaded Methoden werden unterstützt end;
Delphi-Quellcode:
Wann der erste Release sein wird, kann ich noch nicht sagen - aber ich beeil mich
var PE: TSE2RunTime;
begin PE := Compiler.Compile('program Test; begin end.'); try if PE <> nil then // korrekt kompiliert begin // z.B. PE.SaveToFile('Compiled.dat'); PE.Initialize; PE.Run; PE.Finalize; end; finally PE.Free; end; // Oder so PE := TSE2RunTime.Create; try PE.LoadFromFile('Compiled.dat'); PE.Initialize; PE.Run; PE.Finalize; finally PE.Free; end; end; |
![]() |
Delphi 11 Alexandria |
#72
Meine Frage zielte auch eher auf die Anwendung. Das sich intern viel geänder hat, habe ich erwartet.
Markus Kinzler
|
![]() |
FreePascal / Lazarus |
#73
![]() Hallo little Dave,
ich verfolge deine Scriptengine nun schon seit einer Weile gespannt. Das Projekt hört sich auf jeden Fall hochinteressant an. Vielleicht kann ich die Script Engine ja in Andorra 2D integrieren um so die GUI, Gameplay usw. steuern zu können. Weiter so, Andreas |
![]() |
Lazarus |
#75
Gibt es welche Updates?
Oder Testversionen? Es warten wohl viele auf diese Script-Engine =) MfG, Eugen |
![]() |
Delphi 7 Professional |
#76
Sorry das ich mich in letzter Zeit (bzw. in den letzten 6 Monaten) nicht mehr so oft melde. Das kommt halt davon wenn man nicht mehr Student sondern Azubi ist.
Also ich arbeite immer noch an der Script-Sprache. Jedoch hat sich bei mir ein heftiger Design-Fehler eingeschlichen, der mich dazu zwang, relativ viel neu zu schreiben. Jedoch bin ich langsam wieder auf nem grünen Ast. Ich kann bereits externe Klassen in die Script-Engine einbinden, externe Objekte erstellen, Funktionen aufrufen und Properties abfragen und setzen. Es ist also schon sehr viel erledigt. Zudem kann ich auch einzelne Script-Funktionen aus dem Programm heraus aufrufen. Jetzt werd ich mal schauen, dass ich die Classes-Unit einbaue. Dann hat man schonmal nen guten Grundstock. Was jedoch noch nicht funktioniert sind arrays und records. Jedoch denke ich, dass ich es diesmal besser umsetzen werden. Eine Testversion würd ich ja schon gerne mal hochladen, jedoch bin ich mir nicht mehr so ganz sicher, ob das wirklich gut ist. Nach dem letzten großen Design-Fehler bin ich mir nicht mehr sicher, wieviel sich an den Aufrufen noch ändern wird. Es gibt noch viel zu tun, jedoch versuch ich in den nächten 2 Monaten was ordendliches fertig zu stellen. Für garantieren kann ich leider nichts. |
![]() |
Lazarus |
#77
![]() weiter so =) ![]() Also nicht mehr lange und die ScriptEngine unterstützt Classes? also OOP? MfG, Eugen |
![]() |
Delphi 7 Professional |
#78
Naja, so weit bin ich dann noch nicht.
Also ich hab die Script-Engine so aufgebaut, dass ich sie möglichst einfach erweitern kann. Alle wichtigen Eigenschaften wie virtual, overload, override, usw. sind schon als reservierte Worte drinnen und werden auch schon ein wenig benutzt. Jedoch kann man noch keine eigenen Klassen erstellen. Aber ich will das irgendwie hinbekommen ![]() |
![]() |
|
#79
moin !
bin eben per zufall hier im thread gelandet und wollte es ja nicht glauben ! das beschriebene hier ist die lösung meines prob ! ich habe ein recht großes projekt in delphi mit TjvInterpreter geschrieben... nun wollte ich das ganze ding neu coden, diesmal aber für linux und dafür fpc nutzen. wie sicherlich bekannt ist tjvinterpreter nicht fpc tauglich und so setze ich jetzt mal alles auf dieses pferd hier ! das ist echt klasse und ich freue mich schon auf deine umsetzung... hast ein weiteren fan der sein nächstes projekt mit deinem code schmücken möchte ![]() greez, sky... EDIT: so, habe nun doch noch etwas weiter im netz nach scripting möglichkeiten gesucht. nun brauch ich eine doch recht objektive meinung deines interpeter: kannst du dich mit dem ![]() greez & thx, sky... |
![]() |
Delphi 7 Professional |
#80
Hallo,
ich meld mich mal wieder *g*. In meinem letzten Post (der ja doch schon 2,5 Monate her ist ![]() Aber ich hab mir gedacht - machste mal nen Status-Update - und diesmal ist es wirklich ein gewaltiger Schritt, den ich geschafft habe, denn .... *trommelwirbel* ... ich habe es endlich geschafft, dass meine Script-Sprache objekt-orientiertes Arbeiten möglich macht. Im Klartext heißt das, dass man jetzt im Script eigene Klassen erstellen kann (natürlich mit Variablen, Properties, Methoden, Constructor, Destructor, ...) und diese dann im Script verwenden. Dabei unterstützten die Klassen sogar Vererbung (also Zugriff auf Public/Protected-Properties/Methoden von Eltern-Klassen, Methoden überschreiben, usw.). Am besten ich zeig euch mal ein kleines Script:
Delphi-Quellcode:
Wenn ich dieses Script ausführe, bekomme ich folgende Ausgabe in der Konsole:
program Project1;
type TTest1 = class(TObject) private FABC : integer; public constructor Create; override; procedure Test1; virtual; property ABC : integer read FABC; end; TTest2 = class(TTest1) public constructor Create; override; procedure Test1; override; end; TTest3 = class(TTest2) public procedure Test1; override; end; { TTest1 } constructor TTest1.Create; begin inherited; Self.FABC := 1024; Console.WriteLine('TTest1.Create'); end; procedure TTest1.Test1; begin Console.WriteLine('TTest1.Test1'); end; { TTest2 } constructor TTest2.Create; begin inherited; Console.WriteLine('TTest2.Create'); end; procedure TTest2.Test1; begin inherited; Console.WriteLine('TTest2.Test1'); end; { TTest3 } procedure TTest3.Test1; begin inherited; Self.FABC := 512; // nur sichtbar, da in gleicher Unit Console.WriteLine('TTest3.Test1'); end; { Main } var p: TTest1; // Der Basistyp begin p := TTest3.Create; // eine abgeleitete Variante davon try Console.WriteLine(p.ABC); p.Test1; Console.WriteLine(p.ABC); finally p.Free; end; end.
Code:
Das ist jetzt schon etwas schwerer zu lesen, aber wenn man mal mit dem Finger den Ablauf so langgeht, dann kann man das schon ganz gut nachvollziehen.
TTest1.Create
TTest2.Create 1024 TTest1.Test1 TTest2.Test1 TTest3.Test1 512 Die Script-Klassen kann ich auch aus dem Programm heraus erstellen und die Vererbung nutzen. Hier mal ein wenig Pseudo-Code (Pseudo-Code, da die einzelnen Methoden noch ein paar andere Paremter haben, die hierfür erstmal nur stören würden)
Delphi-Quellcode:
Das ganze funktioniert schon sehr gut - jedoch muss ich den Compiler noch viel strenger machen. Zudem muss ich noch den Befehl "reintroduce" einbauen sowie den "inherited" - Befehl erweitern. Außerdem warten noch ein paar Bugs darauf, gelöscht zu werden.
var aClass : Pointer;
aObject : Pointer; method : Pointer; begin // erstmal die Klasse suchen, die erstellt werden soll aClass := FRunTime.CodeAccess.FindClass('TTest3'); // dann eine "Instanz" der Klasse erzeugen aObject := FRunTime.CreateClass(aClass); // dann noch die Basis-Methode suchen method := FRunTime.CodeAccess.FindMethod('TTest1.Test'); // und dann die Methode mit "aObject" als Self-Parameter aufrufen FRunTime.Call(method, [aObject]); // -> jetzt wird im Script nicht die Funktion TTest1.Test ausgeführt, sondern // jetzt wird die Funktion "TTest3.Test" ausgeführt. end; Ich hoffe, dass ein paar Leute eine object-orientierte Script-Sprache brauchen könnten - ich brauch sie auf jeden fall ![]() Grüße |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |