Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

1

04.07.2014, 00:27

[Alpha] Eine kleine Programmiersprache

Ist ja gerade so Mode, da dachte ich mir, ich präsentiere meine kleine Sprache auch mal. Sie nennt sich Alpha, beschränkt sich bisweilen auf nur einen Datentypen und kann bisher Variablen halten, Terme berechnen (bis auf Div/Mod Operatoren) und etwas ausgeben.
Nachdem sich meine BA auf Transcompiler beschränkte, wollte ich, wie wahrscheinlich viele hier, auch endlich mal eine "wirkliche" Sprache verfassen. Angefangen habe ich dabei mit dem schönen Tutorial hier: http://magazin.c-plusplus.de/artikel/Compilerbau
Allerdings ist es IMO schon etwas in die Jahre gekommen und schon etwas quick and dirty. Aber das kann man ja niemanden verübeln, ist ja auch ein riesen Thema.
Ich habe jedenfalls darauf aufgebaut und es kam mein Repo 'Compiler' (https://github.com/Dgame/Compiler) dabei heraus. Das war erstmal ein fixer Versuch, das ganze gelernte besser umzusetzen. Allerdings hab' ich dann doch schnell gemerkt, dass meine Planung nicht ausreichend war und ich immer wieder auf Hindernisse stieß. Also habe ich schließlich aufgehört und nun nochmal von vorne begonnen, mit einem hoffentlich besser durchdachten Aufbau. Herausgekommen ist dabei jedenfalls Alpha: https://github.com/Dgame/Alpha

Mein Ziel ist es, genau wie in dem obigen Tutorial, eine mehr oder minder vollständig funktionierende und zu gebrauchende Sprache zu entwickeln und dann daraus ein paar Schritt für Schritt Tutorials zu machen und auf meinem Blog zu posten. Es gibt sicher noch andere, die auch den Traum haben, mal eine eigene Sprache gemacht zu haben und vllt. hilft denen das ja weiter. :)

Die Sprache selbst wird in Assembler übersetzt (genauer gesagt GAS) und unterstützt theoretisch 16, 32 und 64 Bit Systeme, wobei bisher nur 32 Bit getestet wurden.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

idontknow

unregistriert

2

04.07.2014, 00:30

Oha direkte Übersetzung in Assembler (oder was genau ist GAS?). Kannst das mal bisschen ausführen (wieso, weshalb warum). Kingt ja doch etwas nach einer waghalsigen Aktion! Ansonsten coole Sache, dass du vorhast ein Tutorial daraus zu machen :)

Ahja habe kein Beispielcode gefunden in dem Repo, also wie schaut die Sprache aus? (Snippet!)

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

3

04.07.2014, 00:38

Genau, GAS ist GNU Assembler. Damit wurde in dem Compilerbau-Tutorial ebenfalls gearbeitet, also hatte ich dort die meisten aktuellen Kenntnisse. :)
Snippets kannst du dir in der main ansehen, die sind momentan einfach noch fest verdrahtet für einen kompletten Testdurchlauf, was sich mit dem nächsten Commit aber ändern wird:
https://github.com/Dgame/Alpha/blob/master/main.cpp
Der Output jeder dieser Einträge findest du im Output Ordner: https://github.com/Dgame/Alpha/tree/master/Output
Und sofern es dich interessiert, hier ist die äußerst schlanke Runtime: https://github.com/Dgame/Alpha/blob/master/rt.c :D

Das mit dem Tutorial rührt daher, dass ich selbst echt viel gesucht habe, aber kaum etwas gefunden habe, das wirklich gut ist. Sogar das Beispiel welches im Drachenbuch entwickelt wird, ist dagegen nicht so prall.
Also warum nicht diese Lücke schließen. :)

edit:
Als kleine Snippet Zusammenfassung:

Zitat

var a = 42
print a
print 23
print 1 + 2 * 3


Pro Zeile also ein Befehl sozusagen und kein Comma Operator. :D
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

idontknow

unregistriert

4

04.07.2014, 00:39

