Simple Script Max

Kommentare anzeigen Worklog abonnieren
Gehe zu Seite Zurück  1, 2, 3, 4, 5, 6, 7, 8  Weiter

Worklogs Simple Script Max

Vererbung und mehr!

Samstag, 21. November 2009 von coolo
Hallo,

ich hab in den letzten zwei Tagen soviel gemacht, das ich schon fast vergessen habe was genau ich gemacht habe Very Happy

Naja beginnen wir mal mit den einfachsten Sachen.
Die erste richtig coole Neuerung ist die RegisterClass(Class:Object, Name:String) FUnktion. Mit dieser Funktion kann man ganze Klassen ins Script implementieren. Beide "Seiten" (Das Script sowie das BMax Programm) können darauf zugreifen. Dies wird durch das tolle Reflection Modul von BlitzMax relisiert.
Außerdem kann man die Instanzen in Listen/Arrays (ist ja das selbe) speichern. Dadurch eröffnen sich unerahnte Möglichkeiten.

Hier ein kleines Beispiel:
BlitzMax: [AUSKLAPPEN]
SeedRnd(MilliSecs())
Graphics(640,480,0,30)

Type TPlayer
Field X:Int
Field Y:Int
Field Image:TImage

Method Update()
If (KeyDown(KEY_LEFT) && Self->X>3)
Self->X=Self->X-3
ElseIf(KeyDown(KEY_RIGHT) && Self->X<640)
Self->X=Self->X+3
EndIf
DrawText("FPS: "+getFPS(),10, 10)
DrawText("Position: " + Self->Image->X + ", " + Int(Self->Image->Y),10,30)
Self->Image->SetPosition(Self->X, Self->Y)
Self->Image->Draw()
EndMethod
Method New()
Self->X=320
Self->Y=400
Self->Image=New(TImage)
Self->Image->Load("gfx/Player.png")
Self->Image->SetPosition(Self->X,Self->Y)
EndMethod
EndType

Type TShot
Field X:Int
Field Y:Int
Method Update()
DrawOval(Self->X,Self->Y,10,10)
Self->Y=Self->Y-4
EndMethod
Method New(X:Int,Y:Int)
Self->X=x
Self->Y=y
EndMethod
Method Delete()
EndMethod
EndType

Local Player:TPlayer=New TPlayer()
Local ShotList:TShot[]
Local SelPlayer:TPlayer

Repeat
Cls()

If (KeyHit(KEY_SPACE))
Local Shot:TShot=New TShot(Player->X, 400)
ShotList[Shot]=Shot
EndIf
ForEach("ShotList", "SelPlayer")
If (Exist(SelPlayer))
SelPlayer->Update()
If (SelPlayer->Y<0)
SelPlayer->Delete()
ShotList[SelPlayer]=Null
EndIf
EndIf
Next
Player->Update()
Flip(1)
Until (KeyHit(KEY_ESCAPE) Or AppTerminate())

Das ganze läuft ziemlich stabil und schnell.

Weiters habe ich Vererbung eingebaut. Damit ist es nun auch möglich Instanzen zu casten (mit dem CastTo Operator). Außerdem habe ich mich ein wenig von Java/C#/BlitzMax inspirieren lassen. Jedes Objekt leitet sich von der Klasse "Object" ab. Somit kann man wild umhercasten Very Happy.
Kleines Beispiel:
BlitzMax: [AUSKLAPPEN]
Type TBaseType
Method ToString()
Print("Ich bin ein String")
EndMethod
EndType

Type TTest Extends TBaseType
Field X:Int
Method Update()
Print("Basis")
EndMethod
EndType

Type TTest2 Extends TTest
Method Update()
Self->X=100
Print(Self->X)
Print("Ende")
EndMethod
EndType

Local Test:TTest2=New(TTest2)
Test->Update()
Local Test1:TTest=New(TTest)
Test1->Update()
Test1 CastTo TBaseType CastTo Object->ToString()


Außerdem sieht man, dass der "Super" Zeiger implementiert wurde. Mittlerweile ist SimpleScriptMax in Sachen Vererbung sehr weit fortgeschritten.
Das Methoden überladen funktioniert auch (Sieht Methode Update() im Sample). Dabei müssen die Parameter nicht übereinstimmen, jediglich der Name muss gleich sein.

Hier ist noch ein kleines casting Beispiel:
BlitzMax: [AUSKLAPPEN]
Type TTest
Field X:Int
EndType
Type OtherType
EndType

Local Test:TTest=New(TTest)
Test->X=10
Print(Test->X)
Test=Test CastTo Object
//Test->X=100 //Fehlermeldung
Test=Test CastTo TTest
Test->X=100
Print(Test->X)

If (Test EqualsTo OtherType) //langsamer:(Test CastTo TOtherType)==True
Print("Test ist OtherType") //Wird nicht angezeigt
EndIf

Es gibt auch einen Operator "EqualsTo" mit dem kann man überprüfen ob eine Instanz von einer Klasse geerbt hat bzw. diese ist.

Als nächstes kommen die statischen Funktionen/Methoden dran. Diese werden sicher weniger arbeit sein ;D.

MfG
Coolo

Simple Script Max schlägt zurück!

Donnerstag, 19. November 2009 von coolo
*trommelwirbel*

Tadaaa!
Seit einiger Zeit arbeite ich nun an einem Rewrite von Simple Script 2. Der Anstoß kam, als damals der BCC28 startete.
Doch warum zur Hölle mache ich das?
Nunja, ganz genau weiß ich das selber nicht, aber es ist nunmal so. Simple Script Max hat mittlerweile den Funktionsumfang von Simple Script 2 bei weitem überreicht. Mehrdimensionale Dynamische Arrays und fast fertiges OOP sind im Moment die komplexesten Highlights.

Doch was wurde aus ThunderScript? ThunderScript ist Tot, aus dem einfachen Grund weil es mir zu komplex wurde das ganze zu bewerkstelligen, deshalb hab ich die Motivation verloren (Der Compiler selber war schon zu 35% fertig [Syntax Baum erstellen hat ja schon funktioniert]).

Kommen wir wieder zurück zu Simple Script Max.
Es unterstützt wie gesagt Assoziative Arrays und einfaches OOP (Methoden und Attribute). Außerdem gibt es mittlerweile Funktionen. Diese sind im Gegensatz zu der SimpleScript2 Version keine üblen Hacks und funktionieren somit ohne Probleme.
Andere Festures:

Variablen (Int, Float, Byte, String, Long, Short, Double)
• Schleifen (Repeat – Until, Repeat – Forever, While – Wend, For – Next)
kombinierbar
• If Abfragen (If, Else, Elseif)
• Local/Global (Erweitertes Scoping, jede If Abfrage/Schleife eröffnet einen neuen
Scope)
• ForEach Support für Arrays
• Einfache Erweiterbarkeit

