diff --git a/schala-repl/src/language.rs b/schala-repl/src/language.rs index 1d532ce..fe5b1b5 100644 --- a/schala-repl/src/language.rs +++ b/schala-repl/src/language.rs @@ -12,6 +12,7 @@ pub enum ExecutionMethod { Compile, Interpret, } + impl Default for ExecutionMethod { fn default() -> ExecutionMethod { ExecutionMethod::Interpret diff --git a/schala-repl/src/repl/command_tree.rs b/schala-repl/src/repl/command_tree.rs index dcf19ac..f4508b6 100644 --- a/schala-repl/src/repl/command_tree.rs +++ b/schala-repl/src/repl/command_tree.rs @@ -1,6 +1,6 @@ use super::Repl; -type BoxedCommandFunction = Box<(fn(&mut Repl, Vec) -> Option)>; +pub type BoxedCommandFunction = Box<(fn(&mut Repl, Vec<&str>) -> Option)>; #[derive(Clone)] pub enum CommandTree { diff --git a/schala-repl/src/repl/mod.rs b/schala-repl/src/repl/mod.rs index 8bd0e28..a478fdc 100644 --- a/schala-repl/src/repl/mod.rs +++ b/schala-repl/src/repl/mod.rs @@ -7,7 +7,7 @@ use colored::*; use itertools::Itertools; use crate::language::{ProgrammingLanguageInterface, EvalOptions, ComputationRequest, ComputationResponse}; mod command_tree; -use self::command_tree::CommandTree; +use self::command_tree::{CommandTree, BoxedCommandFunction}; const HISTORY_SAVE_FILE: &'static str = ".schala_history"; const OPTIONS_SAVE_FILE: &'static str = ".schala_repl"; @@ -92,6 +92,32 @@ impl Repl { */ } + fn get_function_from_directives<'a>(directives: &'a CommandTree, commands: &Vec<&str>) -> Result<&'a BoxedCommandFunction, String> { + let mut dir_pointer: &CommandTree = &directives; + let mut idx = 0; + + loop { + match dir_pointer { + CommandTree::Top(subcommands) | CommandTree::NonTerminal { children: subcommands, .. } => { + let next_command = match commands.get(idx) { + Some(cmd) => cmd, + None => break Err(format!("Command requires arguments")) + }; + idx += 1; + match subcommands.iter().find(|sc| sc.get_cmd() == *next_command) { + Some(command_tree) => { + dir_pointer = command_tree; + }, + None => break Err(format!("Command {} not found", next_command)) + }; + }, + CommandTree::Terminal { name, function, .. } => { + break function.as_ref().ok_or(format!("No action specified for: {:?}", commands)); + } + } + } + } + fn handle_interpreter_directive(&mut self, input: &str) -> Option { let mut iter = input.chars(); iter.next(); @@ -105,21 +131,11 @@ impl Repl { } let directives = self.get_directives(); - - let mut dir_pointer: &CommandTree = &directives; - for command in commands.iter() { - match dir_pointer { - CommandTree::Top(subcommands) | CommandTree::NonTerminal { children: subcommands, .. } => { - let q = subcommands; - - - }, - CommandTree::Terminal { name, .. } => { - - } - } + let result: Result<&BoxedCommandFunction, String> = Repl::get_function_from_directives(&directives, &commands); + match result { + Ok(f) => f(self, commands), + Err(err) => Some(err.red().to_string()) } - Some(format!("you typed {:?}", commands)) } fn get_cur_language_state(&mut self) -> &mut Box { @@ -167,11 +183,11 @@ impl Repl { */ CommandTree::Top(vec![ - CommandTree::term_with_function("exit", Some("exit the REPL"), Box::new(|repl: &mut Repl, cmds: Vec| { + CommandTree::term_with_function("exit", Some("exit the REPL"), Box::new(|repl: &mut Repl, _cmds: Vec<&str>| { repl.save_before_exit(); ::std::process::exit(0) })), - CommandTree::term_with_function("quit", Some("exit the REPL"), Box::new(|repl: &mut Repl, cmds: Vec| { + CommandTree::term_with_function("quit", Some("exit the REPL"), Box::new(|repl: &mut Repl, _cmds: Vec<&str>| { repl.save_before_exit(); ::std::process::exit(0) })),