Files
TerminalBasic/openspec/specs/sprach-frontend/spec.md
Chili Palmer a6f005d023 OpenSpec: phase-2-bytecode-vm archiviert, Delta-Specs in Hauptspecs gesynct
- Neue Hauptspecs: bytecode-kompilat, vm-ausfuehrung,
  vm-fehlerbehandlung, konsolen-basisbibliothek
- Erweitert: sprach-frontend (Typisiertes HIR als Sema-Ausgabe),
  kompat-testkorpus (Laufzeitvergleich, Phase-2-Korpusabdeckung)
- Change nach openspec/changes/archive/2026-09-02-phase-2-bytecode-vm
  verschoben; openspec validate --all: 9/9

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-02 11:33:51 +02:00

123 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# sprach-frontend Specification
## Purpose
Das Sprach-Frontend übersetzt Terminal-Basic-Quelltext (VBDOS-kompatibler
Dialekt) in einen typgeprüften AST: Lexer, fehlertoleranter Parser und
semantische Analyse mit Diagnostik nach den Meldungstexten des Vorbilds.
## Requirements
### Requirement: Lexikalische Analyse nach Sprachreferenz
Der Lexer SHALL Quelltext gemäß docs/sprachreferenz.md §1 zerlegen:
Typ-Suffixe (`% & ! # $ @`) an Bezeichnern und Literalen, case-insensitive
Keywords (Bibliotheksnamen bleiben Bezeichner), `'`/`REM`-Kommentare,
`:`-Anweisungstrenner, Zeilenfortsetzung mit `_`, Hex- (`&H`) und
Oktal-Literale (`&O`), `""`-Escape in Strings sowie die Metabefehle
`'$INCLUDE`, `'$STATIC`, `'$DYNAMIC`.
#### Scenario: Suffix trennt Bibliotheksfunktion von Keyword
- **WHEN** der Lexer `STRING$` und `STRING` liest
- **THEN** wird `STRING$` als Bezeichner (Builtin) und `STRING` als Typ-Keyword erkannt
#### Scenario: Zeilenfortsetzung
- **WHEN** eine Zeile nach Leerraum mit `_` endet
- **THEN** wird die Folgezeile ohne Zeilenende-Token angeschlossen
### Requirement: Literal-Typisierung
Der Lexer SHALL numerische Literale typisieren: Ganzzahlen INTEGER → LONG
→ Gleitkomma nach Wertebereich; `E`-Exponent → SINGLE, `D`-Exponent →
DOUBLE; Suffixe erzwingen den Typ (Überlauf → Diagnose „Overflow");
Dezimalpunkt-Literale bis 7 signifikante Stellen → SINGLE, darüber →
DOUBLE (Projektentscheidung 2026-09-02); `@`-Literale als
Currency-Festkomma ×10 000.
#### Scenario: Schwelle SINGLE/DOUBLE
- **WHEN** die Literale `1.5` und `3.14159265` gelext werden
- **THEN** ist `1.5` SINGLE und `3.14159265` DOUBLE
### Requirement: Vollständige Anweisungs-Grammatik
Der Parser SHALL den Anweisungssatz des Dialekts in einen AST überführen,
darunter: Zuweisung inkl. `MID$`-Anweisung, `PRINT`/`LPRINT` (mit
`USING`/`#`-Datei, `?`-Kurzform), `INPUT`/`LINE INPUT`, `IF` (Block und
einzeilig, `THEN zeilennummer`), `SELECT CASE` (Werte, `TO`-Bereiche,
`IS`-Vergleiche, `CASE ELSE`), `FOR`/`DO`/`WHILE`-Schleifen mit `EXIT`,
`GOTO`/`GOSUB`/`RETURN`/`ON … GOTO|GOSUB`, `ON [LOCAL] ERROR`/`RESUME`,
`DIM`/`REDIM`/`ERASE`/`CONST`/`DEFtype`/`OPTION`/`TYPE…END TYPE`/
`DECLARE`/`SUB`/`FUNCTION`/`CALL`, `COMMON`/`SHARED`/`STATIC`,
`DATA`/`READ`/`RESTORE`, `DEF FN` (einzeilig und Blockform),
`VIEW PRINT`, `NAME … AS`, Ereignissteuerung (`TIMER/KEY(n)/UEVENT
ON|OFF|STOP`) sowie die komplette Datei-E/A-Grammatik (`OPEN` in beiden
Syntaxen inkl. `ISAM`-/`ACCESS`-/`LOCK`-Klauseln, `CLOSE`, `FIELD`,
`GET`/`PUT`, `LSET`/`RSET`, `WRITE`, `SEEK`, `LOCK`/`UNLOCK`).
Zeilennummern und Labels am Zeilenanfang SHALL als Sprungziele erfasst
werden.
#### Scenario: Blockstrukturen über mehrere Zeilen
- **WHEN** ein `SELECT CASE` mit `CASE 1: PRINT "eins"` und `CASE ELSE` geparst wird
- **THEN** entsteht ein Select-Knoten mit zwei Armen und Inline-Anweisungen im ersten Arm
#### Scenario: Fehlertoleranz je Anweisung
- **WHEN** eine Anweisung einen Syntaxfehler enthält
- **THEN** wird eine Diagnose mit Position gesammelt, bis zum Anweisungsende synchronisiert und die Folgeanweisung normal geparst
### Requirement: Semantische Prüfung
Die Semantik SHALL prüfen: Typkompatibilität (numerisch ↔ numerisch,
String ↔ String; sonst „Type mismatch"), implizite Deklaration bei
Erstverwendung (Suffix-getrennte Variablen), `DEFtype`-Buchstabenbereiche,
`OPTION EXPLICIT` („Variable not defined"), Arrays (implizit, `DIM`,
`REDIM`; doppelte explizite Deklaration → „Duplicate definition"),
UDT-Feldzugriffe (`kunde.name` mit Feldtyp; unbekanntes Feld → „Element
not defined"), `SHARED`-Import von Modulvariablen in Prozeduren,
Konstantenfaltung für `CONST` (nicht konstant → „Invalid constant"),
Sprungziele („Label not defined") sowie Prozedur- und Builtin-Signaturen
(Anzahl → „Argument-count mismatch", Typen).
#### Scenario: Typkonflikt
- **WHEN** `a$ = 1` geprüft wird
- **THEN** wird „Type mismatch" mit Quelltextposition gemeldet
#### Scenario: UDT-Feldtyp
- **WHEN** ein `TYPE` mit Feld `Name AS STRING * 30` deklariert ist und `k.Name = 5` geprüft wird
- **THEN** wird „Type mismatch" gemeldet
### Requirement: Compile-Zeit-Abweisung deklarierter Non-Features
Die Semantik MUST jede Verwendung der in docs/sprachreferenz.md
(„Abweichungen") deklarierten Non-Features — Hardware-Nähe (`PEEK`,
`POKE`, `INP`, `OUT`, `WAIT`, `BLOAD`/`BSAVE`, `VARPTR`-Familie, `CALL
ABSOLUTE`/`INTERRUPT`, `IOCTL`), `CHAIN`, Grafik-Anweisungen, `SOUND`/
`PLAY` und die Event-Geräte `COM`/`PEN`/`PLAY`/`STRIG` — zur Compile-Zeit
mit der Meldung „Feature unavailable" abweisen. Dokumentierte Features
außerhalb dieser Liste MUST NOT abgewiesen werden (Guiding Principle).
#### Scenario: Hardware-Zugriff
- **WHEN** `POKE 100, 1` oder `x = PEEK(100)` kompiliert wird
- **THEN** erscheint die Compile-Diagnose „Feature unavailable"
### Requirement: Diagnostik mit Vorbild-Meldungen
Diagnosen SHALL exakte 1-basierte Quelltextpositionen (Zeile, Spalte)
tragen; die Meldungstexte SHALL dem Katalog des Vorbilds folgen, wo eine
Entsprechung existiert (z. B. „Type mismatch", „Duplicate definition",
„Label not defined", „Subprogram not defined", „Overflow").
#### Scenario: Position in der Diagnose
- **WHEN** in Zeile 3 ein Typkonflikt auftritt
- **THEN** nennt die Diagnose Zeile 3 und die Spalte des Ausdrucks
### Requirement: Typisiertes HIR als Sema-Ausgabe
Die semantische Analyse SHALL neben den Diagnosen einen typisierten,
abgesenkten Zwischenbaum (HIR) liefern, der die Codegen-Eingabe bildet:
Namen sind zu Slot-/Tabellenindizes aufgelöst, jeder Ausdrucksknoten
trägt seinen Ergebnistyp, `CONST`-Werte sind gefaltet, `DEFtype`-Regeln
angewandt und implizite Konvertierungen als explizite
Konvertierungsknoten materialisiert. Bei Diagnosen mit Fehlercharakter
darf kein HIR für das betroffene Konstrukt garantiert werden; ein
diagnose-freies Modul MUST ein vollständiges HIR ergeben.
#### Scenario: Konvertierung wird materialisiert
- **WHEN** `d# = i% + 1.5#` semantisch analysiert wird
- **THEN** enthält das HIR einen expliziten Konvertierungsknoten INTEGER→DOUBLE unter dem Additionsknoten und die Zuweisung trägt den Zieltyp DOUBLE
#### Scenario: Diagnose-freies Modul liefert HIR
- **WHEN** ein Korpusmodul ohne Diagnosen analysiert wird
- **THEN** liefert das Frontend ein HIR, aus dem der Codegen ohne erneute Namens- oder Typauflösung Bytecode erzeugen kann