Zwei neue Capabilities in den Hauptspecs: - datei-eio: Dateiverwaltung, drei Zugriffsarten, UTF-32-Festtextfelder, Recordkonvertierung, Sperren, Dateisystem-Anweisungen - sprachinventar: das Vollstaendigkeits-Inventar als pruefbares Artefakt Fortgeschrieben: textbildschirm (Doppelzellen, Groessenunabhaengigkeit, Bildschirmanweisungen), konsolen-basisbibliothek (Host-Neuschnitt, volle String-/Format-/Datums-/Finanzbibliothek), kompat-testkorpus (Snapshot-Vergleich, Nachweis der Groessenunabhaengigkeit), sprach-frontend (Signaturpflicht, ON-ERROR-Scoping, DATA-Rohtext). Bilanz: +32 Anforderungen, 6 geaendert, 1 ersetzt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
8.9 KiB
datei-eio Specification
Purpose
Die Datei-E/A stellt die Dateiverwaltung des Dialekts bereit: sequenzieller, wahlfreier und binärer Zugriff über Dateinummern, Record-Puffer mit Festtextfeldern, Positions- und Statusfunktionen sowie die Dateisystem-Anweisungen — plattformübergreifend und mit den Laufzeitfehlern des Vorbilds.
Requirements
Requirement: Dateinummern und Öffnen in drei Zugriffsarten
OPEN SHALL in beiden Syntaxen des Vorbilds (Klausel- und Kurzform) die
Zugriffsarten sequenziell (INPUT, OUTPUT, APPEND), wahlfrei
(RANDOM) und binär (BINARY) unterstützen und die Datei an eine
Dateinummer binden. FREEFILE SHALL die kleinste freie Dateinummer
liefern. CLOSE ohne Argument SHALL alle offenen Dateien schließen,
RESET ebenso. Eine bereits belegte Dateinummer MUST Laufzeitfehler 55
„File already open" auslösen, eine nicht geöffnete Nummer Fehler 52
„Bad file name or number", eine fehlende Datei bei INPUT Fehler 53
„File not found".
Scenario: Sequenzielles Schreiben und Lesen
- WHEN eine Datei mit
OPEN "d.txt" FOR OUTPUT AS #1beschrieben, geschlossen und mitFOR INPUTwieder geöffnet wird - THEN liefert das Lesen genau die geschriebenen Zeilen
Scenario: Doppeltes Öffnen derselben Nummer
- WHEN
OPENeine bereits offene Dateinummer verwendet - THEN tritt Laufzeitfehler 55 auf
Scenario: Freie Dateinummer
- WHEN
#1offen ist undFREEFILEaufgerufen wird - THEN liefert
FREEFILEeine Nummer, die noch nicht belegt ist
Requirement: Sequenzielle Datenübertragung
PRINT # SHALL wie PRINT formatieren (Druckzonen, Zahlendarstellung mit
Vorzeichenspalte), WRITE # SHALL Elemente komma-getrennt mit Strings in
Anführungszeichen schreiben. INPUT # SHALL komma-getrennte Felder lesen
und dabei Anführungszeichen auswerten, LINE INPUT # die ganze Zeile ohne
Zeilenende. EOF SHALL das Erreichen des Dateiendes melden; Lesen über das
Dateiende hinaus MUST Laufzeitfehler 62 „Input past end of file" auslösen.
Scenario: WRITE # und INPUT # sind gegenläufig
- WHEN
WRITE #1, "a,b", 5geschrieben und die Zeile mitINPUT #1, s$, ngelesen wird - THEN enthält
s$den Texta,bundnden Wert 5
Scenario: Lesen über das Dateiende
- WHEN
INPUT #1, xnach dem letzten Datensatz ausgeführt wird - THEN tritt Laufzeitfehler 62 auf
Requirement: Wahlfreier Zugriff mit Record-Puffern
OPEN … FOR RANDOM … LEN = n SHALL Datensätze fester Länge bereitstellen.
GET und PUT SHALL einen Datensatz an einer 1-basierten Recordnummer
lesen bzw. schreiben; ohne Nummer gilt der Satz nach der letzten Operation.
FIELD SHALL den Recordpuffer in benannte Festtextfelder aufteilen,
LSET/RSET SHALL links- bzw. rechtsbündig in ein Feld schreiben und
überlange Werte abschneiden. Alternativ SHALL GET/PUT mit einer
Variablen eines benutzerdefinierten Typs arbeiten.
Scenario: Datensatz schreiben und an gleicher Stelle lesen
- WHEN ein Record an Position 3 geschrieben und anschließend von Position 3 gelesen wird
- THEN stimmen alle Feldwerte mit den geschriebenen überein
Scenario: RSET schneidet ab
- WHEN in ein Feld der Länge 5 mit
RSETder TextABCDEFGgeschrieben wird - THEN enthält das Feld genau 5 Zeichen
Requirement: Record-Konvertierungsfunktionen
Die Bibliothek SHALL die Konvertierungsfunktionen für Recordpuffer
bereitstellen: MKI$, MKL$, MKS$, MKD$ und MKC$ wandeln einen
numerischen Wert in seine Byte-Darstellung als String, CVI, CVL,
CVS, CVD und CVC wandeln zurück. Jedes Paar MUST gegenläufig sein.
Ein Argument, dessen Länge nicht zur Zielbreite passt, MUST
Laufzeitfehler 5 „Illegal function call" auslösen. MKSMBF$, MKDMBF$,
CVSMBF und CVDMBF SHALL dieselbe Rolle für das
Microsoft-Binärformat älterer BASIC-Versionen erfüllen; ist dieses
Format ein deklariertes Non-Feature, MUST die Ablehnung namentlich
erfolgen und in der Sprachreferenz unter „Abweichungen" stehen.
Scenario: MK und CV sind gegenläufig
- WHEN
CVL(MKL$(123456))ausgewertet wird - THEN ist das Ergebnis 123456
Scenario: Falsche Argumentlänge
- WHEN
CVI("x")mit einem ein Zeichen langen String ausgewertet wird - THEN tritt Laufzeitfehler 5 auf
Requirement: Festtextfelder als UTF-32 mit fester Recordlänge
Feste Strings (STRING * n) in Recordpuffern SHALL als UTF-32 gespeichert
werden — 4 Bytes je Zeichen, damit STRING * n stets genau 4 * n Bytes
belegt und die Recordlänge unabhängig vom Zeicheninhalt konstant bleibt.
Die daraus folgende Binär-Inkompatibilität zu Dateien des Vorbilds ist
beschlossen (2026-09-02) und MUST in der Sprachreferenz unter
„Abweichungen" dokumentiert sein.
Scenario: Recordlänge unabhängig vom Inhalt
- WHEN in ein Feld
STRING * 10einmalabcund einmaläöüßÄÖÜgeschrieben wird - THEN belegt der Datensatz in beiden Fällen dieselbe Byteanzahl und der Folgesatz beginnt an derselben Position
Requirement: Binärzugriff auf Byteebene
OPEN … FOR BINARY SHALL byteweise Positionierung erlauben. GET/PUT
SHALL an einer 1-basierten Byteposition lesen bzw. schreiben, wobei die
übertragene Länge der Größe der Zielvariablen entspricht. SEEK als
Anweisung SHALL die Position setzen, SEEK als Funktion sie liefern.
Scenario: Positioniertes Byte überschreiben
- WHEN in einer Binärdatei an Position 4 ein Byte geschrieben und anschließend gelesen wird
- THEN liefert das Lesen den geschriebenen Wert und die übrigen Bytes bleiben unverändert
Requirement: Positions- und Statusfunktionen
LOF SHALL die Dateigröße in Bytes liefern, LOC die aktuelle Position
in der Einheit der Zugriffsart (Datensatz bei RANDOM, Byte bei
BINARY), SEEK die nächste Lese-/Schreibposition und FILEATTR den
Modus bzw. das Betriebssystem-Handle. Alle Funktionen MUST bei einer nicht
geöffneten Dateinummer Laufzeitfehler 52 auslösen.
Scenario: Größe nach dem Schreiben
- WHEN 100 Bytes geschrieben wurden und
LOF(1)aufgerufen wird - THEN liefert
LOF(1)den Wert 100
Scenario: Statusfunktion auf geschlossener Datei
- WHEN
LOF(9)ohne offene Datei 9 aufgerufen wird - THEN tritt Laufzeitfehler 52 auf
Requirement: Satzsperren
LOCK und UNLOCK SHALL einen Datensatz-, Byte- oder den gesamten
Dateibereich sperren und wieder freigeben. Auf Plattformen ohne
entsprechende Sperrmechanik MUST das Verhalten in der Sprachreferenz unter
„Abweichungen" dokumentiert sein statt still abzuweichen.
Scenario: Sperren und Freigeben
- WHEN ein Datensatzbereich gesperrt und anschließend mit denselben Grenzen freigegeben wird
- THEN läuft die Folgeoperation auf diesem Bereich ohne Fehler
Requirement: Dateisystem-Anweisungen mit plattformübergreifender Pfadsemantik
KILL, NAME … AS, FILES, CHDIR, CHDRIVE, MKDIR, RMDIR,
CURDIR$, DIR$ sowie SHELL als Anweisung und als Funktion SHALL
verfügbar sein. CURDIR$ SHALL das aktuelle Verzeichnis liefern, DIR$
den ersten bzw. — bei leerem Argument — den nächsten Treffer eines
Suchmusters und den leeren String, wenn keiner mehr folgt. Die
SHELL-Funktion SHALL den Beendigungsstatus des aufgerufenen Prozesses
liefern. CHDRIVE SHALL auf Plattformen ohne Laufwerksbuchstaben
namentlich abgewiesen oder als Non-Feature dokumentiert werden. Pfade SHALL sowohl \ als auch / als Trennzeichen
akzeptieren und auf die Konvention der laufenden Plattform abgebildet
werden; Laufwerksbuchstaben SHALL auf Nicht-Windows-Plattformen als
gewöhnlicher Namensbestandteil behandelt oder mit benannter Ablehnung
abgewiesen werden. Fehlende Dateien MUST Fehler 53 auslösen, fehlende
Pfade Fehler 76 „Path not found".
Scenario: Rückwärts-Schrägstrich auf Unix
- WHEN
OPEN "unter\d.txt" FOR OUTPUT AS #1auf einer Unix-Plattform ausgeführt wird - THEN entsteht die Datei
d.txtim Verzeichnisunter
Scenario: Verzeichnis durchlaufen
- WHEN
DIR$("*.txt")und danachDIR$("")wiederholt ausgewertet werden - THEN liefern sie nacheinander alle passenden Namen und zuletzt den leeren String
Scenario: Fehlender Pfad
- WHEN
MKDIRin einem nicht existierenden Elternverzeichnis aufgerufen wird - THEN tritt Laufzeitfehler 76 auf
Requirement: LPRINT als Druckausgabe
LPRINT und LPRINT USING SHALL wie PRINT formatieren und in einen
Druckerkanal schreiben. LPOS SHALL die aktuelle Spalte im
Druckerpuffer liefern. Existiert auf der Plattform kein Druckerkanal,
MUST das Ziel (Datei, Standardausgabe oder Ablehnung) in der
Sprachreferenz unter „Abweichungen" dokumentiert sein.
Scenario: LPRINT formatiert wie PRINT
- WHEN
LPRINT 1; 2ausgeführt wird - THEN entspricht der erzeugte Text der Ausgabe von
PRINT 1; 2
Scenario: Druckerspalte
- WHEN nach
LPRINT "abc";die FunktionLPOS(0)ausgewertet wird - THEN liefert sie die Spalte hinter dem ausgegebenen Text