Geplant ist außerdem noch:
• Select / Case
• Erweitertes OOP (Vererbung, Polymorphie sowie Statische Funktionen/Variablen)
• Fehlermanagement
• Garbage Collector (Nicht mehr verwendete Objekte löschen)
• IDE
• Wrapper und DLL erstellen (für BB und GLBasic)
• API
• Speicherblöcke (Normale Arrays, wie sie in BMax existieren, keine Assoziativen)
• Referenzen

Hier sind einige Scripte die bereits richtig kompilieren:
Code: [AUSKLAPPEN]
Type TClass3
   Method Update()
      Print("In Klasse3!")
   EndMethod
EndType
Type TClass2
   Field Class3:TClass3
   Method Update()
      Print("In Klasse2!")
   EndMethod
   Method getClass3()
      Print("Bekomme Klasse3")
      Return (Self->Class3)
   EndMethod
EndType

Type TClass
   Field EInFeld:Int
   Field Class2:TClass2

   Method HalloWelt(Parameter:Int)
      Self->EinFeld=Parameter
      Print("Hallo Welt "+Self->EinFeld)
      Self->TschuessWelt()
   EndMethod
   Method TschuessWelt()
      Print("Tschuess Welt: "+Self->EinFeld)
   EndMethod
   method GetClass(EineInt:Int)
      Print("Eine bloede Int: "+EineINt)
      return(Self->Class2)
   EndMethod
EndType

Local Class:TClass=New(TClass)
Class->HalloWelt(70)
Class->Class2=New(TClass2)
Class->getClass(5)->Update()
Class->getClass(6)->Class3=New(TClass3)
Class->getClass(100)->getClass3()->Update()


Code: [AUSKLAPPEN]
Type TTest
   Method New(EineInt:Int)
      Print("Im Konstruktor: "+EineInt)
   EndMethod
   Method Delete()
      Print("In Destruktor!")
   EndMethod
   Method Update()
      Print("Hallo!!!111")
   EndMethod
EndType

Local Test:TTest=New TTest(10)//Daraus wird: __newTTest(10)
Test->Update()
Test->Delete()
//Test->Update() //Fehlermeldung


Code: [AUSKLAPPEN]
Type TClass2
   Field Val:Int
   Field class:TClass3
EndType
Type TAuto
   Field X:int
   Field Y:int
   Field Class2:TClass2
EndType
Type TClass3
   Field CC:TClass4
   Field YY:String
EndType
Type TClass4
   Field Val:Int
EndType

Local Instanz:TAuto=New(TAuto)
Instanz->X=100
Instanz->Class2=New(TClass2)
Instanz->Class2->Val=800
Instanz->class2->class=New(TClass3)
Print(Instanz->class2->class)
Instanz->class2->class->YY="Hallo Welt"
Print(Instanz->X)
Print(Instanz->Class2->val)
Print(Instanz->Class2->class->YY)
Instanz->Class2->class->CC=New(TClass4)
Instanz->Class2->class->CC->Val=-1111
Print(Instanz->Class2->class->CC->Val)


Code: [AUSKLAPPEN]
Local MeineTable:Int[]
MeineTable[10]=100

Print("Hallo: "+MeineFunc(MeineTable,1000,-800,"Hallo Welt",,"gaga"))
Print("Beende!")

Function MeineFunc(Array:Int,Hallo:int,einParameter:int, Welt:String,gg:int=5, txt:String="Hallo ihr")
   Print(Array[10])
   Print("Hallo Welt in Funktion")
   Print(Welt)
   if (1==1)
      Print("Scoping funktioniert")
   endif
   Print("Paramater: "+Hallo+ "einerauch: "+einParameter)
   print("gg: "+gg+ " txt: "+txt)
   Func2()
   return(10)
EndFunction

Function Func2()
   Print("Hallo")
EndFunction


MfG
Coolo

Who the fu*** is Motivation?

Freitag, 3. Juli 2009 von coolo
Hi Leutz,
nun nach ziemlich langer Zeit melde ich mich nun wieder, hatte die letzten Monaten ein richtiges Motivationstief, welches seit gut 2 Tagen überwunden ist, und nun kann ich berichten das ThunderScript Compiler mittlerweile ordentlichen Bytecode erzeugt (Definiert Klassen, findet den Anfang und Ende von bytecode usw.). Das heißt auch, dass bald die Arbeiten an der VM beginnen werden. Da werde ich auch merken ob das Bytecode System welches ich mir ausgedacht habe auch wirklich so funktioniert, oder ob ich noch was hinzufügen muss.

Folgender Code :
Code: [AUSKLAPPEN]

TBAsic.print("Hallo Welt")
global meinefloat:Float=10.2
if (meinefloat==10.2) //So kann man auch auf MeineFloat zugreifen
{
   local meineint:int=20 //Definiere eine Variable Namens meineint vom Typ in mit dem Wert 20
   TBasic.print(meineint)

}

Wird zu
Code: [AUSKLAPPEN]

registerclass tbasic
static
size 3
registerfield Width
type Int
index 1
registerfield Height
type Int
index 2
registerfield Null
registerfunc Print
type Int
index 3
file
str ""
par
str ""
registerfunc Null
registerclass Null
startscope 72
call print
push
str "Hallo Welt"
hold 1
pointer 0
operator =
push
float 10.2
exit
check 0
pointer 0
operator ==
push
float 10.2
startscope 71
hold 2
pointer 0
operator =
push
int 20
call print
pointer 0
endscope 63
endscope 48

Im moment stehen lediglich noch 4 Dinge für den Compiler: Pop/Mov Befehl implementieren und auch die FromPointer OpCodes (PopFromPointer, MoveFromPointer und auch PushFromPointer) Atm sind nur Workarounds drinnen. Außerdem muss noch statt den Funktionsnamen beim callen deren Stackposition angegeben werden.

Aber der Schweirigste Teil ist schon geschafft!

Weiter Gehts!

Montag, 25. Mai 2009 von coolo
Hallo nach vielen Stunden,
da nun der BCC zu ende ist, werd ich mich wieder voll auf ThunderScript stürzen. ThunderScript wird Plattformunabhängig sein (Unter MacOS X und Windows wurde es bereits erfolgreich getestet). Die IDE ist auch schon geplant (Wird höchstwahrscheinlich mit WxMax und Scintilla geschrieben werden), steht aber noch in den Sternen, da man ja zuerst wenigstens Kompilieren können sollte.

Nun gut, zum Kompilieren: Ich bin zum Schluss gekommen, dass das Kompilieren der wichtigste Part am ganzen System ist, deswegen habe ich mich dazu entschlossen diesen Part am besten zu planen und nicht so schnell wie möglich wie zum Beispiel das beim Mathe Parser der Fall war. Dennoch kann ich den ersten Erfolg vermelden:
Code: [AUSKLAPPEN]

push
str "Hallo Welt"
call 1

