GLScriptBasic

Previous topic - Next topic

Kitty Hello

bin schon ganz hibbelig.

metzzo

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:
Code (glbasic) Select
//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:
Code (glbasic) Select
<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
That's no Bug, that's my project!

http://programming-with-design.at/

Kitty Hello

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?

metzzo

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/ ob das wirklich ausreichend ist weiß ich nicht.
That's no Bug, that's my project!

http://programming-with-design.at/

metzzo

#79
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:


Bereits umgesetzte Befehle:
* SHOWSCREEN
* DRAWLINE
* DRAWRECT
* DRAWSPRITE
* ROTOSPRITE
* ZOOMSPRITE
* STRETCHSPRITE
* ROTOZOOMSPRITE
* CLEARSCREEN
* BLACKSCREEN
* RGB
* SYSTEMPOINTER
* MOUSESTATE
* LOADSPRITE

MfG
That's no Bug, that's my project!

http://programming-with-design.at/

Kitty Hello

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.

backslider

Bitte erst ab 16 folgenden Text lesen:

*STÄNDER*

:good:

Codeguru


metzzo

#83
sorry, since school started, i was not able to continue work on GLBS. I will continue work as soon as possible :)

That's no Bug, that's my project!

http://programming-with-design.at/

metzzo

#84
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:
Code (glbasic) Select
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
That's no Bug, that's my project!

http://programming-with-design.at/

metzzo

#85
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
Code (glbasic) Select
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:
Code (glbasic) Select

//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:


That's no Bug, that's my project!

http://programming-with-design.at/

Kitty Hello

really looking great.

metzzo

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:
Code (glbasic) Select
// --------------------------------- //
// 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
That's no Bug, that's my project!

http://programming-with-design.at/

pinete

#88
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!

metzzo

#89
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

That's no Bug, that's my project!

http://programming-with-design.at/