Ahh das Test-Array sind einzelne Programme :p. Ich habe selber nicht genau drauf geschaut, aber macht jetzt Sinn :D

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

5

04.07.2014, 01:02

So, nun sind die Testdateien extern und werden geladen. Snippets/Testdateien sind jetzt unter dem Ordner 'Input' zu finden.
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

6

04.07.2014, 10:07

Sollten wir uns langsam alle auf eine Syntax einigen damit alles kompatibel ist? :D

Aber schon cool mit der Übersetzung zu Assembler.
Hab mir mal den Code angesehen und vieles kommt mir z.B. im Parser auch bekannt vor. Mal sehen ob ich dann für mich ein paar Ideen mitnehme (sicherlich).

Mal sehen wer als nächstes eine Sprache anfängt :P

LukasBanana

Alter Hase

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

7

04.07.2014, 10:23

Gefällt mir gut, vor Allem die Assembler Ausgabe sieht schon gar nicht schlecht aus :thumbup:

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

8

04.07.2014, 12:52

Und die ersten Probleme rollen an. :)
Ich implementiere gerade die Div und Modulo Operationen (sind ja beides nahezu identische Abläufe) allerdings habe ich ein kleines Problem: Division ist ja genau wie Subtraktion nicht assoziativ, also müssen die Operanden in der umgedrehten Reihenfolge hinein. Hat jemand eine Idee, wie sich das am schönsten bewerkstelligen lässt oder wie man das direkt in Assembler umsetzt?
Für print 4 / 2 sieht mein Code bisher so aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.text
.globl _prog
_prog:

pushl   %ebp
movl    %esp, %ebp
movl    $4, %eax
pushl   %eax
movl    $2, %eax
movl    $0, %edx
movl    %eax, %ebx
idiv    %ebx
popl    %eax
pushl   %eax
call    _println_int
addl    $4, %esp
popl    %ebp
ret


Aber es müssten natürlich zuerst die 2 und dann die 4 kommen. Theoretisch müsste ich also jeden Term einmal darauf untersuchen, und wenn ein Op::Div darin vorkommt, müsste ich die vorherigen beiden Operanden vertauschen. Eine nicht gerade schöne Lösung, da ich dann jeden Term zweimal anfassen/durchlaufen muss.
Für Subtraktion war das Problem durch die Umdrehung der Operanden lösbar, aber das scheint wohl nicht der Fall zu sein für Division.

Zur Vollständigkeit: Der obige Term wird in folgender Form/Reihenfolge gespeichert: 4 2 /
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

9

04.07.2014, 13:46

Ok, gelöst durch eine kleine Umstellung:
Wenn der übernächste Parameter ein Op::Div oder Op::Mod ist, dann wird nichts gepusht und der nächste Wert nicht im AX Register, sondern in BX Register gespeichert. Der Div/Mod Operator muss demnach auch das Register AX nicht mehr in das Register BX moven. Nun klappt es und sieht folgendermaßen aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.text
.globl _prog
_prog:

pushl   %ebp
movl    %esp, %ebp
movl    $4, %eax
movl    $2, %ebx
movl    $0, %edx
idiv    %ebx
pushl   %eax
call    _println_int
addl    $4, %esp
popl    %ebp
ret
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Architekt

Community-Fossil

  • »Architekt« ist der Autor dieses Themas

Beiträge: 2 481

Wohnort: Hamburg

Beruf: Student

  • Private Nachricht senden

10

04.07.2014, 17:23

Noch ein kleines Update: Habe die Print Ausgabe ein wenig optimiert. Vorher wurden auch einzelne Ergebnisse, wie z.B. bei print 42 oder print a, erstmal ins AX Register gemoved und dann dieses Register gepusht. Besteht der Term jedoch nur aus einem Element, kann er direkt gepusht werden. Das geschieht jetzt auch.

Zum Vergleich:
Vorher:

Quellcode

1
2
movl    $42, %eax
pushl   %eax

Nachher (jetzt):

Quellcode

1
pushl   $42
Der einfachste Weg eine Kopie zu entfernen ist sie zu löschen.
- Stephan Schmidt -

Werbeanzeige