Workspace mit sechs Crates (tb-frontend, tb-vm, tb-runtime, tb-ui, tb-cli, tb-ide) als Geruest fuer die Re-Implementierung des DOS-BASIC-Dialekts. Binaries: tbdos (IDE/TUI) und tbdosc (Standalone-Compiler). PLAN.md dokumentiert Phasen, Explorations- schritte und die Abwaegung der VM-/Runtime-Optionen (Entscheidung: eigene Bytecode-VM, TBVM). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
10 KiB
PLAN — Terminal Basic
Arbeitsplan für die Re-Implementierung des DOS-BASIC-Dialekts (1992) in Rust. Dieses Dokument wird fortgeschrieben: erledigte Punkte werden abgehakt, Entscheidungen mit Datum und Begründung festgehalten.
Konvention: [ ] offen · [x] erledigt · [~] in Arbeit
Leitplanken
- Referenzverhalten schlägt Eleganz. Bei Zweifeln zählt das beobachtbare Verhalten des Vorbilds (inkl. Fehlercodes, Rundung, Formatierung), nicht das, was „richtiger" wäre. Abweichungen werden dokumentiert.
- Markenrecht: Der Name des Vorbilds wird in Code, Doku und Artefakten nicht verwendet. Wir sprechen vom „Vorbild" bzw. „dem Dialekt".
- Jede Phase endet mit lauffähigen Tests gegen eine wachsende
Kompatibilitäts-Testsuite (Verzeichnis
tests/compat, geplant).
Phase 0 — Exploration und Grundsatzentscheidungen
0.1 Sprach- und Bibliotheksreferenz rekonstruieren
- Sprachreferenz zusammentragen: Anweisungen, Funktionen, Operatoren,
Typsystem (INTEGER, LONG, SINGLE, DOUBLE, STRING, CURRENCY,
feste Strings,
TYPE…END TYPE), Typ-Suffixe (% & ! # $ @),DEFINT-Familie, Sichtbarkeitsregeln (SHARED,COMMON,STATIC) - Forms-/Steuerelemente-Referenz: Steuerelementtypen, Eigenschaften, Methoden, Ereignisse, Standardwerte, Fokus- und Z-Reihenfolge
- Dateiformate dokumentieren: Quelltext (
.BAS), Formulare (.FRM, Textformat mitVERSION/Begin…End-Blöcken), Projekt (.MAK) - Laufzeitfehler-Katalog (Codes + Meldungstexte) erfassen
- Testkorpus aufbauen: kleine Referenzprogramme, deren erwartete Ausgabe dokumentiert ist (Grundlage der Kompatibilitäts-Testsuite)
0.2 VM-/Runtime-Entscheidung (Aufstellung der Optionen)
Anforderungen an die Ausführungsschicht: BASIC-Fehlersemantik
(ON ERROR GOTO/RESUME mit ERR/ERL), GOSUB/RETURN,
unterbrechbare Ausführung (Debugger-Einzelschritt, Strg+Untbr,
ereignisgesteuerte Forms-Hauptschleife), dynamische Strings/Arrays mit
BASIC-Semantik, serialisierbares Kompilat, gute Fehlerortung (Zeile/Spalte).
| Option | Vorteile | Nachteile | Eignung |
|---|---|---|---|
| 1. Eigene Bytecode-VM in Rust („TBVM") | Volle Kontrolle über Semantik (Fehlerbehandlung, GOSUB, Events, Suspend/Resume); Bytecode als .tbc serialisierbar; Debugger-Integration trivial (Zeileninfo im Bytecode); keine Fremdabhängigkeit |
Eigenaufwand für VM, GC/Refcounting für Strings/Arrays; „nur" Interpreter-Geschwindigkeit | Empfohlen — Interpreter-Tempo genügt für 80×25-Programme bei Weitem |
| 2. Tree-Walking-Interpreter | Schnellster Weg zu ersten laufenden Programmen; ideal zum Validieren der Semantik | Langsam; Debugger/Resume-Semantik unsauber; wäre später Wegwerfcode | Optional als Bootstrap in Phase 1, dann ersetzen |
| 3. WebAssembly-Ziel (wasmtime/wasmer) | Ausgereifte VMs mit JIT (Cranelift); portables, standardisiertes Kompilat; Sandbox; theoretisch Browser-Ausführung | BASIC-Semantik passt schlecht: ON ERROR/RESUME, GOSUB und unterbrechbare Ausführung müssen aufwendig transformiert werden (Relooper/State-Machine); Strings/Arrays komplett selbst verwalten; Debugging über zwei Ebenen; schwere Abhängigkeit |
Später als zweites Backend denkbar (gleiche IR), nicht als Start |
| 4. Cranelift direkt (JIT auf nativen Code) | Native Geschwindigkeit; Rust-eigenes Projekt, gut eingebettet | Gleiche Semantik-Transformationsprobleme wie WASM; kein portables Kompilat; JIT auf allen drei Plattformen pflegen | Nur falls Performance je Thema wird — unwahrscheinlich |
| 5. LLVM-AOT (inkwell) | Maximale Performance, echte Executables | Sehr schwere Toolchain-Abhängigkeit (LLVM-Build je Plattform); lange Kompilierzeiten; Debugger/Edit-Run-Zyklus der IDE leidet massiv | Ungeeignet für dieses Projekt |
| 6. Transpilation auf fremde Skript-VM (Lua via mlua/piccolo) | Ausgereifte VM mit GC geschenkt | Semantik-Mismatch (Zahlentypen, Fehler-/Eventmodell, 1-basierte vs. BASIC-Arrays mit OPTION BASE); Fehlerortung und Debugger bilden schlecht ab |
Ungeeignet |
| 7. Transpilation nach Rust (AOT) | Native Binaries, keine VM | Kein Interpretermodus → IDE-Kernfeatures (Direktfenster, Start ohne Build-Wartezeit, Debugger) praktisch unmöglich; Rust-Toolchain als Laufzeitvoraussetzung | Ungeeignet als Primärziel |
Entscheidung (2026-09-01): Eigene Stack-basierte Bytecode-VM (Option 1, TBVM). Die IR/Bytecode-Schicht wird sauber vom Interpreter getrennt, sodass später ein zweites Backend (WASM via Cranelift, Option 3) ergänzt werden kann, ohne das Frontend anzufassen. Für die Ausführungsgeschwindigkeit typischer Terminal-Programme ist ein Interpreter mehr als ausreichend; entscheidend sind Debugger-Fähigkeit, exakte Fehlersemantik und der schnelle Edit-Run-Zyklus der IDE.
- Optionen aufstellen und bewerten (siehe Tabelle)
- Bytecode-Grobdesign: Stack-Maschine, Konstantenpool, Zeilentabelle für Diagnostik/Debugger, Aufrufkonventionen (SUB/FUNCTION vs. GOSUB)
- Speichermodell für Werte: Tagged Enum vs. NaN-Boxing; Refcounting für Strings/Arrays (kein Zyklenrisiko im Dialekt → Rc genügt)
0.3 Ratatui-/Terminal-Spike
- 80×25-Zellenpuffer (Zeichen + Farbattribut) als eigenes Widget rendern; Verhalten bei kleineren/größeren Terminals festlegen (Letterboxing?)
- Codepage-437-Abbildung auf Unicode (Rahmenzeichen, Symbole) prüfen — Darstellungstest unter Windows Terminal, gnome-terminal, iTerm2
- 16-Farben-Palette und Blink/Intensity-Attribut abbilden
- Maus-Ereignisse (crossterm) und Sondertasten (F1–F12, Alt-Kombis) testen; bekannte Terminal-Einschränkungen dokumentieren
- Ereignisschleifen-Architektur: Terminal-Events → Event-Queue → VM-Ticks
Phase 1 — Sprach-Frontend (tb-frontend)
- Lexer inkl. Typ-Suffixe, Zeilennummern/Labels,
REM/'-Kommentare, case-insensitive Keywords - AST für Module, Prozeduren, Anweisungen, Ausdrücke, Deklarationen
- Parser (zeilenorientiert, fehlertolerant — die IDE prüft pro Zeile)
- Semantik: Symboltabellen, implizite Deklaration,
DEFINT-Regeln, Typprüfung und -konvertierung,OPTION EXPLICIT/OPTION BASE, Array-Dimensionierung (statisch/dynamisch,REDIM) - Diagnostik mit exakten Positionen und den Meldungstexten des Vorbilds
- Meilenstein: kompletter Testkorpus parst und wird typgeprüft
Phase 2 — Bytecode und VM (tb-vm)
- Bytecode-Format und Serialisierung (
.tbc) - Codegenerator AST → Bytecode
- Interpreter: Ausdrücke, Kontrollfluss (
IF,SELECT CASE, Schleifen,GOTO/GOSUB), Prozeduraufrufe,BYREF-Semantik - Fehlerbehandlung:
ON ERROR GOTO/RESUME,ERR/ERL, Fehlerkaskaden - Unterbrechbarkeit: Tick-Grenzen, Breakpoints, Einzelschritt, Variableninspektion (Grundlage für IDE-Debugger)
- Meilenstein: Konsolen-Testkorpus läuft mit korrekter Ausgabe (
tbdosc run)
Phase 3 — Laufzeitbibliothek (tb-runtime) und Bildschirm (tb-ui::screen)
- Strings:
LEFT$,MID$(auch als Anweisung),INSTR,STR$/VAL,SPACE$,STRING$,LTRIM$/RTRIM$,UCASE$/LCASE$… - Zahlenformatierung:
PRINT-Zonen,PRINT USING(vollständig), Banker's Rounding,CINT/CLNG/CSNG/CDBL/CCUR - Mathematik:
RND/RANDOMIZE(kompatibler PRNG!), trigonometrische Funktionen, Integer-Überlaufverhalten (Fehler 6) - Datei-E/A:
OPEN(sequenziell/random/binär),INPUT#/LINE INPUT#,PRINT#/WRITE#,GET/PUTmit Record-Typen,EOF/LOF/SEEK, Pfadsemantik plattformübergreifend - Bildschirm:
PRINT,LOCATE,COLOR,CLS,INPUT,INKEY$,CSRLIN/POS,WIDTH,VIEW PRINTauf dem Zellenpuffer - Meilenstein: klassische Konsolenprogramme laufen unverändert
Phase 4 — Forms-Engine (tb-ui::forms)
- Formular-Modell: Eigenschaften, Lade-/Entladezyklus,
SHOW/HIDE(modal/nicht-modal) - Steuerelemente: CommandButton, TextBox, ListBox, ComboBox, CheckBox, OptionButton, Frame, Label, HScrollBar/VScrollBar, PictureBox (Text), Timer — mit allen Eigenschaften/Methoden/Ereignissen des Vorbilds
- Menüsystem (Menüleiste, Shortcuts, Access Keys)
- Fokus-/Tab-Reihenfolge, Access-Keys, Maussteuerung
.FRM-Dateiformat lesen/schreiben (Kompatibilität zu Originaldateien)- Ereignisdispatch: Event-Queue ↔ VM (Ereignisprozeduren
Name_Ereignis) - Meilenstein: Beispiel-Formularprogramme aus dem Testkorpus laufen
Phase 5 — IDE (tb-ide)
- IDE-Rahmen: Menüleiste, MDI-artige Fensterverwaltung, Statuszeile, klassisches Farbschema
- Editor: Syntaxprüfung/-normalisierung pro Zeile (Keywords groß, Leerzeichen), Suchen/Ersetzen, Hilfe-Verweise
- Projektverwaltung (
.MAK): mehrere Module/Formulare - Formular-Designer: Steuerelemente platzieren/verschieben/skalieren, Eigenschaftenfenster
- Ausführen aus der IDE: Start/Unterbrechen/Fortsetzen/Neustart
- Debugger: Breakpoints, Einzelschritt/Prozedurschritt, Direktfenster, Überwachungsausdrücke
- Meilenstein: Programm komplett in der IDE schreiben, gestalten, debuggen und ausführen
Phase 6 — Kompatibilität, Politur, Distribution
- Kompatibilitäts-Testsuite ausbauen (Snapshot-Tests der Bildschirmausgabe)
- Plattformtests: Windows Terminal, Linux (mind. 2 Emulatoren), macOS
- Performance-Pass über die VM (nur falls nötig)
tbdosc build→ binäres Ergebnis:.tbc-Bytecode bzw. eigenständig ausführbares Programm (Bytecode + eingebetteter Runner)- Dokumentation: Sprachreferenz, Migrationshinweise, Beispielprogramme
- CI (GitHub Actions: Build + Tests auf allen drei Plattformen), Releases
Offene Fragen
- Umgang mit
CURRENCY(@): als i64-Festkomma (×10 000) — klären, ob das Vorbild ihn überhaupt in allen Kontexten unterstützt - ISAM-Dateiunterstützung des Vorbilds: nachbilden oder als Nicht-Ziel erklären?
PEEK/POKE/CALL INTERRUPTu. ä. Hardware-Nähe: sinnvolle Teilmenge emulieren (z. B. Bildschirmspeicher B800) oder Laufzeitfehler?- Verhalten bei Terminals < 80×25: Mindestgröße erzwingen oder scrollen?
- Lizenzwahl (MIT im Rahmen angenommen — bestätigen)