diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index 5dbfaa1..5e4de2c 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -19,6 +19,7 @@ extern crate ena; use stopwatch::Stopwatch; +use std::time::Duration; use std::cell::RefCell; use std::rc::Rc; use std::collections::HashSet; @@ -234,12 +235,13 @@ impl SourceReference { } } +#[derive(Default)] struct PassDebugArtifact { - artifact: Option + artifacts: Vec } impl PassDebugArtifact { fn add_artifact(&mut self, artifact: String) { - self.artifact = Some(artifact) + self.artifacts.push(artifact) } } @@ -254,55 +256,46 @@ fn stage_names() -> Vec<&'static str> { ] } + impl ProgrammingLanguageInterface for Schala { fn get_language_name(&self) -> String { format!("Schala") } fn get_source_file_suffix(&self) -> String { format!("schala") } fn run_computation(&mut self, request: ComputationRequest) -> ComputationResponse { let ComputationRequest { source, debug_requests } = request; - let stage_names = stage_names(); self.source_reference.load_new_source(source); + fn output_wrapper( + n: usize, + func: F, + input: Input, + schala: &mut Schala, + stage_durations: &mut Vec<(String, Duration)>, + sw: &Stopwatch, + debug_requests: &HashSet) -> Result + where F: Fn(Input, &mut Schala, Option<&mut PassDebugArtifact>) -> Result, + { + let stage_names = stage_names(); + let mut debug_artifact = if debug_requests.contains(&DebugAsk::ByStage { stage_name: stage_names[n].to_string() }) { + Some(PassDebugArtifact::default()) + } else { + None + }; + let output = func(input, schala, debug_artifact.as_mut()); + stage_durations.push((stage_names[n].to_string(), sw.elapsed())); + output + } + let sw = Stopwatch::start_new(); let mut stage_durations = Vec::new(); - let main_output: Result = { - let n = 0; - let debug_artifact = None; - let output = tokenizing(source, self, debug_artifact); - stage_durations.push((stage_names[n].to_string(), sw.elapsed())); - output - }.and_then(|tokens| { - let n = 1; - let debug_artifact = None; - let output = parsing(tokens, self, debug_artifact); - stage_durations.push((stage_names[n].to_string(), sw.elapsed())); - output - }).and_then(|ast| { - let n = 2; - let debug_artifact = None; - let output = symbol_table(ast, self, debug_artifact); - stage_durations.push((stage_names[n].to_string(), sw.elapsed())); - output - }).and_then(|ast| { - let n = 3; - let debug_artifact = None; - let output = typechecking(ast, self, debug_artifact); - stage_durations.push((stage_names[n].to_string(), sw.elapsed())); - output - }).and_then(|ast| { - let n = 4; - let debug_artifact = None; - let output = ast_reducing(ast, self, debug_artifact); - stage_durations.push((stage_names[n].to_string(), sw.elapsed())); - output - }).and_then(|reduced_ast| { - let n = 5; - let debug_artifact = None; - let output = eval(reduced_ast, self, debug_artifact); - stage_durations.push((stage_names[n].to_string(), sw.elapsed())); - output - }); + let main_output: Result = Ok(source) + .and_then(|source| output_wrapper(0, tokenizing, source, self, &mut stage_durations, &sw, &debug_requests)) + .and_then(|tokens| output_wrapper(1, parsing, tokens, self, &mut stage_durations, &sw, &debug_requests)) + .and_then(|ast| output_wrapper(2, symbol_table, ast, self, &mut stage_durations, &sw, &debug_requests)) + .and_then(|ast| output_wrapper(3, typechecking, ast, self, &mut stage_durations, &sw, &debug_requests)) + .and_then(|ast| output_wrapper(4, ast_reducing, ast, self, &mut stage_durations, &sw, &debug_requests)) + .and_then(|reduced_ast| output_wrapper(5, eval, reduced_ast, self, &mut stage_durations, &sw, &debug_requests)); let total_duration = sw.elapsed(); let global_output_stats = GlobalOutputStats {