Files
TerminalBasic/PLAN.md
Chili Palmer 5821ace0cf Projektrahmen: Cargo-Workspace, README und PLAN
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>
2026-09-01 16:21:09 +02:00

10 KiB
Raw Blame History

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.

  • 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 (F1F12, 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)