feat: Add debug mode and trace logs

Introduce a debug mode that collects and displays execution trace logs.
This involves adding an `AppTab` enum to manage UI state and modifying
the
`compile` function to handle debug execution.
This commit is contained in:
Michael Schimmel
2026-02-18 00:59:42 +01:00
parent faada16723
commit 799f3a2123
+67 -13
View File
@@ -20,12 +20,21 @@ struct Example {
content: String, content: String,
} }
#[derive(PartialEq)]
enum AppTab {
Output,
Trace,
}
struct CompilerApp { struct CompilerApp {
source_code: String, source_code: String,
current_example_path: Option<PathBuf>, current_example_path: Option<PathBuf>,
save_as_name: String, save_as_name: String,
show_save_as: bool, show_save_as: bool,
output_log: String, output_log: String,
trace_logs: Vec<String>,
active_tab: AppTab,
debug_enabled: bool,
env: Environment, env: Environment,
is_first_frame: bool, is_first_frame: bool,
examples: Vec<Example>, examples: Vec<Example>,
@@ -63,6 +72,9 @@ impl Default for CompilerApp {
save_as_name: String::new(), save_as_name: String::new(),
show_save_as: false, show_save_as: false,
output_log: String::from("Ready to compile..."), output_log: String::from("Ready to compile..."),
trace_logs: Vec::new(),
active_tab: AppTab::Output,
debug_enabled: false,
env: Environment::new(), env: Environment::new(),
is_first_frame: true, is_first_frame: true,
examples, examples,
@@ -73,19 +85,38 @@ impl Default for CompilerApp {
impl CompilerApp { impl CompilerApp {
fn compile(&mut self) { fn compile(&mut self) {
let start = std::time::Instant::now(); let start = std::time::Instant::now();
match self.env.run_script(&self.source_code) { self.trace_logs.clear();
Ok(result) => {
let result = if self.debug_enabled {
match self.env.run_debug(&self.source_code) {
Ok((res, logs)) => {
self.trace_logs = logs;
self.active_tab = AppTab::Trace;
res
}
Err(e) => Err(e),
}
} else {
self.env.run_script(&self.source_code)
};
match result {
Ok(val) => {
let duration = start.elapsed(); let duration = start.elapsed();
let now = chrono::Local::now().format("%H:%M:%S").to_string(); let now = chrono::Local::now().format("%H:%M:%S").to_string();
self.output_log = format!( self.output_log = format!(
"Execution Successful.\nResult: {}\n\nDuration: {:?}\nFinished at: {}", "Execution Successful.\nResult: {}\n\nDuration: {:?}\nFinished at: {}",
result, val,
duration, duration,
now, now,
); );
if !self.debug_enabled {
self.active_tab = AppTab::Output;
}
} }
Err(e) => { Err(e) => {
self.output_log = format!("Error during Compilation/Execution: {}", e); self.output_log = format!("Error during Compilation/Execution: {}", e);
self.active_tab = AppTab::Output;
} }
} }
} }
@@ -227,6 +258,8 @@ impl eframe::App for CompilerApp {
self.compile(); self.compile();
} }
ui.checkbox(&mut self.debug_enabled, "Debug Mode");
if ui.button("Dump AST").clicked() { if ui.button("Dump AST").clicked() {
self.dump_ast(); self.dump_ast();
} }
@@ -286,9 +319,16 @@ impl eframe::App for CompilerApp {
} }
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Output / Logs:"); ui.selectable_value(&mut self.active_tab, AppTab::Output, "Output");
if ui.button("Copy to Clipboard").clicked() { ui.selectable_value(&mut self.active_tab, AppTab::Trace, "Execution Trace");
ui.ctx().copy_text(self.output_log.clone()); ui.add_space(20.0);
if ui.button("Copy Content").clicked() {
let text = match self.active_tab {
AppTab::Output => self.output_log.clone(),
AppTab::Trace => self.trace_logs.join("\n"),
};
ui.ctx().copy_text(text);
} }
}); });
@@ -296,13 +336,27 @@ impl eframe::App for CompilerApp {
egui::ScrollArea::vertical() egui::ScrollArea::vertical()
.id_salt("output_log_scroll") .id_salt("output_log_scroll")
.show(ui, |ui| { .show(ui, |ui| {
ui.add_sized( match self.active_tab {
ui.available_size(), AppTab::Output => {
egui::TextEdit::multiline(&mut self.output_log) ui.add_sized(
.font(egui::TextStyle::Monospace) ui.available_size(),
.desired_width(f32::INFINITY) egui::TextEdit::multiline(&mut self.output_log)
.interactive(true) .font(egui::TextStyle::Monospace)
); .desired_width(f32::INFINITY)
.interactive(true)
);
},
AppTab::Trace => {
let mut combined = self.trace_logs.join("\n");
ui.add_sized(
ui.available_size(),
egui::TextEdit::multiline(&mut combined)
.font(egui::TextStyle::Monospace)
.desired_width(f32::INFINITY)
.interactive(false)
);
}
}
}); });
}); });