feat: Add tracing support to AST tool
Introduce a `--trace` flag to the AST tool that enables the TracingObserver. This allows users to see the detailed execution steps of their scripts. Also, refactor the main and AST tool to better handle tracing and performance statistics.
This commit is contained in:
+38
-1
@@ -26,11 +26,15 @@ struct Cli {
|
|||||||
/// Dump the compiled AST
|
/// Dump the compiled AST
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
dump: bool,
|
dump: bool,
|
||||||
|
|
||||||
|
/// Run with TracingObserver enabled
|
||||||
|
#[arg(short, long)]
|
||||||
|
trace: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let cli = Cli::parse();
|
let cli = Cli::parse();
|
||||||
let env = Environment::new();
|
let mut env = Environment::new();
|
||||||
|
|
||||||
if cli.bench || cli.update_bench {
|
if cli.bench || cli.update_bench {
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
@@ -54,6 +58,8 @@ fn main() {
|
|||||||
Ok(dump) => println!("{}", dump),
|
Ok(dump) => println!("{}", dump),
|
||||||
Err(e) => eprintln!("Error dumping AST: {}", e),
|
Err(e) => eprintln!("Error dumping AST: {}", e),
|
||||||
}
|
}
|
||||||
|
} else if cli.trace {
|
||||||
|
execute_trace(&mut env, &script_str);
|
||||||
} else {
|
} else {
|
||||||
execute(&env, &script_str);
|
execute(&env, &script_str);
|
||||||
}
|
}
|
||||||
@@ -65,6 +71,8 @@ fn main() {
|
|||||||
Ok(dump) => println!("{}", dump),
|
Ok(dump) => println!("{}", dump),
|
||||||
Err(e) => eprintln!("Error dumping AST: {}", e),
|
Err(e) => eprintln!("Error dumping AST: {}", e),
|
||||||
}
|
}
|
||||||
|
} else if cli.trace {
|
||||||
|
execute_trace(&mut env, &content);
|
||||||
} else {
|
} else {
|
||||||
execute(&env, &content);
|
execute(&env, &content);
|
||||||
}
|
}
|
||||||
@@ -88,3 +96,32 @@ fn execute(env: &Environment, source: &str) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn execute_trace(env: &mut Environment, source: &str) {
|
||||||
|
match env.compile(source) {
|
||||||
|
Ok(compiled) => {
|
||||||
|
let linked = env.link(compiled);
|
||||||
|
let mut vm = myc::ast::vm::VM::new(env.global_values.clone());
|
||||||
|
let mut observer = myc::ast::vm::TracingObserver::new();
|
||||||
|
match vm.run_with_observer(&mut observer, &linked) {
|
||||||
|
Ok(result) => {
|
||||||
|
for line in observer.logs {
|
||||||
|
println!("{}", line);
|
||||||
|
}
|
||||||
|
println!("Result: {}", result);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
for line in observer.logs {
|
||||||
|
println!("{}", line);
|
||||||
|
}
|
||||||
|
eprintln!("Runtime Error: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Compilation Error: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+22
-25
@@ -96,29 +96,19 @@ impl CompilerApp {
|
|||||||
// Reset environment for a fresh run
|
// Reset environment for a fresh run
|
||||||
self.env = Environment::new();
|
self.env = Environment::new();
|
||||||
|
|
||||||
let res = (|| -> Result<(myc::ast::types::Value, std::time::Duration, std::time::Duration, std::time::Duration), String> {
|
let res = (|| -> Result<(myc::ast::types::Value, std::time::Duration), String> {
|
||||||
let start_compile = std::time::Instant::now();
|
|
||||||
let compiled = self.env.compile(&self.source_code)?;
|
|
||||||
let duration_compile = start_compile.elapsed();
|
|
||||||
|
|
||||||
let start_link = std::time::Instant::now();
|
|
||||||
let linked = self.env.link(compiled);
|
|
||||||
let duration_link = start_link.elapsed();
|
|
||||||
|
|
||||||
let start_run = std::time::Instant::now();
|
let start_run = std::time::Instant::now();
|
||||||
let result = if self.debug_enabled {
|
let result = if self.debug_enabled {
|
||||||
let mut vm = myc::ast::vm::VM::new(self.env.global_values.clone());
|
let (res, logs) = self.env.run_debug(&self.source_code)?;
|
||||||
let mut observer = myc::ast::vm::TracingObserver::new();
|
|
||||||
let res = vm.run_with_observer(&mut observer, &linked);
|
|
||||||
|
|
||||||
// Batch-truncate logs for GUI performance (once after execution)
|
// Batch-truncate logs for GUI performance
|
||||||
let mut logs = observer.logs;
|
let mut display_logs = logs;
|
||||||
if logs.len() > 1000 {
|
if display_logs.len() > 1000 {
|
||||||
logs.truncate(1000);
|
display_logs.truncate(1000);
|
||||||
logs.push("... [Trace truncated to 1,000 entries] ...".to_string());
|
display_logs.push("... [Trace truncated to 1,000 entries] ...".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
for line in &mut logs {
|
for line in &mut display_logs {
|
||||||
if line.len() > 255
|
if line.len() > 255
|
||||||
&& let Some((idx, _)) = line.char_indices().nth(255) {
|
&& let Some((idx, _)) = line.char_indices().nth(255) {
|
||||||
line.truncate(idx);
|
line.truncate(idx);
|
||||||
@@ -126,25 +116,32 @@ impl CompilerApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.trace_logs = logs;
|
self.trace_logs = display_logs;
|
||||||
self.active_tab = AppTab::Trace;
|
self.active_tab = AppTab::Trace;
|
||||||
res?
|
res?
|
||||||
} else {
|
} else {
|
||||||
self.env.run(&linked)?
|
self.env.run_script(&self.source_code)?
|
||||||
};
|
};
|
||||||
let duration_run = start_run.elapsed();
|
let duration_run = start_run.elapsed();
|
||||||
|
|
||||||
Ok((result, duration_compile, duration_link, duration_run))
|
Ok((result, duration_run))
|
||||||
})();
|
})();
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Ok((val, d_compile, d_link, d_run)) => {
|
Ok((val, d_run)) => {
|
||||||
let d_total = start_total.elapsed();
|
let d_total = start_total.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!(
|
|
||||||
"Execution Successful.\nResult: {}\n\nPhases:\n - Compile: {:?}\n - Link: {:?}\n - Run: {:?}\n\nTotal Duration: {:?}\nFinished at: {}",
|
let mut stats = format!(
|
||||||
val, d_compile, d_link, d_run, d_total, now,
|
"Execution Successful.\nResult: {}\n\nTotal Duration: {:?}\nFinished at: {}",
|
||||||
|
val, d_total, now,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if !self.debug_enabled {
|
||||||
|
stats.push_str(&format!("\nRun Phase: {:?}", d_run));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.output_log = stats;
|
||||||
if !self.debug_enabled {
|
if !self.debug_enabled {
|
||||||
self.active_tab = AppTab::Output;
|
self.active_tab = AppTab::Output;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user