FireBasic

Kommentare anzeigen Worklog abonnieren
Gehe zu Seite Zurück  1, 2

Worklogs FireBasic

Viele kleine Biester und anderes...

Dienstag, 10. März 2009 von flona
Da die Schule ja nun wieder begonnen hat, ist die Zeit wieder knapper bemessen, aber ich habe trotzdem mal wieder ein paar Stunden gefunden um mich an FireBasic hinzusetzen und weiterzumachen.

Im Moment schraube ich an einem kleinen Programm für einen Freund, das die Nutzungsdauer für bestimmte Programme einschränkt und/oder dieses mit einem Passwort versieht. Dieses möchte ich komplett in FireBaisc umsetzen, wobei ich dann natürlich auf viele kleine Bug's gestoßen bin. Diese konnten aber bisher fast alle durch ein zwei Zeilen Code beseitigt werden, alle bis auf einen:

Er trat z.B bei Konstruktionen wie folgender auf: Code: [AUSKLAPPEN]
ArrayFunc(1,2)[3].fieldtest.method()

Er wäre zwar auch durch relativ kleine Umwandlungen zu beheben gewesen, aber ich habe schon längere Zeit die Variablenverarbeitung mit einem leicht kritischen Auge beobachtet und dachte, dass es mal an der Zeit sei es komplett zu überarbeiten bzw. es neu zu schreiben ... und á vola .. Mehr Funktionalität in weniger als halb soviel Code wie zuvor Very Happy (vorher: 400 Zeilen/nachher: 150 Zeilen).

Außerdem(ich vergaß es im ersten Post zu erwähnen Embarassed ) habe ich die Optimierung, die den generierten Quellcode optimiert, neugeschrieben und sie ebenfalls ein klein wenig erweitert. Die Optimierung beruht auf Textersetzungen und funktioniert wie folgt: Es gibt eine einfache Datei die Definitionen enthält:
Code: [AUSKLAPPEN]
<optimize>
<code>
      mov eax,*1
      mov dword [*2],eax
</code>
<generate>
      mov dword [*2],*1
</generate>
</optimize>


Die Optimierung wandelt dann z.B:
Code: [AUSKLAPPEN]
mov eax,5
mov dword [ebp-4],eax

in
Code: [AUSKLAPPEN]
mov dword [ebp-4],5

um. Nun können auch mehrere Platzhalter im -Teil in einer Zeile verwendet werden.

Bis bald Wink

Erweiterungen...

Sonntag, 1. März 2009 von flona
Gestern und heute kamen wieder drei neue Dinge dazu:
Arrow Arrays
Funktionieren ähnlich wie in BMax, werden allerdings noch nicht als Objekte behandelt:
Code: [AUSKLAPPEN]
arr[]=[3,4,6,9]
arr[0]=1

For i=0 To 3
    Notify arr[i]
Next


Arrow TRebar
Die Rebar kennt ihr bestimmt alle aus Word & Co.. Sie besteht aus mehreren 'Bands' die jeweils einen Text und ein Child-Window(Gadget) enthalten können. Die Bands können vom Benutzer in Größe und Position geändert werden. Hier ein Beispiel:
Code: [AUSKLAPPEN]
win:TWindow=CreateWindow("Window1",50,50,300,300,Desktop())
win.onClose(*End)

rebar:TRebar=CreateRebar(win)
combo:TComboBox=CreateComboBox(50,50,100,20,win)
combo.AddItem("Blubb")
rebar.AddBand("TComboBox",combo)
prog:TProgressBar=CreateProgressBar(0,0,80,20,win)
rebar.AddBand("",prog)
prog.SetPos(60)

Und der zugehörige Screen:
user posted image

Arrow Bisher wurden immer alle verfügbaren Befehle von FireBasic in die ASM-Datei miteingebunden. Jetzt werden nur noch die Benutzten hinzugefügt.

Events, Events, ...

