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>
This commit is contained in:
116
openspec/specs/vm-ausfuehrung/spec.md
Normal file
116
openspec/specs/vm-ausfuehrung/spec.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# vm-ausfuehrung Specification
|
||||
|
||||
## Purpose
|
||||
Die TBVM führt das Bytecode-Kompilat mit der exakten Semantik des
|
||||
Dialekts aus: Ausdrücke mit der Zahlenkonvertierungs-Matrix des Vorbilds,
|
||||
Kontrollfluss, Prozeduraufrufe mit BYREF, `GOSUB`, unterbrechbare
|
||||
`step()`-Ausführung als Grundlage für Debugger und Ereignisschleife.
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Zahlenkonvertierungs-Matrix
|
||||
Die VM SHALL implizite und explizite Zahlenkonvertierungen nach der in
|
||||
docs/tbvm-design.md dokumentierten Matrix ausführen, insbesondere:
|
||||
Gleitkomma→Ganzzahl rundet kaufmännisch zur nächsten geraden Zahl
|
||||
(Banker's Rounding); Bereichsüberschreitung löst Fehler 6 „Overflow"
|
||||
aus; `/` liefert stets Gleitkomma, `\` und `MOD` konvertieren ihre
|
||||
Operanden vorab zu Ganzzahlen; logische Operatoren (`AND`, `OR`, `XOR`,
|
||||
`EQV`, `IMP`) arbeiten bitweise auf zu Ganzzahlen konvertierten
|
||||
Operanden; CURRENCY rechnet als Festkomma ×10 000. Die Matrix SHALL
|
||||
durch ein Korpusprogramm mit dokumentierter Sollausgabe abgedeckt sein.
|
||||
|
||||
#### Scenario: Banker's Rounding
|
||||
- **WHEN** `PRINT CINT(0.5); CINT(1.5); CINT(2.5)` ausgeführt wird
|
||||
- **THEN** lautet die Ausgabe ` 0 2 2 `
|
||||
|
||||
#### Scenario: Überlauf bei Konvertierung
|
||||
- **WHEN** einer INTEGER-Variablen der Wert 40000 zugewiesen wird
|
||||
- **THEN** tritt Laufzeitfehler 6 „Overflow" auf
|
||||
|
||||
#### Scenario: Ganzzahldivision rundet Operanden vor
|
||||
- **WHEN** `PRINT 7.5 \ 2` ausgeführt wird
|
||||
- **THEN** wird 7.5 zuerst zu 8 gerundet und die Ausgabe ist ` 4 `
|
||||
|
||||
### Requirement: Kontrollfluss
|
||||
Die VM SHALL `IF`/`ELSEIF`/`ELSE`, `SELECT CASE` (Werte, Bereiche,
|
||||
`IS`-Vergleiche, `CASE ELSE`), `FOR`/`NEXT` (inkl. `STEP`, null
|
||||
Durchläufen bei unpassender Grenze), `DO`/`LOOP` (alle vier
|
||||
Bedingungsformen), `WHILE`/`WEND`, `GOTO`, `ON expr GOTO/GOSUB` und
|
||||
`EXIT FOR/DO` mit der Semantik des Vorbilds ausführen.
|
||||
|
||||
#### Scenario: FOR ohne Durchlauf
|
||||
- **WHEN** `FOR i% = 3 TO 1: PRINT i%: NEXT` ausgeführt wird
|
||||
- **THEN** wird der Schleifenkörper nicht betreten
|
||||
|
||||
#### Scenario: Korpus Kontrollfluss
|
||||
- **WHEN** `tests/compat/kontrollfluss.bas` ausgeführt wird
|
||||
- **THEN** entspricht die Ausgabe byte-genau `kontrollfluss.out`
|
||||
|
||||
### Requirement: GOSUB/RETURN neben Prozeduraufrufen
|
||||
`GOSUB` SHALL die Rücksprungadresse auf einem GOSUB-Stack im aktuellen
|
||||
Frame ablegen (kein eigener Frame); `RETURN` kehrt dorthin zurück,
|
||||
`RETURN label` an das benannte Ziel. Ein `RETURN` ohne anhängigen
|
||||
`GOSUB` MUST Fehler 3 „RETURN without GOSUB" auslösen.
|
||||
|
||||
#### Scenario: RETURN ohne GOSUB
|
||||
- **WHEN** ein Programm `RETURN` ohne vorangehendes `GOSUB` ausführt
|
||||
- **THEN** tritt Laufzeitfehler 3 auf
|
||||
|
||||
### Requirement: Prozeduraufrufe mit BYREF-Semantik
|
||||
SUB-/FUNCTION-Aufrufe SHALL eigene Frames mit Locals-Slots verwenden.
|
||||
Variablen, Arrayelemente und UDT-Felder werden BYREF übergeben
|
||||
(Änderungen im Rumpf wirken auf das Argument zurück); ein geklammertes
|
||||
Argument oder ein Ausdruck wird als temporärer Wert übergeben (BYVAL-
|
||||
Wirkung). `STATIC`-Prozeduren behalten ihre Locals zwischen Aufrufen;
|
||||
rekursive Aufrufe nicht-statischer Prozeduren erhalten frische Locals.
|
||||
`DEF FN`-Funktionen werten im Modulkontext aus (Zugriff auf
|
||||
Modulvariablen), ihre Parameter wirken lokal.
|
||||
|
||||
#### Scenario: BYREF wirkt zurück
|
||||
- **WHEN** `SUB Inc(x%) : x% = x% + 1 : END SUB` mit `Inc n%` aufgerufen wird
|
||||
- **THEN** ist `n%` danach um 1 erhöht
|
||||
|
||||
#### Scenario: Klammern erzwingen Wertübergabe
|
||||
- **WHEN** dieselbe SUB mit `Inc (n%)` aufgerufen wird
|
||||
- **THEN** bleibt `n%` unverändert
|
||||
|
||||
### Requirement: DATA/READ/RESTORE
|
||||
`READ` SHALL die `DATA`-Konstanten des Moduls in Deklarationsreihenfolge
|
||||
konsumieren und in den Zieltyp konvertieren; `RESTORE [label]` setzt den
|
||||
Lesezeiger auf den Anfang bzw. auf die erste `DATA`-Anweisung ab dem
|
||||
Label. Lesen hinter dem letzten Element MUST Fehler 4 „Out of DATA"
|
||||
auslösen; eine nicht konvertierbare Konstante MUST Fehler 13 „Type
|
||||
mismatch" auslösen.
|
||||
|
||||
#### Scenario: Out of DATA
|
||||
- **WHEN** ein Programm mehr Werte liest als `DATA` bereitstellt
|
||||
- **THEN** tritt Laufzeitfehler 4 auf
|
||||
|
||||
### Requirement: Unterbrechbare step()-Ausführung
|
||||
Die VM SHALL als zustandsbehaftete, vom Einbetter getriebene Struktur
|
||||
ausführbar sein: An Anweisungsgrenzen prüft sie ein Flag-Wort und kann
|
||||
anhalten (Breakpoint auf (Modul, Zeile), Einzelschritt, Abbruchwunsch).
|
||||
Im angehaltenen Zustand MUST der Einbetter Variableninhalte (Skalare,
|
||||
Arrayelemente, UDT-Felder) inspizieren und die Ausführung fortsetzen
|
||||
können. Die Tick-Prüfung erfolgt nur an Anweisungsgrenzen, nicht pro
|
||||
Opcode.
|
||||
|
||||
#### Scenario: Breakpoint hält an
|
||||
- **WHEN** ein Breakpoint auf Zeile 10 gesetzt ist und die Ausführung Zeile 10 erreicht
|
||||
- **THEN** hält die VM vor der Anweisung an und meldet Modul und Zeile
|
||||
|
||||
#### Scenario: Inspektion im Halt
|
||||
- **WHEN** die VM an einem Breakpoint steht
|
||||
- **THEN** liefert die Inspektions-API den aktuellen Wert einer benannten Variablen
|
||||
|
||||
### Requirement: Programmende im Runner
|
||||
Außerhalb der IDE SHALL `END` (und das Erreichen des Programmendes) den
|
||||
Prozess mit Exit-Code 0 beenden; `STOP` SHALL mit der Meldung
|
||||
`STOP in line n` (bzw. Modul/Zeile) und einem Exit-Code ungleich 0
|
||||
terminieren (Projektentscheidung 2026-09-02). `SYSTEM` verhält sich wie
|
||||
`END`. `CONT` existiert nur als IDE-Konzept (Phase 5) und ist kein
|
||||
Programmbestandteil.
|
||||
|
||||
#### Scenario: STOP im Runner
|
||||
- **WHEN** ein per `tbc run` gestartetes Programm `STOP` in Zeile 7 ausführt
|
||||
- **THEN** endet der Prozess mit Exit-Code ungleich 0 und die Meldung nennt Zeile 7
|
||||
Reference in New Issue
Block a user