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>
86 lines
3.6 KiB
Markdown
86 lines
3.6 KiB
Markdown
# 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?
|