Q

Übersicht Sonstiges Projekte

Neue Antwort erstellen

Farbfinsternis

Betreff: Q

BeitragSa, März 05, 2011 23:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Dies ist ein Nebenprojekt von jBB. Es soll die jBB Programmierung erleichtern.

Da viele JavaScript meiden weil es kompliziert erscheint oder als "hässlich" eingestuft wird, habe ich angefangen einen Konverter zu schreiben. Dieser kann leider nicht BMax oder BB Code konvertieren, auch wenn "Q" recht ähnlich aussieht. "Q" ist eine Mischung aus BB und BlitzMax und das einzige Programm dass der Konverter derzeit umsetzen kann sieht so aus:
BlitzMax: [AUSKLAPPEN]

Global myImage = LoadImage("media/pointer.png")

' "As INIT" definiert diese Funktion als Initialisierungsfunktion
Function myInit() As INIT
Graphics 800, 600, 30
SetColor 255, 255, 255
ClsColor 90, 120, 200
HidePointer
End Function

' "As MAIN" definiert diese Funktion als Hauptfunktion
Function myGame() As Main
Cls

Local mx = MouseX()
Local my = MouseY()

DrawImage myImage, mx, my

End Function

rem
Diese Funktion ist frei und wird von der Hauptfunktion,
oder einer Funktion welche die Hauptfunktion aufruft,
aufgerufen
end rem

Function Test(x:Int, y:Int, val:String = "Hallo:Welt")

End Function


... daraus macht der Konverter folgendes:
Code: [AUSKLAPPEN]

<!DOCTYPE html>
<html>
<head>
   <title>Hallo Welt</title>
   <script type='text/javascript' src='js/jbb.js'></script>
   <script type='text/javascript'>
      var myImage  =  LoadImage("media/pointer.png");

      function myInit(){
         Graphics('jBBGame', myGame, 30);
         SetColor(255, 255, 255);
         ClsColor(90, 120, 200);
         HidePointer();
      };

      function myGame(){
         Cls();
         var mx = MouseX();
         var my = MouseY();
         DrawImage(myImage, mx, my);
      };

      function Test(x, y, val){
      };
   </script>
</head>
<body onLoad='myInit();'>
   <canvas id='jBBGame' width='800' height='600'>
      Sorry, your browser doesn't support Canvas.
   </canvas>
</body>
</html>


Dieses Beispiel kann man sich hier live anschauen.

Das Tool wird über die Konsole (Terminal) gestartet und erwartet zumindest den Parameter "file=meinFetterQCode"
Alles in Allem sind derzeit folgende Parameter für den Konverter definiert:

  • file - definiert die Datei die konvertiert werden soll (muss angegeben werden!)
  • output - wie heißt die Datei die erzeugt werden soll (".html" wird automatisch angefügt)
  • strict - bewirkt derzeit noch nichts, in Zukunft werden bei strict = 1 alle Parameter eines Funktionsaufrufs auf ihren korrekten Typ hin überprüft.
  • sitetitle - definiert den Titel der HTML Seite die erzeugt wird
  • tabsize - gibt an mit wievielen Tabs eingerückt wird, voreingestellt ist 1 Tab
  • waitforres - wird diesem Parameter 1 übergeben wartet das JS Programm in LoadImage() und LoadSound() solange bis die entsprechende Resource geladen wurde. Ich empfehle das sein zu lassen
  • jbbsource - definiert von wo das Programm jBB einbinden soll. Default ist "js/jbb.js"
  • nocanvas - definiert die Meldung die ausgegeben werden soll wenn der Browser das HTML5 Canvas nicht unterstützt.

Alle diese Daten haben Default-Werte, einzig "file" muss angegeben werden damit der Konverter weiß was er laden und konvertieren soll.

Beispiel:
Code: [AUSKLAPPEN]
jbbconv file=test.jbb output=index.html sitetitle="Mein fettes HTML5 Game"


Wer StarTrek:TNG kennt wird wissen warum ich die "Sprache" (eigentlich ist es ja keine, der Source wird extrem naiv umgewandelt) "Q" genannt habe Wink

Hier der BMax Source des Konverters:
BlitzMax: [AUSKLAPPEN]

SuperStrict

Framework brl.filesystem
Import brl.retro
Import brl.linkedlist

Const FUNC_TYPE_CUSTOM:Int = 0
Const FUNC_TYPE_INIT:Int = 1
Const FUNC_TYPE_MAIN:Int = 2

