Cross Platform Basic

Kommentare anzeigen Worklog abonnieren
Gehe zu Seite 1, 2  Weiter

Worklogs Cross Platform Basic

Was zum Teufel?

Mittwoch, 29. Dezember 2010 von coolo
Guten Morgen!

Ja, Cross Platform Basic war nun für recht lange Zeit auf Eis gelegt. Was wohl an meinem "2 Phasen Zyklus" liegt. Dieser besagt, dass ich eine bestimmte Zeit an einem Compiler bastle und danach die Motivation verliere und ein Spiel programmiere. Dumm nur, dass diese Zeit nicht reicht um entweder ein Spiel zu programmieren oder einen Compiler zu bauen. Deswegen habe ich Cross Platform Basic einigermaßen übersichtlich gestaltet, weswegen ich recht schnell wieder rein finde.

Nunja, die "Spielephase" ist nun wieder (vorerst) zu Ende und es wird wieder an der Sprache gearbeitet.

Was ist bisher geschehen?
Hauptsächlich wurde etwas aus Cross Platform Basic entfernt. Nämlich die Vererbung, Polymorphie und das Information Hiding. Vererbung und Polymorphie deshalb, weil es einfach viel zu fehleranfällig war und es deshalb eine reimplementation brauchen würde. Jedoch ist dieses Sprachkonstrukt sowieso nicht teil des Konzeptes. Es lautet: "Schreibe einfachen Code einmal, verwende ihn überall". Jedoch wird durch derartige Objektorientierte Features alles recht kompliziert und dies soll nicht sein. Information Hiding wiederum lief fehlerlos und konnte bereits ohne Bangen eingesetzt werden. Wieso habe ich mich dagegen entschieden? Es passte auch nicht in das Konzept von CPB. Information Hiding ist nur dann notwendig, wenn man wirklich riesige Klassen plant zu erstellen. Aber genau dafür ist diese Sprache nicht gedacht. Ich hoffe ihr versteht dies (Methoden blieben allderdings, da diese sehr zur Übersichtlichkeit beitragen und nicht wirklich die Sache verkomplizieren).

Garbage Collector
Ja, das leidige Thema wurde erneut aufgegriffen. Hauptsächlich deswegen, weil der TinyGC den ich verwendete unsagbar langsam war. Daraufhin habe ich BoehmGC versucht zu verwenden, jedoch war dessen Verhalten sehr merkwürdig, was ihn leider auch aus dem Geschäft holte (außerdem haben die Finalizer einen Bug).
Daraufhin habe ich mich natürlich erneut hingesetzt und eben so einen "Müllsammler" versucht zu implementieren. Der erste Versuch ging ordentlich in die Hose. Das Programm stürzte sofort ab und hätte auch in der Theorie nicht wirklich gute Dienste geleistet.
Dann jedoch bekam ich vom Forummitglied maximilian den Tipp einen "Shadow Stack" zu verwenden. Das Hauptproblem war ja an meinem ersten Versuch, dass ich keinen Zugriff auf den Stack hatte, um so alle aktuellen Lokalen Variablen aufzurufen. Dieser Shadow Stack simuliert das ganze, in dem in jedem Scope die Funktion "stack_enter()" aufgerufen wird und beim Verlassen die Funktion "stack_leave()" aufgerufen wird. Bis jetzt nichts Besonderes, jedoch nun wurd JEDE lokale Variable beim deklarieren via "stack_push(&variable)" auf eben diesem registriert. Dadurch hat man zu jedem Zeitpunkt des Programmes die Information welche Referenzen es gibt und worauf diese zeigen.
Nun gut, dies war der erste Meilenstein. Ich musste schließlich noch einen Mark&Sweep Algorithmus implementieren (dieser geht den Stack durch und markiert jedes erreichbare Objekt, und jedes Objekt welches nicht erreichbar ist wird einfach gelöscht). Das Hauptprobelm an diesem Algorithmus' ist ja, herauszufinden ob nun ein Objekt erreichbar ist oder nicht. Hierbei genügt es nicht nur den Shadow Stack abzuarbeiten, man muss auch "tiefer" suchen. Hierfür gibt es drei Möglichkeiten:
Arrow Jedes Objekt speichert zur Laufzeit(=Tags), was es ist und was es hat (leider sehr ineffizient) so macht es Java
Arrow Beim kompilieren werden die Typsignaturen statisch gespeichert und dann abgelaufen. Dies ist der herkömmliche Weg, wenns schnell sein soll.
Arrow Jedes Objekt enthält einen Funktionspointer auf eine Funktion, welches eben jenes Objekt abarbeitet. Dies ist quasi ein Zwischending aus beiden Möglichkeiten. Ich weiß nicht ob es diesen Ansatz schon zuvor gab, aber bis jetzt scheint der Overhead für den Funktionspointer recht gering zu sein.

Tja dies habe ich natürlich implementiert. Referenzen auf Referenzen funktionieren (auch zyklische). Jedoch stürzt das Programm beim abarbeiten von Arrays ab, was aber hauptsächlich daran liegt, dass der Compiler einen Bug hat, der beim kompilieren nach C große Folgen hat, dies wird natürlich noch gefixt.

Grafikengine
Diese wurde auch in den Grundzügen bereits implementiert und getestet. Hierbei gibt es zwei Zweige:
Arrow Software Modus: Hier verwende ich SDL zur Grafikanzeige, Tasteneingabe und dem Rest. Leider unterstützt SDL kein Hardwarebeschleunigtes Alpha/Rotieren/Skalieren/etc. weswegen in diesem Modus dies aufwändig simuliert werden muss (= sehr langsam). Hierbei war auch ein Problem den GCC überhaupt zu bringen das ganze zu linken. Dies wurde allerdings auch gelöst, da ich ursprünglich relative Pfade verwendete.

Arrow Hardware Modus: Hier verwende ich SDL für den OpenGL Grafik Kontext, Testeneingabe und dem Rest. Danach wird via OpenGL alles angezeigt. Dies hat den Vorteil, dass alles viel schneller rotiert/skaliert/alpharisiert(gibts das Wort überhaupt?) werden kann.

Im Software Modus funktioniert, das was funktionieren sollte schon gut. Jedoch wird im Hardware Modus keine Transparenz(= Die Transparent Farbe, wie zum Beispiel Rosa) in den BMP's dargestellt.

ToDo:
Arrow Andere Grafikformate als .bmp unterstützen (hierbei soll SDL_gfx verwendet werden)
Arrow Schriften anzezeigen (hierbei wird ein eigenes bitmap Font System verwendet, dadurch ist es platformunabhängiger)
Arrow Sound (fehlt komplett)
Arrow Animationen (Laden anzeigen,...)
Arrow Kollision (Pixelbasiert, Rechteck - Rechteck, Linie - Linie, Polygon - Polygon)
Arrow Primitive Formen (Ellipse, Linie, Rechteck, Polygon, Punkt)
Arrow Hardware-Modus: ImageBuffer unterstützen (per FBOs)
Arrow Software-Modus: Rotieren/Skalieren/Alpha simulieren (ich glaube Alpha beherrscht SDL)
Arrow Diverse Hilfsfunktionen (Vektor Funktionen, Getter,...)

Zuletzt noch ein kleines Codebeispiel (wirklich nur sehr schnell hingefetzt):
BlitzMax: [AUSKLAPPEN]
graphicsInit("Hallo Welt",640,480)


Global PlayerY:Int = 480/2 - 128/2
Global GegnerY:Int = 480/2 - 128/2

Global Image:Int = LoadImage("gfx/paddle.bmp")
While AppTerminate()==0 And Key(keyEscape())==0
DoPlayer()
DoGegner()
UpdateEvent
ShowScreen
Wend

Function DoPlayer:Void()
PlayerY = PlayerY + (Key(KeyUp()) - Key(KeyDown()))
DrawImage Image, MouseX(), PlayerY
EndFunction
Function DoGegner:Void()
DrawImage Image, 640-40,GegnerY
EndFunction




Tja dann gibt es noch kleinere Sachen. Wie zum Beispiel der "Language" Verwalter. Dieser speichert zu jeder Sprache die einzelnen Informationen. Wodurch theoretisch schon jetzt andere Backends möglich wären.
So sieht es aus:
Code: [AUSKLAPPEN]
<compiler>
   <lang name="C">
      <platform name="windows">
         <compiler command="%COMPILERDIR%/Language/C/windows/bin/gcc.exe -c -O3 -Wall %COMPILERDIR%/%FILENAME% " />
         <linker command="%COMPILERDIR%/Language/C/windows/bin/gcc.exe -o
         compileexe.exe
         
         -lmingw32
         %COMPILERDIR%/%PLATFORMPATH%/SDL.dll
         -lSDLmain
         
         -mwindows
         -lopengl32
         
         CCode.o
         %COMPILERDIR%/Language/C/windows/lib/libopengl32.a
         
         %COMPILERDIR%/%PLATFORMPATH%/cpb_core.o
         %COMPILERDIR%/%PLATFORMPATH%/cpbgraphics.o" />
      </platform>
      <platform name="linux">
         <compiler command="Language/C/linux/bin/gcc.exe -o %FILENAME%" />
      </platform>
      <platform name="macosx">
         <compiler command="Language/C/macosx/bin/gcc.exe -o %FILENAME%" />
      </platform>
   </lang>
   
   <current language="C" platform="windows" />
</compiler>

Information Hiding - Der Duschvorhang für Programmierer

Montag, 30. August 2010 von coolo
Hallo,
ich weiß ursprünglich hieß es dass ich nun eine zweiwöchige Pause mache. Doch ich konnte einfach nicht widerstehen dieses Feature einzubauen.

Ich weiß nicht wieso BlitzMax dies nicht beherrscht, obwohl es nicht wirklich schwer ist dies zu implementieren. Da Information Hiding in Types ein rein syntaktischer Vorgang ist, gibt es keinen Einfluss auf das XML Format.

Private, Public und Protected wurde implementiert. Friendly hats doch nicht geschafft, da ich keinen Sinn dahinter sehe (wenn man sowas braucht, wozu gibts setter/getter?).
Code: [AUSKLAPPEN]
Type Vererbt
   Private
   Field HahaIchBinPrivat:Float=99.999991
   Protected
   
   Field Hallo:Int = 100
   
   Public
   
   Function Test1:Void()
      Print "Hiho"
      Print "In Test1 "+This.Hallo
   EndFunction
EndType
 
Type VerVererbt Extends Vererbt
   Function Test2:Void()
      This.Hallo=This.Hallo+1
      Print "In Test2"
   EndFunction
EndType
Type VerVerVererbt Extends VerVerErbt
   Function Blub:Void()
      This.Hallo=-1
   EndFunction
EndType
Type BlubTyp
   Field Hallo:Int=200
   Field Tschuess:Int=300
   Function Hihi:Void()
      Print "Blubbig: "+This.Hallo+" - "+This.Tschuess
   EndFunction
EndType
VerVerErbt(New VerVerVererbt).Test2()
Print "Next0"
Local Normal:Vererbt=New Vererbt
//Normal.Hallo=10

Normal.Test1()
Print "Next"
Local TestVer:VerVererbt=New VerVererbt
TestVer.Test1()
Print "Next2"
TestVer.Test2()
Vererbt(TestVer).Test1()
BlubTyp(Object(New BlubTyp)).Hihi()

Dieses Snippet zeigt auch gleich die verbesserte Polymorphie. Sie kommt aber unter gewissen umständen noch ins stocken und stürzt ab, dies wird noch behoben.

Habt ihr Anregungen/Wünsche (Syntax, Ide,...), ich wäre offen für alles, schreibt es einfach in die Kommentare.


Polymorphie

Donnerstag, 26. August 2010 von coolo
Hallo!
den letzten Tagen habe ich mich voll der Polymorphie gewidmet. Dies war ein ziemlich schwieriges Unterfangen, da ich dies zuvor nie in dieser Art umgesetzt habe. Um Polymorphie zu implementieren braucht man sog. "Virtual Method Tables" (kurz VTables) diese beinhalten je den funktionspointer zur aktuellen Methodenimplementation. Gesagt Getan, nach 4 Stunden habe ich meine eigenen versuche dies zu einzubauen wieder entfernt und habe folgenden Beispielcode gefunden: Code: [AUSKLAPPEN]
#include <stdio.h>

/* class definitions */
typedef struct Base
{
    void (**vtable)();
    int _x;
} Base;

typedef struct Child
{
    void (**vtable)();
/* begin base class slice */
    int _x;
/* end base class slice */
    int _y;
} Child;

/* class method implementations */
void Base_ToString(Base const* obj) { printf("Base: (%d)\n", obj->_x); }
void Child_ToString(Child const* obj) { printf("Base: (%d,%d)\n", obj->_x, obj->_y); }

/* vtable implementation */
enum { Call_ToString };
void (*Base_Vtable[])() = { &Base_ToString };
void (*Child_Vtable[])() = { &Child_ToString };

/* virtual method implementation */
void ToString(Base const* obj)
{
    obj->vtable[Call_ToString](obj);
}

int main()
{
    /* pick the vtable for objects at compile time */
    Base base = {Base_Vtable, 123};
    Child child = {Child_Vtable, 456, 789};

    Base* a = &base;
    Base* b = (Base*)&child;

    /* call the virtual methods */
    ToString(a);
    ToString(b);
}


Schnell habe ich dies umgesetzt, sodass es nahezu 1 zu 1 arbeitete. DOCH das Programm stürzte ohne Vorwarnung ab, an einer nahezu beliebigen Stelle. Ich konnte mir einfach nicht erklären warum.
Nach 2 Tagen fehlersuchen ist mir eingefallen, dass Arrays in C Scope abhängig sind, und nach dem verlassen von diesem ist das Array eben ungültig, selbst dann wenn man den Pointer darauf weiter verwendet. Da die Funktionspointer in genau solchem Array zwischengespeichert worden waren trat eben dies ein. Nun nachdem ich das geändert habe und stattdessen Pointer verwendete funktionierte es bereits besser. Jedoch stürzte es nun an einer späteren Stelle ab. Diesmal bin ich darauf gekommen dass die VID vergabe (die Position im Array, wo die Funktionspointer gespeichert waren) falsch war. Dies zu ändern war wiederum eine harte nuss, was ich allerdings geschafft habe.

Nun gibt es nurnoch Probleme beim casten der Klassen untereinander, also sowas: VerVerErbt(New VerVerVererbt).Test2(). Was hauptsächlich daran liegt weil ich nicht weiß was C intern macht wenn man (StructA)StructB schreibt. Ich könnte dies natürlich durch div. Workarounds umgehen (jede Klasse hat einen Pointer auf deren Unterklasse und wenn gecastet wird, wird einfach die klasse mit diesem pointer ersetzt usw.) aber diese wären eher suboptimal.

Auf der anderen Seite wurden wieder einige Bugs gefunden. Unter anderem wenn eine Variable "Self" hieß wurde korrekter XML Code erzeugt, jedoch sobald diese Variable nach BlitzMax Code umgewandelt wird, kam eine Syntax Fehlermeldung seitens BMax. Dies habe ich einfach lösen können indem jede Variable die Prefixe _VariablenName_ bekommt.

Außerdem stürzte der Compiler unter gewissen Umständen ab, wenn man Types definiert.