Es ist zwar nicht komplett, das Scope handling und dergleichen fehlt noch und das registrieren und das setzen der FUnktionen im Speicher per register_func bleibt noch aus, aber ruhig Blut das kommt alles noch Wink.

Was gibts noch zu erzählen? Ich habe die OpCode Liste vervollständigt, hier ist die Liste direkt vom SourceCode entnommen:
Code: [AUSKLAPPEN]

Const OP_PUSH:Byte=1 'setzt einen Wert auf dem Stack
Const OP_CHECK:Byte=2 'Überprüft den letzten Stack, wenn wahr, führe den nächsten OpCode aus
Const OP_EXIT:Byte=3 'Gehe aus dem aktuellen Scope
Const OP_POP:Byte=4 'Lösche den letzten Inhalt vom Stack
Const OP_SCOPE:Byte=5 'heißt dass ein neuer Scope beginnt
Const OP_ENDSCOPE:Byte=6 'Heißt das der Scope endet
Const OP_CALL:Byte=7 'Der Klassentyp vom aktuellen Stack ist der angegeben wert
Const OP_HOLD:Byte=8 'Fügt dem Scope eine Variable hinzu
Const OP_MOVE:Byte=9 'Weist der Variable den letzten Stackeintrag zu
Const OP_VAR:Byte=10 'Gibt den Inhalt der Variable aus
Const OP_REGISTERFUNC:Byte=11 'Registriert eine neue Funktion im Speicher
Const OP_PAR:Byte=12 'Fügt einen Parameter hinzu
Const OP_FILE:Byte=13 'Fügt zu einer Funktion ein File hinzu
Const OP_JUMP:Byte=14 'Springt zu den nächsten OpCodes
Const OP_INT:Byte=15 'Der Token ist ein Int
Const OP_FLOAT:Byte=16 'Der Token ist ein Float
Const OP_DOUBLE:Byte=17 'Der Token ist ein Double
Const OP_SHORT:Byte=18 'Der Token ist ein Short
Const OP_LONG:Byte=19 'Der Token ist ein Long
Const OP_BYTE:Byte=20 'Der Token ist ein Byte
Const OP_STRING:Byte=21 'Der Token ist ein String
Const OP_POINTER:Byte=22 'Heißt das es auf einen Pointer zeigt
Const OP_OPERATOR:Byte=23 'Ein Operator (+,-,*,/,...)
Const OP_RETURN:Byte=24 'Setzt den Return Wert für die gerade ausgewählte Funktion
Const OP_FUNCINDEX:Byte=25 'Setzt den Index der Funktion mit der sie aufgerufen wird
Const OP_NULL:Byte=26 'Wenn auf dieses Objekt zugegriffen wird, dann gibts nen Error
Const OP_CREATECLASS:Byte=27 'Erzeugt einen neuen Speicherbereich
Const OP_CALLFROMPOINTER:Byte=28 'Ruft eine Funktion vom ausgewählten Pointer aus
Const OP_PUSHFROMPOINTER:Byte=29 'Setzt einen Wert vom ausgewähltem Pointer
Const OP_POPFROMPOINTER:Byte=30 'Löscht einen Wert vom Stack vom gewählten Pointer
Const OP_VARFROMPOINTER:Byte=32 'Gibt den Inhalt einer Variable aus vom pointer


Bis dann euer Coolo Wink

Kompilier das Tier!

Freitag, 1. Mai 2009 von coolo
Hallo!
In letzter Zeit habe ich mich ans endgültige Bytecode Format rangewagt, dabei stellten sich einige Fragen auf, welche dank LordChaos und Noobody gelöst wurden (ua. das implementieren von Rekursiven Functionen. usw.). Außerdem wurde der Matheparser verfeinert, sodass er komplizierteste Funktionen ausrechnen kann, nur bei Termen ohne einem Operator, kommt er ins stottern, da der Mathe Baum, der erstellt wird, nur einen Ast erstellt, wenn ein Operator im Term ist, das muss ich in Zukunft noch verbessern.

Das Kompilieren funktioniert bei einigen Ausdrücken schon sehr gut, wobei ich noch an einem Bug festhänge, der Auftritt wenn mehrere Scopes aneinander hängen. Da ich das ganze Rekursiv aufrufe ist es etwas schwerer diesen Fehler zu finden. Aber ich werde ihn mit Sicherheit finden.

Bytecode Format:
Code: [AUSKLAPPEN]

aus:
If (1==2*4+1)
{
   local blubb:int=10
   TBasic.Print(blubb)
}
Wird:
scope 12 //in 12 Opcodes endet dieser Scope wo der Scope beendet
   registerfunc Tbasic_print
      par
      str "" //1. Parameter ist ein String

      file //Das weist sozusagen
      str "" // Es ist eine Interne Funktion

      funcindex 1 //Der Index mit dem die Function angesprochen wird ist 1

      return null//Gibt nichts zurück
   registerfunc Tbasic_end
      return null //Gibt nichts zurück

      file
      str "" // Es ist eine Interne Funktion

      funcindex 2 //Der Index mit dem die Function angesprochen wird ist 2
   registerfunc null

   jump 2 'Überspringt die nächsten 2 OpCodes
   call 2
   push
   int 2 //pushe ein Ibjekt vom Typ Int
   push
   int 4
   operator * // Multiplizioert die letzten 2 Stacks
   push
   int 1
   operator + // addiert die letzten 2 Stacks
   push
   int 1
   operator ==
           
   check 0
   exit // wenn das letzte Element == 0 ist, geh aus dem Scope
   
   scope 12
      hold 1 //Reserviert einen Speicher an 1. Stelle
      push
      int 10
      move 1// Variable mit dem Index 1 bekommt den Inhalt vom letzten stack
      pop //der letzte stack wird gelöscht
      push //Fügt dem Stack die Variable mit dem Index 1 hinzu
      var 1 //Gibt den Inhalt von der Variable an Index 1
      call 1
      pop //den letzten Stack löschen
   endscope 23
endscope //1 ist die Zeile wo der Scope anfängt






Local klasse:Ttest=new(Ttest)
klasse.blubb()

type TTest
{
   method blubb:int()
   {
      TBasic.Print("Blubb")
   }
}

Wird zu:
scope 12
   registerclass TTest
      registerfunction blubb
         file
         str "method.byte"
         funcindex 1
         return int
      registerfunction null
      classindex 1
   registerclass null //Es darf keine Klasse mehr fpr diesen Scope zugewisen werden
   
   hold 1 //mit dem index 1 wird sie angesprochen
   
   push
   createclass 1//Erzeugt eine Klasse mit dem Index von 1
   move 1 //Bewge den inhalt vom obersten Stack Eintrag in den 1. Speicher
   push
   pointer 1 //Pointer von 1
   callfrompointer 1 //rufe ab der Position vom Pointer 1 Eintrag weiter in Reihenfolge eine Funktion
   pop
   pop
