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:
@@ -41,11 +41,17 @@ enum Value {
|
||||
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.
|
||||
- **Fehlerbehandlung:** Zwei Ebenen (Scoping geklärt 2026-09-04).
|
||||
`ON LOCAL ERROR GOTO x` setzt einen Handler im aktuellen Frame; sein
|
||||
Sprungziel muss im selben Rumpf liegen. `ON ERROR GOTO x` **ohne**
|
||||
`LOCAL` setzt den modulweiten Handler — auch aus einer Prozedur heraus,
|
||||
und sein Sprungziel liegt dann im Modulrumpf (der Codegenerator löst es
|
||||
über Prozedur 0 auf, die zuerst übersetzt wird).
|
||||
Ein Laufzeitfehler sucht zuerst lokale Handler die Aufrufkette hinauf,
|
||||
dann den modulweiten; beim modulweiten wird bis Frame 0 abgewickelt,
|
||||
weshalb `RESUME NEXT` dort hinter dem Prozeduraufruf fortsetzt. Der
|
||||
Handler setzt `ERR`/`ERL`; `RESUME` nutzt den gemerkten
|
||||
Anweisungs-Offset. Ein Fehler im Handler ist fatal (keine Kaskaden).
|
||||
|
||||
## Ausführungsmodell / Unterbrechbarkeit
|
||||
|
||||
@@ -136,6 +142,20 @@ Windows 11, `cargo bench -p tb-vm`):**
|
||||
- DOUBLE-Schleife: ≈ 5,2 Mio Iterationen/s
|
||||
- SUB-Aufrufe mit BYREF: ≈ 5,2 Mio Aufrufe/s
|
||||
- String-Lasten (MID$/INSTR/Verkettung): ≈ 0,8 Mio Runden/s
|
||||
**Nachmessung nach Phase 3 (2026-09-04, macOS, Apple Silicon,
|
||||
`cargo bench -p tb-vm`)** — die Zustellpunkte des neuen `Host` (Anzeige
|
||||
nur bei geändertem Bildschirm, Ereignisabholung alle 1024 Anweisungen)
|
||||
kosten nichts Messbares:
|
||||
|
||||
- Compile-Budget: Einzelmodul 508 Zeilen **0,77 ms**; Projekt 49 760
|
||||
Zeilen **53 ms** (≈ 950 000 Zeilen/s)
|
||||
- VM-Durchsatz: INTEGER-Schleife **11,0 Mio/s**, DOUBLE **12,2 Mio/s**,
|
||||
SUB-Aufrufe **10,7 Mio/s**, String-Lasten **2,4 Mio Runden/s**
|
||||
|
||||
(Die höheren Zahlen gegenüber 2026-09-02 gehen auf die andere Maschine
|
||||
zurück, nicht auf eine Optimierung — gemessen wurde beide Male derselbe
|
||||
Benchmark.)
|
||||
|
||||
- Einordnung: bei ≈ 13 Instruktionen je Schleifeniteration entspricht
|
||||
das ≈ 60 Mio Instruktionen/s — Vorbild-Programme auf 1992er-Hardware
|
||||
werden um weit mehr als den Faktor 100 übertroffen; für 80×25-
|
||||
@@ -145,14 +165,18 @@ Windows 11, `cargo bench -p tb-vm`):**
|
||||
## Zahlenkonvertierungs-Matrix (Feindesign, 2026-09-02)
|
||||
|
||||
Grundlage: Original-Hilfe (Topics „Arithmetic Operators", „CINT/CLNG",
|
||||
„MOD", „Numeric Types"). Zellen ohne belastbare Fundstelle sind mit
|
||||
`TODO verify` markiert; der Korpustest `konvertierung.bas` verankert die
|
||||
Matrix ausführbar.
|
||||
„MOD", „Numeric Types"). Vier Punkte sind dort **nicht** geregelt; sie
|
||||
wurden am 2026-09-04 entschieden und sind unten als *Projektentscheidung*
|
||||
gekennzeichnet — sie gelten damit als bewusste Festlegung, nicht als
|
||||
rekonstruiertes Vorbildverhalten. Der Korpustest `konvertierung.bas`
|
||||
verankert die Matrix ausführbar.
|
||||
|
||||
**Rangfolge für Promotion:** INTEGER < LONG < CURRENCY < SINGLE < DOUBLE.
|
||||
Ausnahme: CURRENCY gemischt mit SINGLE oder DOUBLE ergibt **DOUBLE**
|
||||
(nicht SINGLE), damit keine Festkomma-Präzision in f32 verloren geht
|
||||
(`TODO verify` gegen PDS-Hilfe; plausibelste Lesart).
|
||||
(nicht SINGLE). *Projektentscheidung 2026-09-04:* Die Original-Hilfe
|
||||
regelt diesen Fall nicht. CURRENCY trägt 19 signifikante Stellen, SINGLE
|
||||
nur 7 — eine Promotion nach SINGLE zerstörte genau die Genauigkeit, für
|
||||
die es den Typ gibt. DOUBLE (16 Stellen) ist die nächstbeste Wahl.
|
||||
|
||||
**Ergebnistyp binärer Operatoren** (l op r; T = promoteter Typ):
|
||||
|
||||
@@ -161,7 +185,7 @@ Ausnahme: CURRENCY gemischt mit SINGLE oder DOUBLE ergibt **DOUBLE**
|
||||
| `+ - *` | T; gleiche Typen bleiben erhalten | Ganzzahl-/CURRENCY-Überlauf → Fehler 6 (auch INTEGER+INTEGER promotet **nicht**) |
|
||||
| `/` | DOUBLE, wenn ein Operand DOUBLE oder CURRENCY, sonst SINGLE | Division durch 0 → Fehler 11 |
|
||||
| `\` `MOD` | INTEGER, wenn beide Operanden INTEGER, sonst LONG | Operanden werden **vorher** kaufmännisch (banker's) auf Ganzzahl gerundet; außerhalb LONG → Fehler 6; Divisor 0 → Fehler 11; `MOD`-Vorzeichen wie Dividend |
|
||||
| `^` | DOUBLE, wenn ein Operand DOUBLE oder CURRENCY, sonst SINGLE (`TODO verify`) | Rechnung intern in DOUBLE; 0 ^ negativ → Fehler 11; negative Basis mit nicht-ganzem Exponent → Fehler 5 |
|
||||
| `^` | DOUBLE, wenn ein Operand DOUBLE oder CURRENCY, sonst SINGLE (*Projektentscheidung 2026-09-04*) | Rechnung intern in DOUBLE; 0 ^ negativ → Fehler 11; negative Basis mit nicht-ganzem Exponent → Fehler 5 |
|
||||
| `= <> < <= > >=` | INTEGER (−1/0) | Vergleich im promoteten Typ; Strings codepoint-weise |
|
||||
| `NOT AND OR XOR EQV IMP` | INTEGER, wenn alle Operanden INTEGER, sonst LONG | bitweise; Operanden vorher banker's-gerundet auf Ganzzahl, außerhalb LONG → Fehler 6 |
|
||||
| unäres `-` | Typ des Operanden | −(−32768) INTEGER → Fehler 6 |
|
||||
@@ -188,13 +212,21 @@ via `CINT`/`CLNG`/`CSNG`/`CDBL`/`CCUR` — identische Semantik):
|
||||
- INTEGER/LONG: dezimal ohne Dezimalpunkt.
|
||||
- SINGLE: bis 7 signifikante Stellen, kürzeste Darstellung, keine
|
||||
führende Null vor dem Dezimalpunkt (`.5`), keine nachgestellten
|
||||
Nullen; außerhalb des Festformat-Bereichs Exponentialform `mE±xx`
|
||||
(exakte Schwelle `TODO verify`; umgesetzt: Exponentialform, wenn der
|
||||
Dezimalexponent < −7 oder ≥ 7 ist).
|
||||
Nullen; außerhalb des Festformat-Bereichs Exponentialform `mE±xx`.
|
||||
*Projektentscheidung 2026-09-04:* Die Original-Hilfe nennt keine
|
||||
Schwelle. Gewählt ist der Dezimalexponent < −7 oder ≥ 7 — damit bleibt
|
||||
jeder Wert im Festformat, der sich mit den 7 signifikanten Stellen des
|
||||
Typs verlustfrei schreiben lässt (`9999999` fest, `1E+07`
|
||||
exponentiell; `.0000001` fest, `1E-08` exponentiell).
|
||||
- DOUBLE: wie SINGLE mit bis 16 signifikanten Stellen und `D±xx` als
|
||||
Exponentmarke.
|
||||
- CURRENCY: Festformat mit bis zu 4 Nachkommastellen, nachgestellte
|
||||
Nullen entfallen (`TODO verify`).
|
||||
Nullen entfallen (`2.5000@` → `2.5`, `1.10@` → `1.1`).
|
||||
*Projektentscheidung 2026-09-04:* Die Original-Hilfe nennt kein
|
||||
Ausgabeformat. Gewählt ist dieselbe Regel wie bei den übrigen
|
||||
Zahlentypen — nachgestellte Nullen entfallen —, damit `PRINT` über alle
|
||||
Typen einheitlich wirkt. Wer feste Nachkommastellen braucht, nutzt
|
||||
`PRINT USING`.
|
||||
- `PRINT` stellt nicht-negativen Zahlen ein Leerzeichen, negativen ein
|
||||
`-` voran und hängt stets ein Leerzeichen an; `STR$` nur das führende
|
||||
Leerzeichen/`-`, kein nachgestelltes.
|
||||
@@ -266,6 +298,9 @@ als Vergleichs-/Sprungkette abgesenkt.
|
||||
## Offene Punkte
|
||||
|
||||
Keine — die Punkte aus Phase 0 (Opcode-Satz, Konvertierungsmatrix,
|
||||
`STOP`/`CONT` im Runner) sind oben ausgearbeitet; verbleibende
|
||||
Detailunsicherheiten sind als `TODO verify` direkt an den betroffenen
|
||||
Zellen markiert und über den Testkorpus abgesichert.
|
||||
`STOP`/`CONT` im Runner) sind oben ausgearbeitet. Die vier Stellen, zu
|
||||
denen die Original-Hilfe schweigt, sind am 2026-09-04 als
|
||||
*Projektentscheidung* festgelegt, an Ort und Stelle begründet und über
|
||||
`tests/compat/konvertierung.bas` ausführbar verankert. Sollte je eine
|
||||
belastbare Fundstelle auftauchen, die ihnen widerspricht, gilt sie —
|
||||
die Entscheidungen sind Lückenfüller, keine Setzungen gegen das Vorbild.
|
||||
|
||||
Reference in New Issue
Block a user