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:
+67
-13
@@ -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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user