Freitag, 27. Februar 2009 von flona
Heute habe ich das Eventsystem neugeschrieben und erweitert. Am besten zuerst ein Beispiel dann der Hintergrund:
Code: [AUSKLAPPEN]
win:TWindow=CreateWindow("Window1",50,50,300,300,Desktop())
win.onClose(*End)
win.onMove(*Notify,"Moved")

win2:TWindow=CreateWindow("Window2",350,50,300,300,Desktop(),TWindow.Titlebar+TWindow.Sizeable)
win2.onClose(*End)
win2.onMove(*Notify,"Moved")
win2.onSize(*PSize,"bla")

Function PSize(Msg$,hwnd:TWindow)
    hwnd.SetShape(350,50,400,400)
    Notify Msg$
EndFunction

Wie man oben sieht kann man nun Parameter hinter den Funktionspointern angeben. Außerdem wird automatisch das Handle des Fensters als letzter Parameter übergeben.
Ob die Parameter verarbeitet werden oder nicht ist die Entscheidung des Programmierers. Folgende modifizierte Funktion würde auch ohne Probleme funktionieren:
Code: [AUSKLAPPEN]
Function PSize()
    Notify "bubb"
EndFunction


So das wars aber auch schon wieder

TTimer und Zufall

Dienstag, 24. Februar 2009 von flona
So, die letzten Tage war ich ein wenig von meinem zweiten Hobby(Klettern) abgelenkt, aber heute habe ich mal wieder Zeit gefunden um folgendes einzubauen:
Arrow Die Klasse TTimer
Code: [AUSKLAPPEN]
Type TTimer
    Field Handle:INT
    Method SetTimeOut(TimeOut:INT)
    Method onTick(Proc)
    Method Free()
End Type

Arrow Funktionen zur Zufallszahlengenerierung: SeedRnd, Rand. Die Funktion Rand benutzt diesen Algorithmus.



Bis bald ...

Bug behoben

Samstag, 21. Februar 2009 von flona
So, nach einigen Tagen Untätigkeit hab ich mich heute mal hingesetzt und einen schwerwiegenden Bug gesucht, gefunden und behoben Very Happy . Wenn man nämlich mehrere Elemente zu einer TList hinzufügte stürzte das Programm einfach ab.

Dann noch ein kleines Code Beispiel wie TList benutzt wird, was allerdings nichts neues sein sollte.

Code: [AUSKLAPPEN]
Type TTest
    Field Number:INT
EndType

list:TList=New TList
For i=1 To 10
   test:TTest=New TTest
   test.Number=i
   list.Add(test)
Next

Notify "Number of elements in list: "+list.Count

For test=EachIn list
    Notify test.Number
Next
End


Einen GC habe ich noch nicht eingebaut.

Mehr habe ich im Moment nicht zu berichten

Ein paar kleine Änderungen

Montag, 16. Februar 2009 von flona
So, hab mich heute mal wieder ein bisschen hingesetzt und ein bisschen weitergemacht.

Wichtigsten Änderungen:
Arrow Das Grundgerüst der IDE steht jetzt (Danke an dieser Stelle an coolo)
Arrow Ich habe peacemakers Vorschlag umgesetzt und die Linked Lists rausgeworfen und stattdessen TList hinzugefügt

Zu mehr bin ich heute leider nicht gekommen, danke an dieser Stelle ans G8 und den Nachmittagsunterricht Wink .
Werde die nächsten Tage mal einen Screen von der IDE hochladen. Heute bin ich einfach zu müde Wink .

In diesem Sinne bis bald

Wie's bis jetzt aussieht

Sonntag, 15. Februar 2009 von flona
So ich glaube es ist an der Zeit, dass ich mein Projekt hier auch mal reinstelle. Smile

Es handelt sich um einen Compiler ... die meisten denken wahrscheinlich jetzt an die zahlreichen Skriptsprachen und Compiler, die hier in den Worklogs schlummern.

Also nochmal genauer: Die Sprache heißt FireBasic und ist an die Syntax von BlitzMax angelehnt. Sie beherrscht Ansätze von OOP und ist auf die Entwicklung von Anwendungen mit GUI auf Windows ausgerichtet.

