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>
187 lines
10 KiB
Markdown
187 lines
10 KiB
Markdown
# Phase 3 (Kern) — Laufzeitbibliothek, Bildschirm und Datei-E/A
|
||
|
||
## Why
|
||
|
||
Phase 2 hat eine lauffähige VM geliefert, aber nur eine dünne
|
||
Bibliotheksscheibe: rund 50 dokumentierte Anweisungen und Funktionen sind
|
||
im Frontend zwar typgeprüft, senken aber auf `HStmtKind::Unsupported`/
|
||
`HExpr::Unsupported` ab und enden zur Laufzeit in Fehler 73. Betroffen
|
||
sind alle Bildschirmanweisungen (`CLS`, `LOCATE`, `COLOR`, `VIEW PRINT`,
|
||
`CSRLIN`, `POS`, `INKEY$`), die komplette Datei-E/A, `PRINT USING`,
|
||
die Datums-/Zeitfunktionen und die System-Anweisungen. Klassische
|
||
Konsolenprogramme des Vorbilds laufen damit nicht.
|
||
|
||
Zusätzlich fehlt das Messinstrument: die Leitplanke „Vollständigkeit ist
|
||
das Soll" fordert ein Inventar aller Anweisungen/Funktionen mit
|
||
Abdeckungsstatus als Abnahmekriterium für Phase 6 — bislang existiert nur
|
||
die Implementierungsseite (die `Unsupported`-Marker), nicht die Sollseite
|
||
aus der Original-Hilfe.
|
||
|
||
Dieser Change löst den Plan-Meilenstein „klassische Konsolenprogramme
|
||
laufen unverändert" ein. ISAM ist als eigener Change `phase-3-isam`
|
||
ausgegliedert und schließt Phase 3 ab.
|
||
|
||
## What Changes
|
||
|
||
- **Vollständigkeits-Inventar** (`docs/inventar.md`): Tabelle aller
|
||
Anweisungen, Funktionen und Metabefehle des Vorbilds aus der
|
||
Original-Hilfe mit Status `implementiert` / `offen` / `Non-Feature`
|
||
und Fundstelle. Ein automatischer Test gleicht die Tabelle gegen
|
||
`builtin_fn`/`builtin_stmt` und die `Unsupported`-Marker im Code ab;
|
||
Divergenz schlägt fehl. Damit misst sich die Abdeckung selbst.
|
||
- **Bildschirmpuffer wandert nach `tb-runtime`** (Entscheidung
|
||
2026-09-03, Explore-Session): `Cell`/`TextScreen` mit der kompletten
|
||
Bildschirmsemantik (Cursor, Farbattribute, Scrollen, `VIEW PRINT`,
|
||
`resize`) ziehen ratatui-frei von `tb-ui::screen` nach
|
||
`tb-runtime::screen`. In `tb-ui` bleiben nur die Ratatui-Anbindung
|
||
(`basic_color`, `impl Widget`) und künftig der Terminal-Adapter.
|
||
Begründung: `PRINT`, `LOCATE`, `CLS` und `SCREEN()` sind Elemente der
|
||
Laufzeitbibliothek und müssen den Puffer erreichen; zugleich bleiben
|
||
`tb-vm` und `tb-runtime` damit frei von einer Terminal-Abhängigkeit,
|
||
sodass jedes Bildschirmverhalten ohne Terminal prüfbar ist. Die
|
||
Forms-Engine bleibt laut PLAN.md in `tb-ui::forms` (Entscheidung
|
||
2026-09-03) und zeichnet von dort in denselben Puffer — `tb-ui` hängt
|
||
künftig an `tb-runtime`, nicht umgekehrt.
|
||
- **BREAKING: `Host`-Trait neu geschnitten**: statt `write(&str)` /
|
||
`read_line()` künftig Präsentation eines Zellenpuffers und
|
||
Ereignisabfrage. `write`/`read_line` können den Bildschirmzustand
|
||
nicht transportieren (`LOCATE`, `COLOR`, `CSRLIN`, `SCREEN(r,c)` liest
|
||
vom Bildschirm zurück). Betrifft `ConsoleHost`, `CaptureHost` und
|
||
`tbc run`.
|
||
- **BREAKING: Korpusvergleich auf Bildschirm-Snapshot** (getrimmt):
|
||
`.out`-Dateien halten künftig das Textbild des Puffers bis zur letzten
|
||
belegten Zelle statt eines Byte-Streams; eine Attributebene kommt nur
|
||
hinzu, wenn das Programm `COLOR` verwendet. Die acht bestehenden
|
||
Golden Files werden neu erzeugt. Ein Byte-Stream kann `LOCATE`/`COLOR`
|
||
nicht abbilden.
|
||
- **Bildschirmanweisungen und -funktionen**: `CLS`, `COLOR`, `LOCATE`,
|
||
`WIDTH`, `SCREEN` (Anweisung und Funktion), `VIEW PRINT`, `CSRLIN`,
|
||
`POS`, `INKEY$`, `INPUT$`, `TAB`, `SPC`, `KEY` (inkl. Klärung des
|
||
Umfangs der Funktionstasten-Makros `KEY LIST`/`ON`/`OFF`).
|
||
- **80×25 ist nirgends eine feste Grenze** (Vorgabe des Projektinhabers
|
||
2026-09-03, Priorität für das ganze Programm): 80×25 steht stets als
|
||
Synonym für „voller Bildschirm". Kein beobachtbares Verhalten darf eine
|
||
feste Spalten- oder Zeilenzahl voraussetzen — `CLS`, der
|
||
voreingestellte Scrollbereich, Umbruch- und Scrollgrenzen sowie die
|
||
Bereichsprüfungen von `LOCATE` und `SCREEN()` folgen den aktuellen
|
||
Abmessungen. Größenänderungen während der Ausführung werden als
|
||
Ereignis zugestellt und angepasst (Inhalt oben links erhalten, Cursor
|
||
und `VIEW PRINT`-Bereich geklemmt). Das Mindestmaß 80×25 bleibt
|
||
ausschließlich eine untere Schranke der Darstellung.
|
||
- **Breite Unicode-Zeichen belegen zwei Zellen** (Entscheidung
|
||
2026-09-02): Zellenmodell, Cursorfortschritt, `POS`/`LOCATE` und
|
||
Umbruch am rechten Rand berücksichtigen die Darstellungsbreite
|
||
(unicode-width). Ersetzt die bisherige Regel „1 Zeichen = 1 Zelle".
|
||
- **Vollständige String- und Zahlenbibliothek**: die restlichen
|
||
dokumentierten Stringfunktionen sowie `PRINT USING` und `FORMAT$`
|
||
vollständig, inklusive Klärung des `%`-Präfixes bei Feldüberlauf.
|
||
- **Datums- und Zeitfunktionen**: `NOW`, `DATESERIAL`, `TIMESERIAL`,
|
||
`DATEVALUE`, `TIMEVALUE`, `DAY`, `MONTH`, `YEAR`, `WEEKDAY`, `HOUR`,
|
||
`MINUTE`, `SECOND` sowie `DATE$`/`TIME$` als Anweisungsform.
|
||
- **Finanzmathematik** (Befund aus Aufgabe 1.1, 2026-09-03 — im
|
||
ursprünglichen Umfang übersehen): `FV#`, `PV#`, `Pmt#`, `IPmt#`,
|
||
`PPmt#`, `NPer#`, `Rate#`, `NPV#`, `IRR#`, `MIRR#`, `SLN#`, `SYD#`,
|
||
`DDB#`.
|
||
- **Record-Konvertierungsfunktionen** (ebenfalls Befund 1.1):
|
||
`MKI$`/`MKL$`/`MKS$`/`MKD$`/`MKC$` und `CVI`/`CVL`/`CVS`/`CVD`/`CVC`
|
||
sowie die MBF-Varianten `MKSMBF$`/`MKDMBF$`/`CVSMBF`/`CVDMBF` — sie
|
||
gehören zum `FIELD`-basierten wahlfreien Zugriff.
|
||
- **Weitere Befunde aus 1.1**: `CURDIR$`, `DIR$`, `CHDRIVE`,
|
||
`SHELL` als Funktion, `LPOS`, `STACK` (Anweisung und Funktion),
|
||
`SYSTEM`, `ERDEV`/`ERDEV$`, `SetFormatCC`.
|
||
- **Signaturen für alle Inventarelemente**: Die Semantik führt für jedes
|
||
im Inventar geführte Element eine Signatur, auch wenn das
|
||
Laufzeitverhalten noch aussteht — sonst enden dokumentierte Elemente
|
||
in „unbekannter Bezeichner" statt in einer namentlichen Ablehnung.
|
||
- **Mathematik vervollständigen**: kompatibler `RND`/`RANDOMIZE`-PRNG
|
||
(gleiche Zahlenfolge wie das Vorbild bei gleichem Startwert),
|
||
Rundungsverhalten, Integer-Überlauf → Fehler 6.
|
||
- **Datei-E/A**: `OPEN` in beiden Syntaxen (sequenziell, random, binär),
|
||
`CLOSE`, `RESET`, `PRINT #`, `WRITE #`, `INPUT #`, `LINE INPUT #`,
|
||
`GET`, `PUT`, `FIELD`, `LSET`, `RSET`, `SEEK` (Anweisung und
|
||
Funktion), `EOF`, `LOF`, `LOC`, `FREEFILE`, `FILEATTR`, `LOCK`/
|
||
`UNLOCK`, `NAME … AS`, `LPRINT`. Feste Strings in Records als UTF-32
|
||
(Entscheidung 2026-09-02, 4 Bytes/Zeichen, feste Recordlänge).
|
||
- **System-Anweisungen**: `FILES`, `KILL`, `CHDIR`, `MKDIR`, `RMDIR`,
|
||
`SHELL`, `ENVIRON`/`ENVIRON$`, `CLEAR`, `FRE`, `TRON`/`TROFF`,
|
||
plattformübergreifende Pfadsemantik.
|
||
- **Drei Altlasten aus Phase 2**:
|
||
- `ON ERROR GOTO`-Scoping: ein Handler-Label auf Modulebene ist auch
|
||
aus Prozeduren heraus ansprechbar; heute wird nicht-lokales
|
||
`ON ERROR` in einer Prozedur fälschlich wie `ON LOCAL ERROR`
|
||
behandelt (`sema.rs`, `lower_stmt`/`OnError`).
|
||
- DATA-Rohtext: unquotierte `DATA`-Elemente verlieren die Groß-/
|
||
Kleinschreibung, weil der Lexer Bezeichner normalisiert.
|
||
- `TODO verify`-Zellen der Konvertierungsmatrix in
|
||
`docs/tbvm-design.md` gegen die Original-Hilfe auflösen
|
||
(CURRENCY-Promotion mit Gleitkomma, `^`-Ergebnistyp,
|
||
Exponentialform-Schwellen, CURRENCY-Ausgabeformat).
|
||
|
||
**Non-Goals:** ISAM (eigener Change `phase-3-isam`, schließt Phase 3 ab);
|
||
Forms-Engine, Ereignisschleife und Ereignissteuerung (`TIMER/KEY(n) ON|
|
||
OFF|STOP`, `ON SIGNAL`/`SIGNAL`, `SETUEVENT`, `MSGBOX`, `INPUTBOX$` —
|
||
Phase 4); IDE und
|
||
Debugger (Phase 5); `tbc build --exe` (Phase 6). Die Forms-Engine bleibt
|
||
laut PLAN.md in `tb-ui::forms` (Entscheidung 2026-09-03); dieser Change
|
||
schafft ihr mit dem Puffer in `tb-runtime` nur die Zeichenfläche.
|
||
|
||
## Capabilities
|
||
|
||
### New Capabilities
|
||
|
||
- `datei-eio`: Dateiverwaltung und Datenübertragung — `OPEN`/`CLOSE`,
|
||
die drei Zugriffsarten (sequenziell, random, binär), Record-Layout mit
|
||
UTF-32-Festtextfeldern, `FIELD`/`LSET`/`RSET`, Positions- und
|
||
Statusfunktionen (`EOF`/`LOF`/`LOC`/`SEEK`/`FREEFILE`/`FILEATTR`),
|
||
Sperren, Dateisystem-Anweisungen und plattformübergreifende
|
||
Pfadsemantik.
|
||
- `sprachinventar`: das Vollständigkeits-Inventar als prüfbares
|
||
Artefakt — Aufbau der Tabelle, Statusvokabular, Pflicht zur
|
||
Vollständigkeit gegenüber der Original-Hilfe und der automatische
|
||
Abgleich gegen den Code.
|
||
|
||
### Modified Capabilities
|
||
|
||
- `textbildschirm`: Der Zellenpuffer SHALL in `tb-runtime` liegen und
|
||
ratatui-frei sein; das Unicode-Zellenmodell wechselt von „1 Zeichen =
|
||
1 Zelle" auf Darstellungsbreite (breite Zeichen belegen zwei Zellen);
|
||
neue Anforderung für die Bildschirmanweisungen des Dialekts auf dem
|
||
Puffer.
|
||
- `konsolen-basisbibliothek`: Der `Host`-Trait wechselt vom Stream- auf
|
||
ein Bildschirmmodell (Präsentation + Ereignisabfrage); die
|
||
Funktionsliste wird von der Korpusscheibe auf die vollständige
|
||
String-, Zahlen-, Formatierungs- (`PRINT USING`) und Datums-/
|
||
Zeitbibliothek erweitert; `RND` erhält eine Kompatibilitätsanforderung.
|
||
- `kompat-testkorpus`: Der Laufzeitvergleich wechselt vom Byte-Stream
|
||
auf einen getrimmten Bildschirm-Snapshot; neue Abdeckungsanforderung
|
||
für Bildschirm-, Formatierungs- und Datei-E/A-Semantik.
|
||
- `sprach-frontend`: `ON ERROR GOTO` auf Modulebene SHALL aus
|
||
Prozeduren heraus ansprechbar sein (bisher fälschlich lokal);
|
||
unquotierte `DATA`-Elemente SHALL ihren Rohtext behalten.
|
||
|
||
## Impact
|
||
|
||
- `crates/tb-ui`: `screen.rs` verliert Puffer und Semantik an
|
||
`tb-runtime`; zurück bleiben `basic_color` und `impl Widget` als
|
||
Adapter auf den Runtime-Puffer. Neue Abhängigkeit `tb-runtime`
|
||
(bisher waren beide Blätter im Abhängigkeitsgraphen); `forms.rs`
|
||
bleibt als Platzhalter für Phase 4 unberührt.
|
||
- `crates/tb-runtime`: neues `screen`-Modul; `host.rs` neu geschnitten
|
||
(**BREAKING**); `strings`, `format`, `math`, `datetime`, `fileio`,
|
||
`builtins` von Stub/Scheibe auf Vollimplementierung; neue
|
||
Abhängigkeit `unicode-width`.
|
||
- `crates/tb-frontend`: rund 50 `Unsupported`-Marker weichen echter
|
||
Absenkung; rund 30 bislang signaturlose Elemente (Finanzmathematik,
|
||
`MK…$`/`CV…`, `CURDIR$`, `DIR$`, `CHDRIVE`, `LPOS`, `STACK`, `SYSTEM`,
|
||
`ERDEV`/`ERDEV$`, `SetFormatCC`) erhalten Signaturen; `sema.rs` (`ON ERROR`-Scoping), `lexer.rs` (DATA-Rohtext).
|
||
- `crates/tb-vm`: neue Builtin-Indizes; `Instr::Unsupported` bleibt für
|
||
die verbleibenden Phase-4-Marker bestehen.
|
||
- `crates/tb-cli`: `tbc run` auf den neuen `Host`; Harness auf
|
||
Snapshot-Vergleich (**BREAKING** für die acht bestehenden `.out`).
|
||
- `tests/compat`: acht Golden Files neu erzeugt, neue Korpusdateien für
|
||
Bildschirm, `PRINT USING`, Datei-E/A, Datum/Zeit, breite Zeichen.
|
||
- `docs/`: neu `docs/inventar.md` und `docs/bibliothek.md`;
|
||
fortgeschrieben `docs/sprachreferenz.md` (Doppelzellen, `KEY n`,
|
||
`PRINT USING`-Überlauf) und `docs/tbvm-design.md`
|
||
(Konvertierungsmatrix). PLAN.md-Haken folgen bei Abschluss.
|