Phase 3 (Kern): Laufzeitbibliothek, Bildschirm und Datei-E/A

Setzt den OpenSpec-Change phase-3-runtime-bildschirm um (77/77 Aufgaben).
Abdeckung laut Inventar: 195 implementiert, 37 offen, 53 Non-Feature.

Vollstaendigkeits-Inventar
- docs/inventar.md mit 285 Eintraegen aus den Themenlisten von
  bas7advr.hlp und qb45advr.hlp, je mit Status und Fundstelle
- crates/tb-frontend/tests/inventar.rs haelt die Tabelle in beide
  Richtungen gegen den Code; der Abdeckungsstand kann nicht veralten

Bruchschritt (Puffer, Host, Korpus)
- Cell/TextScreen ziehen ratatui-frei nach tb-runtime::screen; tb-ui
  behaelt Farbabbildung, Widget und den neuen Terminal-Host
- Host wechselt vom Zeichenstrom auf Anzeige des Zellenpuffers plus
  Ereignisse (Taste, Groessenaenderung, Abbruch)
- Korpusvergleich auf getrimmten Bildschirm-Snapshot; die acht
  bestehenden Sollausgaben blieben dabei unveraendert

Groessenunabhaengigkeit
- 80x25 ist nirgends mehr eine feste Grenze; Groessenaenderungen waehrend
  der Ausfuehrung werden zugestellt (Inhalt oben links erhalten, Cursor
  und VIEW PRINT geklemmt)
- Korpusnachweis: dasselbe Programm bei 80x25 und 120x40 mit je eigener
  Sollausgabe, plus ein Programm mit Groessenwechsel mitten im Lauf

Bibliothek
- Breite Unicode-Zeichen belegen zwei Zellen (Cursor, POS, Randumbruch)
- Bildschirm: CLS, COLOR, LOCATE, WIDTH, VIEW PRINT, SCREEN, CSRLIN, POS
- Tastatur: INKEY$, INPUT$, Funktionstasten-Makros (KEY n / LIST / ON)
- PRINT USING, LPRINT USING, FORMAT$, SetFormatCC
- Mathematik mit kompatiblem PRNG (gleiche Saat, gleiche Folge)
- Datum und Zeit mit Serienwerten ab 1899
- Finanzmathematik: FV#, PV#, Pmt#, IPmt#, PPmt#, NPer#, Rate#, NPV#,
  IRR#, MIRR#, SLN#, SYD#, DDB#
- Datei-E/A: sequenziell, RANDOM (Recordpuffer und UDT-Variablen),
  BINARY, FIELD/LSET/RSET, Statusfunktionen, Dateisystem, MK$/CV
- System: ENVIRON, FRE, CLEAR, TRON/TROFF, STACK, ERDEV, ERR-Anweisung

Altlasten aus Phase 2
- ON ERROR GOTO auf Modulebene ist aus Prozeduren ansprechbar
  (prozeduruebergreifender Fixup im Codegenerator)
- DATA behaelt seinen Rohtext (Gross-/Kleinschreibung, innerer Leerraum)
- Die vier TODO-verify-Zellen der Konvertierungsmatrix sind aufgeloest

Vom Inventar aufgedeckte Fehler
- Zwoelf Non-Features wies der Compiler entgegen der Phase-1-Spec nicht
  ab (CALLS, SSEG, POINT, VIEW, COM, PEN, STRIG, STICK, die
  String*-Routinen, LINE und OPEN "COMn:") -- geschlossen
- Drei Gruppen fehlten im urspruenglichen Umfang: Finanzmathematik,
  Record-Konvertierung, Rest der Dateisystemfunktionen
- bas7advr.hlp allein ist keine vollstaendige Quelle; das Inventar
  bildet die Vereinigung mit qb45advr.hlp

Neue Changes
- phase-3-isam: schliesst Phase 3 ab (Speicherschicht redb)
- phase-3-ortszeit: zieht die UTC-Abweichung zurueck

Neue Abhaengigkeit: unicode-width.
Dokumentiert: sprachreferenz.md und tbvm-design.md sind TODO-frei,
docs/bibliothek.md neu, PLAN.md fortgeschrieben.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-04 06:54:19 +02:00
parent a6f005d023
commit 52ccbb5848
94 changed files with 10421 additions and 792 deletions

161
PLAN.md
View File

