diff --git a/schala-lang/language/src/lib.rs b/schala-lang/language/src/lib.rs index ac83280..03ffefb 100644 --- a/schala-lang/language/src/lib.rs +++ b/schala-lang/language/src/lib.rs @@ -273,24 +273,35 @@ impl ProgrammingLanguageInterface for Schala { debug_responses: &'a mut Vec, } - fn output_wrapper(n: usize, func: F, input: Input, tok: &mut PassToken) -> Result + fn output_wrapper(n: usize, func: F, input: Input, token: &mut PassToken) -> Result where F: Fn(Input, &mut Schala, Option<&mut PassDebugArtifact>) -> Result { let stage_names = stage_names(); - let ask = DebugAsk::ByStage { stage_name: stage_names[n].to_string(), token: None }; - let mut debug_artifact = tok.debug_requests.get(&ask).map(|_| - PassDebugArtifact { - parsing: if stage_names[n] == "parsing" { Some(ParsingDebugType::CompactAST) } else { None }, - ..Default::default() - } - ); - let output = func(input, tok.schala, debug_artifact.as_mut()); + let cur_stage_name = stage_names[n]; + let ask = token.debug_requests.iter().find(|ask| ask.is_for_stage(cur_stage_name)); + let mut debug_artifact = ask.and_then(|ask| match ask { + DebugAsk::ByStage { token, .. } => token.as_ref(), + _ => None + }).map(|token| { + let parsing = if cur_stage_name != "parsing" { + None + } else { + Some(match &token[..] { + "compact" => ParsingDebugType::CompactAST, + "expanded" => ParsingDebugType::ExpandedAST, + "trace" => ParsingDebugType::Trace, + _ => ParsingDebugType::CompactAST, + }) + }; + PassDebugArtifact { parsing, ..Default::default() } + }); + let output = func(input, token.schala, debug_artifact.as_mut()); - tok.stage_durations.push((stage_names[n].to_string(), tok.sw.elapsed())); + token.stage_durations.push((cur_stage_name.to_string(), token.sw.elapsed())); if let Some(artifact) = debug_artifact { for value in artifact.artifacts.into_iter() { - let resp = DebugResponse { ask: ask.clone(), value }; - tok.debug_responses.push(resp); + let resp = DebugResponse { ask: ask.unwrap().clone(), value }; + token.debug_responses.push(resp); } } output diff --git a/schala-repl/src/language.rs b/schala-repl/src/language.rs index 34542a1..92b03ec 100644 --- a/schala-repl/src/language.rs +++ b/schala-repl/src/language.rs @@ -41,6 +41,15 @@ pub enum DebugAsk { ByStage { stage_name: String, token: Option }, } +impl DebugAsk { + pub fn is_for_stage(&self, name: &str) -> bool { + match self { + DebugAsk::ByStage { stage_name, .. } if stage_name == name => true, + _ => false + } + } +} + pub struct DebugResponse { pub ask: DebugAsk, pub value: String diff --git a/schala-repl/src/repl/directive_actions.rs b/schala-repl/src/repl/directive_actions.rs index 1a112c7..346bc16 100644 --- a/schala-repl/src/repl/directive_actions.rs +++ b/schala-repl/src/repl/directive_actions.rs @@ -57,7 +57,7 @@ impl DirectiveAction { let response = match meta_response { LangMetaResponse::ImmediateDebug(DebugResponse { ask, value }) => match ask { - DebugAsk::ByStage { stage_name: ref this_stage_name, ref token } if *this_stage_name == stage_name => value, + DebugAsk::ByStage { stage_name: ref this_stage_name, ..} if *this_stage_name == stage_name => value, _ => return Some(format!("Wrong debug stage")) }, _ => return Some(format!("Invalid language meta response")), @@ -65,21 +65,29 @@ impl DirectiveAction { Some(response) }, Show => { - let stage_name = match arguments.get(0) { + let this_stage_name = match arguments.get(0) { Some(s) => s.to_string(), None => return Some(format!("Must specify a stage to show")), }; - let ask = DebugAsk::ByStage { stage_name, token: None }; + let token = arguments.get(1).map(|s| s.to_string()); + repl.options.debug_asks.retain(|ask| match ask { + DebugAsk::ByStage { stage_name, .. } if *stage_name == this_stage_name => false, + _ => true + }); + + let ask = DebugAsk::ByStage { stage_name: this_stage_name, token }; repl.options.debug_asks.insert(ask); None }, Hide => { - let stage_name = match arguments.get(0) { + let stage_name_to_remove = match arguments.get(0) { Some(s) => s.to_string(), None => return Some(format!("Must specify a stage to hide")), }; - let ask = DebugAsk::ByStage { stage_name, token: None }; - repl.options.debug_asks.remove(&ask); + repl.options.debug_asks.retain(|ask| match ask { + DebugAsk::ByStage { stage_name, .. } if *stage_name == stage_name_to_remove => false, + _ => true + }); None }, TotalTimeOff => total_time_off(repl, arguments), diff --git a/schala-repl/src/repl/directives.rs b/schala-repl/src/repl/directives.rs index 06de3c9..c1a91d3 100644 --- a/schala-repl/src/repl/directives.rs +++ b/schala-repl/src/repl/directives.rs @@ -3,7 +3,17 @@ use crate::repl::directive_actions::DirectiveAction; pub fn directives_from_pass_names(pass_names: &Vec) -> CommandTree { let passes_directives: Vec = pass_names.iter() - .map(|pass_name| { CommandTree::nonterm_no_further_tab_completions(pass_name, None) }) + .map(|pass_name| { + if pass_name == "parsing" { + CommandTree::nonterm(pass_name, None, vec![ + CommandTree::nonterm_no_further_tab_completions("compact", None), + CommandTree::nonterm_no_further_tab_completions("expanded", None), + CommandTree::nonterm_no_further_tab_completions("trace", None), + ]) + } else { + CommandTree::nonterm_no_further_tab_completions(pass_name, None) + } + }) .collect(); CommandTree::Top(get_list(&passes_directives, true)) }