endscope


Außerdem sieht man, dass das System extrem flexibel ist, per Index kann auf jeden deklarierten Speicherbereich zugegriffen werden! Neu ist der OpCode CallfromPointer und Pointer, mit diesen Befehlen wird es möglich sein ein OOP System zu implementieren, da im Grunde genommen Klassen auch nur ein vordefinierter Speicherbereich sind.

Außerdem habe ich mich an einer kleiner Änderung im SprachDesign gewagt: Primitive Datentypen (Int, Float,...) Werden beim deklarieren auch solche sein und keine Klassen. Aber um das Sprachkonzept weiter zubehalten (Alles ist ein Objekt) Wird währenddessen eine Gleichnamige Klasse erstellt, welche eine Refernz auf die Variable besitzt, dadurch können weiterhin so praktische Dinge wie Meineint.Adress() und der Mist ausgeführt werden!

Bis bald
Euer Coolo!

Auf zum Atem!

Samstag, 25. April 2009 von coolo
..schrie ein Superheld von den Simpsons in irgendeiner Folge! So ging es mir in den letzten Tagen auch als ich Operatorvorrang implementieren wollte. Gegen Anfang dachte ich mir, dass das in 2 Stunden erledigt ist. Denkste, aus diesen 2 Stunden wurden 2 Tage, warum? Ursprünglich wollte ich Punkt vor Strich genau so machen wie in SimpleScript2. Aber das ging natürlich nicht, da ja jetzt in Bytecode umgewandelt wird. Also musste eine andere Methode her. Inspirieren habe ich mich lassen von HamZta/Peacemaker, mit seinem Tipp, den Infix Term(1+1) in einen Präfix Term (ADD 1 1) umzuwandeln. Leichter gesagt als getan, dazu musste ich zuerst einen Syntaxbaum erstellen und einen Rekursiven (Topdown) Parser erstellen. Nach einiger Zeit war es endlich soweit und der Mathe Parser funktionierte. Zwar kann er noch keine Klammern Regeln, aber Punkt vor Strich schon.

So siehts bisher aus:

Code: [AUSKLAPPEN]

Script Zeile: TBasic.print(1+1*3-4/8*4)
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: 1
Token mit dem Text: +
Token mit dem Text: 1
Token mit dem Text: *
Token mit dem Text: 3
Token mit dem Text: -
Token mit dem Text: 4
Token mit dem Text: /
Token mit dem Text: 8
Token mit dem Text: *
Token mit dem Text: 4
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
----------------------------Token analysieren
Unbekannten gefunden: print
Int gefunden: 1
Int gefunden: 1
Int gefunden: 3
Int gefunden: 4
Int gefunden: 8
Int gefunden: 4
------------------------------KOMPILIEREN
Ein neuer Scope wurde geöffnet
Statische Klasse wurde erstelle
Methode mit dem Namen: print
Aktuelle Prio: 1
Nummer: 4
Nummer: *
Nummer: 8
Nummer: /
Nummer: 4
Nummer: -
Nummer: 3
Nummer: *
Nummer: 1
Nummer: +
Nummer: 1
Aktuelle Prio: 2
Nummer: 4
Operator: *
Nummer: 017BBD98
Operator: /
Nummer: 017BBD38
Nummer: -
Nummer: 3
Operator: *
Nummer: 017BBCD8
Nummer: +
Nummer: 1
Aktuelle Prio: 3
Nummer: 017BBD38
Operator: -
Nummer: 017BBC78
Operator: +
Nummer: 017BBC18
Aktuelle Prio: 4
Nummer: 017BBC18
Aktuelle Prio: 5
Nummer: 017BBC18
8 : * : 4
4 : / : 017BBD98
1 : * : 3
017BBCD8 : - : 017BBD38
1 : + : 017BBC78
ASTADRESS 017BBD98
OPERATOR *
VALUE1 8
VALUE2 4
ASTADRESS 017BBD38
OPERATOR /
VALUE1 4
VALUE2 017BBD98
ASTADRESS 017BBCD8
OPERATOR *
VALUE1 1
VALUE2 3
ASTADRESS 017BBC78
OPERATOR -
VALUE1 017BBCD8
VALUE2 017BBD38
ASTADRESS 017BBC18
OPERATOR +
VALUE1 1
VALUE2 017BBC78
Ein Scope wurde geschlossen


Wie man sieht werden bereits Methoden/Felder erkannt und zugeordnet. Dies funktioniert mit Reflection, da es ja beim Compilieren nicht um jede Millisekunde geht.

Außerdem habe ich mich an ein Bytecode Format herangewagt. Das heißt, wie das Script später in bytecode ausschauen wird (NAtürlich ein wenig vereinfacht, da ja in Wirklichkeit alles in Zahlen umgewandelt wird, und eingerückt hab e ich es nur der Übersichtlichkeit halber)
Code: [AUSKLAPPEN]

aus:
If (1==2*4+1)
{
   local blubb:int=10
   TBasic.Print(blubb)
}
 Wird:
scope 12 //12 ist die Zeile wo der Scope beendet
   push 2
   push 4
   operator * // Multiplizioert die letzten 2 Stackeinträge
   push 1
   operator + // addiert die letzten 2 Stackeinträge
   push 1
   operator ==
            
   check 0 // wenn das letzte Element == 0 ist
   exit //geht aus dem aktuellen Scope
   pop //der letzte stackeintrag wird gelöscht
   pop //der letzte stackeintrag wird gelöscht
   pop //der letzte stackeintrag wird gelöscht
   pop //der letzte stackeintrag wird gelöscht
   scope 12
      classtyp int //heißt das alle nachfolgenden Variablen Ints werden
      hold blubb //fügt dem Scope blubb hinzu
      index 1 //Der Index der Variable ist 1
      classtyp null //es darf keine Variable mehr deklariert werden
      push 10
      move blubb // blubb bekommt den Inhalt vom letzten stack
      pop //der letzte stack wird gelöscht
      push //Fügt dem Stack die Variable mit dem Index 1 hinzu
      var 1
      class TBasic //Von der Klasse TBasic
      method print //Die Print Methode aufrufen
      pop //den letzten Stack löschen
   endscope 23
endscope //1 ist die Zeile wo der Scope anfängt

Ursprünglich wollte ich es wie in Assembler machen, wobei ich Assembler nie wirklich verstanden habe, und dadurch meinen eigenen Mist erfunden habe Wink.

Bei Anregungen und Tipps, könnt ihr mir gerne eine PN oder einen Kommentar Eintrag senden!

SVN!

Samstag, 18. April 2009 von coolo
Hallöchen,
Simple Script 3 wurde heute umbenannt in ThunderScript, die Namensänderung erfolgt dadurch das der Grundgedanke von SimpleScript (Einfaches Scripten, Schnell und Einfach) nicht mehr im Vordergrund steht. Jetzt heißt es: Komfortables Objekt Orientiertes Scripten größerer Projekte mit geringen Aufwand.

