diff --git a/schala-repl/src/language.rs b/schala-repl/src/language.rs index 3ea7f4f..d3e552f 100644 --- a/schala-repl/src/language.rs +++ b/schala-repl/src/language.rs @@ -9,6 +9,7 @@ pub struct LLVMCodeString(pub String); pub struct EvalOptions { pub execution_method: ExecutionMethod, pub debug_passes: HashMap, + pub debug_timing: bool, } #[derive(Debug, Hash, PartialEq)] @@ -55,7 +56,7 @@ impl UnfinishedComputation { FinishedComputation { artifacts: self.artifacts, text_output, - durations: self.durations + durations: self.durations, } } pub fn output(self, output: Result) -> FinishedComputation { @@ -68,6 +69,22 @@ impl UnfinishedComputation { } impl FinishedComputation { + + fn get_timing(&self) -> Option { + if self.durations.len() != 0 { + let mut buf = String::new(); + write!(&mut buf, "Timing: ").unwrap(); + for duration in self.durations.iter() { + let timing = (duration.as_secs() as f64) + (duration.subsec_nanos() as f64 * 1e-9); + write!(&mut buf, "{}s, ", timing).unwrap() + } + write!(&mut buf, "\n").unwrap(); + Some(buf) + } else { + None + } + } + pub fn to_repl(&self) -> String { let mut buf = String::new(); for (stage, artifact) in self.artifacts.iter() { @@ -77,15 +94,11 @@ impl FinishedComputation { write!(&mut buf, "{}: {}\n", stage, output).unwrap(); } - let debug_timing = true; - if debug_timing { - write!(&mut buf, "Timing: ").unwrap(); - for duration in self.durations.iter() { - let timing = (duration.as_secs() as f64) + (duration.subsec_nanos() as f64 * 1e-9); - write!(&mut buf, "{}s, ", timing).unwrap() - } - write!(&mut buf, "\n").unwrap(); + match self.get_timing() { + Some(timing) => write!(&mut buf, "{}", timing).unwrap(), + None => () } + match self.text_output { Ok(ref output) => write!(&mut buf, "{}", output).unwrap(), Err(ref err) => write!(&mut buf, "{} {}", "Error: ".red().bold(), err).unwrap(), @@ -169,23 +182,23 @@ pub trait ProgrammingLanguageInterface { #[macro_export] macro_rules! pass_chain { - ($state:expr, $options:expr; $($pass:path), *) => { + ($state:expr, $eval_options:expr; $($pass:path), *) => { |text_input| { let mut comp = UnfinishedComputation::default(); - pass_chain_helper! { ($state, comp, $options); text_input $(, $pass)* } + pass_chain_helper! { ($state, comp, $eval_options); text_input $(, $pass)* } } }; } #[macro_export] macro_rules! pass_chain_helper { - (($state:expr, $comp:expr, $options:expr); $input:expr, $pass:path $(, $rest:path)*) => { + (($state:expr, $comp:expr, $eval_options:expr); $input:expr, $pass:path $(, $rest:path)*) => { { use std::time; use schala_repl::PassDebugOptionsDescriptor; let pass_name = stringify!($pass); let (output, duration) = { - let ref debug_map = $options.debug_passes; + let ref debug_map = $eval_options.debug_passes; let debug_handle = match debug_map.get(pass_name) { Some(PassDebugOptionsDescriptor { opts }) => { let ptr = &mut $comp; @@ -199,9 +212,11 @@ macro_rules! pass_chain_helper { let elapsed = start.elapsed(); (pass_output, elapsed) }; - $comp.durations.push(duration); + if $eval_options.debug_timing { + $comp.durations.push(duration); + } match output { - Ok(result) => pass_chain_helper! { ($state, $comp, $options); result $(, $rest)* }, + Ok(result) => pass_chain_helper! { ($state, $comp, $eval_options); result $(, $rest)* }, Err(err) => { $comp.output(Err(format!("Pass {} failed with {:?}", pass_name, err))) } @@ -209,7 +224,7 @@ macro_rules! pass_chain_helper { } }; // Done - (($state:expr, $comp:expr, $options:expr); $final_output:expr) => { + (($state:expr, $comp:expr, $eval_options:expr); $final_output:expr) => { { let final_output: FinishedComputation = $comp.finish(Ok($final_output)); final_output diff --git a/schala-repl/src/repl.rs b/schala-repl/src/repl.rs index 8d3e78a..a66ea79 100644 --- a/schala-repl/src/repl.rs +++ b/schala-repl/src/repl.rs @@ -134,7 +134,11 @@ impl Repl { CommandTree::term("passes", None), CommandTree::NonTerminal(format!("show"), passes_directives.clone(), None), CommandTree::NonTerminal(format!("hide"), passes_directives.clone(), None), - ], Some(format!("show or hide pass info for a given pass, or display the names of all passes"))), + CommandTree::NonTerminal(format!("timing"), vec![ + CommandTree::term("on", None), + CommandTree::term("off", None), + ], None), + ], Some(format!("show or hide pass debug info for a given pass, or display the names of all passes, or turn timing on/off"))), CommandTree::NonTerminal(format!("lang"), vec![ CommandTree::term("next", None), CommandTree::term("prev", None), @@ -228,6 +232,11 @@ impl Repl { fn handle_debug(&mut self, commands: Vec<&str>) -> Option { let passes = self.get_cur_language().get_passes(); match commands.get(1) { + Some(&"timing") => match commands.get(2) { + Some(&"on") => { self.options.debug_timing = true; None } + Some(&"off") => { self.options.debug_timing = false; None } + _ => return Some(format!(r#"Argument to "timing" must be "on" or "off""#)), + }, Some(&"passes") => Some( passes.into_iter() .map(|desc| {