Type tParameter
Field parName:String
Field parType:String
Field parDefault: String

Method setName(pName:String)
Self.parName = pName
End Method

Method setType(pType:String)
Self.parType = pType
End Method

Method setDefault(pDefault:String)
Self.parDefault = pDefault
End Method
End Type


Type tFunction
Global _list:TList

Field funcName:String
Field funcType:Int
Field parameters:TList
Field source:TList

Method New()
If Self._list = Null Then Self._list = New TList
Self._list.AddLast(Self)

Self.parameters = New TList
Self.source = New TList
Self.funcType = FUNC_TYPE_CUSTOM
End Method

Method setName(fName:String)
Self.funcName = fName
End Method

Method setType(fType:Int)
Self.funcType = fType
End Method

Method addParameter(par:String, pType:String = "", pDefault:String = "")
Local p:tParameter = New tParameter
p.setName(par)
p.setType(pType)
p.setDefault(pDefault)
Self.parameters.AddLast(p)
End Method

Method addSourceLine(sourceLine:String)
Self.source.AddLast(sourceLine)
End Method
End Type
Global functions:tFunction

Type tGlobal
Global _list:TList
Field v:String
Field val:String

Function addGlobal(variable:String, value:String)
Local g:tGlobal = New tGlobal
If g._list = Null Then g._list = New TList

g.v = variable
g.val = value
g._list.AddLast(g)
End Function
End Type


' pruefen ob eine Datei uebergeben wurde
If AppArgs.length <= 1 Then QuitMessage("Nichts zum uebersetzen...")

Global strictMode:Byte = False
Global siteTitle:String = "jBB"
Global tabSize:Int = 1
Global tab:String = ""
Global inFile:String = ""
Global outFile:String = "output.html"
Global waitForRes:Byte = False
Global jBBSource:String = "js/jbb.js"
Global jBBWidth:Int = 800
Global jBBHeight:Int = 600
Global jBBSpeed:Int = 30
Global jBBCanvasID:String = "jBBGame"
Global jBBInitFunc:String = ""
Global jBBMainFunc:String = ""
Global noCanvasMessage:String = "Sorry, your browser doesn't support Canvas."

' weitere Argumente iterieren
For Local i:Int = 1 To AppArgs.length - 1
Local args:String[] = AppArgs[i].split("=")
Select args[0].toLower()
Case "file" ; inFile = args[1].Trim();
Case "output" ; outFile = args[1].Trim()
Case "strict" ; If args[1].Trim() = "1" Then strictMode = True;
Case "sitetitle" ; siteTitle = args[1].Trim()
Case "tabsize" ; tabSize = Int(args[1])
Case "waitforres" ; If args[1].Trim() = "1" Then waitForRes = True;
Case "jbbsource" ; jBBSource = args[1].Trim()
Case "width" ; jBBWidth = Int(args[1].Trim())
Case "height" ; jBBHeight = Int(args[1].Trim())
Case "fps" ; jBBSpeed = Int(args[1].Trim())
Case "canvasid" ; jBBCanvasID = args[1].Trim()
Case "nocanvas" ; noCanvasMessage = args[1].Trim()
End Select
Next

' TabSize setzen
For Local t:Int = 1 To tabSize
tab:+ Chr(9)
Next

