Die Sprache .ae
Programmieren auf Deutsch: Die eigene Sprache von AetherOS hat deutsche Befehle, einen eigenen Compiler und ist nah an der Hardware. Geschrieben wird mit ihr heute der eigene Kernel – der Teil von AetherOS, der nicht auf Linux aufsetzt, sondern mit einem selbst geschriebenen Startlader direkt auf dem Prozessor beginnt. Diese Seite zeigt beides ehrlich: was der Parser versteht und was die Übersetzer daraus wirklich machen.
02_Aerona_OS/03_Compiler.
So sieht .ae aus
Ein Ausschnitt aus test.ae, der 39 Zeilen langen Testdatei des Compilers – unverändert, auch die Kommentare mit ihrer Schreibweise. Auf wenigen Zeilen steckt fast alles darin, was .ae ausmacht: feste Werte, ein Zeiger auf den Bildschirmspeicher bei 0xB8000, eine Funktion mit drei Werten, eine Schleife und eine Zeile echter Maschinencode. Diese Datei übersetzt der frühe Weg nach C; der Kernel selbst ist in denselben Wörtern geschrieben.
// 1. Konstanten (Wichtig für Hardware-Register)
fest VGA_BUFFER = 0xB8000
fest OK_CODE = 1
// 2. Hardware Zeiger-Deklaration (Pointer auf Speicher-Adresse)
zeiger vga = VGA_BUFFER
funktion schreibe_zeichen(index, zeichen, farbe)
// 3. Zeiger-Zuweisung (Speichere Wert an Adresse vga + index)
vga[index * 2] = zeichen
vga[(index * 2) + 1] = farbe
ende
funktion init_system()
asm "cli" // Deaktiviere Interrupts - Nackter Assembly Code!
variabel i = 0
solange i < 10
schreibe_zeichen(i, 65, 15) // 'A' in Weiss
i = i + 1
ende
rueckgabe OK_CODE
endeDie Merkmale
Deutsche Befehle
funktion … ende,wenn … sonst … ende– jeder Block endet mitende, geschweifte Klammern gibt es nicht.solange,wiederhole … mal– die eine Schleife prüft eine Bedingung, die andere zählt.variabel,fest,zeiger,rueckgabe– nachrueckgabemuss immer ein Wert stehen, ein leeres Zurückkehren kennt der Parser nicht.und,oder– in Bedingungen übersetzt sie bisher nur der frühe C-Weg, nicht der für x86. Wer sicher gehen will, schachtelt zweiwenn.lade "datei.ae"bindet andere Dateien ein. So bleibt jede Kernel-Datei unter der 300-Zeilen-Grenze des Regelwerks.
Nah an der Hardware
- Speicher über Zeiger direkt ansprechen – ohne Betriebssystem darunter, das dazwischengehen könnte.
- Hardware-Ports lesen und schreiben, in 8 oder 16 Bit. So spricht der Kernel mit Tastatur, Maus, der Uhr im CMOS und dem Lautsprecher.
- Maschinencode direkt einbetten mit
asm. Der Befehl muss als Text in Anführungszeichen dahinter stehen. - Hexadezimale Zahlen wie
0xB8000. Eine Zahl beginnt immer mit einer Ziffer; danach darf sie x und die Buchstaben A bis F enthalten.
Ganz deutsch
- Namen dürfen Umlaute und ß enthalten, groß wie klein. Andere Sonderbuchstaben wie é kennt der Lexer nicht und bricht mit „Unbekanntes Zeichen“ ab.
- Kommentare beginnen mit // und reichen bis zum Zeilenende. Einen Kommentar über mehrere Zeilen gibt es nicht.
Alle Schlüsselwörter
Der Lexer kennt genau 22 Schlüsselwörter. und und oder zählt er nicht dazu: Er behandelt sie als Verknüpfungszeichen, gleichbedeutend mit && und || – beide Schreibweisen gehen also. Die Liste steht als eine einzige Zeile in lexer.js; wer ein Wort daraus als Namen für eine eigene Variable nimmt, bekommt vom Parser einen Fehler. Nachgezählt am 27. September 2026.
Aufbau
funktion, ende, rueckgabe, lade
Damit gliedert sich ein Programm in benannte Stücke. lade fällt aus der Reihe: Es wird vor dem Parser aufgelöst, nicht von ihm.
Werte
variabel, fest, zeiger
Alle drei verlangen sofort einen Anfangswert nach einem Gleichheitszeichen. Ein Name ohne Wert lässt sich nicht anlegen.
Ablauf
wenn, sonst, solange, wiederhole, mal
Fünf Wörter für Entscheidungen und Schleifen. Ein eigenes „sonst wenn“ gibt es nicht; man schachtelt ein zweites wenn in den sonst-Teil.
Hardware
speicher, asm, lese_port, lese_port16, schreibe_port, schreibe_port16
Sechs Wörter für das, was eine übliche Sprache hinter einer Bibliothek versteckt. speicher[adresse] liest oder schreibt eine Stelle im Arbeitsspeicher, die Port-Wörter sprechen Geräte an.
Bildschirm
text_setzen und zahl_setzen schreiben an eine Stelle des Textbildschirms. schreibe ist angelegt, erzeugt aber in keinem der Übersetzer Code. Der Parser nimmt es an; der frühe C-Weg schreibt an seine Stelle aber nur einen Kommentar mit dem Rat, text_setzen zu nehmen – ohne Betriebssystem darunter gibt es keine Konsole, in die man einfach schreiben könnte.
Reserviert
lese ist ein Schlüsselwort, das der Parser noch nicht verarbeitet. Steht es am Anfang einer Zeile, bricht er mit „Unerwarteter Befehl“ ab. Das Wort ist also vergeben, bevor es eine Aufgabe hat.
wiederhole … mal versteht der Parser. Übersetzt wird es bisher nur vom frühen C-Generator, nicht für x86 oder ARM64. Im Kernel steht es deshalb kein einziges Mal – dort zählt jede Schleife mit solange und einer eigenen Variable.
Der Compiler
x86
Übersetzt in ein rohes Startabbild aus Maschinencode – 64 KB für den eigenen Kernel. Einen fremden Assembler braucht dieser Weg nicht: Der Generator schreibt die Bytes für den Prozessor selbst. Das Abbild aether.img im Projekt ist genau 65.536 Bytes groß und trägt das Dateidatum 21. Juli 2026.
ARM64
Soll in Assembler für ARM-Prozessoren übersetzen. Heute kommt dabei nur ein Teil heraus: Der Generator erwartet Rechnungen unter einem anderen Namen, als der Parser sie liefert, und übersetzt sie deshalb nicht. Die letzte Ausgabe stammt vom 30. Juni 2026. Anders als beim x86-Weg entsteht hier Text, aether_arm64.s – zum fertigen Programm macht ihn erst ein fremder ARM64-Assembler, den das Projekt nicht mitbringt.
Irgendwann sich selbst
Geplant ist, dass ein Programm in .ae den Compiler eines Tages ersetzt. Umgesetzt ist das noch nicht. Die Datei, die diesen Plan beschreibt, 03_Compiler/bootstrap.js, ist ein Gerüst von 35 Zeilen: Ihr Lexer liefert eine leere Liste, ihr Generator immer dasselbe leere C-Programm. Der Ordner des Compilers enthält am 27. September 2026 18 JavaScript-Dateien mit zusammen 2.287 Zeilen, Prüfreihen eingerechnet; die längste hat 280.
Vom Quelltext zum Abbild
So entsteht aus den .ae-Dateien das Abbild des Kernels. Jeder Schritt ist eine eigene Datei in 02_Aerona_OS/03_Compiler, keine länger als 280 Zeilen – man kann jeden für sich lesen, ohne die anderen zu kennen:
- Zusammensetzen.
bau_nackt_os.jsersetzt jedelade-Anweisung durch den Inhalt der genannten Datei. Jede Datei kommt nur einmal hinein. Das geht über eine einfache Textsuche, bevor irgendetwas verstanden wird – deshalb darf eine Datei ruhig von mehreren Stellen geladen werden. - Zerlegen.
lexer.jsteilt den Text in fünf Arten von Bausteinen: Schlüsselwörter, Namen, Zahlen, Texte und Zeichen. Leerzeichen, Zeilenumbrüche und Kommentare fallen dabei weg; nur die Zeilennummer merkt er sich für Fehlermeldungen. - Ordnen. Der Parser – drei Dateien,
parser-base.js,parser-expr.jsundparser.js– baut daraus eine Baumstruktur des Programms. Darin steht zum Beispiel, dass eine Schleife eine Bedingung und einen Rumpf hat; welche Bytes daraus werden, weiß er noch nicht. - Übersetzen. Der x86-Generator macht daraus Maschinencode, verteilt auf fünf Dateien von
x86_generator.jsbisx86_helper.js. Mit der Angabe--target=arm64entsteht stattdessen ARM64-Assembler. Derselbe Baum lässt sich so für zwei Prozessoren übersetzen – wie weit das trägt, steht weiter unten. - Einspielen. Das Skript
bauen.batruft danachupdate_emulator_image.jsauf. Es schreibt das fertige Abbildaether.imgals Text von 87.384 Zeichen in den Emulator des Simulators. Das ist die Base64-Schreibweise der 65.536 Bytes; das Skript legt sie auch gleich in die gepackten Simulator-Ordner, damit der Simulator, den man startet, denselben Kernel hat. Vorsicht:bauen.batschreibt am Ende immer „FERTIG!“ – auch wenn das Übersetzen gescheitert ist; dann spielt es eben das alte Abbild ein.
Der eigene Startlader
Die ersten 512 Bytes des Abbilds schreibt der Compiler selbst. Dieser Startlader holt den Rest über das BIOS nach und springt dann in den Aerona-Code. Warum genau 512 Bytes und was am Ende stehen muss, erklärt Betriebssystem-Wissen.
Ein früher Weg nach C
Ein früher Generator übersetzt die Testdatei test.ae in C-Code. Er ist der einzige der drei Übersetzer, der und, oder und wiederhole kann. Für den Kernel wird er nicht benutzt: Aus C würde erst ein fremder Compiler ein startfähiges Abbild machen.
Erst zusammensetzen
Der Parser selbst kennt lade nicht. Deshalb muss der erste Schritt vor allen anderen laufen. Wer ihn überspringt, bekommt „Unerwarteter Befehl 'lade'“ – genau daran scheitert die Prüfreihe weiter unten.
Dieser Compiler ist NUR EIN WERKZEUG, geschrieben in Node.js.
02_Aerona_OS/03_Compiler/bootstrap.js – ein Gerüst für den späteren Selbstbau; der Weg, der heute das Abbild baut, beginnt bei bau_nackt_os.js
Was die Übersetzer wirklich können
Der Parser versteht mehr, als die Übersetzer daraus machen. Das ist der ehrlichste Satz über .ae: Ein Programm kann fehlerfrei durch Lexer und Parser gehen und trotzdem nicht das tun, was dasteht. Nachgelesen im Quelltext am 23. September 2026 – „ja“ heißt, der Übersetzer erzeugt dafür Code:
| Baustein | früher C-Weg | x86 | ARM64 |
|---|---|---|---|
| Rechnen mit + − × ÷ | ja | ja | nein |
ein Vergleich in wenn oder solange | ja | ja | nein |
Bedingungen mit und / oder | ja | nein – der Teil dahinter läuft immer | nein |
wiederhole … mal | ja | nein | nein |
text_setzen | ja | ja | nein |
zahl_setzen | nein | ja | nein |
schreibe | nein | nein | nein |
Die Lücke bei und und oder
Für x86 erzeugt der Übersetzer nur bei einem einzelnen Vergleich einen Sprung. In den 46 Modulen des Kernels verknüpfen 130 der 1.193 Bedingungen mit und oder oder. Am fertigen Abbild nachgezählt: Von den 54 Vergleichen mit der Zahl 1.024 stehen genau die 9 ohne Verknüpfung darin, die 45 mit Verknüpfung fehlen.
16 Bit
Jede Zahl ist im Kernel 16 Bit groß, also 0 bis 65.535. Verglichen wird mit Vorzeichen. Variablen und Parameter liegen an festen Adressen ab 0x0500, je zwei Bytes, nicht auf einem Stapel. Das ist einfach zu übersetzen, hat aber eine Folge: Eine Funktion, die sich selbst aufruft, überschreibt ihre eigenen Werte.
Stille bei Unbekanntem
Ruft ein Programm eine Funktion, die es nicht gibt, meldet der Übersetzer keinen Fehler. Als Anweisung entsteht nichts, in einer Rechnung steht dort 0. Ein Tippfehler im Namen fällt also nicht beim Bauen auf, sondern erst, wenn der Kernel sich anders verhält als gedacht.
Maschinencode mit asm
Rund 80 Befehle kennt der Übersetzer beim Namen, von cli bis syscall, dazu Muster für mov, call und xchg. Alles andere liest er als Folge von Bytes. Dafür müssen es Zahlen sein, durch Kommas getrennt; ein unbekanntes Wort fällt ohne Warnung einfach weg.
Schutzgitter im Übersetzer
Der x86-Generator baut kleine Prüfungen direkt in den Maschinencode ein. Geprüft wird also beim Laufen, nicht beim Bauen – der Übersetzer kann eine Adresse vorher meist nicht kennen, weil sie erst aus einer Rechnung entsteht. Ohne Betriebssystem darunter fängt sonst niemand einen falschen Schreibzugriff ab:
Interrupt-Tabelle
Über einen Zeiger lässt sich nichts unterhalb der Adresse 1024 schreiben. Dort liegt die Tabelle, über die der Prozessor Unterbrechungen abwickelt. Im 16-Bit-Modus hat sie 256 Einträge zu je vier Bytes. Wird dort ein Eintrag überschrieben, springt der Prozessor bei der nächsten passenden Unterbrechung ins Leere.
Bildschirmspeicher
Schreibzugriffe mit speicher[…] ab Adresse 4000 werden verworfen. Der Textbildschirm belegt genau 4000 Bytes: 80 × 25 Zeichen mit je zwei Bytes. Die Grenze ist also so gezogen, dass der ganze Bildschirm beschreibbar bleibt und kein Byte mehr.
Textposition
Liegt die Stelle für text_setzen oder zahl_setzen außerhalb von 80 × 25 Zeichen, wird nichts geschrieben. Es gibt dann keine Meldung – der Text fehlt einfach. Gezählt wird ab 0, die letzte gültige Stelle ist Spalte 79, Zeile 24.
Der Kernel Aerona Aether OS
62 Dateien Code in .ae mit 9.735 Zeilen übernehmen, was sonst eine Standardbibliothek täte: Zeichenketten, Speicherverwaltung, Prozesse und Planung, Dateisysteme, eine Shell, Bildschirm und Tastatur. Sogar ein Lader für Windows-Programme ist angelegt, zurzeit aber abgeschaltet. Zwei weitere .ae-Dateien sind keine Programme, sondern Planungstexte: kernel_gui_installer.ae und kernel_spiel.ae mit je 65 Zeilen. Am 27. September 2026 nachgezählt – die Zahlen gelten unverändert, zusammen 64 Dateien mit 9.865 Zeilen.
- 46 Module sind eingebunden, 14 vorhandene sind abgeschaltet. Weitere 82 stehen nur als Name in der Startdatei – Dateien dazu gibt es nicht. Die Startdatei ist damit zugleich Plan und Bauliste: Man sieht, was kommen soll, und daneben, was es schon gibt.
- Manche Funktionen sind Platzhalter: Es gibt sie dem Namen nach, sodass andere Module sie schon aufrufen können, aber sie tun noch nicht, was der Name verspricht. Welche Teile des Kernels schon arbeiten, steht auf der Seite Der eigene Kernel.
- Die Prüfreihe
test_x86_compiler.jsbricht zurzeit ab: Sie liest 19 Kernel-Module als reinen Text, ohne ihrelade-Anweisungen aufzulösen – und in einem davon steht eine. Am 27. September 2026 erneut laufen lassen: Die Ausgabe endet weiter mit „Unerwarteter Befehl 'lade' in Zeile 1723“. Das steht seit mindestens 13. September offen in02_Aerona_OS/LIESMICH.md.
Die Shell
Ihr Hilfetext nennt zwölf Befehle: help, ls, format, neu, lese, schreibe, kopiere, loesche, umbenennen, free, reboot und winrun. Die Namen mischen Deutsch und Englisch, so wie sie im Quelltext stehen. winrun steht noch in der Liste, führt aber ins Leere: Weil der Lader für Windows-Programme abgeschaltet ist, landet der Befehl in einem Platzhalter aus kernel_dummys_2.ae, der sofort 0 zurückgibt.
Der Bildschirm
Ein Textbildschirm mit 80 Spalten, 25 Zeilen und 16 Farben. Die unterste Zeile ist eine Leiste mit „[ START ]“ und einer Uhr. Einen Grafikmodus mit einzelnen Bildpunkten schaltet der eigene Kernel nicht ein; die Fenster, die man aus dem Simulator kennt, gehören zur Oberfläche auf Linux, nicht zu ihm.
Die Startdatei
echter_boot.ae bindet 43 Dateien direkt ein, drei weitere kommen über andere Module dazu. Die Datei selbst hat 185 Zeilen. Das Abbild ist genau 64 KB groß. Ein Kommentar nennt diese Grenze als Grund fürs Abschalten – er steht allerdings über 18 Namen, zu denen es keine Dateien gibt.