Außerdem habe ich heute an einem SVN Repo gearbeitet, und ist schon voll "Funktionstüchtig". Das heißt ihr könnt jetzt auch mal was ausprobieren, und könnt mir auch Bug Meldungen zuschicken. Also viel Spaß beim Source anschauen.

Außerdem habe ich am Grundgerüst des Variablen Systems eingebaut, das heißt nun ist es fix, auch Datentypen wie Int, Float und so sind Objekte, dadurch ist die Scriptengine nicht so schnell wie Lua oder dergleichen, aber das ist sowieso der Fall, da Lua extrem optimiert wurde.

Als kleinen Nebeneffekt ist auch der Anfang für das Scope Management eingebaut worden, das heißt es gibt bereits jetzt Lokale/Globale Variablen. Im Grunde genommen ist eine Globale Variable nur eine Lokale Variable welche zuallererst in der Hierachie ist.

Als kleinen Boni wurden jetzt auch die Kommentare eingebaut, ich weiß das ist eine Kleinigkeit, aber anders als in den beiden Vorgänger Versionen gibt es jetzt auch Kommentare über mehrere Zeilen, das von C bekannte /* */ Duo.

Code:
Code: [AUSKLAPPEN]

Script Zeile: print("Hallo Welt")
Script Zeile: print(1*1+1*2/4)
Script Zeile: global meinefloat:Float=10.2
Script Zeile: if (1==1)
Script Zeile: {
Script Zeile:    local meineint:int=20 //Definiere eine Variable Namens meineint vom Typ in mit dem Wert 20
Script Zeile:    print(meineint)
Script Zeile: }
Script Zeile: /*
Script Zeile: Das sollte ein Test für die Kommentare sein
Script Zeile: Oben sollte Punkt vor Strich stattfinden
Script Zeile: Unten sollte demonstrieren das erkennen der variablen
Script Zeile: */
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "Hallo Welt"
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: 1
Token mit dem Text: *
Token mit dem Text: 1
Token mit dem Text: +
Token mit dem Text: 1
Token mit dem Text: *
Token mit dem Text: 2
Token mit dem Text: /
Token mit dem Text: 4
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: global meinefloat
Token mit dem Text: :
Token mit dem Text: float
Token mit dem Text: =
Token mit dem Text: 10.2
-------------------------------------------
Token mit dem Text: if
Token mit dem Text: (
Token mit dem Text: 1
Token mit dem Text: ==
Token mit dem Text: 1
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: local meineint
Token mit dem Text: :
Token mit dem Text: int
Token mit dem Text: =
Token mit dem Text: 20
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: meineint
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
-------------------------------------------
-------------------------------------------
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
Funktion gefunden! print
String gefunden: "Hallo Welt"
Funktion gefunden! print
Int gefunden: 1
Int gefunden: 1
Int gefunden: 1
Int gefunden: 2
Int gefunden: 4
Token mit dem Text: global
Unbekannten gefunden:  meinefloat
Float gefunden: 10.2
Keyword gefunden: if
Int gefunden: 1
Int gefunden: 1
Token mit dem Text: local
Unbekannten gefunden:  meineint
Int gefunden: 20
Funktion gefunden! print
Unbekannten gefunden: meineint
BEGINSCOPE
CALL print
BRACKET
STRING "Hallo Welt"
ENDBRACKET
CALL print
BRACKET
INT 1
OPERATOR *
INT 1
OPERATOR +
INT 1
OPERATOR *
INT 2
OPERATOR /
INT 4
ENDBRACKET
KEYWORD global
UNKNOWN  meinefloat
AS
CLASS 014C7DF0
OPERATOR =
FLOAT 10.2
KEYWORD if
BRACKET
INT 1
OPERATOR ==
INT 1
ENDBRACKET
BEGINSCOPE
KEYWORD local
UNKNOWN  meineint
AS
CLASS 014C7DC0
OPERATOR =
INT 20
CALL print
BRACKET
UNKNOWN meineint
ENDBRACKET
ENDSCOPE
ENDSCOPE


Auch wurde jetzt ein neues Token eingebaut nämlich das UNKNOWN Token, das bezeichnet ein Token, wo der Lexer _Vermutet_ es sei eine Variable, aber nicht scher weiß ob es wirklich eine ist, da ja das erst im nächsten Durchlauf herausgefunden werden kann.

Hier ist das Google Code Repo: http://code.google.com/p/thunderscript/

Bis dann, euer Coolo!

Who the F*ck is Syntax Baum?

Sonntag, 12. April 2009 von coolo
Hallöchen,
Heute erzähle ich euch mal, was unter der Haube von SS3 läuft. Img Grunde genommen habe ich nun den Lexer fertig geschrieben und habe bereits an der Syntaktischen Analye begonnen, und auch fertig bekommen. Das heißt, aus dem Code kann SS3 bereits die einzelnen Datentypen herausfiltern und Keywords unterstreichen!
Das untere Syntax Beispiel wird folgens analysiert:
Code: [AUSKLAPPEN]
Script Zeile: // If Abfragen:
Script Zeile:
Script Zeile: if (1==1 || 1=0 ^^ 1>3 % 1<4 && 4>=1)
Script Zeile: {
Script Zeile:    TBasic.print("Hallo Welt")
Script Zeile: }
Script Zeile: elseif (1==math.rand(1,2)) //Statt elseif geht auch otherwise
Script Zeile: {
Script Zeile:    TBasic.print("Ansonstenif")
Script Zeile: }
Script Zeile: else
Script Zeile: {
Script Zeile:    TBasic.print("Falsch!")
Script Zeile: }
Script Zeile: TBasic.Waitkey()
Script Zeile:
Script Zeile: //Until Schleife
Script Zeile: local index:int
Script Zeile: {
Script Zeile:    index:+1
Script Zeile:    TBasic.print("Bei Index" & index)
Script Zeile: } until(index>4)
Script Zeile:
Script Zeile: //For Schleife
Script Zeile: for (index=0 TO 10)
Script Zeile: {
Script Zeile:    TBasic.print("For Schleife: " & index)
Script Zeile: }
Script Zeile:
Script Zeile: //While Schleife
Script Zeile: index=0
Script Zeile: while (index<5
Script Zeile: {
Script Zeile:    TBasic.print("While Schleife: " & index)
Script Zeile: }
Script Zeile: /*
Script Zeile:    Ein Kommentar über mehrere Zeilen!
Script Zeile: */
Script Zeile:
Script Zeile: //String example
Script Zeile: local MeinString:String
Script Zeile: MeinString="Hallo Welt!" & Tstring.mid("gluck",2,1)
Script Zeile: Tbasic.print (MeinString)
Script Zeile: Tbasic.print (Tstring.len(Meinstring))
Script Zeile:
Script Zeile: //Float Example
Script Zeile: local meinfloat:Float=5.4
Script Zeile: Tbasic.print(meinfloat)
Script Zeile:
Script Zeile: //Goto example
Script Zeile: goto ("Sinnloser Sprung!")
Script Zeile: Tbasic.print("Ich werde nie angezeigt!!111")
Script Zeile: label("Sinnloser Sprung!")
Script Zeile:
Script Zeile: //inline Bytecode Example
Script Zeile: Inlinebytecode
Script Zeile: {
Script Zeile:    //Hier könnte bereits vorkompilierter Mist stehen
Script Zeile: }
Script Zeile:
Script Zeile: //rechen example
Script Zeile: local meinint:int=5*4-2+(5-1*1)^3+Tmath.rand(4,5)-Tmath.cos(20)
Script Zeile: print (meinint)
Script Zeile:
Script Zeile: //Konstanten example
Script Zeile: local MeineConst:const=100 'Der Datentyp ist immer String
Script Zeile: print (MeineConst)
Script Zeile:
Script Zeile: //Function example
Script Zeile: print(Outputtext())
Script Zeile:
Script Zeile:
Script Zeile: function outputtext(text:String)
Script Zeile: {
Script Zeile:    print(text)
Script Zeile:    return (5)
Script Zeile: }
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: if
Token mit dem Text: (
Token mit dem Text: 1
Token mit dem Text: ==
Token mit dem Text: 1
Token mit dem Text: ||
Token mit dem Text: 1
Token mit dem Text: =
Token mit dem Text: 0
Token mit dem Text: ^
Token mit dem Text: ^
Token mit dem Text: 1
Token mit dem Text: >
Token mit dem Text: 3
Token mit dem Text: %
Token mit dem Text: 1
Token mit dem Text: <
Token mit dem Text: 4
Token mit dem Text: &&
Token mit dem Text: 4
Token mit dem Text: >=
Token mit dem Text: 1
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "Hallo Welt"
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
Token mit dem Text: elseif
Token mit dem Text: (
Token mit dem Text: 1
Token mit dem Text: ==
Token mit dem Text: math
Token mit dem Text: .
Token mit dem Text: rand
Token mit dem Text: (
Token mit dem Text: 1,2
Token mit dem Text: )
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "Ansonstenif"
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "Falsch!"
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: waitkey
Token mit dem Text: (
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: local index
Token mit dem Text: :
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: index
Token mit dem Text: :
Token mit dem Text: +
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "Bei Index"
Token mit dem Text: " & index
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
Token mit dem Text: until
Token mit dem Text: (
Token mit dem Text: index
Token mit dem Text: >
Token mit dem Text: 4
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: for
Token mit dem Text: (
Token mit dem Text: index
Token mit dem Text: =
Token mit dem Text: 0 to 10
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "For Schleife: "
Token mit dem Text: " & index
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: index
Token mit dem Text: =
-------------------------------------------
Token mit dem Text: while
Token mit dem Text: (
Token mit dem Text: index
Token mit dem Text: <
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "While Schleife: "
Token mit dem Text: " & index
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
-------------------------------------------
-------------------------------------------
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: local meinstring
Token mit dem Text: :
-------------------------------------------
Token mit dem Text: meinstring
Token mit dem Text: =
Token mit dem Text: "Hallo Welt!"
Token mit dem Text: " & tstring
Token mit dem Text: .
Token mit dem Text: mid
Token mit dem Text: (
Token mit dem Text: "gluck"
Token mit dem Text: ",2,1
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: meinstring
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: tstring
Token mit dem Text: .
Token mit dem Text: len
Token mit dem Text: (
Token mit dem Text: meinstring
Token mit dem Text: )
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: local meinfloat
Token mit dem Text: :
Token mit dem Text: float
Token mit dem Text: =
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: meinfloat
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: goto
Token mit dem Text: (
Token mit dem Text: "Sinnloser Sprung!"
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: tbasic
Token mit dem Text: .
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "Ich werde nie angezeigt!!111"
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: label
Token mit dem Text: (
Token mit dem Text: "Sinnloser Sprung!"
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: local meinint
Token mit dem Text: :
Token mit dem Text: int
Token mit dem Text: =
Token mit dem Text: 5
Token mit dem Text: *
Token mit dem Text: 4
Token mit dem Text: -
Token mit dem Text: 2
Token mit dem Text: +
Token mit dem Text: (
Token mit dem Text: 5
Token mit dem Text: -
Token mit dem Text: 1
Token mit dem Text: *
Token mit dem Text: 1
Token mit dem Text: )
Token mit dem Text: ^
Token mit dem Text: 3
Token mit dem Text: +
Token mit dem Text: tmath
Token mit dem Text: .
Token mit dem Text: rand
Token mit dem Text: (
Token mit dem Text: 4,5
Token mit dem Text: )
Token mit dem Text: -
Token mit dem Text: tmath
Token mit dem Text: .
Token mit dem Text: cos
Token mit dem Text: (
Token mit dem Text: 20
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: meinint
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: local meineconst
Token mit dem Text: :
Token mit dem Text: const
Token mit dem Text: =
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: meineconst
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: outputtext
Token mit dem Text: (
Token mit dem Text: )
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
-------------------------------------------
Token mit dem Text: function outputtext
Token mit dem Text: (
Token mit dem Text: text
Token mit dem Text: :
Token mit dem Text: string
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: {
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: text
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: return
Token mit dem Text: (
Token mit dem Text: 5
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: }
-------------------------------------------
Keyword gefunden: if
Int gefunden: 1
Int gefunden: 1
Int gefunden: 1
Int gefunden: 0
Int gefunden: 1
Int gefunden: 3
Int gefunden: 1
Int gefunden: 4
Int gefunden: 4
Int gefunden: 1
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
String gefunden: "Hallo Welt"
Keyword gefunden: elseif
Int gefunden: 1
Ungueltiger Token: math
Float gefunden: .
Ungueltiger Token: rand
Ungueltiger Token: 1,2
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
String gefunden: "Ansonstenif"
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
String gefunden: "Falsch!"
Ungueltiger Token: tbasic
Float gefunden: .
Ungueltiger Token: waitkey
Ungueltiger Token: local index
Ungueltiger Token: index
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
String gefunden: "Bei Index"
Ungueltiger Token: " & index
Keyword gefunden: until
Ungueltiger Token: index
Int gefunden: 4
Keyword gefunden: for
Ungueltiger Token: index
Ungueltiger Token: 0 to 10
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
String gefunden: "For Schleife: "
Ungueltiger Token: " & index
Ungueltiger Token: index
Keyword gefunden: while
Ungueltiger Token: index
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
String gefunden: "While Schleife: "
Ungueltiger Token: " & index
Ungueltiger Token: local meinstring
Ungueltiger Token: meinstring
String gefunden: "Hallo Welt!"
Ungueltiger Token: " & tstring
Float gefunden: .
Ungueltiger Token: mid
String gefunden: "gluck"
Ungueltiger Token: ",2,1
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
Ungueltiger Token: meinstring
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
Ungueltiger Token: tstring
Float gefunden: .
Ungueltiger Token: len
Ungueltiger Token: meinstring
Ungueltiger Token: local meinfloat
Ungueltiger Token: float
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
Ungueltiger Token: meinfloat
Ungueltiger Token: goto
String gefunden: "Sinnloser Sprung!"
Ungueltiger Token: tbasic
Float gefunden: .
Funktion gefunden! print
String gefunden: "Ich werde nie angezeigt!!111"
Ungueltiger Token: label
String gefunden: "Sinnloser Sprung!"
Ungueltiger Token: local meinint
Ungueltiger Token: int
Int gefunden: 5
Int gefunden: 4
Int gefunden: 2
Int gefunden: 5
Int gefunden: 1
Int gefunden: 1
Int gefunden: 3
Ungueltiger Token: tmath
Float gefunden: .
Ungueltiger Token: rand
Ungueltiger Token: 4,5
Ungueltiger Token: tmath
Float gefunden: .
Ungueltiger Token: cos
Int gefunden: 20
Funktion gefunden! print
Ungueltiger Token: meinint
Ungueltiger Token: local meineconst
Ungueltiger Token: const
Funktion gefunden! print
Ungueltiger Token: meineconst
Funktion gefunden! print
Ungueltiger Token: outputtext
Ungueltiger Token: function outputtext
Ungueltiger Token: text
Ungueltiger Token: string
Funktion gefunden! print
Ungueltiger Token: text
Ungueltiger Token: return
Int gefunden: 5
-------------------------------------------
KEYWORD if
BRACKET
INT 1
OPERATOR ==
INT 1
OPERATOR ||
INT 1
OPERATOR =
INT 0
OPERATOR ^
OPERATOR ^
INT 1
OPERATOR >
INT 3
OPERATOR %
INT 1
OPERATOR <
INT 4
OPERATOR &&
INT 4
OPERATOR >=
INT 1
ENDBRACKET
BEGINSCOPE
FLOAT .
OPERATOR .
CALL print
BRACKET
STRING "Hallo Welt"
ENDBRACKET
ENDSCOPE
KEYWORD elseif
BRACKET
INT 1
OPERATOR ==
FLOAT .
OPERATOR .
BRACKET
ENDBRACKET
ENDBRACKET
BEGINSCOPE
FLOAT .
OPERATOR .
CALL print
BRACKET
STRING "Ansonstenif"
ENDBRACKET
ENDSCOPE
BEGINSCOPE
FLOAT .
OPERATOR .
CALL print
BRACKET
STRING "Falsch!"
ENDBRACKET
ENDSCOPE
FLOAT .
OPERATOR .
BRACKET
ENDBRACKET
OPERATOR :
BEGINSCOPE
OPERATOR :
OPERATOR +
FLOAT .
OPERATOR .
CALL print
BRACKET
STRING "Bei Index"
ENDBRACKET
ENDSCOPE
KEYWORD until
BRACKET
OPERATOR >
INT 4
ENDBRACKET
KEYWORD for
BRACKET
OPERATOR =
ENDBRACKET
BEGINSCOPE
FLOAT .
OPERATOR .
CALL print
BRACKET
STRING "For Schleife: "
ENDBRACKET
ENDSCOPE
OPERATOR =
KEYWORD while
BRACKET
OPERATOR <
BEGINSCOPE
FLOAT .
OPERATOR .
CALL print
BRACKET
STRING "While Schleife: "
ENDBRACKET
ENDSCOPE
OPERATOR :
OPERATOR =
STRING "Hallo Welt!"
FLOAT .
OPERATOR .
BRACKET
STRING "gluck"
ENDBRACKET
FLOAT .
OPERATOR .
CALL print
BRACKET
ENDBRACKET
FLOAT .
OPERATOR .
CALL print
BRACKET
FLOAT .
OPERATOR .
BRACKET
ENDBRACKET
ENDBRACKET
OPERATOR :
OPERATOR =
FLOAT .
OPERATOR .
CALL print
BRACKET
ENDBRACKET
BRACKET
STRING "Sinnloser Sprung!"
ENDBRACKET
FLOAT .
OPERATOR .
CALL print
BRACKET
STRING "Ich werde nie angezeigt!!111"
ENDBRACKET
BRACKET
STRING "Sinnloser Sprung!"
ENDBRACKET
BEGINSCOPE
ENDSCOPE
OPERATOR :
OPERATOR =
INT 5
OPERATOR *
INT 4
OPERATOR -
INT 2
OPERATOR +
BRACKET
INT 5
OPERATOR -
INT 1
OPERATOR *
INT 1
ENDBRACKET
OPERATOR ^
INT 3
OPERATOR +
FLOAT .
OPERATOR .
BRACKET
ENDBRACKET
OPERATOR -
FLOAT .
OPERATOR .
BRACKET
INT 20
ENDBRACKET
CALL print
BRACKET
ENDBRACKET
OPERATOR :
OPERATOR =
CALL print
BRACKET
ENDBRACKET
CALL print
BRACKET
BRACKET
ENDBRACKET
ENDBRACKET
BRACKET
OPERATOR :
ENDBRACKET
BEGINSCOPE
CALL print
BRACKET
ENDBRACKET
BRACKET
INT 5
ENDBRACKET
ENDSCOPE


Wie man sieht kommen bereits Syntax Fehlermeldungen. Wobei sie nicht richtig sind. Der Analyser weiß ja zu dem Zeitpunkt noch garnicht welche Variablen, Konstanten und FUnktionen gibt, die werden erst im nächsten Kompilier Prozess erkannt.

Das heißt nächstes mal wird der Syntax Baum kurz AST implementiert werden. Das ist einer der wichtigsten Teile am Kompilier, da hier am meisten Optimiert werden kann.

Außerdem habe ich die Syntax für OOP festgelegt:
Code: [AUSKLAPPEN]


//Klassen example
global Carlist:Tlist=New TList
Type TAuto
{
   //Felder
   PUBLIC
   {
      Field x:int
      Field y:int
   }
   PRIVATE
   {
      Field Image:TImage   
   }
   
   //Methoden
   method Draw ()
   {
      self.Image.Drawimage(self.x,self.y) //This geht auch
   }
   method New()
   {
      TBasic.Print("Auto wurde erstellt")
      Carlist.Listaddlast(self)
   }
   method Delete()
   {
      TBasic.Print("Auto wurde gelöscht")
      Carlist.RemoveList(Self)
   }
}
Type Lastwagen Extends TAuto
{
   PRIVATE
   {
      field Movespeed:int
   }
   method Draw()
   {
      TBasic.Print("Ein Lastwagen wird gezeichnet")
      Super.Draw()
   }
}
Tgraphic.Init(640,480)
local car:TAuto=new (TAuto)
car.x=10
car.y=10
car.Draw()
Tgraphic.Flip()


Wie man sieht eine Mischung aus Blitz Max und C#. Wenn ihr was am Syntax auszusetzen habt, könnt ihr es in den Kommentaren schreiben, jetzt ist es noch möglich ihn zu ändern Wink.

Bis dann,
coolo!

Simple Script 3 ist auferstanden!

Mittwoch, 8. April 2009 von coolo
Hallo,
ich konnte mich zum Glück wieder ReReAnimieren neu anzufangen, aber diesmal mit der Objekt Orientierten Programmiersprache, BlitzMax. Dies erlaubt mir einige Dinge, welche ich wirklich vermisst habe, ua. Reflection, (Funktions-)Pointer, OOP, und Geschwindigkeit. Das heißt auch das die Entwicklung viel schneller von statten geht als die 2er und 1er Version. Natürlich habe ich diesmal ziemlich viel geplant, auch habe ich mir gedanken gemacht über die Implementierung der einzelnen Features. Außerdem wird sie nach dem Motto vorgehen: (Fast) Alles ist ein Objekt. Nicht so streng wie Smalltalk, aber doch sehr toll.

Der Syntax wird so lauten, fallls ich irgendeine Änderung daran vornehme, bestraft mich virtuell!!!!111elf
Code: [AUSKLAPPEN]
// If Abfragen:
global Basic:TBasic=new (TBasic) //Wird ja auch in den Funktionen benötigt
local math:Tmath=new (Tmath)
local str:TString=new (TString)

if (1==1 || 1=0 ~ 1>3 % 1<4 && 4>=1)
{
   Basic.print("Hallo Welt")
}
elseif (1==math.rand(1,2)) //Statt elseif geht auch otherwise
{
   Basic.print("Ansonstenif")
}
else
{
   Basic.print("Falsch!")
}
Basic.Waitkey()

//Until Schleife
local index:int
{
   index:+1
   Basic.print("Bei Index" & index)
} until(index>4)

//For Schleife
for (index=0 TO 10)
{
   Basic.print("For Schleife: " & index)
}

//While Schleife
index=0
while (index<5
{
   Basic.print("While Schleife: " & index)
}
rem
{
   Ein Kommentar über mehrere Zeilen!
}

//String example
local MeinString:String
MeinString="Hallo Welt!"+str.mid("gluck",2,1)
basic.print (MeinString)
basic.print (str.len(Meinstring))

//Float Example
local meinfloat:Float=5.4
basic.print(meinfloat)

//Goto example
goto ("Sinnloser Sprung!")
basic.print("Ich werde nie angezeigt!!111")
label("Sinnloser Sprung!")

//inline Bytecode Example
Inlinebytecode
{
   //Hier könnte bereits vorkompilierter Mist stehen
}

//rechen example
local meinint:int=5*4-2+(5-1*1)^3+math.rand(4,5)-math.cos(20)
basic.print (meinint)

//Konstanten example
local MeineConst:const=100
basic.print (MeineConst)

//Function example
basic.print(function.Outputtext()) //Strend nach dem Motto alles ist ein Objekt, man könnte das function. auch weglassen, das würde der Compiler automatisch begradigen


function outputtext(text:String)
{
   basic.print(text)
   return (5)
}


Nunmal zum wesentlichen: Ich habe mir gedacht das String Operationen zu langsam seien, um wirklich schnell zu sein. Dahabe ich mich kurzerhand entschlossen alles nach ByteCode umzuwandeln. Klingt einfacher als es ist. Als erstes habe ich mich an den Lexer gewagt, welcher bereits tadellos arbeitet (Kaum zu glauben das Version 1 und 2 so einen nicht wirklich besaßen...).
Dann habe ich mich zum Compiler gewagt, welcher bereits zu Maschienensprachen ähnlicher Sprache übersetzt:
Code: [AUSKLAPPEN]

print(8*4+1^5)

Print("Hallo Welt")
Print("Ich habe durchfall")
Print(55)
Print(54.4)

Output:
Code: [AUSKLAPPEN]

Script Zeile: print(8*4+1^5)
Script Zeile:
Script Zeile: Print("Hallo Welt")
Script Zeile: Print("Ich habe durchfall")
Script Zeile: Print(55)
Script Zeile: Print(54.4)
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: 8
Token mit dem Text: *
Token mit dem Text: 4
Token mit dem Text: +
Token mit dem Text: 1
Token mit dem Text: ^
Token mit dem Text: 5
Token mit dem Text: )
-------------------------------------------
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "Hallo Welt"
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: "Ich habe durchfall"
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: 55
Token mit dem Text: )
-------------------------------------------
Token mit dem Text: print
Token mit dem Text: (
Token mit dem Text: 54.4
Token mit dem Text: )
-------------------------------------------
Funktion gefunden! print
Operator gefunden: (
Operator gefunden: *
Operator gefunden: +
Operator gefunden: ^
Operator gefunden: )
Funktion gefunden! print
Operator gefunden: (
Operator gefunden: )
Funktion gefunden! print
Operator gefunden: (
Operator gefunden: )
Funktion gefunden! print
Operator gefunden: (
Operator gefunden: )
Funktion gefunden! print
Operator gefunden: (
Operator gefunden: )
-------------------------------------------
CALL print
BRACKET
INT 8
OPERATOR *
INT 4
OPERATOR +
INT 1
OPERATOR ^
INT 5
ENDBRACKET
CALL print
BRACKET
STRING "Hallo Welt"
ENDBRACKET
CALL print
BRACKET
STRING "Ich habe durchfall"
ENDBRACKET
CALL print
BRACKET
INT 55
ENDBRACKET
CALL print
BRACKET
FLOAT 54.4
ENDBRACKET

Wie man sieht ist es noch in String Form, wobei man von diesem Code schätze ich ziemlich einfach in richtige Bytes umwandeln kann.
Außerdem sieht man das Punkt vor Strich noch nicht eingebaut wurden, und String's werden wie in BlitzMax in ein Array umgewandelt werden.

Bis dann,
euer coolo!

R.I.P., leider

Samstag, 4. April 2009 von coolo
Hallo,
heute habe ich eine sehr traurige Nachricht für euch (Oder auch nicht...)! Der Source Code ist vollkommen flöten gegangen. Die Externe Festplatte, hat plötzlich den Geist aufgegeben auch die Backups, die waren nämlich auf der gleichen Externen Festplatte. Das heißt Simple Script 2 ist tot...

Naja, ich habe im Moment keine Lust eine neue Version zu schreiben, üüberhaupt habe ich jetzt keine OLust mehr irgendwas zu programmieren Sad....

Gehe zu Seite Zurück  1, 2, 3, 4, 5, 6, 7, 8  Weiter