# 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 mit `VERSION`/`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. - [x] 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`/`PUT` mit Record-Typen, `EOF`/`LOF`/`SEEK`, Pfadsemantik plattformübergreifend - [ ] Bildschirm: `PRINT`, `LOCATE`, `COLOR`, `CLS`, `INPUT`, `INKEY$`, `CSRLIN`/`POS`, `WIDTH`, `VIEW PRINT` auf 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 INTERRUPT` u. ä. 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)