Da man irgendwie keine Blogs/Worklogs/whatever erstellen kann, erstelle ich hier nun einen Thread. Es soll quasi ein Worklog sein.
Nunja was ist GLScriptBasic? GLSB soll die gleiche Syntax wie GLB haben, also auch gleiche Funktionen und so. Der einzige Unterschied ist halt dass das ganze direkt interpretiert wird, also ohne C++/C Code Erzeugung. Dadurch kann man mehr Platformen unterstützen usw.
Die Vorteile wären:
* Sehr schnelles Kompilieren: Da hier kein komplizierter Code erzeugt wird sondern simpler Zwischencode (Bytecode)
* Jede beliebige Platform: Anders als fürs normale GLBasic muss es für die Zielplatform keinen gcc geben oder dergleichen, sie muss ledliglich eine Turing Vollständige Sprache haben (was JEDE Platform hat). Da man ja "nur" eine VM schreiben muss Ich hab so Visionen von GLSB für Handys usw.
* Einfache Erweiterbarkeit: Der Code wird im Gegensatz zu GLBasic frei ersichtlich sein, womit jeder der etwas davon versteht den Code erweitern kann
* Verwendung von GLBasic als Scriptsprache: Wer kennt es nicht? Man will ein MMORPG/Strategiespiel/anderes Mega Projekt programmieren und hat keine vernünftige Möglichkeit den Spielinhalt auszulagern, damit ist nun Schluss.
Die Nachteile:
* Langsamere Laufzeit: Da der Code interpretiert wird gibt es einen entsprechenden Overhead
* Nicht alle Syntaxelemente umsetzbar: Höchstwahrscheinlich werde ich auf PROTOTYPE und CALLBACK verzichten, da diese zu implementieren ein sehr hoher Aufwand darstellt. Vorallem Inline C++ ist vollkommen unmöglich.
* Keine iPhone Version: Da Apple strikt gegen solche "Interpretierte" Sprachen ist wird es keine iPhone Version geben.
Da es mehr Vorteile als Nachteile gibt, finde ich dass es sich lohnt.
Folgende Dinge funktionieren bereits:
IF - ELSE - ELSEIF - ENDIF
WHILE - WEND
FOR - NEXT
REPEAT - UNTIL
LOCAL - GLOBAL
ToDo (nach der Reihenfolge):
SELECT - CASE - DEFAULT - ENDSELECT
Funktionen und Subs (sind im Prinzip dasselbe)
Arrays
Alle Funktionen "wrappen", damit man *fast* jeden GLBasic Code auführen kann.
Technik: GLSB ist intern ein single pass Compiler, das heißt er arbeitet den Code in einem Durchgang durch. Dadurch ist er besonders schnell. Implementiert wurde er als Rekursiver Top Down Parser, dieser ist eine sehr stabile und auch leicht wartbare Compilerbau Variante.
OpCodes gibt es bereits 25. Von Rechnen bis hin zur Variablen Verwaltung ist alles dabei.
Wie das mit der Lizenz aussehen wird, werde ich mit Gernot weiter besprechen, wir haben da bereits eine Idee.
Folgende Codes werden bereits ohne Fehler kompiliert und ausgeführt:
Standard Syntax:
STDOUT " Hallo "+5
IF 5*9-99
STDOUT 1*4 + " Hallo Welt"
ELSEIF TRUE
STDOUT "GAGA"
ELSEIF FALSE
STDOUT "DABA"
ELSE
STDOUT 73
ENDIF
IF TRUE
GLOBAL k=200
STDOUT k
ENDIF
STDOUT k
LOCAL i
LOCAL j
j=800
STDOUT j
i=100
STDOUT "Variable var: "+i
i=0
WHILE i<10
STDOUT "i: "+i
STDOUT "j: "+j
j=j-1
i=i+1
WEND
FOR i=0 TO 10 STEP 2
STDOUT "For: "+i
NEXT
Simples Pong:
GLOBAL SpielerX=320, BallX=320, BallY=240,Angle=RND(360), Life
Life=4
WHILE TRUE
DRAWRECT SpielerX,50,80,20,RGB(255,0,0)
IF KEY(205)
SpielerX=SpielerX+4
ENDIF
IF KEY(203)
SpielerX=SpielerX-4
ENDIF
BallX=BallX+COS(Angle)*8
BallY=BallY+SIN(Angle)*8
IF BOXCOLL(SpielerX,50,80,20,BallX,BallY,32,32)
BallX=BallX-COS(Angle)*8
BallY=BallY-SIN(Angle)*8
Angle=360-Angle
ENDIF
IF BallX>640-32 OR BallX<0
Angle=180-Angle
ENDIF
IF BallY>480-32
Angle=360-Angle
ENDIF
IF BallY<0
Life=Life-1
BallX=320
BallY=240
Angle=RND(360)
ENDIF
DRAWRECT BallX,BallY,32,32,RGB(0,255,0)
PRINT "Leben: "+Life,10,450
IF Life<1
END
ENDIF
SHOWSCREEN
WEND
mfg
He, das ist ne Coole Idee :-*
Ich hatte auch schonmal an sowas gedacht, aber mir fehlt hierfür der Skill.
Hi.
Nette Idee, doch glbasic läuft doch schon unter Linux, Windows und MacOSX und das nativ recht schnell... Dafür einen Interpreter zuschreiben bedeutet schnelleres compilieren der Programme aber dafür einbusen bei der Geschwindigkeit. Bringt daher eher für die Entwicklung etwas und das Release sollte man weiterhin nativ compilieren...
Ich für meinen Teil bin immer froh wenn ich kein Framework oder einen Interpreter mit schicken muss.. Das hatte mich auch am Anfang sehr an .Net gestört. Der Einzige Vorteil ist die Bytecode file welche für neue Zielsysteme nicht neu compiliert werden muss. Jedoch muss für jedes Zielsystem ein Interpreter bereit stehen...
Und zu deiner Idee das es auf Handys laufen soll... Da kommt nur soetwas wie Android in Frage... Da alle Handys mit JavaME viel zu langsam sind... Dafür war Handy Entwicklung immer schrecklich... Man könnte zwar auch einen Interpreter fürs iPhone schreiben aber dieser würde nicht in den AppStore aufgenommen werden.
xD Es sei denn man macht ein Spiel für den AppStore und macht als EasterEgg heimlich den Interpreter rein... Wenn Apple das nicht weiß kommt das durch war schon so beim C64 Emulator damals so mit einem Basic Interpreter bis es gemerkt wurde.
Aber sonst wüsste ich auch keine Vorteile von der Skriptsprache. Kannst du dazu einbisschen mehr erzählen? Da ich mich selbst sehr gut mit Skript und Programmiersprachen auskenne... Würde mich dein Vorhaben schon weiter interressieren.
Habe ich nicht schon Vorteile oben aufgeschrieben?
Aber naja, eines der wichtigsten Dinge ist halt, dass man damit seine Spiele leicht erweiterbar machen kann. Da man hierbei de Inhalt in einzelne zur Laufzeit kompilierten Dateien auslagern. Wie zum Beispiel einzelne Objekte wie Gegner usw. Dafür wird oft Lua verwendet, aber GLBasic wäre um einiges angenehmer, da man weniger Portierungsprobleme hat.
Außerdem wäre es möglich GLBasic im Browser auszuführen. Dabei braucht man lediglich einen Java Interpreter für Java schreiben.
Besonders diese Vorstellung finde ich sehr interessant.
QuoteNette Idee, doch glbasic läuft doch schon unter Linux, Windows und MacOSX und das nativ recht schnell... Dafür einen Interpreter zuschreiben bedeutet schnelleres compilieren der Programme aber dafür einbusen bei der Geschwindigkeit. Bringt daher eher für die Entwicklung etwas und das Release sollte man weiterhin nativ compilieren...
Es ist nicht als Alternative zu GLBasic gedacht, sondern vielmehr als Ergänzung.
QuoteIch für meinen Teil bin immer froh wenn ich kein Framework oder einen Interpreter mit schicken muss.. Das hatte mich auch am Anfang sehr an .Net gestört. Der Einzige Vorteil ist die Bytecode file welche für neue Zielsysteme nicht neu compiliert werden muss. Jedoch muss für jedes Zielsystem ein Interpreter bereit stehen...
Man braucht kein Framework mitschicken, die Exe IST nämlich die VM das heißt dass man nichts zusätzlich installiert haben muss.
Ich finde die Idee super und wenn das super geht dann kann man auch mal scenen/events in spiele Scripten!
Unerlässlich für ein RPG z.B :)
Wenns was zu testen gibt, sag bescheid!
Ah okay das Skript wird an die vm gehangen. Das ist doch schonmal etwas trotzdem muss man für jedes System weiter hin einzelne vm's mit liefern auch wenn es zu einem Packet gebunden ist. Ähm im Browser ^^ auch wieder eine nette Idee... Muss man halt mal schau wie die performence bei einem Interpreter ist der in Java geschrieben ist...
Was vll auch eine coole Sache wäre GLbasic in verschiedene Sprachen zu über setzen für die es schon Interpreter gibt.
So SELECT CASE DEFAULT ENDSELECT funktioniert nun auch. Hier waren halt die Sachen wie SELECT i; CASE >6 usw. ein wenig komisch zu implementieren aber das funktioniert nun auch endlich.
k=1
SELECT k
CASE 5 TO 10
STDOUT "Case1"
CASE -1
STDOUT "Case2"
CASE k
STDOUT "Case3"
DEFAULT
STDOUT "HHH"
ENDSELECT
Als nächstes kommen Arrays dran. Diese werden aufwändiger sein zu implementieren :(
das alles sieht nach einem großen und längerfristigen interessanten Projekt aus :)
Wenn du das ganze in einem eigenen Blog haben willst, solltest du dich vertrauensvoll an unserer Haus- und Hofmeister Schranzor wenden :)
Richtig Quentin :D
Wenns ein "Blog" werden soll, schreib mir ne PM mit Blognamen und ich mach dir dann einen auf. :offtopic:
Total abgefahren!!
Ich finde die Idee gut. Damit könnte man GLBasic als PHP/Perl/Python Konkurenz machen... ;)
ÃÅ"brigens, ich werde GLBasic so verbiegen, dass die Engine selbst den Lizenzcode abfrägt und damit Wege für eigene IDEs offen sind. Zusätzlich werde ich einen Befehl einbauen "HASLICENSE(feature$, password$)", mit dem Ihr eigene Lizenzen in die IDE einbringen und im Code abfragen könnt.
Den Code-Generator gibt's gratis dazu.
Problem wird dann die Verteilung von gbal Dateien sein, dass man die nicht einsehen kann. Wenn jemand eine gute Idee dazu hat, her damit (anderer Thread, bitte)
Man nehme ein GPC dazu ein stückle code mache eine pre pre komponente namens .gbal man habe es verschlüsselt natürlich.
dann nehme man ein befehl LOADLIB "blah.gbal" und beim kompilieren macht gpc aus der gbal lesbaren code aber tut den nich niemals niemals nie speichern :D
WOW Gernot o.O
Bin sehr überrascht!
Wie schaut es nun mit dem 2D-Part und GLB aus? (Wie wir mal im Chat besprochen hatten).
@Schranz0r: Hier finde ich es besser aufgehoben. Warum? Weil hier einfach viel mehr Besucher schauen, als bei den Blogs.
Naja es geht weiter. Mittlerweile funktionieren die Arrays in ihren Grundzügen. Das heißt:definieren, dimensionieren, setzen und aufrufen ist bereits möglich. Siehe folgenden Code:
LOCAL Array[]
DIM Array[5]
Array[3]=100
STDOUT "Arr: "+Array[3]
LOCAL Array2[] //Der Stack ist manchmal bei zwei Arrays durcheinander gekommen
DIM Array2[10][55]
Array2[-1][5]=10
STDOUT "Array: "+Array2[-1][5]
Als nächstes kommt halt, dass man die Arrays als solches an Funktionen übergibt. Außerdem sollte das zuweisen von Arr[]=Arr2[] funktionieren.
Echt nicht schlecht muss ich sagen :)
Bin mal so frei und mach es Sticky!
Gute Arbeit muss belohnt werden ;)
Wow cool :) Danke
Btw. Array auf Array Zuweisung funktioniert nun also: Arr[]=Arr2[]. Dabei wird wie in GLBasic das Array kopiert anstatt referenziert.
Hey, wann ist es denn soweit?
Das GLScript würde sich optimal zum "scripten" für LR eignen! Bin schon richtig heiss drauf! :good:
Puh ich schätze gegen Ende von den Sommerferien wird es was zum testen geben.
Leider fehlen im Moment noch die zwei wichtigsten Dinge: Types und Funktionen. Vorallem die Types sind in GLBasic recht eigenwillig, weshalb diese viel Zeit in Anspruch werden.
Btw. Nun gibt es auch die fehlenden Operatoren >=,<=,<> und das in GLBasic lange vermisste NOT ;)
NOT kommt in V8. In der Online-Hilfe ist's schon drin ;)
Wann kommt denn GLB 8? :blink:
Wenn's fertig ist ;)
Ich habe mir viel vorgenommen und will auch alles reinpacken. Ich weiß aber, dass manche Sachen schon ziemlich pressieren. Mal sehen. Ich schätze in den nächsten 8 Wochen.
Du bist der Beste :) Freu mich schon, was es wohl alles Neues gibt!
Hey ho!
Nun habe ich SUB's implementiert. Das war einfacher als ich gedacht habe. Naja was gibt es viel dazu zu sagen? Rekursion kann ich noch nicht viel testen, scheint aber bis jetzt zu funktionieren.
Aber Code sagt mehr als 1000 Worte:
GLOBAL gg=10
FOR i=0 TO 10 STEP 2
GOSUB sub1
NEXT
SUB sub1:
LOCAL Hallo=10 //Damit kommt der Stack auch klar
STDOUT "In Sub1 "+Hallo
GOSUB sub2
ENDSUB
SUB sub2:
STDOUT "zzz "+gg
ENDSUB
Hey, das wird ja so richtig genial, wie ich sehe! :good:
Wird es auch Möglichkeiten für z.B. Ladefunktionen, Graphikfunktionen usw. geben? z.B. Loadsprite oder Drawrect?
SOfern Gernot nichts dagegen hat natürlich ;).
Jo. Hau rein. Ich werde in die AGB reinschreiben, dass ein Export der Script-Language als eigenes Produkt unzulässig ist.
(Nicht, dass einer GLBasic.script macht und als Stand-Alone verkauft).
Soll das Teil was kosten?
Da bin ich mir nicht sicher. Vllt. wird es was kosten, da hierbei nur der Source Code mitgeliefert wird, wäre es noch immer von GLBasic abhängig. Es ist schließlich ziemlich viel Aufwand. Aber nur wenn du es auch erlaubst ;)
Ich will das ganze erstmal fertig kriegen und dann schau ich weiter.
Soooooooo
nun habe ich die VM mal ordentlich umstrukturiert. Am meisten hat sich was bei den Stacks verändert. Nun gibt es anstatt einem drei Stacks. Warum habe ich mich dazu entschieden? Ganz einfach, es war mir zu fehleranfällig. Es musste nur irgendwo irgendein Wert vom Stack gelöscht werden damit alles durcheinander kommt. Nun kommt zwar auch alles durcheinander, allerdings kann ich den Fehler um einiges leichter finden, da ja alles geordnet ist. Dadurch entsteht ein geringer Overhead bei Funktionen/subs da ja nun 3 anstatt ein Stack verwaltet werden muss. Aber diesen Nachteil nehme ich in Kauf (es ist eh ziemlich gering).
Ich habe mir nun einen "Plan" gemacht was welche Version können muss:
0.1: Alle Kontrollstrukturen (done)
0.2: Alle Schleifen (done)
0.3: Variablen, Arrays (es fehlen noch String Variablen und Arrays können noch nicht als Parameter fungieren)
0.4: Subs und Funktionen (Subs bereits implementiert)
0.5: Types (Das wird SEHR schwierig)
0.6: Alle Funktionen aus GLBasic implementieren(2D, 3D und NET...) und auch div. Kleinigkeiten wie DATA Statements oder CONSTANT
0.7: API fertigstellen: Diese soll ähnlich flexibel wie die von Lua werden
0.8: Fehlerbereinigung (Hoffentlich nicht allzuviel)
0.9: Geschwindigkeits Optimierung
1.0: ddgui erfolgreich kompilieren und praktisch jedes beliebige Projekt
<1.0: Bugfixes und erweiterte Syntax (FUNCTION in Types, CALLBACk und PROTOTYPEs)
<2.0: Eigene Erweiterungen (stark Erweitertes OOP [Vererbung, Polymorphie,...], div. andere Syntax Elemente und die Java Version des Interpreters)
Tja bis dahin ist ein langer Weg. Mittlerweile ist GLScriptBasic bei Version 0.25. Ich bin allerdings guter Dinge in den Sommerferien (sind ja nurnoch ein Monat bis es soweit ist) bis zur Version 0.5 zu kommen. Ab da wären dann alle Syntax Elemente implementiert.
Ach ja bevor ich es vergesse: FUNCTION's können mittlerweile einen Parameter entgegennehmen:
funk(-999)
FUNCTION funk: Param1
STDOUT "Parameter: "+Param1
ENDFUNCTION
Hi!
Nun wurden Strings fertig implementiert. Das heißt, sie können in Variablen gespeichert werden, als Parameter arbeiten uvm. Dabei sind mir einige böse Bugs aufgefallen, welche ich noch nicht alle entfernen konnte.
LOCAL txt$
txt$="Hallo Welt"
STDOUT txt$
txt$=txt$+100 //Hier wird nicht addiert sondern aneinandergefügt
STDOUT txt$
Somit hat GLScriptBasic Version 0.275 erreicht (Sobald die Arrays 100%ig funktionieren ists bei Version 0.3).
Hallo,
nun nach einer einwöchigen Programmierpause mache ich mit GLScriptBasic weiter. Weshalb die Pause? Ich habe einen hartnäckigen Bug nicht gefunden. Ich habe noch keine Ahnung wo sich dieser Käfer eingenistet hat, aber den werde ich nich finden. Er tritt dann auf wenn eine Subfunktion innerhalb einer Fallunterscheidung/Schleife aufgerufen wird. Hier wird aus irgendeinem Grund jede Variable in ein Array umgewandelt. Worauf hin die gesamte VM durcheinander gerät...
Naja eine kleine Sache habe ich implementiert: INLINE - ENDINLINE
Nun jetzt werdet ihr bestimmt denken "Woah cool" oder "Warum ist der Himmel blau?".
Aber ich muss euch enttäuschen. INLINE ist nur dazu da um OpCodes direkt zu verwenden. Das entspricht quasi Inline Assembler.
Wofür das gut ist? Nunja dadurch dass das ganze bereits "vorkompiliert" ist, braucht der Compiler weniger Zeit zum kompilieren. Außerdem können diverse Optimierungen vorgenommen werden, wozu der Compiler auch nicht in der Lage ist.
INLINE
pushstr "Ich werde in Inline ausgegeben" //Haa Inline OpCodes
call SCRIPT_STDOUT
ENDINLINE
STDOUT "Ich werde in nicht inline ausgegeben"
So Funktionen funktionieren nun auch einwandfrei. Das heißt Rekursion und so funktioniert auch.
LOCAL Array[]
DIM Array[5]
Array[-1]=99
STDOUT funk(20,"Hallo",Array[])
STDOUT rekursiv(-2)
FUNCTION funk: Param, Test$, Arr[]
Param=Param+5
STDOUT "In Funktion!! "+Param+ " "+Test$+" --"+Arr[-1]
RETURN 100
ENDFUNCTION
FUNCTION rekursiv: Pum
IF Pum>10
STDOUT "Aus "+Pum
RETURN Pum
ELSE
STDOUT "Rek: "+Pum
RETURN rekursiv(Pum+1)
ENDIF
ENDFUNCTION
Man kann bereits Strings, Numbers und Arrays als Parameter übergeben. Zurückgeben kann man allerdings nur Numbers. Dies werde ich demnächst ändern. Die Arrays werden im Gegensatz zu GLBasic (noch) kopiert beim übergeben. Dies werde ich allerdings ebenfalls ändern.
Außerdem kann man mittlerweile auch (wie man sieht) Arrays als Parameter übergeben. Das heißt sowas wie "DIMPUSH Array[],10" ist bereits möglich.
Somit erreicht GLScriptBasic Version 0.35
Total krass!
Mega coolo xD
Bleib am Ball, das wird super!
Ist ja nicht um sonst STICKY ;)
Danke euch beiden :)
Im moment arbeite ich an den optionalen Parametern. Dies ist leider nicht so einfach wie gedacht... Ich bleibe am Ball
Optionale Parameter implementiert .... puh.
OptionalTest(10)
OptionalTest(10,-100*2)
OptionalTest(10,-99,"Hallo Ich Welt")
FUNCTION OptionalTest: Hallo, Bum=100, Text$="Hallo Welt"
STDOUT "Hallo: "+Hallo+" Bum: "+Bum+" -"+Text$
ENDFUNCTION
Das war schwieriger als geplant... der Hauptgrund war die Tatsache dass GLScriptBasic ein single pass compiler ist.
Das Hauptproblem war dass erst am Ende des kompilierens feststeht WELCHE Funktionen es gibt. Wodurch beim aufrufen eben dieser nicht klar ist wieviele Parameter diese hat. Dies war als es eine statische Anzahl an Parametern gab nicht weiter schlimm. Jedoch sobald es Variabel viele Parameter gibt muss man auch wissen was aufgerufen wird. Tja, dies konnte ich lösen indem es von einer Funktion nicht eine gibt sondern für jeden optionalen Parameter eine weitere. Diese leitet quasi zu der mit allen Parametern um, ein Umweg. Es ist ein wenig schwer zu erklären... Das Beispiel von oben erzeugt drei verschiedene Funktion: OptionalTest@1, OptionalTest@2, OptionalTest@3. Durch die Anzahl der Parameter kann der Compiler leicht erkennen welche aufgerufen wird.
Ein netter Nebeneffekt: Simple Funktionsüberladung wurde hiermit implementiert. die einzige Vorraussetzung ist halt, dass sich die Parameteranzahl unterscheidet.
Tja als nächstes müssen Arrays auch Strings unterbringen können und diese sollten auch aus einer Funktion zurückgegeben werden können.
Version: 0.35
Oh Mann, das wird richtig böse!!!
Weiter so!!! :good:
Mhmm, ich komme mir nun ziemlich dumm vor.
Ich habe nun seit 3 Tagen einen seltsamen bug gesucht, der Entstand, wenn man Arrays aufruft, deklariert oder redimensioniert. Ich konnte mir bei besten Willen nicht vorstellen woran das Lag (es kam andauernd die Fehlermeldung "Expecting '['" von meinem Compiler.
Nun habe ich den Fehler gefunden... Es lag an den REPEAT - UNTIL Schleifen. Da ich ziemlich oft davon gebrauch machte, und dadurch eben dieser Auftrat. Nunja was war nun der Fehler? In der ersten V8 Beta waren REPEAT UNTIL Schleifen umgedrehte WHILE Schleifen (Also REPEAT - UNTIL TRUE - das wäre immer korrekt gewesen) während in der neueren Version die BEdingung umgedreht war - es wäre schön gewesen wenn das irgendwo stehen würde...
Naja nun geht es weiter...
so sorry :(
Hi,
nur ne kurze Frage : wie ist der momentane Status? ich bräuchte demnächst mal eine gute Scriptsprache für ein Projekt.
MfG
wenn ichs wieder finde schick ich dir lua, glbasic script ist tot *wer hätte das gedacht???*
Oo was is denn da los? War's Fake?
Wenn du das noch findest war's cool, danke!
MfG
benötigst du windows only oder für alle platformen (glaub alle außer iphone)?
Jo, alle Platformen ausser EiFon!
MfG
ok also mit source statt dll, habs nur auf windoof getestet bisher. aber kompilieren sollte es dann für alle
weis net ob du die PN bekommen hast, bei mir zeigt es nichts an (keine gesendeten mails).... aber immer her damit, mal sehen ob ichs versteh und einbauen kann... bin dir auf jeden Fall schonmal Dankbar!
MfG
Es war kein Fake, die Grundlage (Core) war nur ein wenig schlampig programmiert, weswegen Types ein Ding der Unmöglichkeit sind. Außerdem ist ein Bug in der Funktionsverwaltungsroutine im Parser, der dazu führt dass Zeilen einfach doppelt/garnicht ausgeführt werden können. Ich habe mich schon seit über zwei Wochen damit rumgeärgert.... Der Fehler ist und bleibt verborgen.
Ich werde beizeiten (sofern Gernot dies erlaubt) den Souce veröffentlichen (damit niemand denkt es sei ein Fake...).
Sry für Doppelpost...
Aber hier ist der aktuelle (verbuggte) Stand. Den Fehler sieht man nicht sofort, aber wenn man genau hinsieht werden ein paar Funktionen/Subs nicht korrekt aufgerufen:
http://coolo.kilu.de/files/GLScriptBasic.rar (http://coolo.kilu.de/files/GLScriptBasic.rar)
Very impressive! :nw:
Recht schönen Dank!
Ian
War der Fehler jemals behoben Coolo?
Cheers,
Ian
Did I say it wrong? I was trying to ask if Coolo ever managed to find the bug that halted development, Googletranslate is not always great at translating?
Cheers,
Ian
Nope, I tried to find the bug really long (one week), but i really did not find it.
But maybe i will make GLSB2 :D. I'm really sad, because GLSB is a really nice code...
Ah, that's a real pity, I really liked the syntax and the extendablity Coola, it would have been great to use it. I am sorry I cannot help, I know nothing about virtual machines and scripting. :(
I would be very interest in GLSB2 though! :D
Cheers,
Ian
Hi,
ich habe nur eine ganz kurze Frage:
Ist es im Script eigentlich möglich selbst hinterlegte Funktionen aus dem compilierten Code aufzurufen und aufarbeiten zu lassen?
z.B. set_position(x, y, z)
LG
W.
Was meinst du ist der Sinn einer Scriptsprache? :D
Das weiß ich auch! =D
Mir geht es nur darum, daß es auch fehlerfrei funktioniert!
Frage: Gibt's zu den Funktionen irgendwo ein Tutorial oder was ähnliches, wo beschrieben wird, wie ich die einzelnen Daten von außen rein hole???
Is there a piece of script code available that quickly shows the error?
Cheers,
Ian
@WPShadow: Mit der ursprünglich hochgeladenen Variante ging das Aufrufen von im Skript deklarierten Funktionen nicht direkt (man hätte mit der internen Funktionspointer ID arbeiten müssen, welche zur OpCode Position führt).
Dies habe ich nun erleichtert, nun gibt es die Funktion "CallFunction". Erster Parameter ist die VM, zweiter der Name der Funktion und dritter die Anzahl der Parameter (Die braucht es, da ja anhand dieser auch überladen werden kann). Der Link ist derselbe.
Um Daten drauf zu geben, gibt es die Funktionen StackPushNumber/String/NumberArray/StringArray. Um sie vom "Stack" wieder zurück zu bekommen gibt es die StackPopNumber/String/NumberArray/StringArray pedante. Um Funktionen (von GLb aus) hinzuzufügen muss man erstens eine SUB namens "SCRIPT_NAMEDERSUB" definieren, danach in der InitStdFunction() Funktion noch "CreateFunction("NAMEDERSUB",ANZAHLDERPARAMETER)" hinzuschreiben.
@bigsofty: Yes, the problem is already in the current code. If you look closer into the code, you notice, that some Opcodes are not callen. I really don't know why. It happens in the function funk(). If you uncomment the STDOUT you get an error. I think it has its source anywhere at the "optional function parameter parser" but i am not sure about this.
Thanks Coolo, I'll have a wee look, no harm in trying I suppose. :)
Wow!
I really like that pong.txt script!
Is there a newer version of this script!
I've successfully compiled glScriptBasic to Android! Now I can code in glBasicScript on the go (editing a txt file) and then run directly on my device 8)
Functions with referenced parameters (BYREF) will be supported?
For example there is a way to support commands like GETSCREENSIZE w%%, h%% or MOUSESTATE?
There was a bug in Pong.txt: the ball stuck if it touch the pad from the left or right side.
Here is the fixed version:
Quote
GLOBAL SpielerX=100, BallX=100, BallY=100,Angle=RND(360), Life
Life=4
CREATESCREEN 2, 1, 320, 200
WHILE TRUE
USESCREEN 2
CLEARSCREEN RGB(10,10,10)
DRAWRECT SpielerX,20,40,10,RGB(255,50,50)
IF KEY(205)
SpielerX=SpielerX+4
ENDIF
IF KEY(203)
SpielerX=SpielerX-4
ENDIF
BallX=BallX+COS(Angle)*2
BallY=BallY+SIN(Angle)*2
IF BOXCOLL(SpielerX,20,40,10,BallX,BallY,16,16)
BallX=BallX-COS(Angle)*2
BallY=BallY-SIN(Angle)*2
IF BallY-30>0
Angle=360-Angle
ELSE
Angle=180-Angle
ENDIF
ENDIF
IF BallX>320-16 OR BallX<0
Angle=180-Angle
ENDIF
IF BallY>200-16
Angle=360-Angle
ENDIF
IF BallY<0
Life=Life-1
BallX=100
BallY=100
Angle=RND(360)
ENDIF
DRAWRECT BallX,BallY,16,16,RGB(0,255,0)
PRINT "Life: "+Life,10,180
PRINT "Angle: "+Angle,150,180
IF Life<1
END
ENDIF
USESCREEN -1
STRETCHSPRITE 1, 0, 0, 800, 480
SHOWSCREEN
WEND
It also for testing some commands I added to it: CREATESCREEN, USESCREEN, STRETCHSPRITE
I see that nobody interested for glScriptBasic anymore. There is a better solution?
Should I make a new thread in the English boards?
This project is totally awesome. The only problem is, that coolo said he has some tiny bug and can't be bothered to try and fix it. And the code seems so compex, that noone dared to play with it so far. I really want to encourage you to do so. It's really a cool idea.
If I understood correctly (via google translate) there are some bugs when you using arrays. I'm didn't plan to use arrays, so it will ok for me :)
I tried to understand the code yesterday to BYREF, but I didn't make it too far, the code is far too difficult.
Hey Leute!
Ich wollte nur mal kurz anmerken, dass ich an GLBasicScript (2) arbeite. Dies ist ein kompletter Rewrite, der versucht die alten Fehler zu umgehen.
Veränderungen gegenüber der alten Version:
1) 4 Pass Compiler: Eines der Hauptprobleme an der alten Version war, dass es ein Singlepass Compiler war. Hierdurch war es zwar sehr schnell, allerdings war es sehr schwer zu debuggen und viele (einfache) Sachen waren vergleichsweise umständlich zu implementieren.
Die Durchläufe:
- Lexer: Alles in Tokens zerteilen (done)
- Analyser: Alle GLOBAL/FUNCTION/TYPE/CONSTANT/SUB/WHATEVER suchen und registrieren (hier werden bereits Syntaxfehler angezeigt) (done)
- Parser: Einen abstrakten Syntaxbaum erstellen und Syntaxfehler finden (sollten sehr genaue Beschreibungen liefern)
- Generator: Erstellt aus dem Syntaxbaum den Zielcode
2) Compilerbackend ist generisch: Nun erstellt EINE Funktion den Zielcode. Diese ist als CALLBACK deklariert, wodurch man ohne weiteres andere Outputs anvisieren kann (JavaScript, ...). Früher war Codegenerierung mit Codeparsing vermischt.
3) Virtuelle Maschine schneller und optimiert: Die VM wird zu 95% in C++ geschrieben, wodurch ich void* verwenden kann. Die alte Version der VM war in GLB geschrieben. Hauptproblem daran war, dass GLB keine generischen Datentypen anbietet, welche beliebige Daten speichern können (also ein void* Pedant), wodurch das alles viel komplizierter wurde (vorallem die Stackimplmentierung)
4) Abstrakter Syntaxbaum: Im Gegensatz zur alten Version wird nun ein echter AST erstellt, wodurch sogar diverse Optimierungen möglich sind.
5) Mehr Erfahrung: Ich habe in der Zwischenzeit an einem anderen Compiler gearbeitet (der bereits von der Syntax her fertig ist, allerdings habe ich keine Motivation mehr den weiter zu machen)
6) Ich mag Kekse.
Aktueller Stand? Analysing und Lexing funktioniert bereits fehlerfrei, Parsing ist auch schon recht fortgeschritten und die Codegeneration ist genau so fortgeschritten, wie das Codeparsing. Allerdings ist die VM noch in den Kinderschuhen, diese kann lediglich Werte auf den Stack pushen. Aber gut Ding braucht weil :D
Konzept? Dasselbe wie früher (annähernd komplette GLBasicsyntax Unterstützung), allerdings wird auch JavaScript als Output möglich sein (GLBasic im Browser \o/).
Bis jetzt funktioniert dieses Beispielprogramm:
STDOUT 2+4*8
LOCAL i, j, k
i = 204*(2+2)
STDOUT i
NATIVE FUNCTION STDOUT: Output$ //Um die nativen GLBasic Funktionen reinzuholen
NATIVE FUNCTION STDERR: Error$
Kontrollstrukturen kommen als letztes. Variablen->Arrays->Types->Funktionen->Kontrollstrukturen->Rest
Kompiliert zwar, führt aber nicht aus.
So sieht die Funktion aus, welche dann die OpCodes erzeugt.
CALLBACK FUNCTION Generate$: expr AS Expr
//STDOUT "Generating token: "+expr.token.Text$+" in Line "+expr.token.LineContent$+" type: "+expr.Typ+"\n"
LOCAL Text$ = ""
SELECT expr.Typ
CASE EXPR_IS_SCOPE
CurrentScope = expr.ID
Text$ = Text$ + "//startscope\n"
LOCAL Size% = 0
FOREACH Vari IN expr.Varis[]
INC Size, GetDatatypeSize(Exprs[Vari].datatype)
NEXT
Text$ = Text$ + "alloc " + Size + "\n"
FOREACH Ex IN expr.Exprs[]
Text$ = Text$ + Generate$(Exprs[Ex])
NEXT
Text$ = Text$ + "//endscope"
CASE EXPR_IS_OPERATOR
Text$ = Text$ + Generate$(Exprs[expr.Left])
Text$ = Text$ + Generate$(Exprs[expr.Right])
Text$ = Text$ + Operators[expr.Op].Name$
CASE EXPR_IS_INT
Text$ = "pushi "+expr.intval
CASE EXPR_IS_FLOAT
Text$ = "pushf "+expr.floatval
CASE EXPR_IS_STR
Text$ = "pushs "+expr.strval$
CASE EXPR_IS_FUNCCALL
FOREACH param IN expr.Params[]
Text$ = Text$ + Generate$(Exprs[param])
NEXT
Text$ = Text$ + "jmpf "+expr.func.ID
CASE EXPR_IS_VARI
Text$ = Text$ + "pushv "+CalculateVariPos(expr.vari)
CASE EXPR_IS_ASSIGN
Text$ = Text$ + "//Value\n"
Text$ = Text$ + Generate$(Exprs[expr.Right])
Text$ = Text$ + "assign "+CalculateVariPos(expr.vari)
CASE EXPR_IS_EMPTY
CASE EXPR_IS_DEBUG
Error("Invalid Expression (generator error)")
DEFAULT
Error("Unknown expression type (generator error)")
ENDSELECT
RETURN Text$ + "\n"
ENDFUNCTION
Wie man sieht, sehr generisch gehalten, weshalb beliebige Zielsprachen möglich sind.
MfG
Schön zu hören das du wieder an dem Projekt weiter machst!
Finde ich super, aber vorallem Punkt 6 hört sich gut an :)
Wenn das geht, flipp ich voll aus. Wenn Du Hilfe brauchst, bitte melden. Wenn Du keine Hilfe bracuhst, sag mir wie Du's gemacht hast. ;)
:good:
Freut mich zu hören :)
Mittlerweile funktionieren Types, Arrays und Variablen in den Grundzügen. Allerdings wird noch nichts ausgeführt, da die VM noch nicht einmal ansatzweise funktioniert.
Folgender Code wird bereits richtig kompiliert:
STDOUT 2+4*8
LOCAL i, j, k
LET i = 204*(2+2) //LET optional
STDOUT i
STDOUT j
STDOUT k
STDOUT "Hallo Welt"
LOCAL arr1[]
DIM arr1[10]
REDIM arr1[14] //Redim \o/
arr1[8] = 99
STDOUT arr1[8]
LOCAL arr2[]
arr2 = arr1 //kopieren
arr1[] = arr2[] //auch kopieren \o/
LOCAL b AS Buch
b.Seite = 200
STDOUT b.Seite
DIM b.Seiten$[100][100]
LOCAL r AS Regal
DIM r.Buecher[100]
r.Buecher[0] = b
r.Buecher[0].Titel$ = "Harry Potter"
TYPE Regal
Buecher[] AS Buch
ENDTYPE
TYPE Buch
Seite%
Titel$
Besitzer$
Seiten$[]
ENDTYPE
NATIVE FUNCTION STDOUT AS void: Output$
NATIVE FUNCTION STDERR AS void: Error$
Kompilierzeit dafür beträgt 30MS (auf einem Atom Netbook!) und das trotz einem 4 pass Compiler.
Mit freundlichen grüßen, aus Kroatien (Urlaub <3) :)
Der Compiler beherrscht nun Funktionen in _Grundzügen_ das heißt, dass es zwar keine bekannten Fehler gibt, aber dass bestimmt noch vier dutzend versteckt im Code liegen.
Außerdem habe ich den JavaScript Codegenerator angefangen, dieser ist bereits auf dem Stand des Compilers und der erzeugte Code funktioniert wunderprächtig!
Aus:
STDOUT 2+4*8
LOCAL i, j = 999, k = GetInt()
GLOBAL l = GetInt()
LET i = 204*(2+2) //LET optional
STDOUT i
STDOUT j
STDOUT k
STDOUT "Hallo Welt "+100
LOCAL arr1[]
DIM arr1[10]
REDIM arr1[14] //Redim \o/
arr1[8] = 99
STDOUT arr1[8]
LOCAL arr2[]
arr2 = arr1 //kopieren
arr1[] = arr2[]
LOCAL b AS Buch
b.Seite = 200
STDOUT b.Seite
DIM b.Seiten$[100][100]
LOCAL r AS Regal
DIM r.Buecher[100]
r.Buecher[0] = b
r.Buecher[0].Titel$ = "Harry Potter"
STDOUT r.Buecher[0].Titel$
TYPE Regal:
Buecher[] AS Buch
ENDTYPE
TYPE Buch
Seite%
Titel$
Besitzer$
Seiten$[]
ENDTYPE
testFunktion$ 10, 20, 30
andereTestFunktion 40
GOSUB mySub //GOSUB optional
FUNCTION empty:
ENDFUNCTION
FUNCTION testFunktion$: param1, param2, param3
STDOUT "Ich bin in einer Funktion \o/ "+param1+" "+param2+" "+param3
RETURN "ROFL"
ENDFUNCTION
FUNCTION andereTestFunktion: param4
ENDFUNCTION
SUB mySub:
STDOUT "I'm in SUB!!!"
RETURN
STDOUT "Ich werde nie angezeigt lol!"
ENDSUB
FUNCTION GetInt%:
RETURN 42
ENDFUNCTION
Wird:
<html>
<head>
<title>GLBasic</title>
<script type="text/javascript" src="JS/lib.js"></script>
<script type="text/javascript">
function main(){
var i = 0.0, j = 0.0, k = 0.0, arr1 = new Array(), arr2 = new Array(), b = Buch(), r = Regal();
STDOUT(2 + 4 * 8);
i = 204 * 2 + 2;
STDOUT(i);
STDOUT(j);
STDOUT(k);
STDOUT("Hallo Welt " + 100);
//DIM(...);
//REDIM(...);
arr1[8] = 99;
STDOUT(arr1[8]);
arr2 = arr1.slice(0);
arr1 = arr2.slice(0);
b.Seite = 200;
STDOUT(b.Seite);
//DIM(...);
//DIM(...);
r.Buecher[0] = b.clone();
r.Buecher[0].Titel_Str = "Harry Potter";
STDOUT(r.Buecher[0].Titel_Str);
testFunktion$(10, 20, 30);
andereTestFunktion(40);
mySub();
};
function testFunktion_Str(param1, param2, param3) {
STDOUT("Ich bin in einer Funktion \o/ " + param1 + " " + param2 + " " + param3);
return "ROFL";
};
function andereTestFunktion(param4) {
};
function mySub() {
STDOUT("I'm in SUB!!!");
return 0;
STDOUT("Ich werde nie angezeigt lol!");
};
function GetInt() {
return 42;
};
function Regal() {
this.clone = function() {
var other = new Object();
other.Buecher = this.Buecher.clone();
return other;
};
this.Buecher = new Array();
return this;
};
function Buch() {
this.clone = function() {
var other = new Object();
other.Seite = this.Seite;
other.Titel_Str = this.Titel_Str;
other.Besitzer_Str = this.Besitzer_Str;
other.Seiten_Str = this.Seiten_Str.slice(0);
return other;
};
this.Seite = 0;
this.Titel_Str = "";
this.Besitzer_Str = "";
this.Seiten_Str = new Array();
return this;
};
</script>
</head>
<body onLoad="main();">
<textarea name="GLBContent" style="width:100%;height:100%">
</textarea>
</body>
</html>
Außerdem wurden nun die Fehlermeldungen erweitert. Nun motzt der Compiler rum, wenn man eine Funktion doppelt benennt oder wenn man eine Variable verwendet welche nicht existiert (anstatt einfach eine neue Variable implizit zu erstellen) usw.
MfG
<3
Heyho!
Der JavaScript Compiler nimmt langsam Form an! Arrays funktionieren bereits prächtig (Arrayboundchecking muss ich noch implementieren, aber das hat eher geringere Priotität). Auch funktionieren nun Dinge wie GLOBAL a = Foo() und auch FUNCTION bar: xyz = Foo() compilerseitig. Allerdings müssen die beiden Codegeneratoren daran noch angepasst werden. Außerdem funktioniert nun CALLBACK \o/, war vergleichsweise einfach zu implementieren, dank dem tollen 4 pass System.
Folgender Code wird bereits erfolgreich in JavaScript / VM Code kompiliert:
LOCAL i, j = 999, k = GetInt()
GLOBAL l = GetInt()
LET i = 204*(2+2) //LET optional
STDOUT "i: "+i+"\n"
STDOUT "j: "+j+"\n"
STDOUT "k: "+k+"\n"
STDOUT "Hallo Welt "+100+"\n"
LOCAL arr1[]
DIM arr1[10]
REDIM arr1[14] //Redim \o/
arr1[8] = 99
STDOUT "Array 1 an der Stelle 8: "+arr1[8]+"\n"
LOCAL arr2[]
STDOUT "1--- \n"
arr2 = arr1 //kopieren
STDOUT "2--- \n"
arr1[] = arr2[]
STDOUT "3--- \n"
LOCAL b AS Buch
b.AktuelleSeite = 200
STDOUT "buch Seite: "+b.AktuelleSeite+"\n"
DIM b.Seiten$[100][100]
LOCAL r AS Regal
DIM r.Buecher[100]
r.Buecher[0] = b
r.Buecher[0].Titel$ = "Harry Potter"
STDOUT "Erstes Buch im Regal: "+r.Buecher[0].Titel$+"\n"
DIM r.Buecher[0].Seiten[100]
r.Buecher[0].Seiten[0].Text$ = "lol"
TYPE Regal:
Buecher[] AS Buch
ENDTYPE
TYPE Buch
AktuelleSeite
Titel$
Besitzer$
Seiten$[]
Seiten[] AS Seite
ENDTYPE
TYPE Seite
Alter%
Text$
ENDTYPE
testFunktion$ 10, 20, 30
andereTestFunktion 40
GOSUB mySub //GOSUB optional
FUNCTION empty:
ENDFUNCTION
FUNCTION testFunktion$: param1, param2 = 900, param3 = 400
STDOUT "Ich bin in einer Funktion \\o/ "+param1+" "+param2+" "+param3+"\n"
RETURN "ROFL"
ENDFUNCTION
CALLBACK FUNCTION andereTestFunktion: param4
STDOUT "Ich bin da"
ENDFUNCTION
FUNCTION andereTestFunktion: param4
STDOUT "ICH BIN DA SO SUPPPPPER"
ENDFUNCTION
SUB mySub:
STDOUT "I'm in SUB!!! \n"
RETURN
STDOUT "Ich werde nie angezeigt lol! \n"
ENDSUB
FUNCTION GetInt%:
RETURN 42
ENDFUNCTION
wird in JS:
<html>
<head>
<title>GLBasic</title>
<script type="text/javascript" src="JS/lib.js"></script>
<script type="text/javascript">
function main(){
var i = 0.0, j = 0.0, k = 0.0, arr1 = GLBArray(), arr2 = GLBArray(), b = Buch(), r = Regal();
i = 204 * 2 + 2;
STDOUT("i: " + i + "\n");
STDOUT("j: " + j + "\n");
STDOUT("k: " + k + "\n");
STDOUT("Hallo Welt " + 100 + "\n");
DIM(arr1, [10], 0.0);
REDIM(arr1, new Array(14), 0.0);
arr1.values[8] = 99;
STDOUT("Array 1 an der Stelle 8: " + arr1.values[8] + "\n");
STDOUT("1--- \n");
arr2 = arr1.clone(/* 2 */);
STDOUT("2--- \n");
arr1 = arr2.clone(/* 2 */);
STDOUT("3--- \n");
b.AktuelleSeite = 200;
STDOUT("buch Seite: " + b.AktuelleSeite + "\n");
DIM(Seiten_Str, [100, 100], "");
DIM(Buecher, [100], Buch());
r.Buecher.values[0] = b.clone(/* 2 */);
r.Buecher.values[0].Titel_Str = "Harry Potter";
STDOUT("Erstes Buch im Regal: " + r.Buecher.values[0].Titel_Str + "\n");
DIM(Seiten, [100], Seite());
r.Buecher.values[0].Seiten.values[0].Text_Str = "lol";
testFunktion_Str(10, 20, 30);
andereTestFunktion(40);
mySub();
};
function testFunktion_Str(param1, param2, param3) {
var param1 = 0.0, param2 = 0.0, param3 = 0.0;
STDOUT("Ich bin in einer Funktion \\o/ " + param1 + " " + param2 + " " + param3 + "\n");
return "ROFL";
};
function andereTestFunktion(param4) {
var param4 = 0.0;
};
function mySub() {
STDOUT("I'm in SUB!!! \n");
return 0;
STDOUT("Ich werde nie angezeigt lol! \n");
};
function GetInt() {
return 42;
};
function Regal() {
this.Buecher = GLBArray();
this.clone = function() {
var other = new Object();
other.Buecher = this.Buecher.clone();
return other;
};
return this;
};
function Buch() {
this.AktuelleSeite = 0.0;
this.Titel_Str = "";
this.Besitzer_Str = "";
this.Seiten_Str = GLBArray();
this.Seiten = GLBArray();
this.clone = function() {
var other = new Object();
other.AktuelleSeite = this.AktuelleSeite;
other.Titel_Str = this.Titel_Str;
other.Besitzer_Str = this.Besitzer_Str;
other.Seiten_Str = this.Seiten_Str.clone();
other.Seiten = this.Seiten.clone();
return other;
};
return this;
};
function Seite() {
this.Alter = 0;
this.Text_Str = "";
this.clone = function() {
var other = new Object();
other.Alter = this.Alter;
other.Text_Str = this.Text_Str;
return other;
};
return this;
};
</script>
</head>
<body onLoad="main();">
<!--<textarea name="GLBContent" style="width:100%;height:100%">
</textarea>-->
</body>
</html>
Als nächstes sollte ich mich langsam an die VM setzen, diese ist noch kaum angefangen :/
MfG
sieht ja wirklich super aus. Vor allem die Idee, das in JavaScript zu übersetzen, finde ich genial. Wo um alles in der Welt hast du das gelernt?
Hey!!
GLBScript hat nun vordefinierte Variablen bekommen. Das heißt, dass LOCALs/GLOBALs/TYPEs/FUNCTIONs(Parameter) vordefinierte Werte haben können (auch Funktionsaufrufe!). Also FUNCTION Foo: Bar = GetInt(); funktioniert genauso wie GLOBAL Foo = Bar().
Nebenbei habe ich auch FUNCTIONs in TYPEs implementiert. Hier gibt es allerdings noch kleinere Probleme, welche noch gelöst werden müssen (vor allem, wenn eine Methode einen TYPE zurückgibt kommt der Expressionparser nicht ganz klar).
Außerdem konzentriere ich mich im Moment vorwiegend auf den JavaScript - Compiler, da - wie ich finde - das mehr Priorität hat, als eine Scriptsprache für GLB.
Folgender Code wird ohne Probleme kompiliert:
LOCAL i, j = 999, k = GetInt()
LET i = 204*(2+2) //LET optional
STDOUT "i: "+i+"\n"
STDOUT "j: "+j+"\n"
STDOUT "k: "+k+"\n"
STDOUT (4+4*2) + ": Zahl! \n"
STDOUT "Hallo Welt "+100+"\n"
LOCAL arr1[]
DIM arr1[10]
REDIM arr1[14] //Redim \o/
arr1[8] = 99
STDOUT "Array 1 an der Stelle 8: "+arr1[8]+"\n"
LOCAL arr2[]
STDOUT "1--- \n"
arr2 = arr1 //kopieren
STDOUT "2--- \n"
arr1[] = arr2[]
STDOUT "3--- \n"
LOCAL b AS Buch
b.AktuelleSeite = 200
b.GetTitel$()
b.getBuch()
STDOUT "buch Seite: "+b.AktuelleSeite+"\n"
DIM b.Seiten$[100][100]
LOCAL r AS Regal
DIM r.Buecher[100]
r.Buecher[0] = b.getBuch()
r.Buecher[0].Titel$ = "Harry Potter"
STDOUT "Erstes Buch im Regal: "+r.Buecher[0].Titel$+"\n"
DIM r.Buecher[0].Seiten[100]
r.Buecher[0].Seiten[0].Text$ = "lol"
r.Buecher[0].getBesteSeite().Text$ = "ICH MAG ZÜGE"
TYPE Regal:
Buecher[] AS Buch
ENDTYPE
TYPE Buch:
AktuelleSeite
Titel$
Besitzer$
Seiten$[]
Seiten[] AS Seite
BesteSeite AS Seite
FUNCTION GetTitel$: Param = 200, NoParam$ = "lol"
DIM self.Seiten$[40]
RETURN self.Titel$ + "Param: "+Param + " - " + NoParam$
ENDFUNCTION
FUNCTION getBuch AS Buch:
RETURN self
ENDFUNCTION
FUNCTION getBesteSeite AS Seite:
RETURN self.BesteSeite
ENDFUNCTION
ENDTYPE
TYPE Seite:
Alter%
Text$
ENDTYPE
testFunktion$ 10, 20, 30
testFunktion$ 10, 20
andereTestFunktion 40
andereTestFunktion 80
GOSUB mySub //GOSUB optional
defaultTest
FUNCTION testFunktion$: param1 = GetInt(), param2 = l, param3 = "lolo"
STDOUT "Ich bin in einer Funktion \\o/ "+param1+" "+param2+" "+param3+"\n"
RETURN "ROFL"
ENDFUNCTION
FUNCTION defaultTest: param1 = 10, param2 = -1, param3 = 22
ENDFUNCTION
CALLBACK FUNCTION andereTestFunktion: param4
STDOUT "Ich bin da, kein Callback"
ENDFUNCTION
FUNCTION andereTestFunktion: param4
STDOUT "ICH BIN DA CaLLBACk"
ENDFUNCTION
SUB mySub:
STDOUT "I'm in SUB!!! \n"
RETURN
STDOUT "Ich werde nie angezeigt lol! \n"
ENDSUB
FUNCTION GetInt%:
RETURN 42
ENDFUNCTION
GLOBAL l = GetInt() //Rückwärtszugriff
in JS:
<html>
<head>
<title>GLBasic</title>
<script type="text/javascript" src="JS/lib.js"></script>
<script type="text/javascript">
//init globals, default value!!
var l = 0.0;
//init globals, with custom value!!
function __initGlobals() {
l = CAST2FLOAT(GetInt())
}
function main(){
__initGlobals();
var i = 0.0, j = CAST2FLOAT(999), k = CAST2FLOAT(GetInt()), arr1 = GLBArray(), arr2 = GLBArray(), b = Buch(), r = Regal();
i = CAST2FLOAT((204 * (2 + 2)));
STDOUT((("i: " + CAST2STRING(i)) + "\n"));
STDOUT((("j: " + CAST2STRING(j)) + "\n"));
STDOUT((("k: " + CAST2STRING(k)) + "\n"));
STDOUT((CAST2STRING((4 + (4 * 2))) + ": Zahl! \n"));
STDOUT((("Hallo Welt " + CAST2STRING(100)) + "\n"));
DIM(arr1, [10], 0.0);
REDIM(arr1, [14], 0.0);
arr1.values[8] = CAST2FLOAT(99);
STDOUT((("Array 1 an der Stelle 8: " + CAST2STRING(arr1.values[8])) + "\n"));
STDOUT("1--- \n");
arr2 = arr1.clone();
STDOUT("2--- \n");
arr1 = arr2.clone();
STDOUT("3--- \n");
b.AktuelleSeite = CAST2FLOAT(200);
__method__Buch__GetTitel_Str(CAST2FLOAT(200), "lol", b);
__method__Buch__getBuch(b);
STDOUT((("buch Seite: " + CAST2STRING(b.AktuelleSeite)) + "\n"));
DIM(Seiten_Str, [100, 100], "");
DIM(Buecher, [100], Buch());
r.Buecher.values[0] = __method__Buch__getBuch(b).clone();
r.Buecher.values[0].Titel_Str = "Harry Potter";
STDOUT((("Erstes Buch im Regal: " + r.Buecher.values[0].Titel_Str) + "\n"));
DIM(Seiten, [100], Seite());
r.Buecher.values[0].Seiten.values[0].Text_Str = "lol";
testFunktion_Str(10, 20, 30);
testFunktion_Str(10, 20, CAST2FLOAT("lolo"));
andereTestFunktion(40);
andereTestFunktion(80);
mySub();
defaultTest(CAST2FLOAT(10), CAST2FLOAT((0 - 1)), CAST2FLOAT(22));
};
function __method__Buch__GetTitel_Str(Param, NoParam_Str, self) {
DIM(Seiten_Str, [40], "");
return ((((self.Titel_Str + "Param: ") + CAST2STRING(Param)) + " - ") + NoParam_Str);
};
function __method__Buch__getBuch(self) {
return self;
};
function testFunktion_Str(param1, param2, param3) {
STDOUT((((((("Ich bin in einer Funktion \\o/ " + CAST2STRING(param1)) + " ") + CAST2STRING(param2)) + " ") + CAST2STRING(param3)) + "\n"));
return "ROFL";
};
function defaultTest(param1, param2, param3) {
};
function andereTestFunktion(param4) {
STDOUT("ICH BIN DA CaLLBACk");
};
function mySub() {
STDOUT("I'm in SUB!!! \n");
return 0;
STDOUT("Ich werde nie angezeigt lol! \n");
};
function GetInt() {
return 42;
};
function Regal() {
this.Buecher = GLBArray();
this.clone = function() {
var other = new Object();
other.Buecher = this.Buecher.clone();
return other;
};
return this;
};
function Buch() {
this.AktuelleSeite = 0.0;
this.Titel_Str = "";
this.Besitzer_Str = "";
this.Seiten_Str = GLBArray();
this.Seiten = GLBArray();
this.clone = function() {
var other = new Object();
other.AktuelleSeite = this.AktuelleSeite;
other.Titel_Str = this.Titel_Str;
other.Besitzer_Str = this.Besitzer_Str;
other.Seiten_Str = this.Seiten_Str.clone();
other.Seiten = this.Seiten.clone();
return other;
};
return this;
};
function Seite() {
this.Alter = 0;
this.Text_Str = "";
this.clone = function() {
var other = new Object();
other.Alter = this.Alter;
other.Text_Str = this.Text_Str;
return other;
};
return this;
};
</script>
</head>
<body onLoad="main();">
<!--<textarea name="GLBContent" style="width:100%;height:100%">
</textarea>-->
</body>
</html>
@Quentin: Grundlegendes Wissen habe ich aus dem Buch: http://www.amazon.de/Grundlagen-Techniken-Compilerbaus-Niklaus-Wirth/dp/3486585819/ref=sr_1_4?ie=UTF8&qid=1313072704&sr=8-4 , alles weitere lernt man nur durch Learning by doing :P
MfG
Ganz erstaunlich!
Ich hatte mich vor etlichen Jahren mal mit den Drachen-Büchern beschäftigt, aber entnervt aufgegeben.
Großes Kompliment!
Wow, ist das gut!
Heyho!
Die GLBasic Syntax ist fertig implementiert ... naja fast, bis auf Kleinigkeiten (und natürlich bug hunting...)
Also, was habe ich implementiert?
PROTOTYPE, IF - ELSEIF - ELSE - ENDIF, WHILE - WEND, REPEAT - UNTIL, FOR - NEXT, STARDATA - DATA - ENDATA - RESTORE - READ, TRY - CATCH - FINALLY, SELECT - CASE - DEFAULT - ENDSELECT (inkl. die Spompanadeln (http://www.ostarrichi.org/wort-1721-at-Spompanadeln.html) wie CASE >4; CASE 2 TO 8 Außerdem gehen Mehrfachmöglichkeiten, also CASE 1, 2, 3 und so), Vordefinierte Arraygrößen (habe ich persönlich sehr vermisst, also sowas wie LOCAL array[10][10]), DIM als Expression funktioniert auch also: LOCAL arr[] AS Typblubi= DIM[10][10] AS Typblubi, CONSTANT, diverse Bugs wurden gekillt, und weiß Gott was ich noch vergessen habe. Außerdem habe ich die Variablenverarbeitungsroutine neu geschrieben, weil die alte Version einen mysteriösen Fehler hatte, den ich einfach nicht finden konnte.
Was fehlt noch?
ALIAS, BYREF (Es gibt leider keine Pointer in JavaScript, hier muss ich mir noch etwas überlegen), GOTO (gibt kein GOTO in JavaScript, muss hier auch noch etwas rumexperimentieren) und natürlich die ganzen 2D/3D/4D/Sound/... Funktionen von GLB in HTML5 implementieren.
Codebeispiel gibts im Moment leider keines, weil ich auf meinem Netbook bin...
MfG
bin schon ganz hibbelig.
Yay!
BYREF und ALIAS funktionieren nun soweit, dass man sagen kann, dass sie funktionieren (= keine bekannten Bugs). Implementiert habe ich diese, indem ich jede Variable, welche als Referenz verwendet wird in ein Array caste. Hierdurch wird das by reference zurückgegeben, da ja Objekte nicht call by value sind.
Nun gibt es nur noch GOTO als nicht unterstütztes Sprachelement, jedoch bezweifle ich stark, dass ich dieses Sprachelement auch implementieren werde, da JS einfach kein GOTO unterstützt. Vielleicht finde ich noch eine Möglichkeit, jedoch bezweifle ich dies. Außerdem gibt es einen Bug im Moment im Compiler, der auftritt, wenn eine Funktion ein Array als Rückgabewert hat (ja das (sollte) auch funktionieren!)
Weil mir ein wenig langweilig war, habe ich auch gleich CODELINE() und CODEFILE$() implementiert!
Also: Wenn die Sprachelemente alle (ohne bekannte Fehler) funktionieren, werde ich mich ans Porten der Engine kümmern.
Kleines Codebeispiel mit ALIAS/BYREF:
//Simple ALIAS Variable test
LOCAL i = 100
ALIAS j AS i
j = 200
STDOUT "i = "+i+"\n"
//Array test
LOCAL array[10][10]
array[GetInteger()][GetInteger()] = 200
ALIAS v AS array[GetInteger()][GetInteger()]
v = 300
STDOUT "array[GetInteger()][GetInteger()] = " + array[GetInteger()][GetInteger()] + "\n"
//damit keine ungewollten seiteneffekte entstehen, muss ich überüprüfen wie oft GetInteger() aufgerufen wird
FUNCTION GetInteger%:
STATIC Callen
Callen = Callen + 1
STDOUT "Call 'GetInteger', "+Callen+" time(s) \n"
RETURN 5
ENDFUNCTION
//Type ALIAS
TYPE Test
X
ENDTYPE
GLOBAL Tests[10] AS Test
Tests[GetInteger()].X = 100
ALIAS typTest AS Tests[GetInteger()]
typTest.X = 200
STDOUT "Tests[GetInteger()].X = " + Tests[GetInteger()].X+"\n"
//Array Alias
LOCAL arr[10]
ALIAS arr2 AS arr
arr2[GetInteger()] = 400
STDOUT "arr[GetInteger()] = "+arr[GetInteger()]+"\n"
//simple BYREF test
FUNCTION Foo: BYREF a
a = 200
ENDFUNCTION
i = 100
Foo i
STDOUT "i = "+i+"\n"
wird zu JS:
<html>
<head>
<title>GLBasic</title>
<script type="text/javascript" src="JS/lib.js"></script>
<script type="text/javascript">
//init globals, default value!!
var global5_Tests_ref = [GLBArray()];
function main(){
var local1_i_ref = [0.0], alias1_j_ref = [0.0], local5_array_ref = [GLBArray()], alias1_v_ref = [0.0], alias7_typTest_ref = [new Test()], local3_arr_ref = [GLBArray()], alias4_arr2_ref = [GLBArray()];
//line: 3
local1_i_ref[0] = CAST2FLOAT(100);
//line: 4
alias1_j_ref = local1_i_ref //ALIAS;
//line: 5
alias1_j_ref[0] = CAST2FLOAT(200);
//line: 6
STDOUT((((("i = ") + (CAST2STRING(local1_i_ref[0])))) + ("\n")));
//line: 10
local5_array_ref[0] = DIM(GLBArray(), [10, 10], [0.0]);
//line: 11
local5_array_ref[0].values[func10_GetInteger()][func10_GetInteger()][0] = CAST2FLOAT(200);
//line: 12
alias1_v_ref = local5_array_ref[0].values[func10_GetInteger()][func10_GetInteger()] //ALIAS;
//line: 13
alias1_v_ref[0] = CAST2FLOAT(300);
//line: 14
STDOUT((((("array[GetInteger()][GetInteger()] = ") + (CAST2STRING(local5_array_ref[0].values[func10_GetInteger()][func10_GetInteger()][0])))) + ("\n")));
//line: 28
global5_Tests_ref[0] = DIM(GLBArray(), [10], [new Test()]);
//line: 29
global5_Tests_ref[0].values[func10_GetInteger()][0].attr1_X = CAST2FLOAT(100);
//line: 30
alias7_typTest_ref = global5_Tests_ref[0].values[func10_GetInteger()] //ALIAS;
//line: 31
alias7_typTest_ref[0].attr1_X = CAST2FLOAT(200);
//line: 32
STDOUT((((("Tests[GetInteger()].X = ") + (CAST2STRING(global5_Tests_ref[0].values[func10_GetInteger()][0].attr1_X)))) + ("\n")));
//line: 35
local3_arr_ref[0] = DIM(GLBArray(), [10], [0.0]);
//line: 36
alias4_arr2_ref = local3_arr_ref //ALIAS;
//line: 37
alias4_arr2_ref[0].values[func10_GetInteger()][0] = CAST2FLOAT(400);
//line: 38
STDOUT((((("arr[GetInteger()] = ") + (CAST2STRING(local3_arr_ref[0].values[func10_GetInteger()][0])))) + ("\n")));
//line: 45
local1_i_ref[0] = CAST2FLOAT(100);
//line: 46
func3_Foo(local1_i_ref);
//line: 47
STDOUT((((("i = ") + (CAST2STRING(local1_i_ref[0])))) + ("\n")));
}
function func10_GetInteger() {
//line: 19
static6_GetInteger_Callen = ((static6_GetInteger_Callen) + (CAST2FLOAT(1)));
//line: 20
STDOUT((((("Call 'GetInteger', ") + (CAST2STRING(static6_GetInteger_Callen)))) + (" time(s) \n")));
//line: 21
return 5;
//line: 22
return 0;
};
function func3_Foo(param1_a_ref) {
//line: 43
param1_a_ref[0] = CAST2FLOAT(200);
//line: 44
return 0;
};
function Test() {
this.attr1_X = 0.0;
this.clone = function() {
var other = new Object();
other.attr1_X = this.attr1_X;
other.clone = this.clone;
return other;
};
return this;
};
// set default statics:
var static6_GetInteger_Callen = 0.0;
</script>
</head>
<body onLoad="main();">
</body>
</html>
Wie man sieht, arbeite ich nun mehr mit Name mangling (aus dem namen "i" wird local1_i,...) wodurch keine Konflikte mit JavaScript internen Schlüsselwörtern entstehen können und auch kein Konflikt mit Lokalen/Globalen Variablen.
Übrigens: Da der Compiler zu 100% in GLBasic geschrieben ist, wird es möglich sein, dass sich der Compiler selber kompiliert (selfhosting), wodurch der GLB Compiler bald im Browser zur Verfügung steht, wodurch man CROSSPLATFORM auf wirklich JEDER Platform, welche einen JavaScript fähigen Internetbrowser hat GLBasic programmieren kann. Klingt das nicht awesome?
MfG
totally.
Sollen wir ein Programm schreiben, dass eine Code-Datei mit beiden Compilern durchrappelt und das Ergebnis in eine Datei schreibt und dann vergleicht?
Wie kann man in JS Dateien speichern?
Ja, so ein Programm wäre nützlich (evtl auch für dich zum debuggen ob die neuen GLB Versionen mit den alten Kompatibel sind)
Auf die schnelle konnte ich folgendes zum schreiben in Dateien finden: http://dev.w3.org/2006/webapi/FileAPI/ (http://dev.w3.org/2006/webapi/FileAPI/) ob das wirklich ausreichend ist weiß ich nicht.
Hoi!
Da nun wieder Schule begann, komme ich kaum mehr daran an GLBScript weiterzuarbeiten.
* GOTO: Daran habe ich mir die Zähne ausgebissen. Dieses funktioniert zwar _grundsätzlich_ hat aber arge Probleme mit Verschachtelten Schleifen und so, deswegen ist es vorerst deaktiviert. Nebenbei ist sobald EIN goto verwendet wird im Code, der GESAMTE Code langsamer. Das muss leider sein, da der gesamte Code nachher mit einem ProgramCounter verwaltet wird und nachher mit dem über iteriert wird.
* 2D Library: Ja, erste Ergebnisse kann ich hier auch schon vorweisen! Einfache Funktionen sind bereits implementiert. Folgender Code wird perfekt ausgeführt und kompiliert:
(http://coolo.kilu.de/files/glbs_first_html.png)
Bereits umgesetzte Befehle:
* SHOWSCREEN
* DRAWLINE
* DRAWRECT
* DRAWSPRITE
* ROTOSPRITE
* ZOOMSPRITE
* STRETCHSPRITE
* ROTOZOOMSPRITE
* CLEARSCREEN
* BLACKSCREEN
* RGB
* SYSTEMPOINTER
* MOUSESTATE
* LOADSPRITE
MfG
Geilo! Wohin muss man die Medien kopieren, wenn's auf den Server läuft? Einfach in ein Unterverzeichnis "Media"?
[edit]
Sch... auf GOTO! Die Sprache wird wegen der Main-Loop eh nicht 100.0% identisch mit dem Desktop-GLBasic sein können.
Bitte erst ab 16 folgenden Text lesen:
*STÄNDER*
:good:
any news ?
sorry, since school started, i was not able to continue work on GLBS. I will continue work as soon as possible :)
hey!
this weekend i got some freetime and of course i spent my time for GLBScript.
But what happened?
I implemented some new functions in HTML5:
* CREATESCREEN
* USESCREEN
* SHOWSCREEN now uses double buffering (slighly slower, but that's okay)
* GETSCREENSIZE
* GETDESKTOPSIZE
* GETSPRITESIZE
* BOXCOLL
* RND
* PRINT (does not use the GLB font system, yet)
* KEY (does not use hardware scancodes, yet)
I also programmed a simple Pong game in GLBS, and it works great! There were a few bugs, but i fixed them all. The source code:
TYPE TPlayer
X;Y
VX
KLeft%; KRight%
Score%
FUNCTION Update:
LOCAL W, H
GETSCREENSIZE W, H
IF KEY(self.KLeft)
self.VX = self.VX - 2
ENDIF
IF KEY(self.KRight)
self.VX = self.VX + 2
ENDIF
SELECT self.VX
CASE >6
self.VX = 6
CASE <-6
self.VX = -6
ENDSELECT
SELECT self.X
CASE >W-100
self.X = W-100
CASE <0
self.X = 0
ENDSELECT
self.VX = self.VX*0.9
self.X = self.X + self.VX
ENDFUNCTION
FUNCTION Render:
DRAWRECT self.X, self.Y, 100,40, RGB(255,0,0)
ENDFUNCTION
FUNCTION Init: X, Y, KLeft, KRight
self.X = X
self.Y = Y
self.VX = 0
self.KLeft = KLeft
self.KRight = KRight
ENDFUNCTION
ENDTYPE
TYPE TBall
X;Y;VX;VY
FUNCTION Update:
LOCAL W, H
GETSCREENSIZE W, H
LOCAL OldX = self.X, OldY = self.Y
self.Y = self.Y + self.VY
IF self.AnyCollision()
self.VY = -self.VY
self.Y = OldY + self.VY
ENDIF
self.X = self.X + self.VX
IF self.AnyCollision()
self.VX = -self.VX
self.X = OldX + self.VX
ENDIF
IF self.X < 0 OR self.X > W - 20 THEN self.VX = -self.VX
IF self.Y < -20
self.Reset
Player1.Score = Player1.Score + 1
ENDIF
IF self.Y > H
self.Reset
Player2.Score = Player2.Score + 1
ENDIF
ENDFUNCTION
FUNCTION Render:
DRAWRECT self.X, self.Y, 20,20, RGB(0,255,0)
ENDFUNCTION
FUNCTION Init: X, Y, VX, VY
self.X = X
self.Y = Y
self.VX = VX
self.VY = VY
ENDFUNCTION
FUNCTION Reset:
LOCAL W, H
GETSCREENSIZE W, H
Ball.Init W/2 - 10, H/2 - 10, (RND(8) - 4)*2, (RND(8) - 4)*2
ENDFUNCTION
FUNCTION AnyCollision%:
IF BOXCOLL(self.X, self.Y, 20, 20, Player1.X, Player1.Y, 100, 40) OR BOXCOLL(self.X, self.Y, 20, 20, Player2.X, Player2.Y, 100, 40)
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNCTION
ENDTYPE
GLOBAL Player1 AS TPlayer
GLOBAL Player2 AS TPlayer
GLOBAL Ball AS TBall
SUB GLB_ON_INIT:
LOCAL W, H
GETSCREENSIZE W, H
Player1.Init 10,10, 37,39 //left arrow, right arrow, there are no scancodes like in GLB :/
Player2.Init 10,H-50, 65, 68 //a, d
Ball.Reset
ENDSUB
SUB GLB_ON_LOOP:
Player1.Update
Player2.Update
Ball.Update
Player1.Render
Player2.Render
Ball.Render
PRINT "Score: "+Player1.Score+" : "+Player2.Score, 10, 10
SHOWSCREEN
ENDSUB
Live example (http://programming-with-design.at/files/GLBScript/Pong2D/File.html)
Hey!
New Features: FOREACH, Preprocessor and some kind of optimazation.
* FOREACH: Works as expected. I don't use javascript's foreach, because i don't know exactly its behaviour. At the moment FOREACH is a simple for with some assignments.
* Preprocessor: Wasn't too difficult to implement. The only command which was not as easy as expected was "?IF", but with little modification of the expression parser it ran perfectly.
* Optimization: Hardcoded terms like "1 + 1" are now replaced by "2". Not much but I think it was worth it.
Code like
GLOBAL Players$[]
DIM Players$[2]
Players$[0] = "Player1"
Players$[1] = "Player2"
FOREACH P$ IN Players$
STDOUT "Hallo: "+P$
NEXT
STDOUT 100*9-8*(4-10/2)
?IF GLB_VERSION > 0
STDOUT "Oha nice GLB version!"
?ENDIF
?IF 100*5 > 10 AND 4-9 = -5
STDOUT "nice expression dude"
?ENDIF
?IFNDEF HTML5
//Compatibility!
GOSUB GLB_ON_INIT
WHILE TRUE
GOSUB GLB_ON_LOOP
WEND
?ENDIF
Gets now compiled into:
//init globals, default value!!
var global11_Players_Str = GLBArray();
function main(){
//line: 3
DIM(global11_Players_Str, [2], [""]);
//line: 4
global11_Players_Str.values[0] = "Player1";
//line: 5
global11_Players_Str.values[1] = "Player2";
//line: 8
var forEachSaver1 = global11_Players_Str;
for(forEachCounter1 = 0 ; forEachCounter1 < forEachSaver1.values.length; forEachCounter1++) {
local5_P_Str = forEachSaver1.values[forEachCounter1];
{
//line: 7
STDOUT("Hallo: " + local5_P_Str);
}
forEachSaver1.values[forEachCounter1] = local5_P_Str;
};
//line: 9
STDOUT(CAST2STRING(908));
//line: 10
STDOUT("Oha nice GLB version!");
//line: 11
STDOUT("nice expression dude");
}
// set default statics:
really looking great.
Hi!
Last days I was working on a simple XML reader (to open .gbap files), which works like the DOM model (so I don't have to store the whole xml in memory => very short code, it uses an event system using PROTOTYPE)
Then I tried to get this reader working with GLBasicScript, and now it works really fine! To do that I had to fix tons of compiler bugs, then I had to port some of the file functions of GLBasic (which also works fine now, I'm using xmlhttprequest2, so it works quite nice!). And finally had to fix some compiler bugs again!
New functions:
* MID
* LEFT
* RIGHT
* OPENFILE (not finished, it's only possible to read files)
* ENDOFFILE
* READLINE
* CLOSEFILE
* INC
* DEC
* DIMPUSH
* LEN
* GENFILE
This is the GLBasic code:
// --------------------------------- //
// Project: GLBScript
// Start: Monday, November 14, 2011
// IDE Version: 10.159
FUNCTION MyEvent: Name$, Attributes[] AS xmlAttribute
STDOUT "Node: "+Name$+"\n"
FOREACH Att IN Attributes[]
STDOUT "\t"+Att.Name$+": '"+Att.Value$+"'\n"
NEXT
ENDFUNCTION
LOCAL xml AS XML
xml.ReadXML(LoadFile$("Media/GLBScript2.gbap"), MyEvent)
FUNCTION LoadFile$: Path$
LOCAL Text$
LOCAL File% = GENFILE()
IF OPENFILE(File,Path$,1)
WHILE ENDOFFILE(File)=FALSE
LOCAL Line$
READLINE File,Line$
Text$=Text$+Line$+"\n"
WEND
CLOSEFILE File
ELSE
STDOUT "Cannot find file: " + Path$ + "\n"
ENDIF
RETURN Text$
ENDFUNCTION
TYPE xmlAttribute
Name$
Value$
ENDTYPE
PROTOTYPE XMLEvent: Name$, Attributes[] AS xmlAttribute
TYPE XML
Text$; Event AS XMLEvent; Position%; DontCall% = FALSE
FUNCTION ReadXML: Text$, event AS XMLEvent
STDOUT "Parse XML: \n" + Text$
self.Event = event
self.Text$ = Text$
self.Position = 0
self.OverjumpWhitespaces()
//überspringe <? >
IF LEFT$(self.Text$, 2) = "<?"
WHILE self.Get$() <> ">"
INC self.Position
WEND
INC self.Position
ENDIF
self.OverjumpWhitespaces()
TRY
ParseNode()
CATCH Err$
STDOUT Err$
KEYWAIT
FINALLY
ENDFUNCTION
FUNCTION ParseLayer:
self.OverjumpWhitespaces()
WHILE self.Get$() = "<"
// ist es /?
LOCAL HasSlash% = FALSE
INC self.Position
self.OverjumpWhitespaces()
IF self.Get$() = "/"
HasSlash = TRUE
ENDIF
WHILE self.Get$() <> "<"
DEC self.Position
WEND
IF HasSlash THEN RETURN 0
self.ParseNode()
WEND
RETURN 1
ENDFUNCTION
FUNCTION ParseNode:
IF self.Get$() <> "<" THEN THROW "XML Error - Expecting '<'"
INC self.Position
self.OverjumpWhitespaces()
LOCAL Name$ = ParseIdentifier$()
LOCAL Attributes[] AS xmlAttribute
//Attribute holen
IF self.Get$() = " "
self.OverjumpWhitespaces()
WHILE self.Get$() <> "/" AND self.Get$() <> ">"
self.OverjumpWhitespaces()
LOCAL Att AS xmlAttribute
Att.Name$ = self.ParseIdentifier$()
self.OverjumpWhitespaces()
IF self.Get$() <> "=" THEN THROW "XML Error - Expecting '='"
INC self.Position
self.OverjumpWhitespaces()
IF self.Get$() <> "\"" THEN THROW "XML Error - Expecting '\"'"
INC self.Position
LOCAL Pos% = self.Position
WHILE self.Get$() <> "\""
INC self.Position
WEND
INC self.Position
Att.Value$ = MID$(self.Text$, Pos, self.Position - Pos - 1)
self.OverjumpWhitespaces()
DIMPUSH Attributes[], Att
WEND
ENDIF
self.Event(Name$, Attributes[]) //führe event aus
SELECT self.Get$()
CASE ">"
INC self.Position
self.OverjumpWhitespaces()
IF ParseLayer() THEN THROW "XML Error - Unexpected End of File, expecting </"+Name$+">"
self.OverjumpWhitespaces()
IF self.Get$() <> "<" THEN THROW "XML Error - Expecting '<'"
INC self.Position
self.OverjumpWhitespaces()
IF self.Get$() <> "/" THEN THROW "XML Error - Expecting '/'"
INC self.Position
IF Name$ <> self.ParseIdentifier$() THEN THROW "XML Error - Nodes do not match"
IF self.Get$() <> ">" THEN THROW "XML Error Expecting '>'"
INC self.Position
self.OverjumpWhitespaces()
CASE "/"
INC self.Position
IF self.Get$() <> ">" THEN THROW "XML Error - Expecting '>'"
INC self.Position
self.OverjumpWhitespaces()
DEFAULT
THROW "XML Error"
ENDSELECT
ENDFUNCTION
FUNCTION ParseIdentifier$:
LOCAL Pos% = self.Position
WHILE self.Get$() <> " " AND self.Get$() <> "/" AND self.Get$() <> ">" AND self.Get$() <> "="
INC self.Position
WEND
IF self.Position >= LEN(self.Text$) THEN THROW "XML Error"
RETURN MID$(self.Text$, Pos, self.Position - Pos)
ENDFUNCTION
FUNCTION Get$:
IF self.Position >= LEN(self.Text$)
THROW "XML Error - Unexpected End Of File"
ELSE
//DEBUG MID$(self.Text$, self.Position, 1)
RETURN MID$(self.Text$, self.Position, 1)
ENDIF
ENDFUNCTION
FUNCTION OverjumpWhitespaces:
WHILE self.Position < LEN(self.Text$) AND (self.Get$() = " " OR self.Get$() = "\n" OR self.Get$() = CHR$(13))
INC self.Position
WEND
ENDFUNCTION
ENDTYPE
Live Demo (http://www.programming-with-design.at/files/GLBScript/XMLReader/File.html)
Hi coolo!
your project seems awesome. Are there any news about? when do you expect to release it?
BTW it would be very interesting to make a sticky post in the general EN forum :) people would be glad to know how is it the project growing up! :P
best!
hey!
yeah, I'm currently bootstrapping the compiler. That means, the compiler is compiling its own source code. After this process the compiler is running nativly in browsers. The problem is, there is still a lot work left (basically it is compiling, but the generated code is not executed properly)
But well, things I've done since last posting:
* DELETE
* GETTIMERALL
* DIMDEL
* BOUNDS
* INTEGER
* REPLACE
* TRIM
* ASC
* CHR
* fixed tons of bugs
* compiling multiple source files
* ...
Problems i've discovered while bootstrapping:
* i% = 100/i# = 100 does not work (%, # throws an error)
* line numbering is not working properly
* Codefolding modifies the source code in a strange way
I just want to say, that i'm still working on GLBScript. But development is far slower than before. Currently I am porting the 2D engine of GLBasic to HTML5 and fixing tons of bugs.
I am trying, as already mentioned, to bootstrap the compiler to HTML5. The lexer and code analyser is already working properly, but the parser and code generator still crashes. I think in around two months we will have a GLBasic compiler running in every webbrowser!
Fixed bugs:
- TRIM/LTRIM/RTRIM: Now working properly
- REPLACE: Empty strings do not crash the script
- FOREACH: Now working with by ref variables (ALIAS/BYREF)
- DIMPUSH now working with ALIAS/BYREF
- Negative indices in arrays (array[-1]) works.
- Array bound checks are now performed.
- Some speed improvements.
But there is still a lot of work left...
great coolo ! :good:
Quote from: coolo on 2012-Mar-08
... I think in around two months we will have a GLBasic compiler running in every webbrowser!
This would be awesome!
Keep up the good work!
hey!
A short status report: Since last firefox update (version 11) the xmlhttprequests I'm using for getting data for OPENFILE doesn't work with local files anymore. Chrome and Safari does not support it anymore too. So I have to rewrite the whole File I/O system. The approach I am now using is simple: Just embed all data into the HTML file. This way it works in every browser. If you have a better idea, i would love to hear!
Further I just want to say, that I am absolutly in time about porting the GLBasic Compiler to the web! Some little problems (except the rewrite of the IO system) but I think I am able to fix them soon!
Changelog since last update:
Fixed: Repeat - Until now works properly
Fixed: Reference parameters (BYREF) are more robust (THAT was long bug hunting...)
Fixed: REDIM/DIMPUSH speed increased
Fixed: int/float casting handles "1" and "0" correctly
Fixed: >,<,<=,>=,and,or,=,<> was not converted from boolean to integer
Fixed: Recursion in combination with FOREACH had really strange behaviour
Fixed: Negate operator (-) had wrong operator priority
Added: Support for hex values
Added: GETFILELIST
Added: REVINSTR
Added: MOD
Added: READUBYTE
(http://i.chzbgr.com/completestore/2012/3/18/472a25be-12fe-447d-ae7b-ad410f82d50a.jpg)
I see the HTML5 stuff is hidden in German.
Much respect and thanks to Coolo for undertaking this amazing task.
Wish I read German so I could understand more what was going on in this thread.
What about GLScriptBasic?
Have we a script language within GLBasic or not?
I'm still using the old GLSCriptBasic codebase, but there aren't TYPE and some bugs are present.
Sorry for forgetting to mention:
I've made a post in the english section:
http://www.glbasic.com/forum/index.php?topic=8087.0 (http://www.glbasic.com/forum/index.php?topic=8087.0)
Yes I saw it, and I want to send you all my thanks to you make it happen.
What I'm wanted to ask: There will be a VM as in the old GLScriptBasic? So we can compile and run small scripts within our GLBasic program? Would be also nice if we can run more concurrent VMs with different scripts.
I hope I'll find the time... but shouldn't be too time consuming.
It's possible to write a wrapper for V8 (an awesome JavaScript compiler/interpreter, used by Chrome) in GLB, then execute the generated JavaScript code. But I hope that won't be necessary...