OpenSpec-Review dokumentieren und ISAM-Vertragsabweichungen beheben
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-09-05
|
||||
37
openspec/changes/projektmodule-und-kompilat/design.md
Normal file
37
openspec/changes/projektmodule-und-kompilat/design.md
Normal file
@@ -0,0 +1,37 @@
|
||||
## Context
|
||||
|
||||
input_sources/append_project_source erzeugen einen einzigen String, doppelte Definitionen werden teilweise entfernt. FormCatalog.find benutzt den ersten globalen Namen. PROC enthält Code/Zeilen inline, OBJS nur Objektstammdaten. Das CLI-build-Ergebnis verwirft die separaten FormFile-Werte. Siehe proposal.md und die Delta-Specs.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:** Den vorhandenen Compilerpipeline-Vertrag auf ein vollständiges Projekt erweitern und daraus ein allein ausführbares Artefakt liefern.
|
||||
|
||||
**Non-Goals:** Keine IDE-Oberfläche, keine native Executable-Verpackung, keine Binärkompatibilität zu alten unvollständigen TBC-Versionen.
|
||||
|
||||
## Decisions
|
||||
|
||||
### D1 — Quellidentität vor Expansion sichern
|
||||
|
||||
Projektmitglieder und Include-Segmente als Quellen mit stabiler ID führen; physische Datei/Zeile/Spalte getrennt von BASICs numerischem ERL-Label bewahren. Kein nachträgliches Zurückrechnen aus der verketteten Zeilenzahl. Einmodul-APIs können den Projektpfad mit einem Mitglied aufrufen.
|
||||
|
||||
### D2 — Namen innerhalb ihres Containers auflösen
|
||||
|
||||
Form- und Control-IDs bleiben numerisch; Lookup sucht zuerst im expliziten Formular/aktuellen Modul. Modulprozeduren erhalten qualifizierte IDs, Form_Load pro Formular eine eigene Bindung. Doppelte lokale Namen dürfen nicht durch globales Deduplizieren verschwinden; echte Duplikate im selben Scope melden.
|
||||
|
||||
### D3 — Selbstständiges Kompilat
|
||||
|
||||
Vor dem Serialisieren das vollständige Forms-Anfangsmodell mit Werten, Indizes und Eltern-IDs aufnehmen. Lesen rekonstruiert dieselben Anfangswerte; CLI run akzeptiert das neue TBC direkt. Normale Projektdateien müssen nach build zum Ausführen nicht mehr verfügbar sein.
|
||||
|
||||
### D4 — Formatrevision statt zusätzlicher Scheinabschnitte
|
||||
|
||||
Inline-Code und Inline-Quellortinstruktionen beibehalten, aber vollständige Quell-/Modultabelle und Prozedursignaturen hinzufügen. Version 4 reservieren, vorhandene Kennungen dokumentieren und OBJS um vollständige Anfangsdaten erweitern. Kein separater CODE/LINES-Abschnitt allein zur Erfüllung einer veralteten Strukturvorgabe. Unbekannte/ältere inkompatible Versionen klar ablehnen.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- Scope-Änderungen können bisher zufällig verbundene globale Namen verändern → Mehrmodulprogramme mit SHARED/COMMON, wiederholten Includes und gleichnamigen privaten Prozeduren prüfen.
|
||||
- Verlust von ERL-Semantik durch neue Quellorte → numerische Labels und physische Dateizeilen ausdrücklich getrennt testen.
|
||||
- Containeränderung kann fremde Dateien fehlinterpretieren → Längen/IDs/Versionen beim Laden prüfen und Roundtrip-Ausführung mit entfernten Quellen testen.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
Eigenständiger Compiler-/Container-Change. Nach Ereigniszustellung integrieren, falls beide interp.rs ändern. F24 und alle Bytecode-Requirement-Blöcke gehören ausschließlich hierher. Bestehende Spec-/Codeverträge erst nach erfolgreicher Umsetzung synchronisieren und archivieren. Bis dahin bleiben alle Tasks offen. Änderungen als zusammenhängenden Commit je Change integrieren; bei Fehlschlag auf den vorherigen Code zurückgehen und neue Datenformatversionen nicht mit alten Lesern öffnen.
|
||||
30
openspec/changes/projektmodule-und-kompilat/proposal.md
Normal file
30
openspec/changes/projektmodule-und-kompilat/proposal.md
Normal file
@@ -0,0 +1,30 @@
|
||||
## Why
|
||||
|
||||
Mehrere Module/Formulare werden zu einem Quelltext und globalen Objektraum zusammengelegt. Dadurch scheitern formularlokale Namen, Fehlerorte stimmen nicht und FRM-Anfangswerte fehlen nach dem Kompilat-Rundlauf (F09–F11); Containerdokumentation und Spec sind außerdem überholt (F24). Siehe [Review vom 05.09.2026](../../../docs/reviews/2026-09-05-openspec-code-review.md).
|
||||
|
||||
## What Changes
|
||||
|
||||
- Projekt- und Include-Quellen mit ursprünglichem Modul/Datei/Zeile erhalten und Prozeduren/Controls im jeweiligen Namensraum auflösen.
|
||||
- Quellorte und Breakpoints mit Modulidentität durch Frontend, Kompilat und VM führen.
|
||||
- Formularbeschreibungen und Anfangswerte in das eigenständig ladbare Kompilat aufnehmen.
|
||||
- **BREAKING**: Kompilatversion für das vollständige Projektmodell erhöhen; ältere Versionen weiterhin klar mit Versionsnennung ablehnen.
|
||||
- Container-/Opcode-Spezifikation und Dokumentation an das tatsächlich vereinbarte Format angleichen.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
Keine neuen Capability-Pfade.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `bytecode-kompilat`: Eigenständiges Projektkompilat, vollständige Quellorte und dokumentiertes Containerformat.
|
||||
- `sprach-frontend`: Projektübergreifende Diagnostik und formularlokale Objektauflösung.
|
||||
- `forms-objektmodell`: Gleichnamige Controls unterschiedlicher Formulare separat adressieren.
|
||||
- `vm-ausfuehrung`: Breakpoints und Inspektion über Modulidentität ermöglichen.
|
||||
|
||||
## Impact
|
||||
|
||||
CLI input_sources/expand_includes, Frontend SourcePos/HIR/FormCatalog, Codegen/bytecode/interp, FRM-Anwendung, Tests und docs/tbvm-design.md/dateiformate.md. Kein neuer Linker als separater Prozess.
|
||||
|
||||
Eigenständiger Compiler-/Container-Change. Nach Ereigniszustellung integrieren, falls beide interp.rs ändern. F24 und alle Bytecode-Requirement-Blöcke gehören ausschließlich hierher.
|
||||
@@ -0,0 +1,59 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Monomorpher Opcode-Satz
|
||||
Der Codegenerator SHALL jedes HIR-Konstrukt in typisierte, monomorphe
|
||||
Opcodes übersetzen: Arithmetik, Vergleiche und Konvertierungen tragen den
|
||||
Operandentyp im Opcode (kein Tag-Dispatch über Werte zur Laufzeit);
|
||||
implizite Konvertierungen erscheinen als explizite Konvertierungs-Opcodes
|
||||
an den vom HIR bestimmten Stellen. Der Opcode-Satz SHALL in
|
||||
docs/tbvm-design.md vollständig dokumentiert sein.
|
||||
|
||||
Die Dokumentation SHALL sämtliche tatsächlich serialisierbaren Instruktionen einschließlich Forms, Ereignissteuerung und Dateioperationen mit Operanden und Encoding führen.
|
||||
|
||||
#### Scenario: Gemischter Ausdruck wird monomorph
|
||||
- **WHEN** `d# = i% + 1.5#` übersetzt wird (INTEGER-Variable, DOUBLE-Ziel)
|
||||
- **THEN** enthält der Bytecode einen Konvertierungs-Opcode INTEGER→DOUBLE und eine DOUBLE-Addition, keinen generischen Additions-Opcode
|
||||
|
||||
#### Scenario: Namen sind zur Laufzeit aufgelöst
|
||||
- **WHEN** eine Variable oder Prozedur im Bytecode referenziert wird
|
||||
- **THEN** geschieht das über Slot- bzw. Tabellenindizes, nicht über Namens-Lookups
|
||||
|
||||
### Requirement: `.tbc`-Containerformat
|
||||
Das Kompilat SHALL als `.tbc`-Datei serialisierbar und wieder ladbar sein:
|
||||
Magic `TBC\0`, Formatversion und dokumentierte Abschnittstabelle.
|
||||
Der Container SHALL Quellen und Module, Konstantenpool, TYPE-Layouts,
|
||||
modulqualifizierte Prozeduren mit vollständiger Signatur, Locals und Code,
|
||||
DATA sowie die vollständigen Forms-Anfangsbeschreibungen führen.
|
||||
Code und Quellortinformationen SHALL inline in den Prozeduren liegen
|
||||
dürfen; eigenständige CODE-/LINES-Abschnitte sind nicht erforderlich. Laden und erneutes Serialisieren MUST verlustfrei sein;
|
||||
eine unbekannte Formatversion MUST mit einer klaren Fehlermeldung
|
||||
abgewiesen werden.
|
||||
|
||||
Ein aus FRM- oder Projektquellen gebautes Kompilat SHALL ohne erneuten Zugriff auf diese Quellen ausführbar sein und ihre Anfangseigenschaften und Designzeit-Control-Arrays bewahren.
|
||||
|
||||
#### Scenario: Roundtrip
|
||||
- **WHEN** ein kompiliertes Modul als `.tbc` geschrieben und wieder geladen wird
|
||||
- **THEN** ist das geladene Kompilat funktional identisch (gleiche Ausführung, gleiche Zeilenzuordnung)
|
||||
|
||||
#### Scenario: Unbekannte Version
|
||||
- **WHEN** eine `.tbc`-Datei mit höherer Formatversion geladen wird
|
||||
- **THEN** wird das Laden mit einer Meldung abgelehnt, die die Version nennt
|
||||
|
||||
#### Scenario: Formularwerte nach Kompilat-Rundlauf
|
||||
- **WHEN** ein Formular mit Text1.Text = "hello" kompiliert, gespeichert und ohne Quelldatei geladen wird
|
||||
- **THEN** liefert der erste Zugriff auf Text1.Text weiterhin hello
|
||||
|
||||
### Requirement: Zeilentabelle für Fehlerortung
|
||||
Der Bytecode SHALL jede Anweisung ihrem Ursprung (Moduldatei, Zeile)
|
||||
zuordnen, sodass Laufzeitfehlermeldungen, `ERL`, Breakpoints und
|
||||
Einzelschritt die Quellzeile exakt benennen können.
|
||||
|
||||
Die Zuordnung SHALL auch nach Include-Expansion und bei mehreren Projektmitgliedern die ursprüngliche Datei und physische Zeile bewahren. Numerische BASIC-Zeilenlabels für ERL SHALL davon getrennt bleiben.
|
||||
|
||||
#### Scenario: Fehler nennt Zeile
|
||||
- **WHEN** in Zeile 42 eines Programms ein Laufzeitfehler ohne Handler auftritt
|
||||
- **THEN** nennt die Fehlermeldung Zeile 42
|
||||
|
||||
#### Scenario: Fehler aus Projektbibliothek
|
||||
- **WHEN** lib.bas in physischer Zeile 2 einen Fehler auslöst und über app.mak aufgerufen wird
|
||||
- **THEN** nennt die Meldung lib.bas und Zeile 2 statt einer verketteten Projektzeile
|
||||
@@ -0,0 +1,27 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Formulare und Steuerelemente als benannte Objekte
|
||||
Ein Formular SHALL unter seinem Namen ansprechbar sein, ein
|
||||
Steuerelement unter seinem Namen innerhalb seines Formulars. Eigenschaften
|
||||
SHALL über `objekt.eigenschaft` gelesen und geschrieben werden, mit dem
|
||||
in der Forms-Referenz festgelegten Typ und Wertebereich. Es SHALL keine
|
||||
Standardeigenschaft geben: `Text1 = "x"` MUST abgewiesen werden. Das
|
||||
Schreiben eines Wertes außerhalb des Wertebereichs MUST Laufzeitfehler 5
|
||||
auslösen; eine zur Laufzeit schreibgeschützte Eigenschaft MUST bei
|
||||
Zuweisung einen Fehler auslösen.
|
||||
|
||||
#### Scenario: Eigenschaft lesen und schreiben
|
||||
- **WHEN** `Text1.Text = "hallo"` ausgeführt und danach `Text1.Text` gelesen wird
|
||||
- **THEN** liefert der Zugriff `hallo`
|
||||
|
||||
#### Scenario: Keine Standardeigenschaft
|
||||
- **WHEN** ein Programm `Text1 = "x"` enthält
|
||||
- **THEN** wird es abgewiesen und die Meldung nennt `Text1`
|
||||
|
||||
#### Scenario: Wert außerhalb des Bereichs
|
||||
- **WHEN** `Check1.Value = 3` ausgeführt wird
|
||||
- **THEN** tritt Laufzeitfehler 5 auf
|
||||
|
||||
#### Scenario: Getrennte Werte gleichnamiger Controls
|
||||
- **WHEN** Form1!Text1.Text auf a und Form2!Text1.Text auf b gesetzt werden
|
||||
- **THEN** liefern die beiden Zugriffe unabhängig a und b
|
||||
@@ -0,0 +1,50 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### 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").
|
||||
|
||||
Bei Projekten und Includes SHALL jede Diagnose den ursprünglichen Dateinamen mit dessen physischer Zeile und Spalte tragen.
|
||||
|
||||
#### Scenario: Position in der Diagnose
|
||||
- **WHEN** in Zeile 3 ein Typkonflikt auftritt
|
||||
- **THEN** nennt die Diagnose Zeile 3 und die Spalte des Ausdrucks
|
||||
|
||||
#### Scenario: Include-Diagnose
|
||||
- **WHEN** ein eingebundenes Include einen Typfehler enthält
|
||||
- **THEN** nennt die Diagnose die Include-Datei und ihre eigene Quellposition
|
||||
|
||||
### Requirement: Objektzugriffe in Grammatik und Semantik
|
||||
Der Parser SHALL Punktpfade auf Formulare und Steuerelemente
|
||||
(`objekt.eigenschaft`), den Container-Operator
|
||||
`form!steuerelement[.eigenschaft]`, `IF TYPEOF ausdruck IS klasse`, den
|
||||
Metabefehl `$FORM` und die Datentypen `FORM` und `CONTROL` als
|
||||
Parametertypen erkennen. Die Semantik SHALL Eigenschaften gegen die
|
||||
Klasse des Objekts prüfen und ihren Typ bestimmen. Ein Punktpfad, dessen
|
||||
Basis weder ein benutzerdefinierter Typ noch ein bekanntes Objekt ist,
|
||||
MUST eine Diagnose erzeugen, die Basis und Eigenschaft namentlich nennt;
|
||||
er MUST NOT zu einer impliziten Variablen mit Punkt im Namen werden.
|
||||
|
||||
Gleichnamige Steuerelemente unterschiedlicher Formulare SHALL im jeweiligen Formularnamensraum aufgelöst werden; die explizite Containerangabe SHALL vor der lokalen Namenssuche wirken.
|
||||
|
||||
#### Scenario: Unbekanntes Objekt wird benannt
|
||||
- **WHEN** ein Modul `Text9.Text = "a"` ohne Steuerelement `Text9` enthält
|
||||
- **THEN** nennt die Diagnose `Text9` als unbekanntes Objekt statt „Type mismatch" zu melden
|
||||
|
||||
#### Scenario: Unbekannte Eigenschaft wird benannt
|
||||
- **WHEN** ein Modul `Text1.Farbe = 3` enthält
|
||||
- **THEN** nennt die Diagnose `Farbe` als unbekannte Eigenschaft von `TextBox`
|
||||
|
||||
#### Scenario: Eigenschaftstyp wird geprüft
|
||||
- **WHEN** ein Modul `Text1.Text = 5` enthält
|
||||
- **THEN** meldet die Semantik einen Typkonflikt mit Nennung der Eigenschaft
|
||||
|
||||
#### Scenario: TYPEOF
|
||||
- **WHEN** ein Modul `IF TYPEOF Ziel IS CommandButton THEN` enthält
|
||||
- **THEN** wird es übersetzt und die Klasse gegen die bekannten Steuerelementklassen geprüft
|
||||
|
||||
#### Scenario: Gleichnamige Controls verschiedener Formulare
|
||||
- **WHEN** Form1 und Form2 jeweils Text1 enthalten und Form2!Text1.Text gelesen wird
|
||||
- **THEN** wird Text1 in Form2 aufgelöst und das Programm übersetzt diagnosefrei
|
||||
@@ -0,0 +1,24 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### 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.
|
||||
|
||||
Ein Breakpoint SHALL durch Modulidentität und physische Quellzeile bestimmt sein. Gleiche Zeilennummern anderer Module MUST NOT denselben Breakpoint auslösen.
|
||||
|
||||
#### 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
|
||||
|
||||
#### Scenario: Gleiche Zeile in zwei Modulen
|
||||
- **WHEN** ein Breakpoint auf Modul A, Zeile 10 gesetzt ist und Modul B Zeile 10 ausführt
|
||||
- **THEN** läuft B weiter; erst A Zeile 10 hält an
|
||||
15
openspec/changes/projektmodule-und-kompilat/tasks.md
Normal file
15
openspec/changes/projektmodule-und-kompilat/tasks.md
Normal file
@@ -0,0 +1,15 @@
|
||||
## 1. Quellen und Scopes
|
||||
|
||||
- [ ] 1.1 Quell-/Modulidentitäten durch Include-Expansion und Frontend erhalten; verifizieren mit Compile- und Runtimefehlern aus lib.bas:2 und verschachtelten Includes.
|
||||
- [ ] 1.2 Form-/Prozedurscopes korrekt auflösen; verifizieren mit zwei Form_Load-Prozeduren, zwei Text1-Controls und unterschiedlichen Form1!Text1/Form2!Text1-Werten sowie echten Duplikaten im selben Scope.
|
||||
|
||||
## 2. Kompilat und Debugger
|
||||
|
||||
- [ ] 2.1 Vollständige Forms-Anfangsdaten, Quelltabelle und Prozedursignaturen serialisieren; verifizieren durch bytegleichen Kompilat-Rundlauf und gleiche Ausführung inklusive Designzeit-Control-Arrays.
|
||||
- [ ] 2.2 Modulbezogene Breakpoints/Quellortmeldungen ergänzen; verifizieren mit identischen physischen Zeilennummern in zwei Modulen, Include-Fehlern, Einzelschritt und unverändertem ERR/ERL.
|
||||
- [ ] 2.3 CLI-run für TBC anschließen und Versionsgrenze anheben; verifizieren mit build, Entfernen aller Quellen, run des Kompilats und klarer Ablehnung inkompatibler Versionen.
|
||||
|
||||
## 3. Abnahme
|
||||
|
||||
- [ ] 3.1 Container und vollständige Opcode-/Operandentabelle dokumentieren; verifizieren mit Format-/Opcode-Abgleich, cargo test --workspace und dem Compile-Budget.
|
||||
- [ ] 3.2 Delta-Specs vollständig gegen die erhaltenen Szenarien prüfen; verifizieren mit openspec validate projektmodule-und-kompilat --strict und git diff --check.
|
||||
Reference in New Issue
Block a user