Nun kommt eine zweiwöchige Pause bezüglich CPB, weil ich mich voll auf meinen BCC42 Beitrag konzentrieren will.

Planung - Vererbung - Schnitzeljagd

Mittwoch, 18. August 2010 von coolo
Guten Tag,
nun nach dem erholsamen Urlaub (leider ist der Laptop auf halben Wege kaputt gegangen) schreibe ich nun weiter. Beginnen wir mal mit dem was schon aktiv implementiert wurde.

Arrow Arrow Arrow (Einfach) Vererbung:
Nun kann Objekt B von Objekt A erben. Hierbei kann dann Objekt B alle Methoden/Attribute von Objekt A verwenden aber umgekehrt nicht. Wobei Vererbung noch sehr fehlerhaft ist, was daran liegt dass ziemlich viel mit Pointern gearbeitet wird.
Code: [AUSKLAPPEN]
Type Vererbt
   Field Hallo:Int=100
   Function Test1:Void()
      Print "In Test1 "+This.Hallo
   EndFunction
EndType

Type VerVererbt Extends Vererbt
   Function Test2:Void()
      Print "In Test2"
   EndFunction
   ;Function Override Test1:Void()
   ;   Print "In Test 1 aber Überladen: "+This.Hallo
   ;EndFunction
EndType
Type VerVerVererbt Extends VerVerErbt
EndType
Type BlubTyp
   Field Hallo:Int=200
   Field Tschuess:Int=300
   Function Hihi:Void()
      Print "Blubbig: "+This.Hallo+" - "+This.Tschuess
   EndFunction
EndType
VerVerErbt(New VerVerVererbt).Test2()
Local Normal:Vererbt=New Vererbt
Normal.Test1()
Print "Next"
Local TestVer:VerVererbt=New VerVererbt
TestVer.Test1()
TestVer.Test2()
Vererbt(TestVer).Test1()
BlubTyp(Object(New BlubTyp)).Hihi()

Polymorphie wurde ebenfalls noch nicht eingebaut, was hauptsächlich daran liegt, dass es noch keine VTables gibt um die Adresse der einzelnen Methoden zu berechnen. Dies ist aber wieder ein anderes Thema was wieder viel arbeit kosten wird. VTables sind (meistens) Arrays, welche je den Funktionszeiger zur aktuell verwendbaren Methoden hat. Beim vererben wird halt ob vererbt wird oder nicht diese Tabelle überschrieben. Aber wie genau das aussehen wird ist noch nicht klar.

