From a8583f6bc442cc63cf5ed8cbe8b96a92430e2758 Mon Sep 17 00:00:00 2001 From: greg Date: Wed, 22 May 2019 03:32:00 -0700 Subject: [PATCH] Separate command_tree module --- schala-repl/src/repl/directives.rs | 122 +++++++++++++++++++++++++++++ schala-repl/src/repl/mod.rs | 118 ++-------------------------- 2 files changed, 127 insertions(+), 113 deletions(-) create mode 100644 schala-repl/src/repl/directives.rs diff --git a/schala-repl/src/repl/directives.rs b/schala-repl/src/repl/directives.rs new file mode 100644 index 0000000..05b9f31 --- /dev/null +++ b/schala-repl/src/repl/directives.rs @@ -0,0 +1,122 @@ +use std::fmt::Write as FmtWrite; +use itertools::Itertools; + +use crate::repl::Repl; +use crate::repl::command_tree::CommandTree; +use crate::language::{ProgrammingLanguageInterface, LangMetaRequest, LangMetaResponse, DebugRequest, DebugAsk, DebugResponse}; + +pub fn get_directives(language_state: &mut Box) -> CommandTree { + let pass_names = match language_state.request_meta(LangMetaRequest::StageNames) { + LangMetaResponse::StageNames(names) => names, + _ => vec![], + }; + + let passes_directives: Vec = pass_names.iter() + .map(|pass_name| { CommandTree::nonterm_no_further_tab_completions(pass_name, None) }) + .collect(); + + CommandTree::Top(vec![ + CommandTree::terminal("exit", Some("exit the REPL"), vec![], Box::new(|repl: &mut Repl, _cmds: &[&str]| { + repl.save_before_exit(); + ::std::process::exit(0) + })), + CommandTree::terminal("quit", Some("exit the REPL"), vec![], Box::new(|repl: &mut Repl, _cmds: &[&str]| { + repl.save_before_exit(); + ::std::process::exit(0) + })), + CommandTree::terminal("help", Some("Print this help message"), vec![], Box::new(|repl: &mut Repl, cmds: &[&str]| { + Some(repl.print_help_message(cmds)) + })), + CommandTree::nonterm("debug", + Some("Configure debug information"), + vec![ + CommandTree::terminal("list-passes", Some("List all registered compiler passes"), vec![], Box::new(|repl: &mut Repl, _cmds: &[&str]| { + let language_state = repl.get_cur_language_state(); + let pass_names = match language_state.request_meta(LangMetaRequest::StageNames) { + LangMetaResponse::StageNames(names) => names, + _ => vec![], + }; + + let mut buf = String::new(); + for pass in pass_names.iter().map(|name| Some(name)).intersperse(None) { + match pass { + Some(pass) => write!(buf, "{}", pass).unwrap(), + None => write!(buf, " -> ").unwrap(), + } + } + Some(buf) + })), + CommandTree::terminal("show-immediate", None, passes_directives.clone(), + Box::new(|repl: &mut Repl, cmds: &[&str]| { + let cur_state = repl.get_cur_language_state(); + let stage_name = match cmds.get(1) { + Some(s) => s.to_string(), + None => return Some(format!("Must specify a thing to debug")), + }; + let meta = LangMetaRequest::ImmediateDebug( + DebugRequest { ask: DebugAsk::ByStage { stage_name: stage_name.clone() } } + ); + let response = match cur_state.request_meta(meta) { + LangMetaResponse::ImmediateDebug(DebugResponse { ask, value }) => { + if (ask != DebugAsk::ByStage { stage_name: stage_name }) { + return Some(format!("Didn't get debug stage requested")); + } + value + }, + _ => return Some(format!("Invalid language meta response")), + }; + Some(response) + })), + CommandTree::terminal("show", None, passes_directives.clone(), Box::new(|repl: &mut Repl, cmds: &[&str]| { + let stage_name = match cmds.get(0) { + Some(s) => s.to_string(), + None => return Some(format!("Must specify a stage to show")), + }; + let ask = DebugAsk::ByStage { stage_name }; + repl.options.debug_asks.insert(ask); + None + })), + CommandTree::terminal("hide", None, passes_directives.clone(), Box::new(|repl: &mut Repl, cmds: &[&str]| { + let stage_name = match cmds.get(0) { + Some(s) => s.to_string(), + None => return Some(format!("Must specify a stage to hide")), + }; + let ask = DebugAsk::ByStage { stage_name }; + repl.options.debug_asks.remove(&ask); + None + })), + CommandTree::nonterm("total-time", None, vec![ + CommandTree::terminal("on", None, vec![], Box::new(|repl: &mut Repl, _: &[&str]| { + repl.options.show_total_time = true; + None + })), + CommandTree::terminal("off", None, vec![], Box::new(turn_off)), + ]) + ] + ), + CommandTree::nonterm("lang", + Some("switch between languages, or go directly to a langauge by name"), + vec![ + CommandTree::nonterm_no_further_tab_completions("next", None), + CommandTree::nonterm_no_further_tab_completions("prev", None), + CommandTree::nonterm("go", None, vec![]), + ] + ), + CommandTree::terminal("doc", Some("Get language-specific help for an item"), vec![], Box::new(|repl: &mut Repl, cmds: &[&str]| { + cmds.get(0).map(|cmd| { + let source = cmd.to_string(); + let meta = LangMetaRequest::Docs { source }; + let cur_state = repl.get_cur_language_state(); + match cur_state.request_meta(meta) { + LangMetaResponse::Docs { doc_string } => Some(doc_string), + _ => Some(format!("Invalid doc response")) + } + }).unwrap_or(Some(format!(":docs needs an argument"))) + })) + ]) +} + +fn turn_off(repl: &mut Repl, _cmds: &[&str]) -> Option { + repl.options.show_total_time = false; + None +} diff --git a/schala-repl/src/repl/mod.rs b/schala-repl/src/repl/mod.rs index c12d2e0..7e686c7 100644 --- a/schala-repl/src/repl/mod.rs +++ b/schala-repl/src/repl/mod.rs @@ -2,16 +2,17 @@ use std::fmt::Write as FmtWrite; use std::sync::Arc; use colored::*; -use itertools::Itertools; use crate::language::{ProgrammingLanguageInterface, ComputationRequest, ComputationResponse, LangMetaRequest, LangMetaResponse, -DebugRequest, DebugAsk, DebugResponse}; +DebugRequest}; mod command_tree; use self::command_tree::{CommandTree, BoxedCommandFunction}; mod repl_options; use repl_options::ReplOptions; +mod directives; +use directives::get_directives; const HISTORY_SAVE_FILE: &'static str = ".schala_history"; const OPTIONS_SAVE_FILE: &'static str = ".schala_repl"; @@ -207,120 +208,11 @@ impl Repl { fn get_directives(&mut self) -> CommandTree { let language_state = self.get_cur_language_state(); - let pass_names = match language_state.request_meta(LangMetaRequest::StageNames) { - LangMetaResponse::StageNames(names) => names, - _ => vec![], - }; - - let passes_directives: Vec = pass_names.iter() - .map(|pass_name| { CommandTree::nonterm_no_further_tab_completions(pass_name, None) }) - .collect(); - - CommandTree::Top(vec![ - CommandTree::terminal("exit", Some("exit the REPL"), vec![], Box::new(|repl: &mut Repl, _cmds: &[&str]| { - repl.save_before_exit(); - ::std::process::exit(0) - })), - CommandTree::terminal("quit", Some("exit the REPL"), vec![], Box::new(|repl: &mut Repl, _cmds: &[&str]| { - repl.save_before_exit(); - ::std::process::exit(0) - })), - CommandTree::terminal("help", Some("Print this help message"), vec![], Box::new(|repl: &mut Repl, cmds: &[&str]| { - Some(repl.print_help_message(cmds)) - })), - CommandTree::nonterm("debug", - Some("Configure debug information"), - vec![ - CommandTree::terminal("list-passes", Some("List all registered compiler passes"), vec![], Box::new(|repl: &mut Repl, _cmds: &[&str]| { - let language_state = repl.get_cur_language_state(); - let pass_names = match language_state.request_meta(LangMetaRequest::StageNames) { - LangMetaResponse::StageNames(names) => names, - _ => vec![], - }; - - let mut buf = String::new(); - for pass in pass_names.iter().map(|name| Some(name)).intersperse(None) { - match pass { - Some(pass) => write!(buf, "{}", pass).unwrap(), - None => write!(buf, " -> ").unwrap(), - } - } - Some(buf) - })), - CommandTree::terminal("show-immediate", None, passes_directives.clone(), - Box::new(|repl: &mut Repl, cmds: &[&str]| { - let cur_state = repl.get_cur_language_state(); - let stage_name = match cmds.get(1) { - Some(s) => s.to_string(), - None => return Some(format!("Must specify a thing to debug")), - }; - let meta = LangMetaRequest::ImmediateDebug( - DebugRequest { ask: DebugAsk::ByStage { stage_name: stage_name.clone() } } - ); - let response = match cur_state.request_meta(meta) { - LangMetaResponse::ImmediateDebug(DebugResponse { ask, value }) => { - if (ask != DebugAsk::ByStage { stage_name: stage_name }) { - return Some(format!("Didn't get debug stage requested")); - } - value - }, - _ => return Some(format!("Invalid language meta response")), - }; - Some(response) - })), - CommandTree::terminal("show", None, passes_directives.clone(), Box::new(|repl: &mut Repl, cmds: &[&str]| { - let stage_name = match cmds.get(0) { - Some(s) => s.to_string(), - None => return Some(format!("Must specify a stage to show")), - }; - let ask = DebugAsk::ByStage { stage_name }; - repl.options.debug_asks.insert(ask); - None - })), - CommandTree::terminal("hide", None, passes_directives.clone(), Box::new(|repl: &mut Repl, cmds: &[&str]| { - let stage_name = match cmds.get(0) { - Some(s) => s.to_string(), - None => return Some(format!("Must specify a stage to hide")), - }; - let ask = DebugAsk::ByStage { stage_name }; - repl.options.debug_asks.remove(&ask); - None - })), - CommandTree::nonterm("total-time", None, vec![ - CommandTree::terminal("on", None, vec![], Box::new(|repl: &mut Repl, _: &[&str]| { - repl.options.show_total_time = true; - None - })), - CommandTree::terminal("off", None, vec![], Box::new(|repl: &mut Repl, _: &[&str]| { - repl.options.show_total_time = false; - None - })), - ]) - ] - ), - CommandTree::nonterm("lang", - Some("switch between languages, or go directly to a langauge by name"), - vec![ - CommandTree::nonterm_no_further_tab_completions("next", None), - CommandTree::nonterm_no_further_tab_completions("prev", None), - CommandTree::nonterm("go", None, vec![]), - ] - ), - CommandTree::terminal("doc", Some("Get language-specific help for an item"), vec![], Box::new(|repl: &mut Repl, cmds: &[&str]| { - cmds.get(0).map(|cmd| { - let source = cmd.to_string(); - let meta = LangMetaRequest::Docs { source }; - let cur_state = repl.get_cur_language_state(); - match cur_state.request_meta(meta) { - LangMetaResponse::Docs { doc_string } => Some(doc_string), - _ => Some(format!("Invalid doc response")) - } - }).unwrap_or(Some(format!(":docs needs an argument"))) - })) - ]) + get_directives(language_state) } } + struct TabCompleteHandler { sigil: char, top_level_commands: CommandTree,