If Not Instr(inFile, "/") Or Not Instr(inFile, "\") Then inFile = CurrentDir() + "/" + inFile
If FileType(inFile) <> 1 Then quitMessage("Die Eingabedatei kann nicht gelesen werden.")

' Ausgabedatei
If ExtractExt(outFile) <> "html" Then outFile:+ ".html"
Local ostream:TStream = WriteFile(outFile)
Local rest:String = ""
Local pos:Int = 0
Local fName:String = ""
Local pars:String = ""

If(ostream)
' Datei einlesen
Local stream:TStream = ReadFile(inFile)
If stream
While Not stream.Eof()
Local in:String = stream.ReadLine().Trim()

' einzeiliger Kommentar
If Left(in, 1) = "'" Then in = ""

' Kommentar am Ende der Zeile
Local comment:Int = Instr(in, "'")
If comment Then in = Left(in, comment - 1)

' mehrzeiliger Kommentar
If Left(in, 3).toLower() = "rem"
Repeat
in = stream.ReadLine().Trim()
Until Left(in, 6) = "endrem" Or Left(in, 7) = "end rem"
in = ""
EndIf

If in.length > 0
' globale Variable
If Left(in, 6).toLower() = "global"
Local rest:String = Right(in, in.length - 6).Trim()
Local parts:String[] = rest.split("=")
Local v:String = parts[0]
Local func:String = ""

If Left(parts[1].toLower().Trim(), 9) = "loadimage" Then func = parts[1] + ";"
If func = "" Then func = parts[1] + ";"

tGlobal.addGlobal(v, func)
EndIf

' Funktion hinzufügen
If Left(in, 8).toLower() = "function"
functions = New tFunction

' Funktionsnamen lesen
rest = Right(in, in.length - 8).Trim()
pos = Instr(rest, "(")
functions.setName(Left(rest, pos - 1).Trim())

' Parameterliste lesen
rest = Right(rest, rest.length - pos).Trim()
pos = Instr(rest, ")")
pars = Left(rest, pos - 1).Trim()

Local par:String[] = pars.split(",")
For Local a:String = EachIn par
Local pName:String = ""
Local pTyp:String = ""
Local pDef:String = ""

' auf Typisierung pruefen
If Instr(a, ":")
Local pt:String[] = a.split(":")
pName = pt[0].Trim()
pos = Instr(pt[1], "=")
If pos
pTyp = Left(pt[1], pos - 1).Trim()
Else
pTyp = pt[1].Trim()
EndIf
Else
pName = a.Trim()
EndIf

' auf Default pruefen
If Instr(a, "=")
Local pd:String[] = a.split("=")
pDef = pd[1].Trim()
EndIf

functions.addParameter(pName, pTyp, pDef)
Next

' evtl. Postdefs lesen
rest = Right(rest, rest.length - pos).Trim()

If Left(rest, 2).toLower() = "as"
rest = Right(rest, rest.length - 2).Trim()
Select rest.toLower()
Case "init"; functions.setType(FUNC_TYPE_INIT); jBBInitFunc = functions.funcName
Case "main"; functions.setType(FUNC_TYPE_MAIN); jBBMainFunc = functions.funcName
End Select
EndIf

' Rumpf lesen
Repeat
in = stream.ReadLine().Trim()
If in.toLower().Trim() <> "end function" And in.toLower().Trim() <> "endfunction"
functions.addSourceLine(in)
EndIf
Until in.toLower().Trim() = "end function" Or in.toLower().Trim() = "endfunction"
End If
EndIf
Wend
stream.Close()

'Header schreiben
ostream.WriteLine("<!DOCTYPE html>")
ostream.WriteLine("<html>")
ostream.WriteLine("<head>")
ostream.WriteLine(tab + "<title>" + siteTitle + "</title>")
ostream.WriteLine(tab + "<script type='text/javascript' src='" + jBBSource + "'></script>")
ostream.WriteLine(tab + "<script type='text/javascript'>")

For Local g:tGlobal = EachIn tGlobal._list
ostream.WriteLine(tab + tab + "var " + g.v + " = " + g.val)
Next

ostream.WriteLine("")

For Local f:tFunction = EachIn tFunction._list
' Funktionskopf
Local l:String = "function " + f.funcName + "("
For Local p:tParameter = EachIn f.parameters
l:+ p.parName + ", "
Next
l = Left(l, l.length - 2)
l:+ "){"
ostream.WriteLine(tab + tab + l)

' Funktionskoerper
For Local c:String = EachIn f.source
'------------------------------------------------------
' Graphics
If Left(c.toLower(), 8) = "graphics"
Replace(c, "(", " "); Replace(c, ")", "")
rest = Right(c, c.length - 9)
Local p:String[] = rest.Split(",")
If p.length = 1 Then jBBWidth = Int(p[0])
If p.length = 2 Then jBBHeight = Int(p[1])
If p.length = 3 Then jBBSpeed = Int(p[2])

ostream.WriteLine(tab + tab + tab + "Graphics('" + jBBCanvasID + "', " + jBBMainFunc + ", " + jBBSpeed + ");")
EndIf

'------------------------------------------------------
' SetColor
If Left(c.toLower(), 8) = "setcolor"
Local tmp:String[] = splitFunctionCall(c, "setcolor")
Local c:Int[] = [0, 0, 0]
Local z:Int = 0
For Local i:String = EachIn tmp
c[z] = Int(i); z:+ 1
Next
ostream.WriteLine(tab + tab + tab + "SetColor(" + c[0] + ", " + c[1] + ", " + c[2] + ");")
EndIf

'------------------------------------------------------
' ClsColor
If Left(c.toLower(), 8) = "clscolor"
Local tmp:String[] = splitFunctionCall(c, "clscolor")
Local c:Int[] = [0, 0, 0]
Local z:Int = 0
For Local i:String = EachIn tmp
c[z] = Int(i); z:+ 1
Next
ostream.WriteLine(tab + tab + tab + "ClsColor(" + c[0] + ", " + c[1] + ", " + c[2] + ");")
EndIf

'------------------------------------------------------
' Cls
If c.length < 6 And Left(c.toLower(), 3) = "cls"
ostream.WriteLine(tab + tab + tab + "Cls();")
EndIf

'------------------------------------------------------
' Local
If Left(c.toLower(), 5) = "local"
Local varName:String = ""
Local varProc:String = ""

Local rest:String = Right(c, c.length - 5).Trim()
Local pos:Int = Instr(rest, " ")
varName = Left(rest, pos - 1)
Local f:String = Right(rest, rest.length - (pos + 1)).Trim()
Select f.toLower()
Case "mousex()" ; varProc = "MouseX();"
Case "mousey()" ; varProc = "MouseY();"
Default ; varProc = f + ";"
End Select

ostream.WriteLine(tab + tab + tab + "var " + varName + " = " + varProc)
EndIf

'------------------------------------------------------
' DrawImage
If Left(c.toLower(), 9) = "drawimage"
Replace(c, "(", " "); Replace(c, ")", "")
Local rest:String = Right(c, c.length - 9).Trim()
ostream.WriteLine(tab + tab + tab + "DrawImage(" + rest + ");")
EndIf

'------------------------------------------------------
' HidePointer
If Left(c.toLower(), 11) = "hidepointer" Then ostream.WriteLine(tab + tab + tab + "HidePointer();")

'------------------------------------------------------
' ShowPointer
If Left(c.toLower(), 11) = "showpointer" Then ostream.WriteLine(tab + tab + tab + "ShowPointer();")

'ostream.WriteLine(tab + tab + tab + c)
Next

'abschliessen
ostream.WriteLine(tab + tab + "};")
ostream.WriteLine("")
Next

ostream.WriteLine(tab + "</script>")
ostream.WriteLine("</head>")
ostream.WriteLine("<body onLoad='" + jBBInitFunc + "();'>")
ostream.WriteLine(tab + "<canvas id='" + jBBCanvasID + "' width='" + jBBWidth + "' height='" + jBBHeight + "'>")
ostream.WriteLine(tab + tab + noCanvasMessage)
ostream.WriteLine(tab + "</canvas>")
ostream.WriteLine("</body>")
ostream.WriteLine("</html>")

ostream.Close()
Else
QuitMessage(inFile + " kann nicht gelesen werden.")
EndIf
Else
QuitMessage(outFile + " kann nicht geschrieben werden.")
EndIf


Function QuitMessage(msg:String)
WriteStdout("> " + msg + "~n")
End
End Function

Function splitFunctionCall:String[](in:String, funcName:String)
in = Replace(in, "(", " ")
in = Replace(in, ")", " ")
Local tmp:String = Right(in, in.length - funcName.length)
Local pars:String[] = tmp.Split(",")

Return pars
End Function
Farbfinsternis.tv

Farbfinsternis

BeitragMo, März 07, 2011 22:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Ein erstes Release ist am Start:

www.sedm.de/jbb/misc/q.zip

Im Archiv befinden sich mehrere Textdateien die erläutern was "Q" ist, wie es funktioniert und wie man es anwendet. Sollten da noch Fragen sein: Hier rein! Wink
Farbfinsternis.tv

Eingeproggt

BeitragDi, März 08, 2011 17:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Seh ich das an deinem Beispiel richtig dass der Konverter noch keine Default-Parameter erkennt und auf die in JS so irrsinnig umständliche Art übersetzt?
Ist auch nur ne Kleinigkeit aber fehlende Default-Parameter treiben mich bei JS regelmäßig in den Wahnsinn - einfach weils ein super Konzept ist was da fehlt... Naja, wenn das alles ist was ich zu meckern hab dann is ja gut Wink

mfG, Christoph.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

Farbfinsternis

BeitragDi, März 08, 2011 18:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Kommt alles noch, es fehlen ja auch noch Schleifen und der Strict-Mode.
Farbfinsternis.tv

Neue Antwort erstellen


Übersicht Sonstiges Projekte

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group