Files
TerminalBasic/openspec/changes/phase-5-06-debugger-und-direktfenster/design.md

32 lines
5.7 KiB
Markdown

## Context
Die VM hat `add_module_breakpoint(module, line)`, `set_step`, Quellortabfragen und `inspect` für aktuelle Locals/Globals, Arrayelemente und UDT-Felder. Die Breakpoint-Identität enthält noch keine Datei; Calls-Ansicht, Ausdrucks-Compiler im pausierten Frame, Step Over, Watchpoints, History und Set Next Statement fehlen. Fehlerhandler werden intern durch `handle_error` gewählt und Frames gegebenenfalls abgewickelt. Die fortsetzbare Sitzung kommt aus 04.
## Goals / Non-Goals
**Goals:** Debugger als opt-in-Steuerung derselben VM; sichtbare Quellorte und beobachtete Werte gehören immer zur pausierten Kompilatrevision.
**Non-Goals:** Zweiter BASIC-Interpreter, Rückgängigmachen von Datei-/Timer-/Netzwerknebenwirkungen, ungeprüftes Setzen des rohen Programmzählers oder persistentes Debugger-Bytecodeformat.
## Decisions
1. IDE-Breakpoints verwenden Dokument-/Modulidentität und eine durch Textedits mitgeführte Marke. Beim Compile werden sie an vorhandene Source-/Stmt-Grenzen des konkreten Kompilats gebunden, einschließlich Datei-ID. Die bestehende Modul-/Zeilen-API bleibt für bisherige Einbetter erhalten; die IDE benutzt die präzisere API. Eine Zeile mit mehreren Statements hält beim Eintritt in die Zeile, ein Step kann jede einzelne Anweisung zeigen. Nicht ausführbare Zeilen werden sichtbar ungebunden und nicht still auf eine fremde Datei verschoben.
2. Fortsetzen überspringt nur die gerade gemeldete Halteprüfung am aktuellen Stmt und nicht einen späteren erneuten Besuch. Step Over verfolgt konkrete Frameidentität und Tiefe, nicht nur Prozedurname oder Zeilennummer. Run to Cursor besitzt einen temporären Halt mit begrenzter Lebensdauer. Events, rekursive Frames, GOSUB und Fehlerhandler behalten ihre bestehenden Eintritts-/Rückkehrregeln; Breakpoints haben Vorrang vor einem Step-Over-Ende.
3. Eine lesbare Frame-/Symbolansicht liefert Calls und Watch-Kontext. Ausgewählter Inspektionsrahmen und aktiver Ausführungsrahmen sind getrennt. Ausdrücke werden mit Frontend/Sema/Codegen in einen kurzlebigen Debug-Kontext übersetzt, der tatsächliche Slots referenziert. Es wird keine eigene Arithmetik oder Typkonvertierung implementiert. Watches erlauben Literale, Operatoren, erreichbare Variablen, Arrays/UDTs und nachweislich reine Intrinsics; Benutzerprozeduren und zustandsverändernde Funktionen sind dort mit Diagnose ausgeschlossen. Das ist eine ausdrücklich dokumentierte Schutzregel für automatische Beobachtung; solche Aufrufe sind im Direktfenster möglich.
4. **Watchpoint-Vorgabe:** Halt bei wahrer boolescher Bedingung an der nächsten Statement-Grenze. Nach Continue wird die aktuelle Prüfung einmal übersprungen; eine weiterhin wahre Bedingung kann an der nächsten Grenze wieder halten. Watchpoints werden nur bei aktiven Einträgen ausgewertet; fehlerhafte Einträge zeigen einen Fehler und werden bis zur Korrektur nicht als „wahr“ behandelt. Keine dauerhafte Mehrarbeit im CLI-Standardpfad.
5. Immediate übersetzt erlaubte Anweisungen über denselben Frontend-/VM-Pfad in einen temporären Debug-Aufrufrahmen. Bestehende Symbole referenzieren die pausierte Sitzung einschließlich BYREF. Normale Seiteneffekte sind ausdrücklich wirksam. Der ursprüngliche Fortsetzungspunkt und die Debug-Kommandogrenze werden gesichert; Syntax-/Sema-Fehler verändern nichts. Runtime-Fehler und ERROR verwenden den bestehenden Fehlerpfad, ohne den Debug-Eintritt mit einer normalen Programmzeile zu verwechseln. Ein erfolgreich abgearbeitetes Kommando kehrt zur Pause zurück; END/SYSTEM/RUN innerhalb eines aufgerufenen Programmpfads werden an die Sitzung aus 04 weitergegeben. Interrupt/Warten benutzt deren fortsetzbare Operationen.
6. Trace aktualisiert Quellmarkierung, History führt einen begrenzten Ring aus Quellorten. Projektvorgabe: 1.024 Einträge, älteste fallen heraus. Die Tasten navigieren nur diesen Trace, nicht VM-Zustände. Aktuell und historisch werden deutlich getrennt; alle Werte gehören weiterhin zum aktuellen Halt. Die Referenz beschreibt keine Rückabwicklung von Nebenwirkungen, deshalb wird kein Zeitreise-System gebaut.
7. Break on Errors ergänzt einen Halt nach Auswahl/Unwinding des zuständigen Handlers, vor dessen erster Anweisung. Fehlerort, ERR/ERL und das vorgesehene RESUME-Ziel werden gesichert. Continue verarbeitet nicht denselben Fehler erneut. Für unbehandelte Fehler bleibt der entsprechende End-/Fehlerzustand unterscheidbar. Tests vergleichen die gesamte Handler-/RESUME-Folge mit deaktivierter Option.
8. Set Next Statement benutzt eine Tabelle zulässiger Statement-Einstiege und Kontrollkontexte aus Codegen/VM. Nur derselbe aktive Frame und kompatible Schleifen-/GOSUB-/Fehlerkontexte sind erlaubt; Eintritt in einen fremden Block oder Handler ist kein roher PC-Sprung. Die Prüfung erfolgt vollständig vor Mutation. Erfolgreicher Sprung hält den Zustand und führt übersprungenen Code nicht aus.
## Risks / Trade-offs
- Gleiche Zeile in mehreren Includes → Binding mit tatsächlicher Datei-ID, expliziter Regressionstest im selben Modul.
- Nebenwirkungen durch Watches → wiederverwendeter Expression-Compiler mit ausdrücklicher Reinheitsgrenze, Zustandsvergleich vor/nach mehrfacher Auswertung.
- Debug-Aufruf und normaler Stack geraten durcheinander → separate Eintrittsmarke, Tests für BYREF, Rekursion, ERROR, Handler, Unterbrechen und RUN.
- Set Next Statement springt in inkonsistente Strukturen → konservativ begründete Ablehnung; keine stillschweigende Reparatur des Programms.
## Migration Plan
Neue Debuggerfunktionen bleiben opt-in. Bestehende Breakpoint- und Run-APIs weiterprüfen; TBC-Quelldaten werden wiederverwendet. Ein Compile-Neustart bindet Breakpoints neu, löscht Frames, History und Watchwerte und behält nur die vom Benutzer definierten Watchausdrücke.