Den Compiler schreibe ich in B+. Dieser erstellt aus dem Sourcecode ASM-Dateien, die wiederum mit dem FlatAssembler assembliert werden und ... tada ... eine EXE. Für diejenigen, die es interessiert, habe ich unten zum Ablauf noch Einzelheiten.

Hier ein kleines Beispiel, das den Aufbau und die Syntax zeigen soll:
Code: [AUSKLAPPEN]
Global statusbar:TStatusBar

win:TWindow=CreateWindow("Window",50,50,300,300,Desktop())
win.onClose(*End)

label:TLabel=CreateLabel("Label:",10,5,100,15,win)

edit:TEdit=CreateEdit(10,25,150,20,win)
edit.SetText("Edit Control")
edit.onChange(*ProcessChange)

progbar:TProgressBar=CreateProgressBar(170,25,100,20,win)
progbar.SetPos(60)

combo:TComboBox=CreateComboBox(170,55,100,20,win,TComboBox.DropDownList)
combo.AddItem("Test")
combo.AddItem("Hallo")
combo.SelectItem 0

but:TButton=CreateButton("3-State-Button",170,85,100,20,win,TButton.ThreeState)
but.SetState TButton.Indeterminate

treeview:TTreeView=CreateTreeView(10,55,150,150,win)
node1=treeview.InsertItem("Node 1")
  treeview.InsertItem("Test",node1)
  treeview.InsertItem("Text",node1)
node2=treeview.InsertItem("Node 2")
  treeview.InsertItem("Hy",node2)

statusbar=CreateStatusBar("Status Bar",win)

Function ProcessChange()
    statusbar.SetText("Status Bar   |   Edit changed: "+(Millisecs()/1000))
EndFunction


Erzeugt wird eine 8KB große exe-Datei, die sich wie folgt dem Benutzer präsentiert:
user posted image




Features
Arrow Viele Schleifentypen
- Repeat..Until
- Repeat..Forever
- While..Wend
- Loop..EndLoop
- For..Next
- ForEach..Next
Arrow If und Select
Arrow INT, STRING und FLOAT
Arrow Kann alle Typen untereinander convertieren
Arrow Dll Im-/Export
Arrow Teilweise OOP:
- Field natürlich
- Vererbung
- Methoden
- Konstruktor/Destruktor
- Type Konstanten
- Automatische Linked List(in Verb. mit ForEach)
Arrow GUI Befehle
- Alles OOP
- Viele Klassen(TWindow, TButton, TEdit, TRichEdit, TGroupBox, TListView, TTabber, TProgressBar, TTreeView, TComboBox, TLabel, TStatusBar)

ToDo
Arrow OOP
- statische Globale
- statische Funktionen
- Abstraktion
- Final
Arrow GUI
- mehr Methoden
- mehr Events
- mehr Gadgets
Arrow Funktionen für den Bereich TCP
Arrow IDE
Arrow Arrays

Ablauf des Kompilierens
Ich demonstriere das ganze mal an einem Beispiel:
Code: [AUSKLAPPEN]
win:TWindow=CreateWindow("Window",50,50,600,500,Desktop())
win.onClose(*End)


