Files
TerminalBasic/docs/tbvm-design.md
Chili Palmer 7e6fa6ea88 Phase 0: Referenzdokumente, Fehlerkatalog, Testkorpus, Ratatui-Spike
Entscheidungen festgehalten: TBVM bestaetigt und eingebettet in die
Executables; durchgaengig UTF-8 statt CP437 (dokumentierte Abweichung).

- docs/: Sprachreferenz, Forms-Referenz, Dateiformate, TBVM-Design
- tb-runtime::errors: klassischer Laufzeitfehler-Katalog (implementiert)
- tb-ui::screen: 80x25-Unicode-Zellenpuffer mit 16-Farben-Abbildung,
  Scrollbereich (VIEW PRINT), Letterboxing; Ratatui-Widget + Tests
- Spike: cargo run -p tb-ui --example spike (Farben, Unicode, Tasten, Maus)
- tests/compat/: erste Referenzprogramme mit byte-genauer Sollausgabe

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-01 16:36:45 +02:00

86 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TBVM — Designentwurf
Eigene Stack-basierte Bytecode-VM (Entscheidung siehe PLAN.md, 0.2).
Die VM ist in `tbdos` (IDE) und in von `tbdosc` erzeugte Executables
eingebettet — identischer Code, identisches Verhalten, schneller Turnaround.
## Werte-Modell
Tagged Enum, kein NaN-Boxing (Einfachheit und Debugbarkeit vor Mikro-
performance):
```rust
enum Value {
Int(i16), // INTEGER
Long(i32), // LONG
Single(f32), // SINGLE
Double(f64), // DOUBLE
Currency(i64), // CURRENCY, Festkomma ×10 000
Str(Rc<str>), // STRING (immutabel geteilt; Copy-on-Write bei MID$-Anweisung)
// Arrays und TYPE-Instanzen leben im Heap-Bereich der VM,
// Variablen-Slots referenzieren sie per Handle (Rc<RefCell<…>>).
}
```
- Kein GC nötig: der Dialekt kennt keine Zyklen (keine Objektreferenzen in
TYPEs, keine Closures) → `Rc` genügt.
- Feste Strings (`STRING * n`) und TYPE-Records werden als eigene
Speicherobjekte mit fester Zeichen-/Elementstruktur geführt.
## Bytecode
- Stack-Maschine, Opcodes 1 Byte + Operanden variabler Länge (u8/u16/u32,
little-endian).
- **Modul-Struktur:** Konstantenpool (Strings, Zahlen), Typtabelle
(TYPE-Layouts), Prozedurtabelle (Signatur, Locals-Anzahl, Code-Offset),
globale Slots, DATA-Segment (für READ/RESTORE), Zeilentabelle.
- **Zeilentabelle:** Abbildung Code-Offset → (Moduldatei, Zeile). Grundlage
für `ERL`, Fehlermeldungen, Breakpoints und Einzelschritt.
- **Aufrufkonventionen:**
- SUB/FUNCTION: eigener Frame (Locals-Slots, Operandenstack-Basis);
BYREF-Parameter als Referenz-Slots (Handle auf Variablen-Slot).
- GOSUB: **kein** Frame — Rücksprungadresse auf separatem GOSUB-Stack im
aktuellen Frame (RETURN prüft diesen zuerst).
- **Fehlerbehandlung:** Pro Frame ein Handler-Zustand (`ON ERROR GOTO x`).
Laufzeitfehler → VM sucht aktiven Handler im aktuellen Modulkontext
(Vorbild: Handler sind modul-/prozedurlokal, TODO: exakte Scoping-Regel
testen), setzt `ERR`/`ERL`, springt. `RESUME` nutzt gemerkten
Anweisungs-Offset.
## Ausführungsmodell / Unterbrechbarkeit
- Die Interpreterschleife läuft in **Ticks**: nach jeder Anweisung (Grenze
aus der Zeilentabelle) prüft sie ein Flag-Set: Breakpoint? Einzelschritt?
Strg+Untbr? Ereignis-Queue nicht leer und Zustellung erlaubt?
- Ereigniszustellung (Forms, Timer) erfolgt kooperativ: nur an
Zustellpunkten (`DOEVENTS`, `SLEEP`, blockierende Eingabe, Ende einer
Ereignisprozedur) — wie im Vorbild.
- Die VM ist eine gewöhnliche zustandsbehaftete Struktur, `step()`-basiert;
die einbettende Schleife (IDE-Debugger oder Runner) treibt sie. Kein
eigener Thread nötig; Terminal-Events werden zwischen Ticks gepollt.
## `.tbc`-Container (Entwurf)
```
Magic "TBC\0" · Formatversion u16 · Flags
Abschnittstabelle: [ (Kennung, Offset, Länge) ]
Abschnitte: CONSTS, TYPES, PROCS, CODE, DATA, LINES, FORMS (serialisierte .FRM-Beschreibungen)
```
Serialisierung mit einfachem eigenem Writer/Reader (kein serde nötig,
Format bleibt stabil und dokumentiert).
## Eigenständige Executables
`tbdosc build --exe` kopiert den vorkompilierten Runner (dieselbe
tb-vm/tb-runtime/tb-ui-Bibliothek wie die IDE) und hängt das `.tbc` als
Ressource an (Anhängen ans Binary + Fußzeile mit Offset/Magic; portabel für
alle drei Plattformen). Alternative — `include_bytes!` + Cargo-Build beim
Nutzer — verworfen: erfordert Rust-Toolchain beim Anwender.
## Offene Punkte
- Opcode-Satz konkret ausformulieren (mit Phase 2)
- Zahlenkonvertierungs-Matrix (implizite Casts, Rundung, Überlauf) als Tabelle
- Verhalten von `STOP`/`CONT` im Runner (ohne IDE): Abbruch mit Meldung?