13 KiB
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 und CASE-Absenkung 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 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ältDEFINT A-ZundFUNCTION Doppelt(x). Erwartete Ausgabe 6, tatsächlichParameter type mismatch: MAIN!DOPPELT. - MAIN enthält
CONST A=3und verwendet B; LIB enthältCONST A=3undCONST B=A+1. Erwartet B=4, tatsächlichLIB.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ächlichType not definedan der gültigen Outer-Definition sowie Folgefehler für Feldzugriffe.
Ursache: import_declarations kopiert rohe Signatur-ASTs ohne den DEFtype-Kontext des definierenden Moduls. Fremde CONST-/TYPE-Knoten werden vor sämtliche lokalen Deklarationen gehängt. 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
erweitert pro Modul eine lokale Katalogkopie um das jeweilige $FORM-Objekt.
Der Linker übernimmt nur die Objekte des ersten Moduls
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 mitCOMMON type mismatch: Cabgewiesen. Die beiden durch Typ-Suffixe verschiedenen Variablen dürfen nebeneinander existieren. - MAIN und LIB deklarieren dasselbe
COMMON SHARED a%(2). MAIN solla%(1)=7setzen und LIB den gemeinsamen Wert 7 ausgeben. Stattdessen entsteht vor dem NutzcodeLIB.bas:1:1: Runtime error 10: Duplicate definition.
Ursache: Die COMMON-Zuordnung
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
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
ü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 erzeugt
file=None und SourcePos::default(). Linkfehler
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: 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 --strictundgit 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.
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.