@@ -245,54 +245,115 @@ Vorgezogen aus Phase 3 (Meilenstein-Voraussetzung): `Host`-Trait
(Konsole/Capture), Builtin-Dispatch-Tabelle, PRINT-Formatierung mit
Druckzonen sowie die Korpus-Stringfunktionen (`tb-runtime`).
## Phase 3 — Laufzeitbibliothek (`tb-runtime`) und Bildschirm (`tb-ui::screen`)
## Phase 3 — Laufzeitbibliothek (`tb-runtime`) und Bildschirm
**Status: Kern abgeschlossen (2026-09-04), ISAM offen.** Umgesetzt im
OpenSpec-Change `phase-3-runtime-bildschirm`; der Rest steckt im Change
`phase-3-isam`, mit dem Phase 3 endet.
Ziel ist die **vollständige** Standardbibliothek des Vorbilds (siehe
Leitplanke Vollständigkeit); die Aufzählungen unten sind Beispiele.
Maßgeblich ist seit 2026-09-03 das Inventar, nicht diese Liste.
- [ ] Vollständigkeits-Inventar erstellen: maschinenlesbare Liste aller
Anweisungen/Funktionen des Vorbilds aus der Original-Hilfe
(dos-help.soulsphere.org, Topic-Listen) mit Status
implementiert/offen/Non-Feature → `docs/inventar.md`; ab dann
Abdeckung je Phase fortschreiben
- [ ] Strings: `LEFT$`, `MID$` (auch als Anweisung), `INSTR`, `STR$`/`VAL`,
`SPACE$`, `STRING$`, `LTRIM$`/`RTRIM$`, `UCASE$`/`LCASE$`
- [ ] Zahlenformatierung: `PRINT`-Zonen, `PRINT USING` (vollständig;
dabei offene Detailfrage klären: `%`-Präfix bei Feldüberlauf),
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. Record-Layout: feste Strings als
**UTF-32** (Entscheidung 2026-09-02 — 4 Bytes/Zeichen, feste
Record-Länge; bewusst inkompatibel zu Vorbild-Dateien)
- [ ] ISAM-Dateiunterstützung (Entscheidung 2026-09-02: wird implementiert,
nicht Non-Feature): Anweisungen/Funktionen der Professional Edition
(`OPEN … FOR ISAM`, Tabellen/Indizes, `SEEKGT`-Familie …) — Umfang
aus der Original-Hilfe inventarisieren, dann implementieren
- [ ] Breite Unicode-Zeichen (Emoji, CJK): belegen **zwei Zellen**
(Entscheidung 2026-09-02) — Zellenmodell und `LOCATE`/`POS`-Semantik
entsprechend umsetzen (unicode-width), Verhalten dokumentieren
- [ ] Bildschirm: `PRINT`, `LOCATE`, `COLOR`, `CLS`, `INPUT`, `INKEY$`,
`CSRLIN`/`POS`, `WIDTH`, `VIEW PRINT` auf dem Zellenpuffer
- [ ] Offene Detailfrage klären: Umfang der `KEY n`-Funktionstasten-Makros
(`KEY LIST`/`ON`/`OFF`) und in docs/sprachreferenz.md festhalten
- [ ] Aus Phase 2 verlagert — `ON ERROR GOTO`-Scoping des Vorbilds im
Frontend abbilden: Handler-Label auf Modulebene ist auch aus
Prozeduren heraus ansprechbar (derzeit wird nicht-lokales
`ON ERROR` in einer Prozedur wie `ON LOCAL ERROR` behandelt,
siehe sema.rs, lower_stmt/OnError)
- [ ] Aus Phase 2 verlagert — DATA-Rohtext erhalten: unquotierte
DATA-Elemente verlieren derzeit die Groß-/Kleinschreibung, weil
der Lexer Bezeichner normalisiert; Rohtext-Erfassung im Lexer,
Korpustest ergänzen
- [ ] Aus Phase 2 verlagert — `TODO verify`-Zellen der
Konvertierungsmatrix (docs/tbvm-design.md) gegen die
Original-Hilfe auflösen: CURRENCY-Promotion mit Gleitkomma,
`^`-Ergebnistyp, Exponentialform-Schwellen der Textdarstellung,
CURRENCY-Ausgabeformat; zugehörige Korpustests nachschärfen
- [ ] Meilenstein: klassische Konsolenprogramme laufen unverändert
- [x] Vollständigkeits-Inventar → [docs/inventar.md](docs/inventar.md):
285 Einträge aus den Themenlisten von `bas7advr.hlp` und
`qb45advr.hlp` mit Status und Fundstelle. Ein Test
(`crates/tb-frontend/tests/inventar.rs`) hält die Tabelle in beide
Richtungen gegen den Code — der Abdeckungsstand kann nicht mehr
veralten. **Stand: 195 implementiert · 37 offen · 53 Non-Feature.**
Die 37 offenen sind 22 ISAM (`phase-3-isam`), 13 Forms und
Ereignissteuerung (Phase 4), `RUN` und `$INCLUDE` (Phase 5).
- [x] **Bildschirmpuffer in die Laufzeit** (Entscheidung 2026-09-03):
`Cell`/`TextScreen` liegen ratatui-frei in `tb-runtime::screen`;
`tb-ui` behält Farbabbildung, Widget und den Terminal-Host. Damit
erreicht die Bibliothek den Puffer, und Bildschirmverhalten ist ohne
Terminal prüfbar.
- [x] **`Host` neu geschnitten** (BREAKING): statt Zeichenstrom nun
Anzeige des Zellenpuffers plus Ereignisse (Taste, Größenänderung,
Abbruch). `write`/`read_line` konnten `LOCATE`, `COLOR`, `CSRLIN`
und das Zurücklesen per `SCREEN(z, s)` nicht transportieren.
- [x] **Korpusvergleich auf Bildschirm-Snapshot** (BREAKING): getrimmt auf
die belegte Fläche, Attributebene nur bei gesetzten Farben. Die acht
bestehenden Sollausgaben blieben dabei unverändert.
- [x] **80×25 ist nirgends eine feste Grenze** (Vorgabe 2026-09-03):
alle Bildschirmpfade rechnen mit der aktuellen Größe;
Größenänderungen während der Ausführung werden zugestellt (Inhalt
oben links erhalten, Cursor und `VIEW PRINT` geklemmt). Der Korpus
weist es nach: dasselbe Programm bei 80×25 und 120×40 mit je eigener
Sollausgabe, plus ein Programm mit Größenwechsel mitten im Lauf.
- [x] Breite Unicode-Zeichen belegen **zwei Zellen** (Emoji, CJK):
Cursorfortschritt, `POS`, Umbruch am rechten Rand und das Leeren der
Gegenhälfte beim Überschreiben.
- [x] Bildschirm: `CLS`, `COLOR`, `LOCATE`, `WIDTH`, `VIEW PRINT`,
`SCREEN` (Anweisung und Funktion), `CSRLIN`, `POS`, `TAB`, `SPC`
- [x] Tastatur: `INKEY$` (nicht blockierend, Sondertasten als
`CHR$(0)+code`), `INPUT$`, Funktionstasten-Makros `KEY n, text$` /
`KEY LIST` / `KEY ON|OFF` (Umfang aus der Original-Hilfe geklärt)
- [x] Strings vollständig; Randfälle (`VAL`-Präfix, `STR$`-Vorzeichenspalte,
Fehler 5 bei Startposition < 1) im Korpus verankert
- [x] Zahlenformatierung: Druckzonen, `PRINT USING`/`LPRINT USING`/
`FORMAT$` vollständig inklusive `%`-Präfix bei Feldüberlauf und
`SetFormatCC`; Banker's Rounding; `CINT`/`CLNG`/`CSNG`/`CDBL`/`CCUR`
- [x] Mathematik inklusive **kompatiblem PRNG**: gleiche Saat ergibt
dieselbe Folge, `RND(0)` wiederholt, `RANDOMIZE` ohne Argument
erfragt den Startwert; Algorithmus dokumentiert
- [x] **Finanzmathematik** (Befund des Inventars — im ursprünglichen
Umfang übersehen): `FV#`, `PV#`, `Pmt#`, `IPmt#`, `PPmt#`, `NPer#`,
`Rate#`, `NPV#`, `IRR#`, `MIRR#`, `SLN#`, `SYD#`, `DDB#`
- [x] Datum und Zeit: Serienwerte, `DATESERIAL`/`TIMESERIAL`,
`DATEVALUE`/`TIMEVALUE`, `DAY``SECOND`, `NOW`, `DATE$`/`TIME$` als
Funktion und Anweisung
- [x] Datei-E/A: `OPEN` in beiden Syntaxen (sequenziell, `RANDOM`,
`BINARY`), `PRINT #`/`WRITE #`/`INPUT #`/`LINE INPUT #`,
`GET`/`PUT` mit Recordpuffer **und** mit UDT-Variablen,
`FIELD`/`LSET`/`RSET`, `EOF`/`LOF`/`LOC`/`SEEK`/`FREEFILE`/
`FILEATTR`, `LOCK`/`UNLOCK`, `LPRINT`/`LPOS`, die
Record-Konvertierungsfunktionen (`MK…$`/`CV…`) und die
Dateisystem-Anweisungen. Feste Strings als **UTF-32**.
- [x] System: `ENVIRON`/`ENVIRON$`, `COMMAND$`, `FRE`, `CLEAR`,
`TRON`/`TROFF`, `STACK`, `ERDEV`/`ERDEV$`, `ERR`-Anweisung
- [x] Aus Phase 2 verlagert — `ON ERROR GOTO`-Scoping: ein modulweiter
Handler ist jetzt aus Prozeduren heraus ansprechbar (Sprungziel im
Modulrumpf, prozedurübergreifender Fixup im Codegenerator); nur
`ON LOCAL ERROR` bleibt prozedurlokal
- [x] Aus Phase 2 verlagert — DATA-Rohtext: der Lexer liefert den
Anweisungstext unverändert, unquotierte Elemente behalten Groß-/
Kleinschreibung und inneren Leerraum
- [x] Aus Phase 2 verlagert — die vier `TODO verify`-Zellen der
Konvertierungsmatrix sind aufgelöst. Die Original-Hilfe schweigt zu
allen vieren; sie sind daher als datierte **Projektentscheidung**
begründet dokumentiert und in `konvertierung.bas` verankert.
- [x] **Meilenstein: klassische Konsolenprogramme laufen unverändert**
alle 22 Korpusprogramme laufen ohne Laufzeitfehler 73; der Fehler
tritt nur noch bei bewusst offenen Elementen auf (ISAM, Forms,
Ereignissteuerung).
- [ ] **ISAM** (Change `phase-3-isam`): `OPEN … FOR ISAM`, Indizes,
Cursor, Satzoperationen, Transaktionen. Speicherschicht `redb`
(Entscheidung 2026-09-03). Damit endet Phase 3.
**Befunde dieser Phase, die den Plan korrigiert haben**
- Das Inventar deckte am ersten Tag zwölf Non-Features auf, die der
Compiler entgegen der Phase-1-Spec **nicht** abwies (`CALLS`, `SSEG`,
`POINT`, `VIEW`, `COM`, `PEN`, `STRIG`, `STICK`, die
`String*`-Routinen sowie `LINE` und `OPEN "COMn:"` an ihrer Syntax).
Alle geschlossen.
- Drei ganze Gruppen fehlten im ursprünglichen Umfang: Finanzmathematik,
Record-Konvertierung und ein Rest an Dateisystemfunktionen.
- `bas7advr.hlp` allein ist **keine** vollständige Quelle: `SGN`, `SQR`,
`SPACE$`, `STRING$`, `CSRLIN`, `BEEP` und `DATE$` als Funktion fehlen
dort. Das Inventar bildet deshalb die Vereinigung mit `qb45advr.hlp`.
**Offene Entscheidungen, die in spätere Phasen zeigen**
- Die Uhr lief zunächst in **UTC**, weil Ortszeit eine
Zeitzonenbibliothek gebraucht hätte. Entscheidung 2026-09-04: die
Bibliothek kommt, die Abweichung wird zurückgezogen → Change
`phase-3-ortszeit`.
- `LPRINT` schreibt am Programmende nach `LPT1.TXT` im Arbeitsverzeichnis;
einen plattformübergreifenden Druckerkanal gibt es nicht.
- Neue Abhängigkeit `unicode-width` (Doppelzellen). Für ISAM kommt `redb`
hinzu.
## Phase 4 — Forms-Engine (`tb-ui::forms`)
- [ ] Eingangsaufgabe (aus Phase 0 übernommen): Ereignisschleifen-
@@ -370,10 +431,14 @@ bleibt gültig. Noch nichts davon ist beschlossen; Sammlung wächst:
mit Record-Buffer-Datentypen, auf denen `SELECT`/`UPDATE`/`INSERT`/
`DELETE` arbeiten (natürliche Weiterentwicklung der ISAM-Idee auf
SQLite als Speicher)
- **Runtime-Bibliotheken als BASIC-Bibliotheken** (2026-09-02): in der
Runtime integrierte Rust-Bibliotheken (z. B. crossterm für direkte
Terminalsteuerung) als eigene, importierbare Bibliotheken für
BASIC-Programme bereitstellen
- **Runtime-Bibliotheken als BASIC-Bibliotheken** (2026-09-02, erweitert
2026-09-04): in der Runtime integrierte Rust-Bibliotheken als eigene,
importierbare Bibliotheken für BASIC-Programme bereitstellen —
- **crossterm** für direkte Terminalsteuerung
- **die Zeitzonenbibliothek** (ab dem Change `phase-3-ortszeit` in der
Laufzeit): Zonennamen, Versatz zu einem Zeitpunkt, Umrechnung
zwischen Zonen. Der Kernstandard braucht davon nur den Versatz für
die Ortszeit; alles Weitere wäre eine Erweiterung.
- Verteilung: `tbc build --exe` als Single-File-Tool-Baukasten
---