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:
@@ -2,14 +2,17 @@
|
||||
|
||||
Rekonstruierte Referenz des Dialekts (DOS-BASIC, Stand 1992: prozedurale
|
||||
BASIC-Familie mit Forms-Erweiterung). Dieses Dokument ist die verbindliche
|
||||
Grundlage für Frontend und Runtime. Unklare Detailfragen sind mit `TODO`
|
||||
markiert und werden per Testkorpus geklärt bzw. entschieden.
|
||||
Grundlage für Frontend und Runtime. Offene Detailfragen sind ausgeräumt
|
||||
(Stand 2026-09-04); wo die Original-Dokumentation schweigt, steht an Ort
|
||||
und Stelle eine datierte Entscheidung mit Begründung.
|
||||
|
||||
**Primärquellen:** Original-Hilfedateien des Vorbilds als HTML unter
|
||||
https://dos-help.soulsphere.org/ (`qck.hlp` Quick Reference, `advr.hlp`
|
||||
Details, `ener.hlp` Fehlermeldungen; Vergleich PDS 7.1: `bas7qck.hlp`)
|
||||
sowie das Original-README der Professional Edition. Aussagen ohne
|
||||
TODO-Markierung sind daraus belegt.
|
||||
ausgewiesene Entscheidung sind daraus belegt; die Themenlisten von
|
||||
`bas7advr.hlp` und `qb45advr.hlp` bilden zusammen das
|
||||
Vollständigkeits-Inventar (docs/inventar.md).
|
||||
|
||||
**Guiding Principle:** Die Original-Dokumentation führt. Jedes dort
|
||||
dokumentierte Sprachelement wird unterstützt oder — nur nach expliziter
|
||||
@@ -94,7 +97,9 @@ stehen am Ende dieses Dokuments; nur diese Liste rechtfertigt Abweisungen.
|
||||
- `DIM [SHARED] var[(dims)] [AS typ]` — `AS`-Klausel: INTEGER, LONG, SINGLE,
|
||||
DOUBLE, STRING, STRING * n, CURRENCY, benutzerdefinierter Typ.
|
||||
- `COMMON [SHARED] [/blockname/] liste` — modulübergreifend (Kette
|
||||
CHAIN-kompatibel im Vorbild; TODO: Relevanz ohne CHAIN klären).
|
||||
CHAIN-kompatibel im Vorbild; ohne `CHAIN` bleibt `COMMON` die
|
||||
Verknüpfung mehrerer Module eines Projekts — geklärt mit der
|
||||
Projektverwaltung in Phase 5).
|
||||
- `SHARED` (in Prozedur): Zugriff auf Modulebene-Variablen.
|
||||
- `STATIC` (in Prozedur): Variablen behalten Werte zwischen Aufrufen;
|
||||
`STATIC`-Attribut an `SUB`/`FUNCTION` macht alle lokalen Variablen statisch.
|
||||
@@ -152,7 +157,8 @@ INTEGER −1 (wahr) / 0 (falsch).
|
||||
oder `DEF…`-Regel.
|
||||
- **Parameterübergabe standardmäßig BYREF.** Klammern um ein Argument
|
||||
(`CALL f((x))`) erzwingen Wertübergabe. `BYVAL` nur in `DECLARE` für
|
||||
externe Routinen (entfällt bei uns; TODO: `BYVAL` allgemein erlauben?).
|
||||
externe Routinen (entfällt bei uns; `BYVAL` allgemein zu erlauben wäre
|
||||
eine Erweiterung über den Kernstandard hinaus → Stufe 2, PLAN.md).
|
||||
- Arrays werden mit `name()` übergeben, TYPEs BYREF.
|
||||
- Rekursion erlaubt (außer bei `STATIC`-Semantik-Konflikten).
|
||||
- `DEF FNname (args) = ausdruck` und Block-`DEF FN … END DEF` (mit
|
||||
@@ -194,8 +200,21 @@ solange ein Menü-Control den Fokus hat. Für Terminal Basic relevant:
|
||||
position, `-` nachgestelltes Minus, `$$` führendes $, `**` Füllsterne,
|
||||
`**$` kombiniert, `^^^^` Exponent; String `&` ganz, `!` erstes Zeichen,
|
||||
`\ \` n Zeichen (Leerzeichen + 2); `_` Literal-Escape; alle anderen
|
||||
Zeichen literal. TODO: `%`-Präfix bei Feldüberlauf (QB-Verhalten) in der
|
||||
Vorbild-Hilfe nicht gelistet — per Test klären, wir übernehmen es vorerst.
|
||||
Zeichen literal.
|
||||
- **Feldüberlauf** (geklärt 2026-09-04): Passt ein Wert nicht in sein
|
||||
Feld, wird er vollständig ausgegeben und die Ausgabe mit `%`
|
||||
eingeleitet (`PRINT USING "##"; 12345` → `%12345`). Die Original-Hilfe
|
||||
listet das nicht; wir übernehmen das Verhalten der QB-Familie, weil ein
|
||||
stilles Abschneiden Zahlen verfälschen würde.
|
||||
- Vorzeichenangaben (`+` vorn, `+`/`-` hinten) belegen eine **eigene**
|
||||
Position neben den Ziffernstellen; `$$` und `**` bringen ihre Stellen
|
||||
dagegen mit.
|
||||
- Die Formatzeichenkette wird wiederholt, solange Werte übrig sind. Eine
|
||||
Zeichenkette ohne Feld bei vorhandenen Werten löst Fehler 5 aus.
|
||||
- `SetFormatCC(ländercode)` setzt das Zeichen für `$$`. Nur wenige Codes
|
||||
sind belegt (1 = `$`, 33 = `F`, 39 = `L`, 44 = `£`, 49 = `DM`,
|
||||
81 = `¥`); alle übrigen behalten `$` — die Tabelle des Vorbilds ist
|
||||
nicht überliefert (dokumentierte Abweichung).
|
||||
- `INPUT ["prompt"{;|,}] var, …` (mit `;` vor Prompt: kein „? ");
|
||||
`LINE INPUT` (ganze Zeile in String).
|
||||
- `INKEY$` (nicht blockierend; "" wenn leer; erweiterte Tasten:
|
||||
@@ -205,13 +224,26 @@ solange ein Menü-Control den Fokus hat. Für Terminal Basic relevant:
|
||||
— arbeiten auf der tatsächlichen Bildschirmgröße (dynamisch, s. Abweichungen).
|
||||
- `COLOR [vg][,hg]` (vg 0–31: 16–31 = blinkend — bei uns als „hell"
|
||||
simuliert, Entscheidung 2026-09-02; hg 0–7), `CLS`,
|
||||
`WIDTH` (im Vorbild 80/40 — bei uns wirkungslos, s. Abweichungen),
|
||||
`WIDTH` (hebt den Puffer höchstens an, s. Abweichungen),
|
||||
`VIEW PRINT oben TO unten` (Scrollbereich).
|
||||
- `TAB(n)`, `SPC(n)` in PRINT-Listen.
|
||||
- `BEEP`, `SOUND freq, dauer` (Terminal-Bell / Nicht-Ziel, s. Abweichungen),
|
||||
`PLAY` (Nicht-Ziel).
|
||||
- `KEY n, text$` / `KEY LIST` / `KEY ON/OFF` (Funktionstasten-Makros +
|
||||
Statuszeile) — TODO: Umfang klären.
|
||||
- **Funktionstasten-Makros** (Umfang geklärt 2026-09-03 aus der
|
||||
Original-Hilfe):
|
||||
- `KEY n, text$` belegt ein Makro. `n` ist 1–10 für F1–F10 sowie 30 und
|
||||
31 für F11/F12; andere Werte lösen Fehler 5 aus. `text$` wird nach
|
||||
**15 Zeichen** abgeschnitten.
|
||||
- `KEY LIST` gibt alle zwölf Makros untereinander aus.
|
||||
- `KEY ON` blendet die Softkey-Zeile in der untersten Bildschirmzeile ein
|
||||
(Tastennummer plus die ersten sechs Zeichen des Makros), `KEY OFF`
|
||||
blendet sie aus. Solange sie sichtbar ist, endet der Scrollbereich
|
||||
darüber, damit die Ausgabe sie nicht überschreibt; ein danach gesetztes
|
||||
`VIEW PRINT` hat Vorrang.
|
||||
- `KEY(n) ON|OFF|STOP` **mit** Index ist Ereignissteuerung und kommt mit
|
||||
der Forms-Engine (Phase 4).
|
||||
- Abweichung: ein kompiliertes Programm startet mit **leeren** Makros;
|
||||
die Vorbelegung des Vorbilds gehörte zu dessen Interpreter-Oberfläche.
|
||||
|
||||
## 10. Datei-E/A
|
||||
|
||||
@@ -240,8 +272,20 @@ solange ein Menü-Control den Fokus hat. Für Terminal Basic relevant:
|
||||
`HEX$`, `OCT$`, `LSET`/`RSET` (Anweisungen).
|
||||
|
||||
**Mathematik:** `ABS`, `SGN`, `INT` (abrunden), `FIX` (Richtung 0), `SQR`,
|
||||
`EXP`, `LOG`, `SIN`, `COS`, `TAN`, `ATN`, `RND[(n)]`, `RANDOMIZE [saat]`
|
||||
(kompatibler PRNG! → Testkorpus), `CINT`, `CLNG`, `CSNG`, `CDBL`, `CCUR`.
|
||||
`EXP`, `LOG`, `SIN`, `COS`, `TAN`, `ATN`, `RND[(n)]`, `RANDOMIZE [saat]`,
|
||||
`CINT`, `CLNG`, `CSNG`, `CDBL`, `CCUR`.
|
||||
|
||||
**Zufallszahlen.** Der Generator ist der lineare Kongruenzgenerator des
|
||||
Vorbilds auf 24 Bit:
|
||||
`zustand = (zustand · &H FD43FD + &H C39EC3) MOD 2^24`, Ergebnis
|
||||
`zustand / 2^24` als SINGLE im Bereich [0, 1).
|
||||
`RND` und `RND(n)` mit `n > 0` liefern die nächste Zahl, `RND(0)`
|
||||
wiederholt die zuletzt gelieferte, `RND(n)` mit `n < 0` setzt den Zustand
|
||||
aus dem Argument. `RANDOMIZE saat` bildet aus der Saat 16 Bit, die die
|
||||
Bits 8–23 des Zustands besetzen; das niederwertige Byte ist fest — damit
|
||||
liefert dieselbe Saat stets dieselbe Folge, unabhängig von vorherigen
|
||||
`RND`-Aufrufen. `RANDOMIZE` ohne Argument fragt den Startwert mit
|
||||
`Random Number Seed (-32768 to 32767)?` ab.
|
||||
|
||||
**Datum/Zeit:** `DATE$` (Funktion und Anweisung — Setzen: Nicht-Ziel),
|
||||
`TIME$`, `TIMER` (Sekunden seit Mitternacht, SINGLE); dazu die nativen
|
||||
@@ -287,7 +331,13 @@ Dialoge:
|
||||
- Der Bildschirmpuffer speichert Unicode-Zeichen; Rahmen werden mit
|
||||
Unicode-Box-Drawing gezeichnet.
|
||||
- Zeichen mit Darstellungsbreite 2 (Emoji, CJK) **belegen zwei Zellen**
|
||||
(Entscheidung 2026-09-02; Umsetzung Phase 3).
|
||||
(Entscheidung 2026-09-02, umgesetzt): der Cursor rückt um zwei Spalten
|
||||
vor, `POS` nennt die Anfangsspalte, `LOCATE` auf die zweite Hälfte
|
||||
wirkt auf den Zeichenanfang. Passt ein breites Zeichen nicht mehr in
|
||||
die Zeile, wandert es als Ganzes in die nächste und die letzte Spalte
|
||||
bleibt leer. Wird eine Hälfte überschrieben, verschwindet die andere.
|
||||
Zeichen der Breite 0 (kombinierende Zeichen) belegen vorerst eine
|
||||
eigene Zelle.
|
||||
- `GET`/`PUT`-Records: feste Strings (`STRING * n`) werden als **UTF-32**
|
||||
gespeichert (4 Bytes/Zeichen, feste Record-Länge) — Binärdateien sind
|
||||
dadurch bewusst inkompatibel zum Vorbild (Entscheidung 2026-09-02).
|
||||
@@ -295,20 +345,60 @@ Dialoge:
|
||||
`OUT`/`WAIT`/`BLOAD`/`BSAVE`/`VARPTR`/`VARSEG`/`SADD`/`CALL ABSOLUTE`/
|
||||
`CALL INTERRUPT`/`IOCTL` werden bereits **zur Compile-Zeit** mit der
|
||||
Meldung „Feature unavailable" abgewiesen (kein Laufzeitfehler).
|
||||
3. **`INKEY$` für erweiterte Tasten** liefert weiterhin
|
||||
`CHR$(0) + code`-Sequenzen mit den klassischen Scancodes (F1 = `CHR$(0)+";"`
|
||||
usw.), damit bestehender Code funktioniert. Zusätzliche moderne Tasten:
|
||||
TODO.
|
||||
Ebenso abgewiesen: die Interlanguage-Schnittstelle (`CALLS`, `SSEG`,
|
||||
`SSEGADD`, `StringAddress`/`StringAssign`/`StringLength`/
|
||||
`StringRelease`), die Eingabegeräte `PEN`, `STRIG`, `STICK` und die
|
||||
serielle Schnittstelle (`COM`, `ON COM`, `OPEN "COMn:"`).
|
||||
3. **`INKEY$` für erweiterte Tasten** liefert `CHR$(0) + code`-Sequenzen
|
||||
mit den klassischen Scancodes, damit bestehender Code funktioniert
|
||||
(festgelegt 2026-09-04): F1–F10 = 59–68, Pos1 = 71, ↑ = 72, Bild↑ = 73,
|
||||
← = 75, → = 77, Ende = 79, ↓ = 80, Bild↓ = 81, Einfg = 82, Entf = 83.
|
||||
Zeichentasten liefern ein Zeichen, Eingabe `CHR$(13)`, Rückschritt
|
||||
`CHR$(8)`, Esc `CHR$(27)`, Tabulator `CHR$(9)`. Strg+C und Strg+Untbr
|
||||
sind Abbruch und erscheinen nicht in `INKEY$`. Tasten heutiger
|
||||
Tastaturen ohne Entsprechung im Vorbild (etwa F11/F12 oder Meta-
|
||||
Kombinationen) liefern nichts — eine eigene Kodierung dafür wäre eine
|
||||
Erweiterung und gehört in Stufe 2.
|
||||
4. **Kein `CHAIN`/Overlay-Mechanismus**; `SHELL` startet die System-Shell.
|
||||
5. **Grafik-Anweisungen** (`SCREEN n>0`, `PSET`, `LINE`, `CIRCLE`, `PAINT`,
|
||||
`DRAW`, Grafik-`GET`/`PUT`, `PALETTE`, `WINDOW`/`VIEW`, `PMAP`, `PCOPY`)
|
||||
sind Nicht-Ziel (Fehler 73). Hinweis: das Vorbild **hatte** die
|
||||
5. **Grafik-Anweisungen** (`SCREEN n>0`, `PSET`, `PRESET`, `LINE`,
|
||||
`CIRCLE`, `PAINT`, `DRAW`, Grafik-`GET`/`PUT`, `PALETTE`, `WINDOW`,
|
||||
`VIEW`, `PMAP`, `PCOPY`, `POINT`) sind Nicht-Ziel und werden **zur
|
||||
Compile-Zeit** mit „Feature unavailable" abgewiesen. Die Formen, die
|
||||
sich ein Schlüsselwort mit einer unterstützten Anweisung teilen, erkennt
|
||||
der Compiler an ihrer Syntax: `LINE` ohne `INPUT`, `GET`/`PUT` mit
|
||||
`(`, `VIEW` ohne `PRINT`. Hinweis: das Vorbild **hatte** die
|
||||
Grafikmodi 0–13, aber nicht gleichzeitig mit Forms (dort Fehler 272
|
||||
„Invalid when forms are showing") — wir übernehmen nur den
|
||||
Forms-/Textmodus-Zweig.
|
||||
6. **`PLAY`/`SOUND`**: `BEEP` = Terminal-Bell; Rest Nicht-Ziel (Fehler 73).
|
||||
5a. **`LPRINT` schreibt in eine Datei** (2026-09-03): einen
|
||||
plattformübergreifenden Druckerkanal gibt es nicht. Der Druckerpuffer
|
||||
geht am Programmende in `LPT1.TXT` im aktuellen Verzeichnis; `LPOS`
|
||||
nennt die Spalte in diesem Puffer.
|
||||
5b. **Satzsperren** (`LOCK`/`UNLOCK`) prüfen nur, ob die Datei offen ist;
|
||||
eine echte Sperre bietet die Plattform nicht einheitlich. `FILEATTR`
|
||||
liefert nur die Modus-Kennzahl (Argument 1); das
|
||||
Betriebssystem-Handle bildet der Dialekt nicht ab und liefert 0.
|
||||
5c. **`CHDRIVE`** ist außerhalb von Windows folgenlos — Laufwerksbuchstaben
|
||||
gibt es dort nicht.
|
||||
6a. **Uhr läuft in UTC** (2026-09-03): `DATE$`, `TIME$`, `TIMER` und `NOW`
|
||||
liefern koordinierte Weltzeit, nicht Ortszeit — die Standardbibliothek
|
||||
von Rust kennt keine Zeitzonen, und eine Zeitzonenbibliothek wäre die
|
||||
erste schwere Abhängigkeit der Laufzeit. `DATE$ = …` und `TIME$ = …`
|
||||
stellen nicht die Systemuhr, sondern einen programmeigenen Versatz;
|
||||
alle Zeitfunktionen rechnen ihn mit ein.
|
||||
6b. **Serielle Datumswerte** zählen Tage ab dem 30.12.1899 (Serie 2 =
|
||||
1.1.1900), der Nachkommaanteil ist die Tageszeit. `WEEKDAY` liefert 1
|
||||
für Sonntag. Zweistellige Jahre gelten in `DATESERIAL` als 19xx, in
|
||||
`DATEVALUE` als 20xx unter 80 und sonst als 19xx.
|
||||
7. **Dynamische Bildschirmgröße** (2026-09-02): kein festes 80×25 — der
|
||||
Bildschirm folgt der Terminalgröße (Mindestgröße 80×25, darunter nur
|
||||
ein Hinweis). `CSRLIN`/`POS`/`LOCATE`/`VIEW PRINT` und das
|
||||
`SCREEN`-Objekt arbeiten auf der tatsächlichen Größe. `WIDTH 40/80`
|
||||
wird akzeptiert, ändert aber nichts (die Größe bestimmt das Terminal).
|
||||
80×25 ist überall nur die **untere Schranke der Darstellung**, nie eine
|
||||
Bildschirmgröße im Verhalten des Programms. Ändert sich die Größe
|
||||
**während der Ausführung**, wird das zugestellt: der Inhalt bleibt oben
|
||||
links erhalten, der Cursor wird in die neuen Grenzen geklemmt, und ein
|
||||
`VIEW PRINT`-Bereich wird am unteren Rand geklemmt bzw. — wenn er ganz
|
||||
vom Schirm fällt — auf den vollen Bildschirm zurückgesetzt.
|
||||
|
||||
Reference in New Issue
Block a user