using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace codelanguage { /// /// Enhanced debugger visualization with call stack, breakpoints, and variable inspection. /// Provides interactive debugging UI with visual indicators for execution state. /// public partial class DebuggerVisualization : UserControl { public ObservableCollection CallStackItems { get; } = new(); public ObservableCollection WatchItems { get; } = new(); public ObservableCollection BreakpointItems { get; } = new(); public ObservableCollection LocalVariables { get; } = new(); private DebuggerService _debugger; private bool _isAttached = false; public DebuggerVisualization() { InitializeComponent(); CallStackList.ItemsSource = CallStackItems; WatchList.ItemsSource = WatchItems; BreakpointsList.ItemsSource = BreakpointItems; LocalsList.ItemsSource = LocalVariables; UpdateUI(); } public void AttachDebugger(DebuggerService debugger) { _debugger = debugger; if (_debugger != null) { _debugger.BreakpointHit += Debugger_BreakpointHit; _debugger.StateChanged += Debugger_StateChanged; } _isAttached = true; UpdateUI(); } public void DetachDebugger() { if (_debugger != null) { _debugger.BreakpointHit -= Debugger_BreakpointHit; _debugger.StateChanged -= Debugger_StateChanged; } _isAttached = false; UpdateUI(); } private void Debugger_BreakpointHit(object? sender, int line) { UpdateUI(); } private void Debugger_StateChanged(object? sender, DebuggerState state) { UpdateUI(); } private void UpdateUI() { if (!_isAttached || _debugger == null) { DebuggerStatus.Text = "No debug session"; DebuggerStatus.Foreground = VisualThemeManager.GetBrush("TextMuted"); CallStackItems.Clear(); WatchItems.Clear(); LocalVariables.Clear(); BreakpointItems.Clear(); return; } // Update status if (_debugger.IsAttached) { if (!_debugger.IsPaused) { DebuggerStatus.Text = "⏸ Running..."; DebuggerStatus.Foreground = VisualThemeManager.GetBrush("Warning"); } else { DebuggerStatus.Text = "⏹ Paused"; DebuggerStatus.Foreground = VisualThemeManager.GetBrush("Success"); } } else { DebuggerStatus.Text = "⊗ Detached"; DebuggerStatus.Foreground = VisualThemeManager.GetBrush("Error"); } // Update current file DebuggerCurrentFile.Text = $"{_debugger.CurrentFile}:{_debugger.CurrentLine}"; // Update call stack CallStackItems.Clear(); var callStack = _debugger.GetCallStack(); foreach (var frame in callStack) { CallStackItems.Add(new DebuggerFrameUI(frame)); } // Update locals LocalVariables.Clear(); var locals = _debugger.GetLocals(); foreach (var kvp in locals) { LocalVariables.Add(new LocalVariableUI(kvp.Key, kvp.Value)); } // Update breakpoints BreakpointItems.Clear(); foreach (var file in _debugger.Breakpoints) { foreach (var line in file.Value) { BreakpointItems.Add(new BreakpointItemUI($"{file.Key}:{line}", true)); } } } private void ContinueButton_Click(object sender, RoutedEventArgs e) { _debugger?.Continue(); } private void StepOverButton_Click(object sender, RoutedEventArgs e) { _debugger?.StepOver(); } private void StepIntoButton_Click(object sender, RoutedEventArgs e) { _debugger?.StepInto(); } private void StepOutButton_Click(object sender, RoutedEventArgs e) { _debugger?.StepOut(); } private void AddWatchButton_Click(object sender, RoutedEventArgs e) { string varName = WatchInputBox.Text; if (string.IsNullOrWhiteSpace(varName)) return; WatchItems.Add(new WatchItemUI(varName)); WatchInputBox.Clear(); } private void RemoveWatchButton_Click(object sender, RoutedEventArgs e) { if (WatchList.SelectedItem is WatchItemUI item) WatchItems.Remove(item); } } public class DebuggerFrameUI { public string ProcName { get; set; } public string File { get; set; } public int Line { get; set; } public string DisplayText => $"{ProcName}() at {File}:{Line}"; public string Icon => "📍"; public DebuggerFrameUI(DebuggerFrame frame) { ProcName = frame.ProcName; File = frame.File; Line = frame.Line; } } public class WatchItemUI { public string VariableName { get; set; } public string DisplayText => $"Watch: {VariableName}"; public string Icon => "👁"; public WatchItemUI(string varName) { VariableName = varName; } } public class BreakpointItemUI { public string Location { get; set; } public bool IsEnabled { get; set; } public string DisplayText => $"{Location} {(IsEnabled ? "✓" : "✗")}"; public string Icon => IsEnabled ? "🔴" : "⭕"; public BreakpointItemUI(string location, bool enabled) { Location = location; IsEnabled = enabled; } } public class LocalVariableUI { public string Name { get; set; } public string Value { get; set; } public string Type { get; set; } public string DisplayText => $"{Name} = {Value}"; public string Icon => "🔤"; public LocalVariableUI(string name, CraftValue value) { Name = name; Type = value.Type; try { Value = value.Type switch { "num" => value.ToNumber().ToString(), "text" => $"\"{value.ToText()}\"", "list" => $"[{value.ListItems.Count} items]", _ => value.ToText() }; } catch { Value = ""; } } } }