Projektmodule und vollständiges TBC-Kompilat umsetzen und Change archivieren
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
# Verifikation: projektmodule-und-kompilat
|
||||
|
||||
Geprüft am 05.09.2026: Arbeitsbaum auf Basis von `58b1f62`, alle sieben
|
||||
Delta-Requirements mit 21 Szenarien, Tasks, D1–D4, Implementierung und
|
||||
Abnahmenachweis. **Sechs offene Befunde; der Change ist nicht abnahmebereit.**
|
||||
Die vorherige Aussage vollständiger Umsetzung wird durch diese Verifikation
|
||||
korrigiert. Der Produktcode wurde bei diesem Review nicht verändert.
|
||||
|
||||
| Dimension | Ergebnis |
|
||||
| --- | --- |
|
||||
| Vollständigkeit | 7/7 Tasks sind angehakt und alle sieben Requirements haben Implementierungspfade. Die Befunde widerlegen jedoch die vollständige Erfüllung insbesondere von 1.1, 1.2 und 2.2; Checkboxen allein sind kein Abnahmenachweis. |
|
||||
| Korrektheit | 437 bestehende Workspace-Tests bestanden; zusätzliche unabhängige Review-Proben: 1 bestanden, 6 fehlgeschlagen. Vier Kernfunktionslücken (CRITICAL), zwei weitere Vertragsabweichungen (WARNING). |
|
||||
| Kohärenz | D4 und die FRM-Grundpfade von D3 sind umgesetzt. Quellorte und Modulkontexte gehen in weiteren Absenkungs-/Importpfaden verloren; der gemeinsame Objektraum berücksichtigt `$FORM` nicht vollständig. |
|
||||
|
||||
## CRITICAL — vor Archivierung beheben
|
||||
|
||||
### V1 — Quellorte und Breakpoints fehlen an Zweig- und Schleifengrenzen
|
||||
|
||||
**Priorität: hoch.** Delta „Zeilentabelle für Fehlerortung“ und
|
||||
„Unterbrechbare step()-Ausführung“, D1, Tasks 1.1/2.2.
|
||||
|
||||
Die Fehlerortung funktioniert bei einfachen Anweisungen, nicht jedoch bei
|
||||
weiteren ausführbaren Teilen zusammengesetzter Anweisungen:
|
||||
|
||||
| Probe | Erwartet | Beobachtet |
|
||||
| --- | --- | --- |
|
||||
| `IF 0 THEN` / `PRINT 1` / `ELSEIF 1/0 THEN` | Fehler 11 in Zeile 3 | Zeile 1 |
|
||||
| `SELECT CASE 1` / `CASE 1/0` | Fehler 11 in Zeile 2 | Zeile 1 |
|
||||
| `FOR i%=32767 TO 32767` / `PRINT 1` / `NEXT` | Überlauf beim NEXT in Zeile 3 | Zeile 2 |
|
||||
| `DO` / `PRINT 1` / `LOOP UNTIL 1/0` | Fehler 11 in Zeile 3 | Zeile 2 |
|
||||
| ELSEIF-Bedingung aus `cond.bi:1` | Include-Datei `cond.bi` | `main.bas:1:1` |
|
||||
| Breakpoint auf ELSEIF in Zeile 3 | Halt vor Bedingung | Programm endet ohne Halt |
|
||||
|
||||
**Ursache:** [ELSEIF-Absenkung](../../../../crates/tb-frontend/src/sema.rs#L1937)
|
||||
und [CASE-Absenkung](../../../../crates/tb-frontend/src/sema.rs#L2914) verwenden
|
||||
den Quellort des äußeren Statements. NEXT-/LOOP-Positionen werden nicht
|
||||
vollständig durch AST/HIR bis zur auszuführenden Grenze getragen. Der
|
||||
[FOR-Codegenerator](../../../../crates/tb-vm/src/codegen.rs#L737) dokumentiert
|
||||
selbst die bisherige Verschiebung einer genauen NEXT-Zuordnung auf Phase 5;
|
||||
das widerspricht der hier übernommenen vollständigen Quellortanforderung.
|
||||
|
||||
**Korrektur:** Physische Positionen aller ausführbaren Zweig-/Schleifenteile
|
||||
bereits beim Parsen erhalten und passende Source-/Stmt-Grenzen ausgeben.
|
||||
Nicht nur Fehlermeldungen umbenennen: Breakpoints, Einzelschritt und RESUME
|
||||
müssen dieselbe richtige Zuordnung verwenden. Numerische ERL-Labels separat
|
||||
lassen. Probe `v1_zweige_und_schleifen_behalten_eigene_quellorte`.
|
||||
|
||||
### V2 — Deklarationsimport verändert Typkontext und Abhängigkeitsreihenfolge
|
||||
|
||||
**Priorität: hoch.** Projektpipeline und vollständige Prozedursignaturen,
|
||||
D2, Tasks 1.2/2.1.
|
||||
|
||||
Drei zulässige Mehrmodulkonstellationen werden abgewiesen:
|
||||
|
||||
- MAIN ruft `Doppelt(3)` auf; LIB enthält `DEFINT A-Z` und
|
||||
`FUNCTION Doppelt(x)`. Erwartete Ausgabe 6, tatsächlich
|
||||
`Parameter type mismatch: MAIN!DOPPELT`.
|
||||
- MAIN enthält `CONST A=3` und verwendet B; LIB enthält `CONST A=3` und
|
||||
`CONST B=A+1`. Erwartet B=4, tatsächlich `LIB.bas:2:1: Invalid constant`.
|
||||
- Beide Module enthalten denselben TYPE Inner. LIB definiert anschließend
|
||||
TYPE Outer mit einem Feld `i AS Inner`; MAIN verwendet Outer.
|
||||
Erwartet korrektes Layout und Feldausgabe 3, tatsächlich `Type not defined`
|
||||
an der gültigen Outer-Definition sowie Folgefehler für Feldzugriffe.
|
||||
|
||||
**Ursache:** [import_declarations](../../../../crates/tb-vm/src/project.rs#L103)
|
||||
kopiert rohe Signatur-ASTs ohne den DEFtype-Kontext des definierenden Moduls.
|
||||
Fremde CONST-/TYPE-Knoten werden [vor sämtliche lokalen Deklarationen
|
||||
gehängt](../../../../crates/tb-vm/src/project.rs#L158). Dadurch fehlen ihnen zu
|
||||
diesem Zeitpunkt lokal vorhandene Abhängigkeiten. Die Fehlerposition in LIB
|
||||
ist hier irreführend: Die dortige Originalreihenfolge ist gültig.
|
||||
|
||||
**Korrektur:** Exportierte Signaturen und Konstanten im Ursprungskontext
|
||||
auflösen; abhängige Typdefinitionen mit erhaltenen Identitäten und gültiger
|
||||
Abhängigkeitsreihenfolge verbinden. Lokale Definitionen und echte Duplikate
|
||||
nicht wieder durch Text-Deduplizierung verstecken. Probe
|
||||
`v2_importierte_deklarationen_behalten_kontext_und_abhaengigkeiten`.
|
||||
|
||||
### V3 — `$FORM`-Module teilen versehentlich dasselbe Formularobjekt
|
||||
|
||||
**Priorität: hoch.** Delta „Objektzugriffe in Grammatik und Semantik“
|
||||
einschließlich `$FORM`, getrennte Formulare, D2/D3, Task 1.2.
|
||||
|
||||
A.bas und B.bas enthalten jeweils `'$FORM`. A setzt `Caption="a"`, ruft eine
|
||||
SUB aus B auf, die dort `Caption="b"` setzt, und liest anschließend die
|
||||
eigene Caption. **Erwartet: a. Beobachtet: b.** Das verknüpfte Objektverzeichnis
|
||||
enthält nur SCREEN und A. Auch `B.Caption` aus A wird als unbekanntes Objekt
|
||||
abgewiesen. Der Fehler besteht nach TBC-Rundlauf fort.
|
||||
|
||||
**Ursache:** [lower_with_forms](../../../../crates/tb-frontend/src/sema.rs#L404)
|
||||
erweitert pro Modul eine lokale Katalogkopie um das jeweilige `$FORM`-Objekt.
|
||||
Der Linker übernimmt [nur die Objekte des ersten Moduls](../../../../crates/tb-vm/src/project.rs#L188)
|
||||
und versetzt die Objektoperanden weiterer Module nicht. Deren Form-ID zeigt
|
||||
anschließend auf A.
|
||||
|
||||
**Korrektur:** Sämtliche FRM- und `$FORM`-Formulare vor der modulweisen
|
||||
Semantik in einen gemeinsamen Katalog mit stabilen IDs aufnehmen oder die
|
||||
Objekt-/Ereignisreferenzen beim Linken vollständig versetzen. Zugriffe,
|
||||
Form_Load-Bindungen und gegenseitige Formreferenzen für beide Quellarten
|
||||
prüfen. Probe `v3_form_metabefehle_erzeugen_getrennte_formularobjekte`.
|
||||
|
||||
### V4 — COMMON verliert Variablenidentität und initialisiert Arrays mehrfach
|
||||
|
||||
**Priorität: hoch.** Designrisiko SHARED/COMMON, D2, Task 1.2 und Erhalt der
|
||||
bestehenden COMMON-Sprachsemantik.
|
||||
|
||||
- Bereits ein Modul mit `COMMON SHARED c%, c$` wird mit
|
||||
`COMMON type mismatch: C` abgewiesen. Die beiden durch Typ-Suffixe
|
||||
verschiedenen Variablen dürfen nebeneinander existieren.
|
||||
- MAIN und LIB deklarieren dasselbe `COMMON SHARED a%(2)`. MAIN soll
|
||||
`a%(1)=7` setzen und LIB den gemeinsamen Wert 7 ausgeben. Stattdessen
|
||||
entsteht vor dem Nutzcode `LIB.bas:1:1: Runtime error 10: Duplicate definition`.
|
||||
|
||||
**Ursache:** Die [COMMON-Zuordnung](../../../../crates/tb-vm/src/project.rs#L270)
|
||||
verwendet nur Block und untypisierten Basisnamen. Arrays haben zusätzlich
|
||||
nur `TypeInit::Empty` als Slotvorbelegung; Elementtyp und Form gehen in der
|
||||
Vergleichsprüfung verloren. Der Slot wird zwar zusammengeführt, aber
|
||||
[beide DIM-Initialisierungen](../../../../crates/tb-vm/src/project.rs#L381)
|
||||
werden ausgeführt.
|
||||
|
||||
**Korrektur:** Vollständige Variablenidentität und Arrayvertrag beim Binden
|
||||
berücksichtigen. Kompatible gemeinsame Arrays einmal initialisieren;
|
||||
inkompatible Deklarationen vor der Ausführung am ursprünglichen Quellort
|
||||
ablehnen. Probe `v4_common_behaelt_typidentitaet_und_initialisiert_arrays_einmal`.
|
||||
|
||||
## WARNING — weitere Vertragsabweichungen
|
||||
|
||||
### V5 — LOAD/UNLOAD umgehen die explizite Containerauflösung
|
||||
|
||||
**Priorität: mittel.** Formularnamensraum und expliziter Containerzugriff,
|
||||
D2, Task 1.2.
|
||||
|
||||
Bei zwei Formularen mit jeweils Text1 als Control-Array werden
|
||||
`LOAD Form2!Text1(3)` und `UNLOAD Form2!Text1(3)` mit
|
||||
`Unknown object 'FORM2!TEXT1'` abgewiesen. Property-Zugriffe und die Übergabe
|
||||
desselben qualifizierten Controls an einen CONTROL-Parameter funktionieren.
|
||||
|
||||
**Ursache:** Der [LOAD-/UNLOAD-Pfad](../../../../crates/tb-frontend/src/sema.rs#L3370)
|
||||
übergibt den gesamten Bang-Pfad an `find_object`; die bereits vorhandene
|
||||
containerbezogene Auflösung wird hier nicht verwendet.
|
||||
|
||||
**Korrektur:** LOAD/UNLOAD über dieselbe Objekt-/Containerauflösung wie
|
||||
Property- und Referenzzugriffe führen; gleichnamige Arrays beider Formulare
|
||||
und dynamische Instanzen gemeinsam prüfen. Probe
|
||||
`v5_load_und_unload_loesen_den_expliziten_container_auf`.
|
||||
|
||||
### V6 — Linkerdiagnosen verlieren Datei, Zeile und Spalte
|
||||
|
||||
**Priorität: mittel.** Delta „Diagnostik mit Vorbild-Meldungen“, D1, Task 1.1.
|
||||
|
||||
MAIN deklariert `SUB F(x%)`, LIB implementiert `SUB F(x$)`. Die Ablehnung ist
|
||||
richtig, die Meldung jedoch `0:0: Parameter type mismatch: MAIN!F` ohne Datei.
|
||||
Das ist eine quellbezogene Diagnose, kein Fehler ohne zuordenbare Quelle.
|
||||
|
||||
**Ursache:** [diagnostic](../../../../crates/tb-vm/src/project.rs#L17) erzeugt
|
||||
`file=None` und `SourcePos::default()`. [Linkfehler](../../../../crates/tb-vm/src/project.rs#L66)
|
||||
werden erst nach `locate_diagnostics` in dieses Format umgewandelt. Dasselbe
|
||||
Problem betrifft COMMON-Konflikte und weitere symbolbezogene Linkfehler.
|
||||
|
||||
**Korrektur:** Ursprung der betroffenen Deklaration bzw. Aufrufstelle mit
|
||||
in die Linker-Symbolinformationen übernehmen und strukturierte Diagnosen
|
||||
mit tatsächlicher SourcePos zurückgeben. Keine pauschale Ersatzposition
|
||||
1:1 eintragen. Probe `v6_linkerdiagnose_nennt_den_urspruenglichen_dateiort`.
|
||||
|
||||
## Szenarioabdeckung und positive Nachweise
|
||||
|
||||
Alle 21 vorhandenen Delta-Szenarien wurden abgeglichen. Die einfachen
|
||||
Originalbeispiele besitzen Implementierungs- und Testnachweise; die oben
|
||||
reproduzierten Randpfade widersprechen den umfassenderen Requirements.
|
||||
|
||||
| Requirement / Szenarien | Ergebnis |
|
||||
| --- | --- |
|
||||
| Monomorpher Opcode-Satz: gemischter Ausdruck, aufgelöste Namen | Vorhandene Codegen-/HIR-Tests bestanden. Alle 152 Opcodes samt Operandentypen und Encodingbreiten stimmen mit der Dokumentation überein. |
|
||||
| TBC: Roundtrip, unbekannte Version, Formularwerte | CLI-/VM-Projekttests bestanden: bytegleicher Rundlauf, hello/world aus Designarrays 0/2 nach Entfernen sämtlicher BAS-/FRM-/MAK-/BI-Quellen, Ablehnung alter/höherer Versionen. V2/V3 begrenzen dennoch das vollständige Projektmodell. |
|
||||
| Quellorte: Fehlerzeile, Bibliotheksfehler | `lib.bas:2` und verschachtelte Include-Fehler bestehen. Unabhängig zusätzlich Fehler in physischer Zeile 42 geprüft. V1 zeigt fehlende Zweig-/Schleifenorte. |
|
||||
| Benannte Objekte: Lesen/Schreiben, keine Standardeigenschaft, Wertebereich, getrennte Controls | Bestehende Semantik-/VM-/Modelltests und neuer Zwei-FRM-Test bestanden; Check1.Value=3 bleibt Fehler 5. V3 betrifft weitere Formularquellen, V5 die weiteren qualifizierten Zugriffspfade. |
|
||||
| Diagnosen: Position, Include-Diagnose | Lexer-/Parser-/Semantikpfad trägt Originalpositionen. V6 betrifft die anschließende Linkerphase. |
|
||||
| Objektgrammatik/-semantik: unbekanntes Objekt/Eigenschaft, Typkonflikt, TYPEOF, gleiche Controls | Bestehende Tests bestanden. V3/V5 verletzen den allgemeinen Modul-/Containervertrag trotz grüner Property-Beispiele. |
|
||||
| Unterbrechung: Breakpoint, Inspektion, gleiche Zeile in zwei Modulen | Unabhängige Probe: MAIN passiert Zeile 10, LIB hält in Zeile 10; qualifizierte Array-/UDT-Inspektion liefert 7/8; Einzelschritt meldet Spalte 5; ERR/ERL bleiben 6/200. V1 lässt Breakpoints an ELSEIF aus. |
|
||||
|
||||
Erneut ausgeführt:
|
||||
|
||||
- `cargo test --workspace`: **437 bestanden, 0 fehlgeschlagen, 1 ignoriert**.
|
||||
Golden-Generator nicht ausgeführt, keine Sollausgaben geändert.
|
||||
- [Review-Proben](review-probes.rs): **1 bestanden, 6 fehlgeschlagen**.
|
||||
Jede fehlgeschlagene Probe entspricht einem der sechs Befunde; mehrere
|
||||
verwandte Reproduktionen werden innerhalb einer Probe gesammelt.
|
||||
- Zusätzlich zeitlich begrenzte CLI-Proben für die Befunde; temporäre
|
||||
Quellverzeichnisse anschließend entfernt.
|
||||
- `cargo bench -p tb-vm --bench compile`: 508 Zeilen **0,54 ms**, 49.760 Zeilen
|
||||
in 20 verbundenen Modulen **67 ms**; beide Budgets erfüllt.
|
||||
- Dokumentation: **152/152 Opcodes**, Operanden-/Gesamtbreiten und **9/9
|
||||
Containerabschnitte** gegen den aktuellen Code abgeglichen.
|
||||
- `cargo fmt --all -- --check`, `openspec validate projektmodule-und-kompilat --strict`
|
||||
und `git diff --check`: bestanden.
|
||||
- Clippy nicht nochmals ausgeführt: keine Produktcodeänderung seit dem
|
||||
erfolgreichen Clippy-Lauf der Implementierungsabnahme. Kein neuer
|
||||
interaktiver Originalsystemvergleich und keine Windows-/Linux-Testmatrix.
|
||||
|
||||
## Review-Proben reproduzieren
|
||||
|
||||
Im Repository-Wurzelverzeichnis ausführen. Der temporäre Treiber hält die
|
||||
noch roten Vertragsproben außerhalb der normalen Workspace-Suite; ihre
|
||||
Erwartungen beschreiben das Sollverhalten. Exit-Code ist bis zur Behebung 101.
|
||||
|
||||
```sh
|
||||
python3 - <<'PY'
|
||||
from pathlib import Path
|
||||
import json, subprocess, tempfile, os
|
||||
root = Path.cwd()
|
||||
with tempfile.TemporaryDirectory(prefix='tb-project-review-') as folder:
|
||||
p = Path(folder)
|
||||
manifest = '[package]\nname="tb-project-review"\nversion="0.0.0"\nedition="2021"\n[workspace]\n'
|
||||
manifest += '[[test]]\nname="probes"\npath=' + json.dumps(str(root / 'openspec/changes/archive/2026-09-05-projektmodule-und-kompilat/review-probes.rs')) + '\n[dependencies]\n'
|
||||
for name in ['tb-ui', 'tb-vm', 'tb-runtime', 'tb-frontend']:
|
||||
manifest += name + ' = {path=' + json.dumps(str(root / 'crates' / name)) + '}\n'
|
||||
(p / 'Cargo.toml').write_text(manifest)
|
||||
result = subprocess.run(['cargo', 'test', '--manifest-path', str(p / 'Cargo.toml'), '--offline', '--test', 'probes', '--', '--nocapture'], env={**os.environ, 'CARGO_TARGET_DIR': str(root / 'target/review-projektmodule')}, timeout=120)
|
||||
raise SystemExit(result.returncode)
|
||||
PY
|
||||
```
|
||||
|
||||
**Abnahmeentscheidung:** V1–V4 vor Archivierung beheben; V5/V6 ebenfalls in
|
||||
die vollständige Umsetzung aufnehmen. Keine zusätzlichen Stilvorschläge.
|
||||
Reference in New Issue
Block a user