Files

13 KiB
Raw Permalink Blame History

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 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ä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 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 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 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 --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.

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.