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>
9.0 KiB
ADDED Requirements
Requirement: Zellenpuffer ohne Terminalabhängigkeit
Der Zellenpuffer mit der vollständigen Bildschirmsemantik (Cursor, Farbattribute, Umbruch, Scrollen, Scrollbereich, Größenänderung) SHALL ohne Terminal instanziierbar, veränderbar und auslesbar sein. Die Anbindung an ein konkretes Terminal SHALL ausschließlich in der Darstellungsschicht liegen. Damit MUST jedes Bildschirmverhalten in automatischen Tests ohne Terminal prüfbar sein, und die Ausführungsschicht MUST NOT von einer Terminal-Bibliothek abhängen.
Scenario: Bildschirmverhalten im Test ohne Terminal
- WHEN ein Testprogramm in einer Umgebung ohne Terminal
LOCATE 5, 10 : PRINT "x"ausführt - THEN trägt die Zelle (5, 10) das Zeichen
xund der Test benötigt kein Terminal
Requirement: Bildschirmanweisungen des Dialekts
CLS, COLOR, LOCATE, WIDTH, VIEW PRINT und die Anweisungsform von
SCREEN SHALL auf dem Zellenpuffer wirken. CLS SHALL den Scrollbereich
löschen und den Cursor an dessen Anfang setzen; CLS 2 SHALL nur den
Textbereich löschen. COLOR SHALL Vordergrund und Hintergrund für
nachfolgende Ausgaben setzen, ausgelassene Argumente lassen den bisherigen
Wert unverändert. WIDTH SHALL die Spalten- und Zeilenzahl setzen, soweit
die Darstellungsfläche es zulässt. VIEW PRINT oben TO unten SHALL den
Scrollbereich begrenzen, VIEW PRINT ohne Argumente ihn auf den ganzen
Bildschirm zurücksetzen.
Scenario: CLS setzt Cursor zurück
- WHEN nach Ausgaben in Zeile 10
CLSausgeführt wird - THEN ist der Puffer leer und
CSRLINliefert 1,POS(0)liefert 1
Scenario: COLOR wirkt nur auf Folgeausgaben
- WHEN
PRINT "a" : COLOR 14, 1 : PRINT "b"ausgeführt wird - THEN trägt die Zelle mit
adas vorherige Attribut und die Zelle mitbVordergrund 14 auf Hintergrund 1
Scenario: Ausgelassenes COLOR-Argument
- WHEN nach
COLOR 14, 1die AnweisungCOLOR , 4ausgeführt wird - THEN bleibt der Vordergrund 14 und der Hintergrund wird 4
Requirement: Bildschirm-Abfragefunktionen
CSRLIN SHALL die aktuelle Cursorzeile liefern, POS(0) die aktuelle
Cursorspalte, beide 1-basiert. Die Funktionsform SCREEN(zeile, spalte [, farbe]) SHALL das Zeichen an der genannten Position als Codepoint
liefern, bei gesetztem dritten Argument stattdessen dessen Farbattribut.
Positionen außerhalb des Bildschirms MUST Laufzeitfehler 5 „Illegal
function call" auslösen.
Scenario: Zeichen zurücklesen
- WHEN
LOCATE 3, 7 : PRINT "Q";ausgeführt und danachSCREEN(3, 7)ausgewertet wird - THEN liefert
SCREEN(3, 7)den Codepoint vonQ
Scenario: Abfrage außerhalb des Bildschirms
- WHEN bei 80×25
SCREEN(30, 1)ausgewertet wird - THEN tritt Laufzeitfehler 5 auf
Requirement: Tastatureingabe ohne Zeilenmodell
INKEY$ SHALL ohne zu blockieren die nächste anstehende Taste liefern:
den leeren String bei leerem Puffer, ein Zeichen bei einer
Zeichentaste, eine zwei Zeichen lange Folge mit führendem Nullzeichen bei
einer Sondertaste. INPUT$(n [, #dateinummer]) SHALL genau n Zeichen
lesen und dabei blockieren, ohne sie am Bildschirm zu wiederholen.
Scenario: INKEY$ bei leerem Tastaturpuffer
- WHEN
INKEY$ohne anstehende Taste ausgewertet wird - THEN liefert es den leeren String und blockiert nicht
Scenario: Sondertaste als zwei Zeichen
- WHEN F1 gedrückt wurde und
INKEY$ausgewertet wird - THEN hat das Ergebnis die Länge 2 und beginnt mit dem Nullzeichen
Requirement: Keine feste Bildschirmgröße im Verhalten
Kein beobachtbares Verhalten SHALL eine feste Spalten- oder Zeilenzahl
voraussetzen. Wo die Referenz des Vorbilds von 80×25 spricht, ist stets
der volle aktuelle Bildschirm gemeint. Insbesondere SHALL CLS den
vollen aktuellen Bildschirm löschen, der Scrollbereich ohne eigene
VIEW PRINT-Einstellung den vollen aktuellen Bildschirm umfassen, der
Zeilenumbruch an der aktuell letzten Spalte erfolgen, das Scrollen an
der aktuell letzten Zeile des Bereichs auslösen und die Grenzprüfung von
LOCATE und der Funktionsform von SCREEN gegen die aktuellen
Abmessungen prüfen. Die Werte 80 und 25 MUST NOT als Grenze in
beobachtbarem Verhalten auftreten.
Scenario: Löschen und Scrollen auf großem Bildschirm
- WHEN der Bildschirm 120×40 misst, in Zeile 40 ein Umbruch erfolgt und danach
CLSausgeführt wird - THEN scrollt der Bildschirm erst an Zeile 40 und
CLSlöscht alle 40 Zeilen
Scenario: Adressierbarkeit jenseits von 80×25
- WHEN der Bildschirm 120×40 misst und
LOCATE 40, 120ausgeführt wird - THEN entsteht kein Fehler und
CSRLINliefert 40,POS(0)liefert 120
Requirement: Größenänderung zur Laufzeit
Ändert sich die Größe der Darstellungsfläche während ein Programm läuft,
SHALL die Größenänderung als Ereignis bis zum Bildschirmzustand
durchgereicht und der Zellenpuffer angepasst werden. Der Inhalt SHALL
oben links erhalten bleiben; der Cursor SHALL in die neuen Grenzen
geklemmt werden; ein VIEW PRINT-Bereich, der nicht mehr vollständig in
den Bildschirm passt, SHALL auf die neuen Grenzen geklemmt und, falls er
dadurch leer würde, auf den vollen Bildschirm zurückgesetzt werden. Alle
programmseitig sichtbaren Größen — CSRLIN, POS, die Grenzen von
LOCATE und der Funktionsform von SCREEN — MUST unmittelbar nach der
Änderung die neuen Abmessungen widerspiegeln.
Scenario: Vergrößerung während der Ausführung
- WHEN ein laufendes Programm bei 80×25 ausgibt und die Fläche auf 120×40 wächst
- THEN bleibt der bisherige Inhalt oben links stehen und
LOCATE 40, 120ist danach zulässig
Scenario: Verkleinerung klemmt den Cursor
- WHEN der Cursor auf Zeile 40 steht und die Fläche auf 80×25 schrumpft
- THEN liegt der Cursor danach innerhalb der neuen Grenzen
Scenario: Scrollbereich überlebt die Verkleinerung
- WHEN
VIEW PRINT 30 TO 38gesetzt ist und die Fläche auf 25 Zeilen schrumpft - THEN ist der Scrollbereich danach gültig und liegt vollständig innerhalb des Bildschirms
MODIFIED Requirements
Requirement: Dynamische Terminalgröße mit Mindestmaß
Der Bildschirm SHALL der Terminalgröße folgen (Puffer per resize
anpassbar; Inhalt bleibt oben links erhalten, Cursor wird geklemmt).
Die Größe SHALL zu jedem Zeitpunkt aus der Darstellungsfläche abgeleitet
und nicht fest vorgegeben werden. Die Mindestgröße ist 80×25: kleinere
Werte werden auf 80×25 geklemmt, und ist die Render-Fläche kleiner als
80×25, SHALL nur ein Hinweis „Terminal zu klein" mit Ist- und
Mindestgröße gerendert werden. Dieses Mindestmaß ist ausschließlich eine
untere Schranke der Darstellung; es MUST NOT als Bildschirmgröße im
Verhalten des Programms auftreten, solange die Fläche größer ist.
Scenario: Vergrößertes Terminal
- WHEN der Bildschirm auf 120×40 gesetzt wird
- THEN sind alle 120 Spalten und 40 Zeilen adressierbar (
LOCATE 40, 120)
Scenario: Zu kleines Terminal
- WHEN die Render-Fläche 60×20 misst
- THEN erscheint statt des Puffers der Hinweis mit Minimum 80×25
Requirement: Unicode-Zellenmodell
Der Puffer SHALL Unicode-Zeichen speichern (keine CP437-Emulation).
Zeichen mit Darstellungsbreite 2 (u. a. Emoji, CJK) SHALL zwei
nebeneinanderliegende Zellen belegen (Entscheidung 2026-09-02): die erste
trägt das Zeichen, die zweite ist als Fortsetzung markiert und MUST NOT
eigenständig beschrieben werden. Der Cursor SHALL nach der Ausgabe eines
breiten Zeichens um zwei Spalten vorrücken; POS SHALL die Spalte des
Zeichenanfangs zählen. Passt ein breites Zeichen nicht mehr in die letzte
Spalte, SHALL es vollständig in die nächste Zeile umgebrochen werden und
die letzte Spalte leer bleiben. LOCATE auf die Fortsetzungszelle SHALL
auf den Zeichenanfang wirken.
Scenario: Umlaute und Symbole
- WHEN
Ä☃ausgegeben wird - THEN belegen
Äund☃je genau eine Zelle
Scenario: Breites Zeichen belegt zwei Zellen
- WHEN an Spalte 1 ein CJK-Zeichen ausgegeben wird
- THEN ist Spalte 2 als Fortsetzung belegt und der Cursor steht auf Spalte 3
Scenario: Breites Zeichen am rechten Rand
- WHEN bei 80 Spalten der Cursor auf Spalte 80 steht und ein breites Zeichen ausgegeben wird
- THEN bleibt Spalte 80 leer und das Zeichen steht in Spalte 1 der Folgezeile
Requirement: 1-basierte Cursor-API mit Bereichsprüfung
LOCATE, CSRLIN und POS SHALL 1-basiert arbeiten. LOCATE
außerhalb der aktuellen Bildschirmgrenzen SHALL Laufzeitfehler 5
„Illegal function call" auslösen. Ausgelassene Argumente von LOCATE
SHALL den jeweiligen Wert unverändert lassen; die Argumente für
Cursorsichtbarkeit und Cursorform SHALL entgegengenommen und, soweit das
Terminal sie nicht abbilden kann, folgenlos bleiben.
Scenario: Grenzprüfung
- WHEN bei 80×25
LOCATE 26, 1aufgerufen wird - THEN tritt Laufzeitfehler 5 auf
Scenario: Ausgelassenes LOCATE-Argument
- WHEN der Cursor auf (5, 9) steht und
LOCATE , 3ausgeführt wird - THEN steht der Cursor auf (5, 3)