Arrow Arrow Arrow Cross Platform Library und Cross Platform Studio:
CPBasic ist nur die unterste Schicht von 3 Programmmodulen:
Arrow CPBasic: Daran arbeite ich gerade
Arrow CPLibrary: Dies ist eine Game Lib, welche allgemein verwendbar sein soll. Diese ist bereits zu 40% geplant (leider auf Papier). Sie wird folgende Dinge unterstützen: Tilemap, Particle, Event Management, Entity System (Jedes Objekt ist eine Entität, und somit ein Objekt), Simple Physik (Jump'n run, Space Shooter, etc Physik), Pathfinding, GUI, Primtives (Images, Sound, ...), div. Listener, AI, FX System und Layer Management. Das Vererbungsdiagramm ist bereits fertig nun fehlen noch einige UML - Diagramme.
Arrow CPStudio: Dieses Programm (in CPB geschrieben) vereint alles. Es wird aus einer IDE, einem Tilemapeditor, AI Scripter, Event Designer, Collision Shape Designer, Animationseditor, GUI Designer usw. bestehen.

Ich weiß das klingt nun alles nach sehr viel (ist es auch). Aber wenn CPBasic fertig ist (die Syntax) habe ich vor die CPL zu implementieren. Dadurch dass CPL intern auf abstrakte Treiber basiert, welche alle nur ein Minimum an Features haben müssen, wird es kein Problem sein diese zu portieren.

Arrow Arrow Arrow Neue geplante Sprachfeatures:
Arrow Operator Überladung: Hier habe ich alles am Papier bereits vorgeplant und habe festgestellt, dass es kein allzugroßes Problem ist.
Syntax dafür:
Code: [AUSKLAPPEN]
Type OpTest
    Field Hihi:Int = 200
    Function Operator:Int(+)
        Return LeftOperand.Hihi+RightOperand.Hihi ;Left/Right Operand sind beide vom Typ OpTest
    EndFunction
EndType
Print New OpTest+New OpTest ;Ausgabe: 400

Arrow ADT: Abstract Datatypes
Dies sind "Schablonen" welche keine Methodenimplementierung hat.
Arrow Konstruktor: Mit Parameter, welche auch Überladbar sind
Arrow Private, Public, Protected, (evtl. Friendly [Also dass bestimmte Attribute zu bestimmten Klassen zugreifbar sind])
Arrow ForEach: Einfaches Iterieren durch Datenstrukturen

Dies war ein etwas "abstrakter" WL Eintrag, was daran liegt dass ich im Urlaub mehr geplant als programmiert habe.

Types omg wtf roflmao

Sonntag, 1. August 2010 von coolo
Guten Vormittag!

In den letzten Tagen war ich natürlich wieder nicht faul.
Arrow Arrow Arrow Types: Die Haupterneuerung sind die Types. Ja, diese sind bereits fertig implementiert. Hierbei sind diese durch BoehmGC gut verwaltet und werden sobald diese nicht mehr gebraucht werden, einfach gelöscht.

Features der Types:
Arrow Beliebig viele Attribute (auch auf sich selbst zeigend)
Arrow Vorwärtsdeklaration (Verwenden der Types bevor man diese deklariert)
Arrow Sie können als Parameter, Rückgabewerte oÄ. fungieren.
Arrow Vordefinierte Attribute (Field MeinAtt:Int = 100)
Arrow (Mehrdimensionale) Arrays von Types
Arrow Methoden (Yay einfache Objekt Orientierte Programmierung)
Arrow Sie sind toll!

Tja die Types waren dank dem neuen Typsystem kein großes Problem.

Das OOP wird intern folgens implementiert: Es wird eine Methode gefunden, und diese wird umbenannt. Dann bekommt diese noch den "This" Parameter, um ein Objekt von anderen unterscheiden zu können. Dabei musste NICHTS am XML Format geändert werden, da alles in normale Funktionen umgewandelt wird.

Es wird lediglich noch _einfache_ Vererbung dazukommen, damit man Listen (und andere Datenstrukturen) halbwegs vernünftig umsetzen kann ... Generics wären wieder zuviel des Guten. Statische Funktionen und all das andere sind ja nur syntaktischer Zucker.
Was mich noch reizen würde, wäre Operatorüberladung. Nicht weil es die Sprache unbedingt braucht, sondern weil es mich reizt dieses Feature einzubauen.

Arrow Arrow Arrow Die Array Umsetzung wurde in C neu geschrieben.
Früher war es folgens implementiert: Aus dem Arrayzugriff MeinArray[3][3] wird MeinArray[3*GetSizeDim(MeinArray,0)+3]. Dies ist auf dem ersten Blick natürlich eine gute Lösung. Jedoch ist es sobald man Methoden unterstützt eher schlecht. Da um auf das Array zu kommen, muss man dann (unerwarteterweise vom Programmierer) zwei mal diese Methode Aufrufen: MeineMethode.GetArray()[2][2] wird MeineMethode.GetArray()[GetSizeDim(MeineMethode.GetArray(),0)*2+2].
Dies habe ich mit Pointer auf Pointer lösen können. Nun werden die Dimensionen beibehalten und man kann normal damit zugreifen: MeineMethode.GetArray()[2][2]. Lediglich das Dimensionieren dauert etwas länger, aber das nehme ich in Kauf.

Arrow Arrow Arrow Käfer! Ja davon wurden wieder einige ins Nirvana befördert.
Unter anderem gab es Probleme bei Mehrfachdeklarationen: Local Var1:Int, Var2:Int,... außerdem wurde bei den Datentypen short, long falsch gecastet, was nun nicht mehr der Fall ist. Nebenbei sind nun vordefinierte Parameter entfixt worden. Nun sind Dinge wie Funktion(,,,100) nicht mehr möglich, was Fehler verursacht hat.


So hiermit ist die Syntax bis auf kleine Zuckerschlecken (Konstanten,...) fertig. Und das innerhalb von einem Monat \o/

Der Plan nun sieht folgendermaßen aus:
Arrow XML->BMX Compiler wieder auf vordermann bringen (der ist noch nicht an das neue Array System angepasst)
Arrow Die Standardfunktionen definieren (Graphik, Sound etc) diese muss jede Platform implementieren
Arrow Modulsystem festlegen: Ein System welches Platformspezifische Dinge festlegt. Wie zum Beispiel die Möglichkeit auf großen Platformen ein GUI System einzubauen
Arrow Standardfunktionen in C implementieren, sodass diese auf Windows, Mac OS X, Linux läuft.
Arrow Alle geplanten Platformen für C implementieren (Win, Linux, Mac, Pandora, Gp2X Wiz,...)
Arrow ...

Folgender Code
BlitzMax: [AUSKLAPPEN]

Local MethodTestInst:TMethodTest=New TMethodTest
MethodTestInst.MethodenTest(100.9)
Print "Haha: "+MethodTestInst.Blub().Blub().Blub().Haha
Print "Aus Methode: "+MethodTestInst.ArrayTest()[4][4]
Print "Rekurive Arrays: " + MethodTestInst.GetArray(400)[1].ArrayTest()[4][4]
Type TMethodTest
Field Haha:Int=20
Function MethodenTest:Void(Param:Int)
Print "In Methode "+Param
This.Haha=100
Print "Aus Methode"
EndFunction
Function MethodenTest:Void(Param:Float)
Print "Ueberladen: "+Param
EndFunction
Function Blub:TMethodTest()
Return This
EndFunction
Function ArrayTest:Int[][]()
Print "In Array Test"
Local Arr:Int[][]=New Int[20][20]
Arr[4][4]=200
Return Arr
EndFunction
Function GetArray:TMethodTest[](MitParam:Int)
Print "GetArray: "+MitParam
Local Arr:TMethodTest[]=New TMethodTest[2]
Arr[1]=New TMethodTest
Return Arr
EndFunction
EndType
Type TTest
Field X:Int=200


Field Y:Float
Field Z:String

Field TestArray:TTest[]=New TTest[20]
EndType

Type TList
Field Start:TLink
EndType
Global EinKleinerTest:TTest=New TTest, Wawa:TTest[]=New TTest[20]
Print "Ein kleiner Test mit vordefinierte Werte: "+EinKleinerTest.X

Type TLink
Field Prev:TLink
Field Succ:TLink
Field Value:Int
EndType

Function CreateList:TList()
Local List:TList=New TList
List.Start=Null
Return List
EndFunction
Global Zeahler:Int

Function Add:TLink(List:TList, Value:Int)
Zeahler=Zeahler+1
Local Link:TLink

Link=New TLink

Link.Value=Value
Link.Prev=List.Start
Link.Succ=Null
If List.Start<>Null Then List.Start.Succ=Link
List.Start=Link

Return Link
EndFunction

Local List:TList = CreateList()
Add(List,4)
Add(List,10)
Add(List,100)

Local Cur:TLink
Cur=List.Start
While Cur<>Null
Print "Linked List: "+Cur.Value
Cur=Cur.Prev
Wend
Local Test:TTest[]=New TTest[2]
Test[1]=New TTest

Test[1].X=10

Print "Test: "+Test[1].X

Test[1].TestArray=New TTest[5]
Test[1].TestArray[1]=New TTest
Test[1].TestArray[1].X=100

Print Test[1].TestArray[1].X

Type TestType2
Field Self:TestType2
EndType
Local Test2:TestType2
Test2=New TestType2
Test2.Self=Test2

Local TmpTyp:TestType2
TmpTyp=Test2
Local j:Int=0
While TmpTyp<>Null
Print "Hallo in Type DUmm"
TmpTyp=TmpTyp.Self
j=j+1
If j>4 Then Break
Wend

Local Typ:TReturnType=GetType()
Typ.HAHA=20
TypAlsParameter(Typ)

Print "Bekomme Typ: "+GetType().HAHA

Function GetType:TReturnType()
Return New TReturnType
EndFunction

Function TypAlsParameter:Void(BlubTest:TReturnType)
Print BlubTest.HAHA
EndFunction

Type TReturnType
Field HAHA:Int=-99
EndType


Local MehrDim:Int[][][]
MehrDim=New Int[5][9][20]
Print "Mehrdim start"
MehrDim[4][8][19]=42
MehrDim[4][4][4]=99

Print MehrDim[4][8][19]
MehrDim=MehrDimTest(MehrDim)
Print "Blub"

Datatypetest
Print "Hallo"

Print("Hallo"+(2*(5+4)+(5*(8+10))+5+5+3))

VorDefiniert()

Local MehrDimString:String[][]
mehrdimstring=New String[5][5]
MehrdimString[2][3]="Hallo"
Print MehrDImString[2][3]

Local AndererTest:Int[][]
AndererTest=New Int[10][10]
For Local X:Int=0 To 9
For Local Y:Int=0 To 9
andererTest[X][Y]=X*9+Y
Next
Next
For Local X:Int=0 To 9
For Local Y:Int=0 To 9
Print "In Array an Position '"+X+"', '"+Y+"': "+AndererTest[X][Y]
Next
Next

Print "MultiDim Array:"+MehrDim[1][1][1]

Local Array:Int[]
Array=New Int[1000]

Array[40]=100*4
Array=ArrayFunktion(Array)
Print "Aus Array Funktion: "+Array[4]
GCCollect()


Print -5

Print Float("5.5")




Local FloatTest:Float=200
Print FloatTest



Global HalloGlobal:Int
HalloGlobal=100

Print "Zweite Zeile"
Local Hallo:Int=40 ;Es gibt Int(%),Float(#),String($),Nichts(Int)
Hallo=100+5*10
Hallo=Hallo+100.0

Print "Text: "+Hallo


If 10*10
Print "Hallo ist gleich 10"
ElseIf 10
If "Hallo Welt"
Print "hallo"
ElseIf 2
Print "Blub"
Else
Print "Gaga"
EndIf
Print "In Elseif"
Else
Print "Blub"
EndIf

Local Tmp:Int=1
While tmp<10
Print "In While - Wend "+Tmp
Tmp=Tmp+1
Wend

Repeat
Print "In Repeat Until"
Break
Until 1

Select 10
Case 5, 20
Print "Hallo"
Print("Blubbig")
Case 7
Print "blub"
Default
Print "in Default"
EndSelect

For Local i:Int=0 To 10
Print "Zahl: "+i
Next

Print Blub("Hallo",10,10.0)
OhneNichts()

Function OhneNichts:Void()
EndFunction

Function Blub:Int(X:Int,Z:String,Y:Int)
Print "X: "+X+" Y: "+Y+" "+Z
Return 100
EndFunction

Function Blub:Int(X:String, Z:Int, Y:Float)
Print "In anderes Blub"
Return -100
EndFunction

Function VorDefiniert:Void(X:Int=100,Y:Float=9.9,Z:String="Gaga")
Print "VORDEFINIERT FTW. "+X+" "+Y+" "+Z
EndFunction


Function ArrayFunktion:Int[](X:Int[])
Print "In Array Funktion: "+X[40]
X=Null
Local Test:Int[]
Test=New Int[10]
Test[4]=22
Return Test
EndFunction

Function MehrDimTest:Int[][][](Y:Int[][][])
Print "In Mehr Dim Array Funktion: "+Y[4][4][4]
Y=Null

Local Test:Int[][][]
Test=New Int[2][2][2]
Test[1][1][1]=100
Return Test
EndFunction

Function Datatypetest:Void()
Local TestShort:Short, TestDouble:Double, TestLong:Long, TestByte:Byte
TestShort=65535
TestDouble=9999.99999
TestLong=9999999
TestByte=255
;short2string usw. muss noch in C implementiert werden
;Print "Short: "+TestShort+" Double: "+TestDouble+" Long: "+TestLong+" Byte: "+TestByte
EndFunction

Print "Aus Array direkt entnommen: "+TestArray()[4][4]
Print "Lustig: "+(++++-------+++----++-----10)
Function TestArray:Int[][]()
Local Array:Int[][]
Array=New Int[8][8]
Array[4][4]=100
Return Array
EndFunction

OptionalTest 100,100

Function OptionalTest:Void(X:Int=100,Y:Int=200,Z:Int=300)
Print X
Print Y
Print Z
EndFunction



Wird zu C kompiliert:
Code: [AUSKLAPPEN]
#include "clib/main.c"
void* allocarray_dim3(int size, int param1, int param2, int param3) {
   int* mem=(void*)GC_malloc(size*param1);
   int  vari1, vari2, vari3;
   for(vari1=0;vari1<param1;vari1++) {
      ((int*)mem[vari1])=GC_malloc(size*param2);
      for(vari2=0;vari2<param2;vari2++) {
         ((int*)((int*)mem[vari1])[vari2])=GC_malloc(size*param3);
      }
   }
   return (void*)mem;
}
void* allocarray_dim2(int size, int param1, int param2) {
   int* mem=(void*)GC_malloc(size*param1);
   int  vari1, vari2;
   for(vari1=0;vari1<param1;vari1++) {
      ((int*)mem[vari1])=GC_malloc(size*param2);
   }
   return (void*)mem;
}
void* allocarray_dim1(int size, int param1) {
   int* mem=(void*)GC_malloc(size*param1);
   int  vari1;
   return (void*)mem;
}
typedef struct _tmethodtest {
   CPB_INT haha;
} TMETHODTEST;
TMETHODTEST* new_TMETHODTEST(TMETHODTEST* tmp ) {
   tmp->haha = 20;
   return tmp;
}
typedef struct _ttest {
   CPB_INT x;
   CPB_FLOAT y;
   CPB_STRING z;
   struct _ttest** testarray;
} TTEST;
TTEST* new_TTEST(TTEST* tmp ) {
   tmp->x = 200;
   tmp->y = 0.000000000;
   tmp->z = "";
   tmp->testarray = (TTEST**)allocarray_dim1(sizeof(TTEST),20);
   return tmp;
}
typedef struct _tlist {
   struct _tlink* start;
} TLIST;
TLIST* new_TLIST(TLIST* tmp ) {
   tmp->start = NULL;
   return tmp;
}
typedef struct _tlink {
   struct _tlink* prev;
   struct _tlink* succ;
   CPB_INT value;
} TLINK;
TLINK* new_TLINK(TLINK* tmp ) {
   tmp->prev = NULL;
   tmp->succ = NULL;
   tmp->value = 0;
   return tmp;
}
typedef struct _testtype2 {
   struct _testtype2* self;
} TESTTYPE2;
TESTTYPE2* new_TESTTYPE2(TESTTYPE2* tmp ) {
   tmp->self = NULL;
   return tmp;
}
typedef struct _treturntype {
   CPB_INT haha;
} TRETURNTYPE;
TRETURNTYPE* new_TRETURNTYPE(TRETURNTYPE* tmp ) {
   tmp->haha = -1*99;
   return tmp;
}
TTEST* einkleinertest=NULL;
TTEST** wawa=NULL;
CPB_INT zeahler=0;
CPB_INT halloglobal=0;

void print_string__dim_0_( CPB_STRING text) {
   print( text);
}

void gccollect();

void ___tmethodtest__methodentest__internmethod___tmethodtest__dim_0__float__dim_0_( TMETHODTEST* this,CPB_FLOAT param);

TMETHODTEST* ___tmethodtest__blub__internmethod___tmethodtest__dim_0_( TMETHODTEST* this);

CPB_INT** ___tmethodtest__arraytest__internmethod___tmethodtest__dim_0_( TMETHODTEST* this);

TMETHODTEST** ___tmethodtest__getarray__internmethod___tmethodtest__dim_0__int__dim_0_( TMETHODTEST* this,CPB_INT mitparam);

TLIST* createlist();

TLINK* add_tlist__dim_0__int__dim_0_( TLIST* list,CPB_INT value);

TRETURNTYPE* gettype();

void typalsparameter_treturntype__dim_0_( TRETURNTYPE* blubtest);

void ohnenichts();

CPB_INT blub_string__dim_0__int__dim_0__float__dim_0_( CPB_STRING x,CPB_INT z,CPB_FLOAT y);

void vordefiniert_int__dim_0__float__dim_0__string__dim_0_( CPB_INT x,CPB_FLOAT y,CPB_STRING z);

CPB_INT* arrayfunktion_int__dim_1_( CPB_INT* x);

CPB_INT*** mehrdimtest_int__dim_3_( CPB_INT*** y);

void datatypetest();

CPB_INT** testarray();

void optionaltest_int__dim_0__int__dim_0__int__dim_0_( CPB_INT x,CPB_INT y,CPB_INT z);
int main() {
   GC_INIT();
   TMETHODTEST* methodtestinst=NULL;
   methodtestinst=new_TMETHODTEST((TMETHODTEST*)GC_malloc(sizeof(TMETHODTEST)));
   ___tmethodtest__methodentest__internmethod___tmethodtest__dim_0__float__dim_0_(methodtestinst,100.900002);
   print_string__dim_0_(joinstr("Haha: ",int2string(___tmethodtest__blub__internmethod___tmethodtest__dim_0_(___tmethodtest__blub__internmethod___tmethodtest__dim_0_(___tmethodtest__blub__internmethod___tmethodtest__dim_0_(methodtestinst)))->haha)));
   print_string__dim_0_(joinstr("Aus Methode: ",int2string(___tmethodtest__arraytest__internmethod___tmethodtest__dim_0_(methodtestinst)[4][4])));
   print_string__dim_0_(joinstr("Rekurive Arrays: ",int2string(___tmethodtest__arraytest__internmethod___tmethodtest__dim_0_(___tmethodtest__getarray__internmethod___tmethodtest__dim_0__int__dim_0_(methodtestinst,400)[1])[4][4])));
   einkleinertest=new_TTEST((TTEST*)GC_malloc(sizeof(TTEST)));
   wawa=(TTEST**)allocarray_dim1(sizeof(TTEST),20);
   print_string__dim_0_(joinstr("Ein kleiner Test mit vordefinierte Werte: ",int2string(einkleinertest->x)));
   TLIST* list=NULL;
   list=createlist();
   add_tlist__dim_0__int__dim_0_(list,4);
   add_tlist__dim_0__int__dim_0_(list,10);
   add_tlist__dim_0__int__dim_0_(list,100);
   TLINK* cur=NULL;
   cur=list->start;
   while ((CPB_INT)(cur!=NULL)) {
      print_string__dim_0_(joinstr("Linked List: ",int2string(cur->value)));
      cur=cur->prev;
   }
   TTEST** test=NULL;
   test=(TTEST**)allocarray_dim1(sizeof(TTEST),2);
   test[1]=new_TTEST((TTEST*)GC_malloc(sizeof(TTEST)));
   test[1]->x=10;
   print_string__dim_0_(joinstr("Test: ",int2string(test[1]->x)));
   test[1]->testarray=(TTEST**)allocarray_dim1(sizeof(TTEST),5);
   test[1]->testarray[1]=new_TTEST((TTEST*)GC_malloc(sizeof(TTEST)));
   test[1]->testarray[1]->x=100;
   print_string__dim_0_(int2string(test[1]->testarray[1]->x));
   TESTTYPE2* test2=NULL;
   test2=new_TESTTYPE2((TESTTYPE2*)GC_malloc(sizeof(TESTTYPE2)));
   test2->self=test2;
   TESTTYPE2* tmptyp=NULL;
   tmptyp=test2;
   CPB_INT j=0;
   j=0;
   while ((CPB_INT)(tmptyp!=NULL)) {
      print_string__dim_0_("Hallo in Type DUmm");
      tmptyp=tmptyp->self;
      j=j+1;
      if (j>4) {
         break;
      }
   }
   TRETURNTYPE* typ=NULL;
   typ=gettype();
   typ->haha=20;
   typalsparameter_treturntype__dim_0_(typ);
   print_string__dim_0_(joinstr("Bekomme Typ: ",int2string(gettype()->haha)));
   CPB_INT*** mehrdim=NULL;
   mehrdim=(CPB_INT***)allocarray_dim3(sizeof(CPB_INT),5,9,20);
   print_string__dim_0_("Mehrdim start");
   mehrdim[4][8][19]=42;
   mehrdim[4][4][4]=99;
   print_string__dim_0_(int2string(mehrdim[4][8][19]));
   mehrdim=mehrdimtest_int__dim_3_(mehrdim);
   print_string__dim_0_("Blub");
   datatypetest();
   print_string__dim_0_("Hallo");
   print_string__dim_0_(joinstr("Hallo",int2string(2*5+4+5*8+10+5+5+3)));
   vordefiniert_int__dim_0__float__dim_0__string__dim_0_(100,9.89999962,"Gaga");
   CPB_STRING** mehrdimstring=NULL;
   mehrdimstring=(CPB_STRING**)allocarray_dim2(sizeof(CPB_STRING),5,5);
   mehrdimstring[2][3]="Hallo";
   print_string__dim_0_(mehrdimstring[2][3]);
   CPB_INT** anderertest=NULL;
   anderertest=(CPB_INT**)allocarray_dim2(sizeof(CPB_INT),10,10);
   { CPB_INT x=0;;
   for (x=0;x<9;x+=1) {
      { CPB_INT y=0;;
      for (y=0;y<9;y+=1) {
         anderertest[x][y]=x*9+y;
      } }
   } }
   { CPB_INT x=0;;
   for (x=0;x<9;x+=1) {
      { CPB_INT y=0;;
      for (y=0;y<9;y+=1) {
         print_string__dim_0_(joinstr(joinstr(joinstr(joinstr(joinstr("In Array an Position '",int2string(x)),"', '"),int2string(y)),"': "),int2string(anderertest[x][y])));
      } }
   } }
   print_string__dim_0_(joinstr("MultiDim Array:",int2string(mehrdim[1][1][1])));
   CPB_INT* array=NULL;
   array=(CPB_INT*)allocarray_dim1(sizeof(CPB_INT),1000);
   array[40]=100*4;
   array=arrayfunktion_int__dim_1_(array);
   print_string__dim_0_(joinstr("Aus Array Funktion: ",int2string(array[4])));
   gccollect();
   print_string__dim_0_(int2string(-1*5));
   print_string__dim_0_(float2string(string2float("5.5")));
   CPB_FLOAT floattest=0.0f;
   floattest=(CPB_FLOAT)(200);
   print_string__dim_0_(float2string(floattest));
   halloglobal=100;
   print_string__dim_0_("Zweite Zeile");
   CPB_INT hallo=0;
   hallo=40;
   hallo=100+5*10;
   hallo=(CPB_INT)((CPB_FLOAT)(hallo)+100.000000);
   print_string__dim_0_(joinstr("Text: ",int2string(hallo)));
   if (10*10) {
      print_string__dim_0_("Hallo ist gleich 10");
     
   } else {
      if (10) {
         if (string2int("Hallo Welt")) {
            print_string__dim_0_("hallo");
           
         } else {
            if (2) {
               print_string__dim_0_("Blub");
               
            } else {
               print_string__dim_0_("Gaga");

            }

         }
         print_string__dim_0_("In Elseif");
         
      } else {
         print_string__dim_0_("Blub");

      }

   }
   CPB_INT tmp=0;
   tmp=1;
   while (tmp<10) {
      print_string__dim_0_(joinstr("In While - Wend ",int2string(tmp)));
      tmp=tmp+1;
   }
   do {
      print_string__dim_0_("In Repeat Until");
      break;
   } while (!(1));
   switch (10) {
      case 5:
         print_string__dim_0_("Hallo");
         print_string__dim_0_("Blubbig");
         break;

      case 20:
         print_string__dim_0_("Hallo");
         print_string__dim_0_("Blubbig");
         break;

      case 7:
         print_string__dim_0_("blub");
         break;

      default:
         print_string__dim_0_("in Default");

   }
   { CPB_INT i=0;;
   for (i=0;i<10;i+=1) {
      print_string__dim_0_(joinstr("Zahl: ",int2string(i)));
   } }
   print_string__dim_0_(int2string(blub_string__dim_0__int__dim_0__float__dim_0_("Hallo",10,10.0000000)));
   ohnenichts();
   print_string__dim_0_(joinstr("Aus Array direkt entnommen: ",int2string(testarray()[4][4])));
   print_string__dim_0_(joinstr("Lustig: ",int2string(-1*-1*-1*-1*-1*-1*-1*-1*-1*-1*-1*-1*-1*-1*-1*-1*10)));
   optionaltest_int__dim_0__int__dim_0__int__dim_0_(100,100,300);
}
void optionaltest_int__dim_0__int__dim_0__int__dim_0_( CPB_INT x,CPB_INT y,CPB_INT z) {
   print_string__dim_0_(int2string(x));
   print_string__dim_0_(int2string(y));
   print_string__dim_0_(int2string(z));
}

CPB_INT** testarray() {
   CPB_INT** array=NULL;
   array=(CPB_INT**)allocarray_dim2(sizeof(CPB_INT),8,8);
   array[4][4]=100;
   return array;
}

void datatypetest() {
   CPB_SHORT testshort=0;CPB_DOUBLE testdouble=0.0f;CPB_LONG testlong=0;CPB_BYTE testbyte=0;
   testshort=(CPB_SHORT)(65535);
   testdouble=(CPB_DOUBLE)(10000.0000);
   testlong=(CPB_LONG)(9999999);
   testbyte=(CPB_BYTE)(255);
}

CPB_INT*** mehrdimtest_int__dim_3_( CPB_INT*** y) {
   print_string__dim_0_(joinstr("In Mehr Dim Array Funktion: ",int2string(y[4][4][4])));
   y=(CPB_INT)(NULL);
   CPB_INT*** test=NULL;
   test=(CPB_INT***)allocarray_dim3(sizeof(CPB_INT),2,2,2);
   test[1][1][1]=100;
   return test;
}

CPB_INT* arrayfunktion_int__dim_1_( CPB_INT* x) {
   print_string__dim_0_(joinstr("In Array Funktion: ",int2string(x[40])));
   x=(CPB_INT)(NULL);
   CPB_INT* test=NULL;
   test=(CPB_INT*)allocarray_dim1(sizeof(CPB_INT),10);
   test[4]=22;
   return test;
}

void vordefiniert_int__dim_0__float__dim_0__string__dim_0_( CPB_INT x,CPB_FLOAT y,CPB_STRING z) {
   print_string__dim_0_(joinstr(joinstr(joinstr(joinstr(joinstr("VORDEFINIERT FTW. ",int2string(x))," "),float2string(y))," "),z));
}

CPB_INT blub_string__dim_0__int__dim_0__float__dim_0_( CPB_STRING x,CPB_INT z,CPB_FLOAT y) {
   print_string__dim_0_("In anderes Blub");
   return -1*100;
}

CPB_INT blub_int__dim_0__string__dim_0__int__dim_0_( CPB_INT x,CPB_STRING z,CPB_INT y) {
   print_string__dim_0_(joinstr(joinstr(joinstr(joinstr(joinstr("X: ",int2string(x))," Y: "),int2string(y)),"  "),z));
   return 100;
}

void ohnenichts() {
}

void typalsparameter_treturntype__dim_0_( TRETURNTYPE* blubtest) {
   print_string__dim_0_(int2string(blubtest->haha));
}

TRETURNTYPE* gettype() {
   return new_TRETURNTYPE((TRETURNTYPE*)GC_malloc(sizeof(TRETURNTYPE)));
}

TLINK* add_tlist__dim_0__int__dim_0_( TLIST* list,CPB_INT value) {
   zeahler=zeahler+1;
   TLINK* link=NULL;
   link=new_TLINK((TLINK*)GC_malloc(sizeof(TLINK)));
   link->value=value;
   link->prev=list->start;
   link->succ=NULL;
   if ((CPB_INT)(list->start!=NULL)) {
      list->start->succ=link;
   }
   list->start=link;
   return link;
}

TLIST* createlist() {
   TLIST* list=NULL;
   list=new_TLIST((TLIST*)GC_malloc(sizeof(TLIST)));
   list->start=NULL;
   return list;
}

TMETHODTEST** ___tmethodtest__getarray__internmethod___tmethodtest__dim_0__int__dim_0_( TMETHODTEST* this,CPB_INT mitparam) {
   print_string__dim_0_(joinstr("GetArray: ",int2string(mitparam)));
   TMETHODTEST** arr=NULL;
   arr=(TMETHODTEST**)allocarray_dim1(sizeof(TMETHODTEST),2);
   arr[1]=new_TMETHODTEST((TMETHODTEST*)GC_malloc(sizeof(TMETHODTEST)));
   return arr;
}

CPB_INT** ___tmethodtest__arraytest__internmethod___tmethodtest__dim_0_( TMETHODTEST* this) {
   print_string__dim_0_("In Array Test");
   CPB_INT** arr=NULL;
   arr=(CPB_INT**)allocarray_dim2(sizeof(CPB_INT),20,20);
   arr[4][4]=200;
   return arr;
}

TMETHODTEST* ___tmethodtest__blub__internmethod___tmethodtest__dim_0_( TMETHODTEST* this) {
   return this;
}

void ___tmethodtest__methodentest__internmethod___tmethodtest__dim_0__float__dim_0_( TMETHODTEST* this,CPB_FLOAT param) {
   print_string__dim_0_(joinstr("Ueberladen: ",float2string(param)));
}

void ___tmethodtest__methodentest__internmethod___tmethodtest__dim_0__int__dim_0_( TMETHODTEST* this,CPB_INT param) {
   print_string__dim_0_(joinstr("In Methode ",int2string(param)));
   this->haha=100;
   print_string__dim_0_("Aus Methode");
}

Urlaub... YAY

Montag, 26. Juli 2010 von coolo
Hallo!

ich bin seit 3 Tagen auf Urlaub und arbeite an Cross Platform Basic mehr denn je (das Wetter ist zu schlecht um was draußen zu unternehmen... Sad ). Ich weiß nichtmal wo ich anfangen soll Very Happy.

Arrow Das Garbage Collector Problem: Dieses wurde nun behoben. Wie? Ich verwende nun doch BoehmGC. BoehmGC ist ein Garbage Collector, der wirklich ALLES kann was das Herz begehrt. Also Multithreading, Finalization,... Aber da ich nur einfaches GC'ing brauche wird es (hoffentlich) kein allzu großes Problem diesen zu porten. Für Platformen welche diesen nicht unterstützen gibt es immer noch TinyGC. Dieser ist von der API 100%ig ident, wodurch ich nichts umändern muss. Der Vorteil von TinyGC im Gegensatz zu BoehmGC ist die Tatsache, dass er keine einzige Zeile Maschinencode hat. Dadurch ist er langsamer, aber hey, man kann nicht alles haben Wink.

Arrow Neues Typsystem: Das ist wohl die am zeitauftreibenste Neuerung. Vorher wurde jeder Datentyp in einem String zwischengespeichert und bei jedem casten usw. wurde HARDGECODED überprüft ob das nun mit diesem Datentyp geht oder nicht. Das war der inoffizielle Grund weswegen ich nur die 3 Datentypen haben wollte Very Happy (wie es nun ist kommt zu einem späteren Zeitpunkt). Nun ist alles schön innerhalb eines Typs und kann beliebig erweitert werden. Ohne diesem neuen Typsystem wären Arrays und Types ein Ding der Unmöglichkeit.
Einen neuen Datentyp definiert man folgens:
Code: [AUSKLAPPEN]
IntDatatype=New TDatatype 'Erzeugt es
IntDatatype.Name="int" 'Den Namen
IntDatatype.Prio=3 'Die Priorität (Je höher desto "wichtiger" ist es, also String<>Int hat String eine höhere Priorität)

IntDatatype.CanCastTo.AddLast(FloatDatatype) 'Wohin kann dieser Datentyp gecastet werden
IntDatatype.CanCastTo.AddLast(StringDatatype)
IntDatatype.CanCastTo.AddLast(ByteDatatype)
IntDatatype.CanCastTo.AddLast(LongDatatype)
IntDatatype.CanCastTo.AddLast(DoubleDatatype)
IntDatatype.CanCastTo.AddLast(ShortDatatype)

Wie man sieht ist es nun beliebig dynamisch und kann auch erweitert werden wie man will. Um diese Sache zu machen musste ich -schätze ich- jede 3. Codezeile ändern.

Arrow Neues Operatoren System: Jaha, das wurde auch neu geschrieben. Ursprünglich hatte jeder Operator seine eigene Methode. Das war bei wenigen Operatoren noch praktikabel, aber nun wo es schon mehr als eine handvoll Operatoren gibt (tendenz steigend Wink) muss ein anderes System her. Nun kann man mit folgender Funktion einen neuen Operator erstellen:
Code: [AUSKLAPPEN]
TOperator.NewOperator(2,"add","+",[TDatatype.IntDatatype,TDatatype.FloatDatatype,TDatatype.LongDatatype,TDatatype.ShortDatatype,TDatatype.ByteDatatype,TDatatype.DoubleDatatype])

TOperator.NewOperator(Priotität des Operators, Wie es im XML Format aussieht, Wie es im Code Aussieht, Die Datentypen welche es entgegennimmt)

Durch dieses System ist der Matheparser nicht nur viel kleiner, er ist wartbarer und ist übersichtlicher. NEIN, es wäre eine Sache von einer halben Stunde Operatorüberladung einzubauen. Der erste überladene Operator ist "+", um Zeichenketten addieren zu können.

Arrow ARRAYS \o/: Jaaahaaaa. Diese sind nun endlich drinnen, durch dem neuen Typsystem waren diese nun eine etwas kleinere Sache. Und durch dem GC ist alles ohne Speicher Lecks. Viel gibt es zu denen nicht zu sagen, aber hey sie waren eine heiden Arbeit...

Arrow Neue Datentypen: Durch dem neuen Typsystem gibt es nun auch die restlichen Datentypen. Short, Long, Double, Byte.

Arrow BlitzMax Compiler: Nun kann Testweise auch nach BlitzMax Code kompiliert werden. Dadurch kann ich ENDLICH bei den BCC's mitmachen Very Happy. Der Vorteil an Bmax ist halt, dass die Grafik Engine schon fertig dabei ist.

Arrow Bugs usw.: Ja da wurden auch einige entfernt (wie man sich denken kann...). Vorallem in Sachen Globale Variablen waren noch einige kleinere Fehler zu vermerken.

Arrow Syntax Fehlermeldungen: Nun wird nach einem Syntax Fehler nicht der Kompiliervorgang beendet und es wird einfach weiter fortgefahren. Dadurch findet man Fehler einfacher und schneller. Ab und Zu kommen noch Fehlermeldungen seitens BMax weil Objekte Null sind, aber diese werden noch gefixt.

Arrow Code usw.: Hier ist mal mein Testcode:
Folgendes:
BlitzMax: [AUSKLAPPEN]
Datatypetest

Print("Hallo"+(2*(5+4)+(5*(8+10))+5+5+3))

VorDefiniert()

Local MehrDim:Int[][][]
Dim MehrDim[5][9][20]
MehrDim[4][8][19]=42
MehrDim[4][4][4]=99
MehrDim=MehrDimTest(MehrDim)

Local MehrDimString:String[][]
Dim mehrdimstring[5][5]
MehrdimString[2][3]="Hallo"
Print MehrDImString[2][3]

Local AndererTest:Int[][]
Dim AndererTest[10][10]
For Local X:Int=0 To 9
For Local Y:Int=0 To 9
andererTest[X][Y]=X*9+Y
Next
Next
For Local X:Int=0 To 9
For Local Y:Int=0 To 9
Print "In Array an Position '"+X+"', '"+Y+"': "+AndererTest[X][Y]
Next
Next

Print "MultiDim Array:"+MehrDim[1][1][1]

Local Array:Int[]
Dim Array[1000]

Array[40]=100*4
Array=ArrayFunktion(Array)
Print "Aus Array Funktion: "+Array[4]
GCCollect()


Print -5

Print Float("5.5")




Local FloatTest:Float=200
Print FloatTest



Global HalloGlobal:Int
HalloGlobal=100

Print "Zweite Zeile"
Local Hallo:Int=40 ;Es gibt Int(%),Float(#),String($),Nichts(Int)
Hallo=100+5*10
Hallo=Hallo+100.0

Print "Text: "+Hallo


If 10*10
Print "Hallo ist gleich 10"
ElseIf 10
If "Hallo Welt"
Print "hallo"
ElseIf 2
Print "Blub"
Else
Print "Gaga"
EndIf
Print "In Elseif"
Else
Print "Blub"
EndIf

Local Tmp:Int=1
While tmp<10
Print "In While - Wend "+Tmp
Tmp=Tmp+1
Wend

Repeat
Print "In Repeat Until"
Break
Until 1

Select 10
Case 5, 20
Print "Hallo"
Print("Blubbig")
Case 7
Print "blub"
Default
Print "in Default"
EndSelect

For Local i:Int=0 To 10
Print "Zahl: "+i
Next

Print Blub("Hallo",10,10.0)
OhneNichts()

Function OhneNichts:Void()
EndFunction

Function Blub:Int(X:Int,Z:String,Y:Int)
Print "X: "+X+" Y: "+Y+" "+Z
Return 100
EndFunction

Function Blub:Int(X:String, Z:Int, Y:Float)
Print "In anderes Blub"
Return -100
EndFunction

Function VorDefiniert:Void(X:Int=100,Y:Float=9.9,Z:String="Gaga")
Print "VORDEFINIERT FTW. "+X+" "+Y+" "+Z
EndFunction


Function ArrayFunktion:Int[](X:Int[])
Print "In Array Funktion: "+X[40]
X=Null
Local Test:Int[]
Dim Test[10]
Test[4]=22
Return Test
EndFunction

Function MehrDimTest:Int[][][](Y:Int[][][])
Print "In Mehr Dim Array Funktion: "+Y[4][4][4]
Y=Null
Local Test:Int[][][]
Dim Test[2][2][2]
Test[1][1][1]=100
Return Test
EndFunction

Function Datatypetest:Void()
Local TestShort:Short, TestDouble:Double, TestLong:Long, TestByte:Byte
TestShort=65535
TestDouble=9999.99999
TestLong=9999999
TestByte=255
Print "Short: "+TestShort+" Double: "+TestDouble+" Long: "+TestLong+" Byte: "+TestByte
EndFunction

Print TestArray()[4][4]

Function TestArray:Int[][]()
Local Array:Int[][]
Dim Array[8][8]
Array[4][4]=100
Return Array
EndFunction

wird zu BMax:
BlitzMax: [AUSKLAPPEN]
SuperStrict
Global halloglobal:Int=0;

Function print_string__dim_0_:Int( text:String)
Print( text);
EndFunction
datatypetest()
print_string__dim_0_("Hallo"+String(2*5+4+5*8+10+5+5+3))
vordefiniert_int__dim_0__float__dim_0__string__dim_0_(100,9.89999962,"Gaga")
Local mehrdim:Int[];
Local Tmp___mehrdim____Array0:Int=5
Local Tmp___mehrdim____Array1:Int=9
Local Tmp___mehrdim____Array2:Int=20
mehrdim=New Int[Tmp___mehrdim____Array0*Tmp___mehrdim____Array1*Tmp___mehrdim____Array2+3]
mehrdim[0]=Tmp___mehrdim____Array0
mehrdim[1]=Tmp___mehrdim____Array1
mehrdim[2]=Tmp___mehrdim____Array2

mehrdim[4*Int(mehrdim[0])*Int(mehrdim[1])*1+8*Int(mehrdim[0])*1+19*1+0+3]=42
mehrdim[4*Int(mehrdim[0])*Int(mehrdim[1])*1+4*Int(mehrdim[0])*1+4*1+0+3]=99
mehrdim=mehrdimtest_int__dim_3_(mehrdim)
Local mehrdimstring:String[];
Local Tmp___mehrdimstring____Array0:Int=5
Local Tmp___mehrdimstring____Array1:Int=5
mehrdimstring=New String[Tmp___mehrdimstring____Array0*Tmp___mehrdimstring____Array1+2]
mehrdimstring[0]=Tmp___mehrdimstring____Array0
mehrdimstring[1]=Tmp___mehrdimstring____Array1

mehrdimstring[2*Int(mehrdimstring[0])*1+3*1+0+2]="Hallo"
print_string__dim_0_(mehrdimstring[2*Int(mehrdimstring[0])*1+3*1+0+2])
Local anderertest:Int[];
Local Tmp___anderertest____Array0:Int=10
Local Tmp___anderertest____Array1:Int=10
anderertest=New Int[Tmp___anderertest____Array0*Tmp___anderertest____Array1+2]
anderertest[0]=Tmp___anderertest____Array0
anderertest[1]=Tmp___anderertest____Array1

For Local x:Int=0 To 9 Step 1
For Local y:Int=0 To 9 Step 1
anderertest[x*Int(anderertest[0])*1+y*1+0+2]=x*9+y
Next
Next
For Local x:Int=0 To 9 Step 1
For Local y:Int=0 To 9 Step 1
print_string__dim_0_("In Array an Position '"+String(x)+"', '"+String(y)+"': "+String(anderertest[x*Int(anderertest[0])*1+y*1+0+2]))
Next
Next
print_string__dim_0_("MultiDim Array:"+String(mehrdim[1*Int(mehrdim[0])*Int(mehrdim[1])*1+1*Int(mehrdim[0])*1+1*1+0+3]))
Local array:Int[];
Local Tmp___array____Array0:Int=1000
array=New Int[Tmp___array____Array0+1]
array[0]=Tmp___array____Array0

array[40*1+0+1]=100*4
array=arrayfunktion_int__dim_1_(array)
print_string__dim_0_("Aus Array Funktion: "+String(array[4*1+0+1]))
GCCollect()
print_string__dim_0_(String(-1*5))
print_string__dim_0_(String(Float("5.5")))
Local floattest:Float=0.0;
floattest=Float(200)
print_string__dim_0_(String(floattest))
halloglobal=100
print_string__dim_0_("Zweite Zeile")
Local hallo:Int=0;
hallo=40
hallo=100+5*10
hallo=hallo+Int(100.000000)
print_string__dim_0_("Text: "+String(hallo))
If (10*10)
print_string__dim_0_("Hallo ist gleich 10")

Else
If (10)
If (Int("Hallo Welt"))
print_string__dim_0_("hallo")

Else
If (2)
print_string__dim_0_("Blub")

Else
print_string__dim_0_("Gaga")

EndIf

EndIf
print_string__dim_0_("In Elseif")

Else
print_string__dim_0_("Blub")

EndIf

EndIf
Local tmp:Int=0;
tmp=1
While (tmp<10)
print_string__dim_0_("In While - Wend "+String(tmp))
tmp=tmp+1
Wend
Repeat
print_string__dim_0_("In Repeat Until")
Exit
Until (1)
Select (10)
Case 5
print_string__dim_0_("Hallo")
print_string__dim_0_("Blubbig")

Case 20
print_string__dim_0_("Hallo")
print_string__dim_0_("Blubbig")

Case 7
print_string__dim_0_("blub")

Default
print_string__dim_0_("in Default")

EndSelect
For Local i:Int=0 To 10 Step 1
print_string__dim_0_("Zahl: "+String(i))
Next
print_string__dim_0_(String(blub_string__dim_0__int__dim_0__float__dim_0_("Hallo",10,10.0000000)))
ohnenichts()
print_string__dim_0_(String(testarray()[4*Int(testarray()[0])*1+4*1+0+2]))

Function testarray:Int[]()
Local array:Int[];
Local Tmp___array____Array0:Int=8
Local Tmp___array____Array1:Int=8
array=New Int[Tmp___array____Array0*Tmp___array____Array1+2]
array[0]=Tmp___array____Array0
array[1]=Tmp___array____Array1

array[4*Int(array[0])*1+4*1+0+2]=100
Return array
EndFunction

Function datatypetest:Int()
Local testshort:Short=0;Local testdouble:Double=0.0;Local testlong:Long=0;Local testbyte:Byte=0;
testshort=Short(65535)
testdouble=Double(10000.0000)
testlong=Long(9999999)
testbyte=Byte(255)
print_string__dim_0_("Short: "+String(testshort)+" Double: "+String(testdouble)+" Long: "+String(testlong)+" Byte: "+String(testbyte))
EndFunction

Function mehrdimtest_int__dim_3_:Int[]( y:Int[])
print_string__dim_0_("In Mehr Dim Array Funktion: "+String(y[4*Int(y[0])*Int(y[1])*1+4*Int(y[0])*1+4*1+0+3]))
y=Null
Local test:Int[];
Local Tmp___test____Array0:Int=2
Local Tmp___test____Array1:Int=2
Local Tmp___test____Array2:Int=2
test=New Int[Tmp___test____Array0*Tmp___test____Array1*Tmp___test____Array2+3]
test[0]=Tmp___test____Array0
test[1]=Tmp___test____Array1
test[2]=Tmp___test____Array2

test[1*Int(test[0])*Int(test[1])*1+1*Int(test[0])*1+1*1+0+3]=100
Return test
EndFunction

Function arrayfunktion_int__dim_1_:Int[]( x:Int[])
print_string__dim_0_("In Array Funktion: "+String(x[40*1+0+1]))
x=Null
Local test:Int[];
Local Tmp___test____Array0:Int=10
test=New Int[Tmp___test____Array0+1]
test[0]=Tmp___test____Array0

test[4*1+0+1]=22
Return test
EndFunction

Function vordefiniert_int__dim_0__float__dim_0__string__dim_0_:Int( x:Int, y:Float, z:String)
print_string__dim_0_("VORDEFINIERT FTW. "+String(x)+" "+String(y)+" "+z)
EndFunction

Function blub_string__dim_0__int__dim_0__float__dim_0_:Int( x:String, z:Int, y:Float)
print_string__dim_0_("In anderes Blub")
Return -1*100
EndFunction

Function blub_int__dim_0__string__dim_0__int__dim_0_:Int( x:Int, z:String, y:Int)
print_string__dim_0_("X: "+String(x)+" Y: "+String(y)+" "+z)
Return 100
EndFunction

Function ohnenichts:Int()
EndFunction

wurd zu C:
Code: [AUSKLAPPEN]
 
#include "clib/main.c"
CPB_INT halloglobal=0;

void print_string__dim_0_( CPB_STRING text) {
   print( text);
}

void gccollect();

void ohnenichts();

CPB_INT blub_string__dim_0__int__dim_0__float__dim_0_( CPB_STRING x,CPB_INT z,CPB_FLOAT y);

void vordefiniert_int__dim_0__float__dim_0__string__dim_0_( CPB_INT x,CPB_FLOAT y,CPB_STRING z);

CPB_ARRAY  arrayfunktion_int__dim_1_( CPB_ARRAY x);

CPB_ARRAY  mehrdimtest_int__dim_3_( CPB_ARRAY y);

void datatypetest();

CPB_ARRAY  testarray();
int main() {
   GC_INIT();;
   datatypetest();
   print_string__dim_0_(joinstr("Hallo",int2string(2*5+4+5*8+10+5+5+3)));
   vordefiniert_int__dim_0__float__dim_0__string__dim_0_(100,9.89999962,"Gaga");
   CPB_ARRAY mehrdim;
   
   int ___mehrdim___tmp0=5;
   int ___mehrdim___tmp1=9;
   int ___mehrdim___tmp2=20;
   mehrdim=GC_malloc((___mehrdim___tmp0*___mehrdim___tmp1*___mehrdim___tmp2)*sizeof(CPB_INT)+1*sizeof(int));
   ((int*)((int*)mehrdim)[0])=GC_MALLOC(3*sizeof(int));
   ((int*)((int*)((int*)mehrdim)[0])[0])=___mehrdim___tmp0;
   ((int*)((int*)((int*)mehrdim)[0])[1])=___mehrdim___tmp1;
   ((int*)((int*)((int*)mehrdim)[0])[2])=___mehrdim___tmp2;

   ((CPB_INT*)mehrdim)[4*getsizearray(mehrdim,0)*getsizearray(mehrdim,1)*1+8*getsizearray(mehrdim,0)*1+19*1+0+1]=42;
   ((CPB_INT*)mehrdim)[4*getsizearray(mehrdim,0)*getsizearray(mehrdim,1)*1+4*getsizearray(mehrdim,0)*1+4*1+0+1]=99;
   mehrdim=mehrdimtest_int__dim_3_(mehrdim);
   CPB_ARRAY mehrdimstring;
   
   int ___mehrdimstring___tmp0=5;
   int ___mehrdimstring___tmp1=5;
   mehrdimstring=GC_malloc((___mehrdimstring___tmp0*___mehrdimstring___tmp1)*sizeof(CPB_STRING)+1*sizeof(int));
   ((int*)((int*)mehrdimstring)[0])=GC_MALLOC(2*sizeof(int));
   ((int*)((int*)((int*)mehrdimstring)[0])[0])=___mehrdimstring___tmp0;
   ((int*)((int*)((int*)mehrdimstring)[0])[1])=___mehrdimstring___tmp1;

   ((CPB_STRING*)mehrdimstring)[2*getsizearray(mehrdimstring,0)*1+3*1+0+1]="Hallo";
   print_string__dim_0_(((CPB_STRING*)mehrdimstring)[2*getsizearray(mehrdimstring,0)*1+3*1+0+1]);
   CPB_ARRAY anderertest;
   
   int ___anderertest___tmp0=10;
   int ___anderertest___tmp1=10;
   anderertest=GC_malloc((___anderertest___tmp0*___anderertest___tmp1)*sizeof(CPB_INT)+1*sizeof(int));
   ((int*)((int*)anderertest)[0])=GC_MALLOC(2*sizeof(int));
   ((int*)((int*)((int*)anderertest)[0])[0])=___anderertest___tmp0;
   ((int*)((int*)((int*)anderertest)[0])[1])=___anderertest___tmp1;

   { CPB_INT x=0;;
   for (x=0;x<9;x+=1) {
      { CPB_INT y=0;;
      for (y=0;y<9;y+=1) {
         ((CPB_INT*)anderertest)[x*getsizearray(anderertest,0)*1+y*1+0+1]=x*9+y;
      } }
   } }
   { CPB_INT x=0;;
   for (x=0;x<9;x+=1) {
      { CPB_INT y=0;;
      for (y=0;y<9;y+=1) {
         print_string__dim_0_(joinstr(joinstr(joinstr(joinstr(joinstr("In Array an Position '",int2string(x)),"', '"),int2string(y)),"': "),int2string(((CPB_INT*)anderertest)[x*getsizearray(anderertest,0)*1+y*1+0+1])));
      } }
   } }
   print_string__dim_0_(joinstr("MultiDim Array:",int2string(((CPB_INT*)mehrdim)[1*getsizearray(mehrdim,0)*getsizearray(mehrdim,1)*1+1*getsizearray(mehrdim,0)*1+1*1+0+1])));
   CPB_ARRAY array;
   
   int ___array___tmp0=1000;
   array=GC_malloc((___array___tmp0)*sizeof(CPB_INT)+1*sizeof(int));
   ((int*)((int*)array)[0])=GC_MALLOC(1*sizeof(int));
   ((int*)((int*)((int*)array)[0])[0])=___array___tmp0;

   ((CPB_INT*)array)[40*1+0+1]=100*4;
   array=arrayfunktion_int__dim_1_(array);
   print_string__dim_0_(joinstr("Aus Array Funktion: ",int2string(((CPB_INT*)array)[4*1+0+1])));
   gccollect();
   print_string__dim_0_(int2string(-1*5));
   print_string__dim_0_(float2string(string2float("5.5")));
   CPB_FLOAT floattest=0.0f;
   floattest=(CPB_FLOAT)(200);
   print_string__dim_0_(float2string(floattest));
   halloglobal=100;
   print_string__dim_0_("Zweite Zeile");
   CPB_INT hallo=0;
   hallo=40;
   hallo=100+5*10;
   hallo=hallo+(CPB_INT)(100.000000);
   print_string__dim_0_(joinstr("Text: ",int2string(hallo)));
   if (10*10) {
      print_string__dim_0_("Hallo ist gleich 10");
     
   } else {
      if (10) {
         if (string2int("Hallo Welt")) {
            print_string__dim_0_("hallo");
           
         } else {
            if (2) {
               print_string__dim_0_("Blub");
               
            } else {
               print_string__dim_0_("Gaga");

            }

         }
         print_string__dim_0_("In Elseif");
         
      } else {
         print_string__dim_0_("Blub");

      }

   }
   CPB_INT tmp=0;
   tmp=1;
   while (tmp<10) {
      print_string__dim_0_(joinstr("In While - Wend ",int2string(tmp)));
      tmp=tmp+1;
   }
   do {
      print_string__dim_0_("In Repeat Until");
      break;
   } while (!(1));
   switch (10) {
      case 5:
         print_string__dim_0_("Hallo");
         print_string__dim_0_("Blubbig");
         break;

      case 20:
         print_string__dim_0_("Hallo");
         print_string__dim_0_("Blubbig");
         break;

      case 7:
         print_string__dim_0_("blub");
         break;

      default:
         print_string__dim_0_("in Default");

   }
   { CPB_INT i=0;;
   for (i=0;i<10;i+=1) {
      print_string__dim_0_(joinstr("Zahl: ",int2string(i)));
   } }
   print_string__dim_0_(int2string(blub_string__dim_0__int__dim_0__float__dim_0_("Hallo",10,10.0000000)));
   ohnenichts();
   print_string__dim_0_(int2string(((CPB_INT*)testarray())[4*getsizearray(testarray(),0)*1+4*1+0+1]));
}
CPB_ARRAY  testarray() {
   CPB_ARRAY array;
   
   int ___array___tmp0=8;
   int ___array___tmp1=8;
   array=GC_malloc((___array___tmp0*___array___tmp1)*sizeof(CPB_INT)+1*sizeof(int));
   ((int*)((int*)array)[0])=GC_MALLOC(2*sizeof(int));
   ((int*)((int*)((int*)array)[0])[0])=___array___tmp0;
   ((int*)((int*)((int*)array)[0])[1])=___array___tmp1;

   ((CPB_INT*)array)[4*getsizearray(array,0)*1+4*1+0+1]=100;
   return array;
}

void datatypetest() {
   CPB_SHORT testshort=0;CPB_DOUBLE testdouble=0.0f;CPB_LONG testlong=0;CPB_BYTE testbyte=0;
   testshort=(CPB_SHORT)(65535);
   testdouble=(CPB_DOUBLE)(10000.0000);
   testlong=(CPB_LONG)(9999999);
   testbyte=(CPB_BYTE)(255);
   print_string__dim_0_(joinstr(joinstr(joinstr(joinstr(joinstr(joinstr(joinstr("Short: ",short2string(testshort))," Double: "),double2string(testdouble))," Long: "),long2string(testlong))," Byte: "),byte2string(testbyte)));
}

CPB_ARRAY  mehrdimtest_int__dim_3_( CPB_ARRAY y) {
   print_string__dim_0_(joinstr("In Mehr Dim Array Funktion: ",int2string(((CPB_INT*)y)[4*getsizearray(y,0)*getsizearray(y,1)*1+4*getsizearray(y,0)*1+4*1+0+1])));
   y=NULL;
   CPB_ARRAY test;
   
   int ___test___tmp0=2;
   int ___test___tmp1=2;
   int ___test___tmp2=2;
   test=GC_malloc((___test___tmp0*___test___tmp1*___test___tmp2)*sizeof(CPB_INT)+1*sizeof(int));
   ((int*)((int*)test)[0])=GC_MALLOC(3*sizeof(int));
   ((int*)((int*)((int*)test)[0])[0])=___test___tmp0;
   ((int*)((int*)((int*)test)[0])[1])=___test___tmp1;
   ((int*)((int*)((int*)test)[0])[2])=___test___tmp2;

   ((CPB_INT*)test)[1*getsizearray(test,0)*getsizearray(test,1)*1+1*getsizearray(test,0)*1+1*1+0+1]=100;
   return test;
}

CPB_ARRAY  arrayfunktion_int__dim_1_( CPB_ARRAY x) {
   print_string__dim_0_(joinstr("In Array Funktion: ",int2string(((CPB_INT*)x)[40*1+0+1])));
   x=NULL;
   CPB_ARRAY test;
   
   int ___test___tmp0=10;
   test=GC_malloc((___test___tmp0)*sizeof(CPB_INT)+1*sizeof(int));
   ((int*)((int*)test)[0])=GC_MALLOC(1*sizeof(int));
   ((int*)((int*)((int*)test)[0])[0])=___test___tmp0;

   ((CPB_INT*)test)[4*1+0+1]=22;
   return test;
}

void vordefiniert_int__dim_0__float__dim_0__string__dim_0_( CPB_INT x,CPB_FLOAT y,CPB_STRING z) {
   print_string__dim_0_(joinstr(joinstr(joinstr(joinstr(joinstr("VORDEFINIERT FTW. ",int2string(x))," "),float2string(y))," "),z));
}

CPB_INT blub_string__dim_0__int__dim_0__float__dim_0_( CPB_STRING x,CPB_INT z,CPB_FLOAT y) {
   print_string__dim_0_("In anderes Blub");
   return -1*100;
}

CPB_INT blub_int__dim_0__string__dim_0__int__dim_0_( CPB_INT x,CPB_STRING z,CPB_INT y) {
   print_string__dim_0_(joinstr(joinstr(joinstr(joinstr(joinstr("X: ",int2string(x))," Y: "),int2string(y)),"  "),z));
   return 100;
}

void ohnenichts() {
}


Tokenizetime: 10
Analysetime: 1
Parsetime: 39
Generatetime: 16
Total: 66


Der der XML Code zu groß ist hier ist er bei nopaste: http://nopaste.php-quake.net/305089

Willkommen in der Familie, Herr Funktionsüberladung.

Mittwoch, 21. Juli 2010 von coolo
Guten Tag.

Das markanteste Feature welches Cross Platform Basic nun unterstützt ist die Funktionsüberladung. Diese ist -wie in anderen Sprachen bereits bekannt- dazu gedacht mehrere Funktionen mit demselben Namen zu haben, welche sich lediglich in derer Signatur unterscheiden. Dadurch ist es um einiges komfortabler damit zu programmieren. Jedoch hat das ganze einen Haken, der Datentyp eines jeden Parameters muss eindeutig bestimmbar sein, ansonsten gibt es eine Fehlermeldung. Es sei denn es gibt nur eine Funktion mit diesem Namen, dann wird automatisch gecastet. Die Optionalen Parameter funktionieren auch nur mit Funktionen welche nicht überladen sind, ich denke nicht das zu ändern da es mir ziemlich viel arbeit bedeutet und man sich sowieso entscheiden muss bei einer Funktion: Überladen oder Optionale Parameter.

Der Garbage Collector ist immer noch eine Baustelle, was daran liegt dass ich keinen Zugriff auf den Stack habe, womit ich nicht eindeutig bestimmen kann welches Objekt gerade benützt wird. Falls jemand eine Lösung hat (ohne Inline Assembler) nur zu, ich bin sehr daran interessiert!

Es gäbe 2 andere Möglichkeiten (wobei jede Nachteile hätte):
Arrow Einen vorgefertigten Garbage Collector verwenden (http://www.hpl.hp.com/personal/Hans_Boehm/gc/). Dieser hätte folgende Vorteile: Es wäre eine Leichtigkeit diesen zu implementieren, CPB wäre Multithreading tauglich (was aber aufgrund anderer Dinge nicht geplant ist), es wäre sehr schnell und zyklische Objekte würden erkannt werden. Nachteile: Der GC wäre nicht Platformunabhängig (auf den ARM Prozessoren funktioniert er afaik nicht)

Arrow Komplett auf den GC verzichten. Hierbei würde beim übergeben als Parameter das Array (oder Objekt) lediglich kopiert werden. Dadurch gäbe es von jedem Objekt exakt einen Pointer. Das würde mir all die Probleme beseitigen, allerdings ist es damit ein Graus zu programmieren. Und Sprachen mit einem GC (Java, C#, Lua,...) wären auch nicht ohne weiteres möglich zu portieren.

Tja so wie es aussieht muss ich übles gehacke einsetzen um diesen Schei***** GC zu implementieren...

Jo0oker ist natürlich auch sehr fleißig und hat schon den Grundstein für die Helpfiles erzeugt: http://www.eggers-sw.de/CPB/Cr...0Basic.htm Er plant auch eine C Syntax als Input (also wie Cross Platform Basic) zu programmieren.

Code: [AUSKLAPPEN]
Local TestArray:String[]
Dim TestArray[20]
TestArray[3]="Wuff"
Print "Hallo: "+TestArray[3]
TestArray=Null

Local Array2:Int[]
Dim Array2[100]
Array2[40]=100
;Array2=Null

Local TestZuweisung:Int[]
TestZuWeisung=Array2  ;//funktioniert noch nicht
Array2=Null

GCCollect()

;Print TestZuweisung[40]

Print -5

Print Float("5.5")


Print("Hallo"+(2*(5+4)+(5*(8+10))))

Local FloatTest:Float=200
Print FloatTest



Global HalloGlobal:Int
HalloGlobal=100

Print "Zweite Zeile"
Local Hallo:Int=40 ;Es gibt Int(%),Float(#),String($),Nichts(int)
Hallo=100+5*10
Hallo=Hallo+100.0

Print "Text: "+Hallo


If 10*10
   Print "Hallo ist gleich 10"
ElseIf 10
   If 1
      Print "hallo"
   ElseIF 2
      Print "Blub"
   Else
      Print "Gaga"
   EndIf
   Print "In Elseif"
Else
   Print "Blub"
EndIf

Local Tmp:Int=1
While tmp<10
   Print "In While - Wend "+Tmp
   Tmp=Tmp+1
Wend

Repeat
   Print "In Repeat Until"
   Break
Until 1

Select 10
   Case 5, 20
      Print "Hallo"
      Print("Blubbig")
   case 7
      Print "blub"
   Default
      Print "in Default"
EndSelect

For Local i:int=0 to 10
   Print "Zahl: "+i
Next

Print Blub("Hallo",10,10.0)
OhneNichts()

Function OhneNichts:Int()
   Print "uuu"
EndFunction

Function Blub:Int(X:Int,Z:String,Y:Int)
   Print "X: "+X+" Y: "+Y+"  "+Z
   Return 100
EndFunction

Function Blub:Int(X:String, Z:Int, Y:Float)
   Print "In anderes Blub"
EndFunction

Wird zu:
Code: [AUSKLAPPEN]
#include "clib/main.c"
CPB_INT halloglobal=0;

void print_string( CPB_STRING text) {
   print( text);
}

void gccollect();

CPB_INT ohnenichts();

CPB_INT blub_string_int_float( CPB_STRING x,CPB_INT z,CPB_FLOAT y);
int main() {
   initgc();
   CPB_GCREF * testarray=voidref;
   testarray=dimstring(20);
   ((CPB_STRING*)testarray->mem->memobj)[3]=newstr("Wuff");
   print_string(joinstr(newstr("Hallo: "),((CPB_STRING*)testarray->mem->memobj)[3]));
   testarray->mem=NULL;
   updatelink(testarray);
   CPB_GCREF * array2=voidref;
   array2=dimint(100);
   ((CPB_INT*)array2->mem->memobj)[40]=100;
   CPB_GCREF * testzuweisung=voidref;
   testzuweisung->mem=array2->mem;
   updatelink(testzuweisung);
   array2->mem=NULL;
   updatelink(array2);
   gccollect();
   print_string(int2string(-1*5));
   print_string(float2string(string2float(newstr("5.5"))));
   print_string(joinstr(newstr("Hallo"),int2string(2*5+4+5*8+10)));
   CPB_FLOAT floattest=0.0f;
   floattest=(float)(200);
   print_string(float2string(floattest));
   halloglobal=100;
   print_string(newstr("Zweite Zeile"));
   CPB_INT hallo=0;
   hallo=40;
   hallo=100+5*10;
   hallo=(int)((float)(hallo)+100.000000);
   print_string(joinstr(newstr("Text: "),int2string(hallo)));
   if (10*10) {
      print_string(newstr("Hallo ist gleich 10"));
     
   } else {
      if (10) {
         if (1) {
            print_string(newstr("hallo"));
           
         } else {
            if (2) {
               print_string(newstr("Blub"));
               
            } else {
               print_string(newstr("Gaga"));

            }

         }
         print_string(newstr("In Elseif"));
         
      } else {
         print_string(newstr("Blub"));

      }

   }
   CPB_INT tmp=0;
   tmp=1;
   while (tmp<10) {
      print_string(joinstr(newstr("In While - Wend "),int2string(tmp)));
      tmp=tmp+1;
   }
   do {
      print_string(newstr("In Repeat Until"));
      break;
   } while (!(1));
   switch (10) {
      case 5:
         print_string(newstr("Hallo"));
         print_string(newstr("Blubbig"));
         break;

      case 20:
         print_string(newstr("Hallo"));
         print_string(newstr("Blubbig"));
         break;

      case 7:
         print_string(newstr("blub"));
         break;

      default:
         print_string(newstr("in Default"));

   }
   CPB_INT i=0;;
   for (i=0;i<10;i+=1) {
      print_string(joinstr(newstr("Zahl: "),int2string(i)));
   }
   print_string(int2string(blub_string_int_float(newstr("Hallo"),10,10.0000000)));
   ohnenichts();
}
CPB_INT blub_string_int_float( CPB_STRING x,CPB_INT z,CPB_FLOAT y) {
   print_string(newstr("In anderes Blub"));
}

CPB_INT blub_int_string_int( CPB_INT x,CPB_STRING z,CPB_INT y) {
   print_string(joinstr(joinstr(joinstr(joinstr(joinstr(newstr("X: "),int2string(x)),newstr(" Y: ")),int2string(y)),newstr("  ")),z));
   return 100;
}

CPB_INT ohnenichts() {
   print_string(newstr("uuu"));
}


Garbage Collector - ich hasse dich!

Dienstag, 20. Juli 2010 von coolo
Hallo,
die letzten 2 Tage haben mir den letzten Nerv gerauft - Ende leider nicht in Sicht... Doch wieso das? Nunja beginnen wir erstmal mit einer guten Nachricht: Die eindimensionalen Arrays funktionieren bereits. Das heißt man kann sie dimensionieren, setzen und verwenden (Sie können allerdings noch nicht als Parameter und Rückgabewert fungieren, weshalb kommt gleich). Arrays of Arrays werden (hoffentlich) kein allzu großes Problem sein, da ich den Code so gehalten habe, dass er auch mehrere Dimensionen handhaben kann (wurde bisher allerdings noch nicht getestet). Außerdem kann eine Bedingung in einem Select Case Konstrukt mehrere Möglichkeiten haben ("Case 10,20,30").

Doch nun zum Garbage Collector (GC). Ursprünglich wollte ich einen Mark & Sweep Collector einbauen, jedoch braucht man dafür den Zugriff auf den Stack, welchen man ohne Inline Assembler natürlich nicht hat.
Deswegen habe ich mich für Reference Counting entschieden, diesen kann man vergleichsweise einfach implementieren, hat aber einen entscheidenden Nachteil... er erkennt keine zyklischen Objekte (also wenn ein Objekt (vie Umwege oder direkt) auf sich selbst zeugt. Reference Counting funktioniert folgens: bei jeder Zuweisung wird der Objekt Counter erhöht und bei jeder =Null Zuweisung verringert, wenn dieser Counter nun 0 ist wird das Objekt vom Speicher gelöscht (was bei zyklischen Objekten eben nie der Fall ist). Ein weiterer Vorteil vom Ref - Counting ist dass er vergleichsweise schnell ist (da hierbei nie/selten alle Objekte durchgegangen werden müssen).

Jedoch hat sich der Reference Counting Algorithmus als doch nicht so einfach zu implementieren herausgestellt. Einfache Konstrukte funktionieren bereits aber andere Dinge wiederum funktionieren nicht...

Folgender Code wird umgewandelt in C:
Code: [AUSKLAPPEN]
Local TestArray:String[]
Dim TestArray[20]
TestArray[3]="Wuff"
Print "Hallo: "+TestArray[3]
TestArray=Null

Local Array2:Int[]
Dim Array2[100]
Array2[40]=100
Array2=Null

;Local TestZuweisung:Int[]
;TestZuWeisung=Array2  //funktioniert noch nicht :/
GCCollect()


Code: [AUSKLAPPEN]
initgc();
   CPB_GCREF * testarray=voidref;
   testarray=dimstring(20);
   ((CPB_STRING*)testarray->mem->memobj)[3]=newstr("Wuff");
   print(joinstr(newstr("Hallo: "),((CPB_STRING*)testarray->mem->memobj)[3]));
   testarray->mem->memobj=NULL;
   updatelink(testarray);
   CPB_GCREF * array2=voidref;
   array2=dimint(100);
   ((CPB_INT*)array2->mem->memobj)[40]=100;
   array2->mem->memobj=NULL;
   updatelink(array2);
   gccollect();

Huiwuh, soviel an einem Tag!

Samstag, 17. Juli 2010 von coolo
Hallo!

Beginnen wir heute ersteinmal was ich NICHT eingebaut habe. Das sind (wie zu erwarten) die Arrays. Diese haben mir heute in der Früh den letzten Nerv geraubt, weswegen ich diese auf morgen verschoben habe (ich weiß, morgen morgen nur nicht heute, sagen alle faulen leute bla bla bla).

Arrow String Lib: Die Strings wurden nun endlich in der C Version implementiert. Dadurch kann man diese schön miteinander addieren und bearbeiten. Ich bin mir aber noch nicht sicher ob hier nicht irgendwelche Speicher Lecks entstehen (habe es noch nicht getestet), ich hoffe mal nicht.
Folgende Funktionen sind drinnen (mehr kommen sowieso nicht):
Arrow Arrow Len: Gibt die Länge eines Strings aus
Arrow Arrow Chr: Ermittelt anhand des ASCII Codes einen String
Arrow Arrow Asc: Ermittelt anhand des Strings den ASCII Code
Arrow Arrow InStr: Sucht innerhalb eines Strings einen anderen String und gibt dessen Position zurück
Arrow Arrow Mid, Left, Right: Extrahiert aus einem String einen anderen
Arrow Arrow Upper/Lower: Macht alle Buchstaben groß/klein.
Arrow Arrow Trim: Entfernt alle Leerzeichen am Anfang und am Ende
Arrow Arrow Replace: Ersetzt in einem String einen anderen String (noch nicht fertig implementiert)

Arrow BUGS BUGS UND NOCH MEHR BUGS: Dank Jo0oker habe ich wieder mindestens 50 Fehler beseitigen können. Somit ist auch möglich 4*-5 zu rechnen oder auch innerhalb benutzerdefinierten Funktionen andere benutzerdefinierte Funktionen auf zu rufen uvm. Außerdem können nun auch Floats mit einem String verknüpft werden. Der C Compiler erzeugt nun auch validen Code.

Arrow Andere Dinge: True/False eingebaut. Not Operator. Außerdem werden nur die Funktionen definiert welche auch wirklich verwendet werden (dadurch bleiben Exen klein usw.)

Arrow Jo0oker war nun auch wieder fleißig. Er hat das erste SPE Programm fertig gestellt, welches auch funktioniert. Er hat die GESAMTE Softpixel Engine 8den BB Wrapper) in Cross Platform Basic zur Verfügung gestellt (leider ist es noch nicht sicher ob es die in die Finale Fassung schafft, da SPE eben nicht auf allen geplanten Platformen läuft) Hier ist der Sourcecode dazu:
Code: [AUSKLAPPEN]
Print("Los gehts")

UseDirect3D9()
Graphics3D(1280,720, 32 ,0)

Local Cam:Int = CreateCamera(0)
Local Cube:Int = CreateCube(0)
PositionEntity(Cube, 0, 0, 10, 0)


While(KeyHit(1) == 0)

   TurnEntity(Cube,1,1,1,0)

   RenderWorld(0)
   
   Print("X: " + String(EntityX(Cam, 0)) + " Y: " + String(EntityY(Cam, 0)) + " Z: " + String(EntityZ(Cam, 0)))
   
   If(KeyDown(200) == 1)
   
      MoveEntity(Cam, 0,0,1)
   
   EndIf
   
   If(KeyDown(208) == 1)
   
      MoveEntity(Cam, 0,0,0-1)
   
   EndIf
   
   Flip(1)
Wend

EndGraphics()


Hier ist mein Testcode:
Code: [AUSKLAPPEN]
<?xml version="1.0"?>
<CPB version="0.1">
  <global>
    <defvar name="halloglobal" type="int"/>
  </global>
  <function name="print" type="void" userfunc="0">
    <param name="text" type="string"/>
  </function>
  <function name="chr" type="string" userfunc="0">
    <param name="value" type="int"/>
  </function>
  <function name="asc" type="int" userfunc="0">
    <param name="text" type="string"/>
  </function>
  <function name="instr" type="int" userfunc="0">
    <param name="text1" type="string"/>
    <param name="text2" type="string"/>
    <param name="start" type="int"/>
  </function>
  <function name="mid" type="string" userfunc="0">
    <param name="text" type="string"/>
    <param name="start" type="int"/>
    <param name="anzahl" type="int"/>
  </function>
  <function name="upper" type="string" userfunc="0">
    <param name="text" type="string"/>
  </function>
  <function name="lower" type="string" userfunc="0">
    <param name="text" type="string"/>
  </function>
  <function name="trim" type="string" userfunc="0">
    <param name="text" type="string"/>
  </function>
  <function name="replace" type="string" userfunc="0">
    <param name="text" type="string"/>
    <param name="suche" type="string"/>
    <param name="ersetze" type="string"/>
    <param name="position" type="int"/>
  </function>
  <function name="ohnenichts" type="int" userfunc="0"/>
  <function name="blub" type="int" userfunc="0">
    <param name="x" type="int"/>
    <param name="z" type="string"/>
    <param name="y" type="int"/>
  </function>
  <code>
    <line number="1">
      <call name="print">
        <param>
          <cast from="int" to="string">
            <call name="asc">
              <param>
                <string value="t"/>
              </param>
            </call>
          </cast>
        </param>
      </call>
    </line>
    <line number="2">
      <call name="print">
        <param>
          <call name="chr">
            <param>
              <int value="112"/>
            </param>
          </call>
        </param>
      </call>
    </line>
    <line number="3">
      <call name="print">
        <param>
          <cast from="int" to="string">
            <call name="instr">
              <param>
                <string value="Hallo Welt"/>
              </param>
              <param>
                <string value="Welt2"/>
              </param>
              <param>
                <int value="0"/>
              </param>
            </call>
          </cast>
        </param>
      </call>
    </line>
    <line number="4">
      <call name="print">
        <param>
          <call name="mid">
            <param>
              <string value="Hallo Welt"/>
            </param>
            <param>
              <int value="3"/>
            </param>
            <param>
              <int value="7"/>
            </param>
          </call>
        </param>
      </call>
    </line>
    <line number="6">
      <call name="print">
        <param>
          <call name="upper">
            <param>
              <string value="hallo klein geschrieben"/>
            </param>
          </call>
        </param>
      </call>
    </line>
    <line number="7">
      <call name="print">
        <param>
          <call name="lower">
            <param>
              <string value="HALLO GRO&#xDF; GESCHRIEBEN"/>
            </param>
          </call>
        </param>
      </call>
    </line>
    <line number="8">
      <call name="print">
        <param>
          <stringadd>
            <left>
              <stringadd>
                <left>
                  <string value="-"/>
                </left>
                <right>
                  <call name="trim">
                    <param>
                      <string value="Hallo Mit Trim      "/>
                    </param>
                  </call>
                </right>
              </stringadd>
            </left>
            <right>
              <string value="-"/>
            </right>
          </stringadd>
        </param>
      </call>
    </line>
    <line number="9">
      <call name="print">
        <param>
          <call name="replace">
            <param>
              <string value="Hallo in Welt"/>
            </param>
            <param>
              <string value="in"/>
            </param>
            <param>
              <string value="nicht"/>
            </param>
            <param>
              <int value="0"/>
            </param>
          </call>
        </param>
      </call>
    </line>
    <line number="11">
      <call name="print">
        <param>
          <cast from="int" to="string">
            <mul>
              <left>
                <int value="-1"/>
              </left>
              <right>
                <int value="5"/>
              </right>
            </mul>
          </cast>
        </param>
      </call>
    </line>
    <line number="13">
      <call name="print">
        <param>
          <cast from="float" to="string">
            <cast from="string" to="float">
              <string value="5.5"/>
            </cast>
          </cast>
        </param>
      </call>
    </line>
    <line number="16">
      <call name="print">
        <param>
          <stringadd>
            <left>
              <string value="Hallo"/>
            </left>
            <right>
              <cast from="int" to="string">
                <add>
                  <left>
                    <mul>
                      <left>
                        <int value="2"/>
                      </left>
                      <right>
                        <add>
                          <left>
                            <int value="5"/>
                          </left>
                          <right>
                            <int value="4"/>
                          </right>
                        </add>
                      </right>
                    </mul>
                  </left>
                  <right>
                    <mul>
                      <left>
                        <int value="5"/>
                      </left>
                      <right>
                        <add>
                          <left>
                            <int value="8"/>
                          </left>
                          <right>
                            <int value="10"/>
                          </right>
                        </add>
                      </right>
                    </mul>
                  </right>
                </add>
              </cast>
            </right>
          </stringadd>
        </param>
      </call>
    </line>
    <line number="18">
      <local>
        <defvar name="floattest" type="float"/>
      </local>
    </line>
    <line number="19">
      <set>
        <name>
          <var name="floattest"/>
        </name>
        <value>
          <cast from="int" to="float">
            <int value="200"/>
          </cast>
        </value>
      </set>
    </line>
    <line number="19">
      <call name="print">
        <param>
          <cast from="float" to="string">
            <var name="floattest"/>
          </cast>
        </param>
      </call>
    </line>
    <line number="23"/>
    <line number="24">
      <set>
        <name>
          <var name="halloglobal"/>
        </name>
        <value>
          <int value="100"/>
        </value>
      </set>
    </line>
    <line number="26">
      <call name="print">
        <param>
          <string value="Zweite Zeile"/>
        </param>
      </call>
    </line>
    <line number="27">
      <local>
        <defvar name="hallo" type="int"/>
      </local>
    </line>
    <line number="28">
      <set>
        <name>
          <var name="hallo"/>
        </name>
        <value>
          <int value="40"/>
        </value>
      </set>
    </line>
    <line number="28">
      <set>
        <name>
          <var name="hallo"/>
        </name>
        <value>
          <add>
            <left>
              <int value="100"/>
            </left>
            <right>
              <mul>
                <left>
                  <int value="5"/>
                </left>
                <right>
                  <int value="10"/>
                </right>
              </mul>
            </right>
          </add>
        </value>
      </set>
    </line>
    <line number="29">
      <set>
        <name>
          <var name="hallo"/>
        </name>
        <value>
          <cast from="float" to="int">
            <add>
              <left>
                <cast from="int" to="float">
                  <var name="hallo"/>
                </cast>
              </left>
              <right>
                <float value="100.000000"/>
              </right>
            </add>
          </cast>
        </value>
      </set>
    </line>
    <line number="31">
      <call name="print">
        <param>
          <stringadd>
            <left>
              <string value="Text: "/>
            </left>
            <right>
              <cast from="int" to="string">
                <var name="hallo"/>
              </cast>
            </right>
          </stringadd>
        </param>
      </call>
    </line>
    <line number="34">
      <if>
        <condition>
          <mul>
            <left>
              <int value="10"/>
            </left>
            <right>
              <int value="10"/>
            </right>
          </mul>
        </condition>
        <line number="35">
          <call name="print">
            <param>
              <string value="Hallo ist gleich 10"/>
            </param>
          </call>
        </line>
        <line number="36">
          <else>
            <line number="36">
              <if>
                <condition>
                  <int value="10"/>
                </condition>
                <line number="37">
                  <if>
                    <condition>
                      <int value="1"/>
                    </condition>
                    <line number="38">
                      <call name="print">
                        <param>
                          <string value="hallo"/>
                        </param>
                      </call>
                    </line>
                    <line number="39">
                      <else>
                        <line number="39">
                          <if>
                            <condition>
                              <int value="2"/>
                            </condition>
                            <line number="40">
                              <call name="print">
                                <param>
                                  <string value="Blub"/>
                                </param>
                              </call>
                            </line>
                            <line number="42">
                              <else>
                                <line number="42">
                                  <call name="print">
                                    <param>
                                      <string value="Gaga"/>
                                    </param>
                                  </call>
                                </line>
                              </else>
                            </line>
                          </if>
                        </line>
                      </else>
                    </line>
                  </if>
                </line>
                <line number="44">
                  <call name="print">
                    <param>
                      <string value="In Elseif"/>
                    </param>
                  </call>
                </line>
                <line number="46">
                  <else>
                    <line number="46">
                      <call name="print">
                        <param>
                          <string value="Blub"/>
                        </param>
                      </call>
                    </line>
                  </else>
                </line>
              </if>
            </line>
          </else>
        </line>
      </if>
    </line>
    <line number="49">
      <local>
        <defvar name="tmp" type="int"/>
      </local>
    </line>
    <line number="50">
      <set>
        <name>
          <var name="tmp"/>
        </name>
        <value>
          <int value="1"/>
        </value>
      </set>
    </line>
    <line number="50">
      <while>
        <condition>
          <less>
            <left>
              <var name="tmp"/>
            </left>
            <right>
              <int value="10"/>
            </right>
          </less>
        </condition>
        <line number="51">
          <call name="print">
            <param>
              <stringadd>
                <left>
                  <string value="In While - Wend "/>
                </left>
                <right>
                  <cast from="int" to="string">
                    <var name="tmp"/>
                  </cast>
                </right>
              </stringadd>
            </param>
          </call>
        </line>
        <line number="52">
          <set>
            <name>
              <var name="tmp"/>
            </name>
            <value>
              <add>
                <left>
                  <var name="tmp"/>
                </left>
                <right>
                  <int value="1"/>
                </right>
              </add>
            </value>
          </set>
        </line>
      </while>
    </line>
    <line number="55">
      <repeat>
        <line number="56">
          <call name="print">
            <param>
              <string value="In Repeat Until"/>
            </param>
          </call>
        </line>
        <line number="57">
          <break/>
        </line>
        <condition>
          <int value="1"/>
        </condition>
      </repeat>
    </line>
    <line number="60">
      <select>
        <condition>
          <int value="10"/>
        </condition>
        <case>
          <condition>
            <int value="5"/>
          </condition>
          <line number="62">
            <call name="print">
              <param>
                <string value="Hallo"/>
              </param>
            </call>
          </line>
        </case>
        <case>
          <condition>
            <int value="7"/>
          </condition>
          <line number="64">
            <call name="print">
              <param>
                <string value="blub"/>
              </param>
            </call>
          </line>
        </case>
        <default>
          <line number="66">
            <call name="print">
              <param>
                <string value="in Default"/>
              </param>
            </call>
          </line>
        </default>
      </select>
    </line>
    <line number="69">
      <for>
        <forvar>
          <declaration>
            <local>
              <defvar name="i" type="int"/>
            </local>
          </declaration>
          <var>
            <var name="i"/>
          </var>
        </forvar>
        <start>
          <int value="0"/>
        </start>
        <to>
          <int value="10"/>
        </to>
        <step>
          <int value="1"/>
        </step>
        <line number="70">
          <call name="print">
            <param>
              <stringadd>
                <left>
                  <string value="Zahl: "/>
                </left>
                <right>
                  <cast from="int" to="string">
                    <var name="i"/>
                  </cast>
                </right>
              </stringadd>
            </param>
          </call>
        </line>
      </for>
    </line>
    <line number="73">
      <call name="blub">
        <param>
          <int value="10"/>
        </param>
        <param>
          <cast from="int" to="string">
            <int value="5"/>
          </cast>
        </param>
        <param>
          <int value="100"/>
        </param>
      </call>
    </line>
    <line number="74">
      <call name="ohnenichts"/>
    </line>
    <line number="76"/>
    <line number="80"/>
  </code>
  <function name="blub" type="int" userfunc="1">
    <param name="x" type="int"/>
    <param name="z" type="string"/>
    <param name="y" type="int"/>
    <code>
      <line number="81">
        <call name="print">
          <param>
            <stringadd>
              <left>
                <stringadd>
                  <left>
                    <stringadd>
                      <left>
                        <stringadd>
                          <left>
                            <stringadd>
                              <left>
                                <string value="X: "/>
                              </left>
                              <right>
                                <cast from="int" to="string">
                                  <var name="x"/>
                                </cast>
                              </right>
                            </stringadd>
                          </left>
                          <right>
                            <string value=" Y: "/>
                          </right>
                        </stringadd>
                      </left>
                      <right>
                        <cast from="int" to="string">
                          <var name="y"/>
                        </cast>
                      </right>
                    </stringadd>
                  </left>
                  <right>
                    <string value="  "/>
                  </right>
                </stringadd>
              </left>
              <right>
                <var name="z"/>
              </right>
            </stringadd>
          </param>
        </call>
      </line>
    </code>
  </function>
  <function name="ohnenichts" type="int" userfunc="1">
    <code>
      <line number="77">
        <call name="print">
          <param>
            <string value="uuu"/>
          </param>
        </call>
      </line>
    </code>
  </function>
</CPB>

#include "clib/main.c"
int halloglobal=0;

void print( CPB_STRING text);

CPB_STRING chr( int value);

int asc( CPB_STRING text);

int instr( CPB_STRING text1,CPB_STRING text2,int start);

CPB_STRING mid( CPB_STRING text,int start,int anzahl);

CPB_STRING upper( CPB_STRING text);

CPB_STRING lower( CPB_STRING text);

CPB_STRING trim( CPB_STRING text);

CPB_STRING replace( CPB_STRING text,CPB_STRING suche,CPB_STRING ersetze,int position);

int ohnenichts();

int blub( int x,CPB_STRING z,int y);
int main() {
   print(int2string(asc(newstr("t"))));
   print(chr(112));
   print(int2string(instr(newstr("Hallo Welt"),newstr("Welt2"),0)));
   print(mid(newstr("Hallo Welt"),3,7));
   print(upper(newstr("hallo klein geschrieben")));
   print(lower(newstr("HALLO GRO GESCHRIEBEN")));
   print(joinstr(joinstr(newstr("-"),trim(newstr("Hallo Mit Trim      "))),newstr("-")));
   print(replace(newstr("Hallo in Welt"),newstr("in"),newstr("nicht"),0));
   print(int2string(-1*5));
   print(float2string(string2float(newstr("5.5"))));
   print(joinstr(newstr("Hallo"),int2string(2*5+4+5*8+10)));
   float floattest=0.0f;
   floattest=(float)(200);
   print(float2string(floattest));
   halloglobal=100;
   print(newstr("Zweite Zeile"));
   int hallo=0;
   hallo=40;
   hallo=100+5*10;
   hallo=(int)((float)(hallo)+100.000000);
   print(joinstr(newstr("Text: "),int2string(hallo)));
   if (10*10) {
      print(newstr("Hallo ist gleich 10"));
     
   } else {
      if (10) {
         if (1) {
            print(newstr("hallo"));
           
         } else {
            if (2) {
               print(newstr("Blub"));
               
            } else {
               print(newstr("Gaga"));

            }

         }
         print(newstr("In Elseif"));
         
      } else {
         print(newstr("Blub"));

      }

   }
   int tmp=0;
   tmp=1;
   while (tmp<10) {
      print(joinstr(newstr("In While - Wend "),int2string(tmp)));
      tmp=tmp+1;
   }
   do {
      print(newstr("In Repeat Until"));
      break;
   } while (!(1));
   switch (10) {
      case 5:
         print(newstr("Hallo"));
         break;
      case 7:
         print(newstr("blub"));
         break;
      default:
         print(newstr("in Default"));
   }
   int i=0;;
   for (i=0;i<10;i+=1) {
      print(joinstr(newstr("Zahl: "),int2string(i)));
   }
   blub(10,int2string(5),100);
   ohnenichts();
}
int blub( int x,CPB_STRING z,int y) {
   print(joinstr(joinstr(joinstr(joinstr(joinstr(newstr("X: "),int2string(x)),newstr(" Y: ")),int2string(y)),newstr("  ")),z));
}

int ohnenichts() {
   print(newstr("uuu"));
}


Tokenizetime: 2
Analysetime: 0
Parsetime: 12
Generatetime: 3
Total: 17

Willkommen im Mehr!

Freitag, 16. Juli 2010 von coolo
Waaas?!? Nach zwei Tagen ist dieser Worklog nun schon fast auf Seite 2? Das muss ich schnell ändern!

Gehen wir mal die Punkte ab welche hinzugekommen sind:
Arrow Vordefinierte Parameter in Funktionen: Dies war einfacher als gedacht zu lösen. Ursprünglich wollte ich dieses Feature per Funktions Überladung implementieren. Doch diese Methode hatte zwei schwerwiegende Probleme. Erstens waren Dinge wie MeineFunktion(,,,,,10) praktisch unmöglich, da man ja für jede erdenkliche Kombination eine Funktion hätte erstellen müssen. Außerdem wären Sprachen die dieses Feature nicht unterstützen (BlitzMax, Lua, ...) ausgeschlossen. Was natürlich nicht sehr gut ist.
Darum habe ich dem Analyser "beigebracht" die vordefinierten Parameter zu extrahieren. Doch hierbei ergibt sich ein Problem: Sobald der Parser begonnen hat zu Parsen kann dieser nicht weitere Tokens aufnehmen. Dieses Problem habe ich einfach gelöst: Intern wird einfach eine neue Instanz von TCompiler erstellt welche eben genau diesen vordefinierten Wert aufnimmt. Danach wird einfach der XML Node von Instanz A in Instanz B übernommen und alle sind glücklich \o/

Arrow Bugs Bugs und noch mehr Bugs: Puh, ich glaube diesmal habe ich um ie 50 Bugs entfernt. Von kleineren Fehlern wie doppelt deklarierte Variablen (Globals) bis hin zu den If's welche deren Geist völlig aufgegeben haben scheint nun alles glatt zu laufen. Der Rechenparser hatte auch Probleme, wenn mehrere gleichwertige Operatoren hintereinander geschrieben wurden (1+5+9+1).

Arrow Kleinere Änderungen: Das XML Format wurde etwas abgeändert sodass Else's immer ein neue "line" Element eröffnen, Sowie dass in "forvar" nun noch zwei Unterelemente sind ("declaration" einmal für die Declaration als solches und "var" der Name der Variable).

Arrow C Compiler: Der C Compiler kann bereits jeglichen Cross Platform Basic Code in (nicht korrekten) C Code umwandeln. Also Fallunterscheidungen, Schleifen usw. funktionieren bereits. Doch wieso ist der Code nicht korrekt? Naja die Strings wurden noch nicht richtig implementiert (sie werden im Moment noch wie in Java/C# gehandhabt) Das werde ich aber ändern indem ich eine eigene String Lib mir schreiben werde. Was mir außerdem sehr wichtig ist, ist dass der erzeugte Code so sauber wie möglich ist. Also schön eingerückt und so weiter. Da man diesen nachher vielleicht weiter verwenden will oder man einfacher Fehler finden kann.

Arrow Der C# Compiler von Jo0oker arbeitet auch schon wie am Schnürchen. Dieser kann bereits sogar mehr als die Sprache selber, nämlich Arrays. Nebenbei hat er Testweise auch die SPE darin verfügbar gemacht.

Arrow Wie gehts weiter? Als nächstes kommen die Arrays dran, diese werden von der Syntax her eine Mischung aus BB und BMax sein (Das XML Format ist noch NICHT final):
Code: [AUSKLAPPEN]
Local Array:Int[]
Dim Array[20]

Array[1]=100

Print Array[1]




<local>
   <arraydef name="Array" type="int" dim="1">
</local>

<set name="__array__">
   <name>
      <array name="Array">
         <dim>
            <int value="1">
         </dim>
      </array>
   </name>
   <value><int value="100"></value>
</set>

<call name="print">
   <param>
      <array name="Array">
         <dim>
            <int value="1">
         </dim>
      </array>
   </param>
</call>



Und nun noch ein Code der all die gezeigten Änderungen beinhaltet:
Code: [AUSKLAPPEN]
<?xml version="1.0"?>
<CPB version="0.1">
  <global>
    <defvar name="halloglobal" type="int"/>
  </global>
  <function name="print" type="void" userfunc="0">
    <param name="text" type="string"/>
  </function>
  <function name="blub" type="int" userfunc="1">
    <param name="x" type="int"/>
    <param name="y" type="int"/>
    <code>
      <line number="56">
        <call name="print">
          <param>
            <stringadd>
              <left>
                <stringadd>
                  <left>
                    <stringadd>
                      <left>
                        <string value="X: "/>
                      </left>
                      <right>
                        <cast from="int" to="string">
                          <var name="x"/>
                        </cast>
                      </right>
                    </stringadd>
                  </left>
                  <right>
                    <string value=" Y: "/>
                  </right>
                </stringadd>
              </left>
              <right>
                <cast from="int" to="string">
                  <var name="y"/>
                </cast>
              </right>
            </stringadd>
          </param>
        </call>
      </line>
    </code>
  </function>
  <code>
    <line number="0">
      <call name="print">
        <param>
          <cast from="int" to="string">
            <add>
              <left>
                <sub>
                  <left>
                    <int value="100"/>
                  </left>
                  <right>
                    <int value="8"/>
                  </right>
                </sub>
              </left>
              <right>
                <mul>
                  <left>
                    <int value="5"/>
                  </left>
                  <right>
                    <int value="6"/>
                  </right>
                </mul>
              </right>
            </add>
          </cast>
        </param>
      </call>
    </line>
    <line number="1">
      <call name="print">
        <param>
          <cast from="int" to="string">
            <sub>
              <left>
                <add>
                  <left>
                    <add>
                      <left>
                        <int value="100"/>
                      </left>
                      <right>
                        <int value="5"/>
                      </right>
                    </add>
                  </left>
                  <right>
                    <int value="10"/>
                  </right>
                </add>
              </left>
              <right>
                <int value="10"/>
              </right>
            </sub>
          </cast>
        </param>
      </call>
    </line>
    <line number="3">
      <call name="print">
        <param>
          <stringadd>
            <left>
              <string value="Hallo"/>
            </left>
            <right>
              <cast from="int" to="string">
                <add>
                  <left>
                    <mul>
                      <left>
                        <int value="2"/>
                      </left>
                      <right>
                        <add>
                          <left>
                            <int value="5"/>
                          </left>
                          <right>
                            <int value="4"/>
                          </right>
                        </add>
                      </right>
                    </mul>
                  </left>
                  <right>
                    <mul>
                      <left>
                        <int value="5"/>
                      </left>
                      <right>
                        <add>
                          <left>
                            <int value="8"/>
                          </left>
                          <right>
                            <int value="10"/>
                          </right>
                        </add>
                      </right>
                    </mul>
                  </right>
                </add>
              </cast>
            </right>
          </stringadd>
        </param>
      </call>
    </line>
    <line number="5"/>
    <line number="6">
      <set name="halloglobal">
        <int value="100"/>
      </set>
    </line>
    <line number="9">
      <local>
        <defvar name="hallo" type="int"/>
        <defvar name="blub" type="float"/>
      </local>
      <set name="hallo">
        <int value="40"/>
      </set>
      <set name="blub">
        <float value="20.3999996"/>
      </set>
    </line>
    <line number="10">
      <set name="hallo">
        <add>
          <left>
            <int value="100"/>
          </left>
          <right>
            <mul>
              <left>
                <int value="5"/>
              </left>
              <right>
                <int value="10"/>
              </right>
            </mul>
          </right>
        </add>
      </set>
    </line>
    <line number="11">
      <set name="hallo">
        <cast from="float" to="int">
          <add>
            <left>
              <cast from="int" to="float">
                <var name="hallo"/>
              </cast>
            </left>
            <right>
              <float value="100.000000"/>
            </right>
          </add>
        </cast>
      </set>
    </line>
    <line number="13">
      <call name="print">
        <param>
          <stringadd>
            <left>
              <string value="Text: "/>
            </left>
            <right>
              <cast from="int" to="string">
                <var name="hallo"/>
              </cast>
            </right>
          </stringadd>
        </param>
      </call>
    </line>
    <line number="16">
      <if>
        <condition>
          <mul>
            <left>
              <int value="10"/>
            </left>
            <right>
              <int value="10"/>
            </right>
          </mul>
        </condition>
        <line number="17">
          <call name="print">
            <param>
              <string value="Hallo ist gleich 10"/>
            </param>
          </call>
        </line>
        <line number="18">
          <else>
            <line number="18">
              <if>
                <condition>
                  <int value="10"/>
                </condition>
                <line number="19">
                  <if>
                    <condition>
                      <int value="1"/>
                    </condition>
                    <line number="20">
                      <call name="print">
                        <param>
                          <string value="hallo"/>
                        </param>
                      </call>
                    </line>
                    <line number="21">
                      <else>
                        <line number="21">
                          <if>
                            <condition>
                              <int value="2"/>
                            </condition>
                            <line number="22">
                              <call name="print">
                                <param>
                                  <string value="Blub"/>
                                </param>
                              </call>
                            </line>
                            <line number="24">
                              <else>
                                <line number="24">
                                  <call name="print">
                                    <param>
                                      <string value="Gaga"/>
                                    </param>
                                  </call>
                                </line>
                              </else>
                            </line>
                          </if>
                        </line>
                      </else>
                    </line>
                  </if>
                </line>
                <line number="26">
                  <call name="print">
                    <param>
                      <string value="In Elseif"/>
                    </param>
                  </call>
                </line>
                <line number="28">
                  <else>
                    <line number="28">
                      <call name="print">
                        <param>
                          <string value="Blub"/>
                        </param>
                      </call>
                    </line>
                  </else>
                </line>
              </if>
            </line>
          </else>
        </line>
      </if>
    </line>
    <line number="31">
      <while>
        <condition>
          <add>
            <left>
              <int value="10"/>
            </left>
            <right>
              <int value="2"/>
            </right>
          </add>
        </condition>
        <line number="32">
          <call name="print">
            <param>
              <string value="In While - Wend"/>
            </param>
          </call>
        </line>
      </while>
    </line>
    <line number="35">
      <repeat>
        <line number="36">
          <call name="print">
            <param>
              <string value="In Repeat Until"/>
            </param>
          </call>
        </line>
        <line number="37">
          <break/>
        </line>
        <condition>
          <sub>
            <left>
              <int value="5"/>
            </left>
            <right>
              <int value="2"/>
            </right>
          </sub>
        </condition>
      </repeat>
    </line>
    <line number="40">
      <select>
        <condition>
          <int value="10"/>
        </condition>
        <case>
          <condition>
            <int value="5"/>
          </condition>
          <line number="42">
            <call name="print">
              <param>
                <string value="Hallo"/>
              </param>
            </call>
          </line>
          <casebreak/>
        </case>
        <case>
          <condition>
            <int value="7"/>
          </condition>
          <line number="44">
            <call name="print">
              <param>
                <string value="blub"/>
              </param>
            </call>
          </line>
          <casebreak/>
        </case>
        <default>
          <line number="46">
            <call name="print">
              <param>
                <string value="in Default"/>
              </param>
            </call>
          </line>
        </default>
      </select>
    </line>
    <line number="49">
      <for>
        <forvar>
          <declaration>
            <local>
              <defvar name="i" type="int"/>
            </local>
          </declaration>
          <var>
            <var name="i"/>
          </var>
        </forvar>
        <start>
          <int value="0"/>
        </start>
        <to>
          <int value="10"/>
        </to>
        <step>
          <int value="1"/>
        </step>
        <line number="50">
          <call name="print">
            <param>
              <stringadd>
                <left>
                  <string value="Zahl: "/>
                </left>
                <right>
                  <cast from="int" to="string">
                    <var name="i"/>
                  </cast>
                </right>
              </stringadd>
            </param>
          </call>
        </line>
      </for>
    </line>
    <line number="53">
      <call name="blub">
        <param>
          <add>
            <left>
              <sub>
                <left>
                  <int value="100"/>
                </left>
                <right>
                  <int value="8"/>
                </right>
              </sub>
            </left>
            <right>
              <mul>
                <left>
                  <int value="5"/>
                </left>
                <right>
                  <int value="6"/>
                </right>
              </mul>
            </right>
          </add>
        </param>
        <param>
          <int value="10"/>
        </param>
      </call>
    </line>
    <line number="55"/>
  </code>
</CPB>

int halloglobal=0;
void print(string text);
int blub(int x,int y) {
   print("X: "+(string)(x)+" Y: "+(string)(y));
}
int main() {
   print((string)(100-8+5*6));
   print((string)(100+5+10-10));
   print("Hallo"+(string)(2*5+4+5*8+10));
   halloglobal=100;
   int hallo=0;float blub=0.0f;
   hallo=100+5*10;
   hallo=(int)((float)(hallo)+100.000000);
   print("Text: "+(string)(hallo));
   if (10*10) {
      print("Hallo ist gleich 10");
     
   } else {
      if (10) {
         if (1) {
            print("hallo");
           
         } else {
            if (2) {
               print("Blub");
               
            } else {
               print("Gaga");

            }

         }
         print("In Elseif");
         
      } else {
         print("Blub");

      }

   }
   while (10+2) {
      print("In While - Wend");
   }
   do {
      print("In Repeat Until");
   } while (!(5-2));
   switch (10) {
      case 5:
         print("Hallo");
      case 7:
         print("blub");
      default:
         print("in Default");
   }
   for (int i=0;i<10;i+=1) {
      print("Zahl: "+(string)(i));
   }
   blub(100-8+5*6,10);
}
Tokenizetime: 4
Analysetime: 0
Parsetime: 14
Generatetime: 5
Total: 23


Btw Jo0oker ist nun offiziell im Team

Gehe zu Seite 1, 2  Weiter