Der Code wird jetzt in mehreren Durchgängen eingelesen, bearbeitet und schließlich wird daraus Assemblercode erstellt.
Im ersten Durchgang wird der Sourcecode eingelesen und geteilt(=Token). Dieser Vorgang wird auch scannen genannt:
Code: [AUSKLAPPEN]
+---------------------+---------------------+
|        Token        |         Typ         |
+---------------------+---------------------+
| WIN                 | Identifier          |
+---------------------+---------------------+
| :                   | Operator            |
+---------------------+---------------------+
| TWINDOW             | Identifier          |
+---------------------+---------------------+
| =                   | Operator            |
+---------------------+---------------------+
| CREATEWINDOW        | Identifier          |
+---------------------+---------------------+
| (                   | Operator            |
+---------------------+---------------------+
| Window              | String              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| 50                  | Number              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| 50                  | Number              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| 600                 | Number              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| 500                 | Number              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| DESKTOP             | Identifier          |
+---------------------+---------------------+
| (                   | Operator            |
+---------------------+---------------------+
| )                   | Operator            |
+---------------------+---------------------+
| )                   | Operator            |
+---------------------+---------------------+
|                     | New Line            |
+---------------------+---------------------+
| WIN                 | Identifier          |
+---------------------+---------------------+
| .                   | Operator            |
+---------------------+---------------------+
| ONCLOSE             | Identifier          |
+---------------------+---------------------+
| (                   | Operator            |
+---------------------+---------------------+
| *                   | Operator            |
+---------------------+---------------------+
| END                 | Identifier          |
+---------------------+---------------------+
| )                   | Operator            |
+---------------------+---------------------+


Im zweiten Durchgang, dem Parser, verhält sich mein Compiler ein wenig anders als üblich. Aus dem Sourcecode wird hier nämlich kein Tree erstellt, sondern er wird nach Funktionen durchsucht, wobei jeder Token einer Funktion zugeordent wird. Die Token, die nicht in einer Funktion stehen werden automatisch in die Hauptfunktion eingefügt. Außerdem werden die Variablen und Strings verarbeitet:
Code: [AUSKLAPPEN]
+---------------------+---------------------+
|        Token        |         Typ         |
+---------------------+---------------------+
| WIN                 | TWINDOW Variable    |
+---------------------+---------------------+
| =                   | Operator            |
+---------------------+---------------------+
| CREATEWINDOW        | Default FunktionTyp |
+---------------------+---------------------+
| (                   | Operator            |
+---------------------+---------------------+
| String1             | STRING Variable     |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| 50                  | Number              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| 50                  | Number              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| 600                 | Number              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| 500                 | Number              |
+---------------------+---------------------+
| ,                   | Operator            |
+---------------------+---------------------+
| DESKTOP             | Default FunktionTyp |
+---------------------+---------------------+
| (                   | Operator            |
+---------------------+---------------------+
| )                   | Operator            |
+---------------------+---------------------+
| )                   | Operator            |
+---------------------+---------------------+
|                     | New Line            |
+---------------------+---------------------+
| WIN                 | TWINDOW Variable    |
+---------------------+---------------------+
| .                   | Operator            |
+---------------------+---------------------+
| ONCLOSE             | Default FunktionTyp |
+---------------------+---------------------+
| (                   | Operator            |
+---------------------+---------------------+
| *                   | Operator            |
+---------------------+---------------------+
| END                 | Default FunktionTyp |
+---------------------+---------------------+
| )                   | Operator            |
+---------------------+---------------------+


Im dritten Durchgang, dem Generator, wird dann, oh Wunder, ASM-Code erstellt. Ich zeige hier mal die Hauptfunktion:
Code: [AUSKLAPPEN]
   WinMain:
      push ebp
      mov ebp,esp
      sub esp,4+28
      mov dword [esp],String1
      mov dword [esp+4],50
      mov dword [esp+8],50
      mov dword [esp+12],600
      mov dword [esp+16],500
      call FB_TWINDOW_Desktop
      mov dword [esp+20],eax
      mov dword [esp+24],1
      call FB_CreateWindow
      mov dword [ebp-4],eax
      sub esp,8
      mov ecx,[ebp-4]
      call Test_Obj_Null
      mov dword [esp],ecx
      mov dword [esp+4],FB_End
      call FB_TWINDOW_onClose
      mov esp,ebp
      pop ebp
      ret


So merke gerade, dass der Eintrag ein bisschen lang geworden ist Wink .

Einen Download gibts dann mal wenn es wirklich was zu testen gibt.

Wenn ihr Fragen habt, fragt Very Happy . (Kommentare oder PN)

Gehe zu Seite Zurück  1, 2