Files

224 lines
13 KiB
Markdown
Raw Permalink 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.
# Verifikation: projektmodule-und-kompilat
Geprüft am 05.09.2026: Arbeitsbaum auf Basis von `58b1f62`, alle sieben
Delta-Requirements mit 21 Szenarien, Tasks, D1D4, 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:** V1V4 vor Archivierung beheben; V5/V6 ebenfalls in
die vollständige Umsetzung aufnehmen. Keine zusätzlichen Stilvorschläge.