Make new CommandTree paradigm work

This commit is contained in:
greg 2019-03-16 11:10:39 -07:00
parent 57f3d39ea1
commit 712da62d35
3 changed files with 35 additions and 18 deletions

View File

@ -12,6 +12,7 @@ pub enum ExecutionMethod {
Compile, Compile,
Interpret, Interpret,
} }
impl Default for ExecutionMethod { impl Default for ExecutionMethod {
fn default() -> ExecutionMethod { fn default() -> ExecutionMethod {
ExecutionMethod::Interpret ExecutionMethod::Interpret

View File

@ -1,6 +1,6 @@
use super::Repl; use super::Repl;
type BoxedCommandFunction = Box<(fn(&mut Repl, Vec<String>) -> Option<String>)>; pub type BoxedCommandFunction = Box<(fn(&mut Repl, Vec<&str>) -> Option<String>)>;
#[derive(Clone)] #[derive(Clone)]
pub enum CommandTree { pub enum CommandTree {

View File

@ -7,7 +7,7 @@ use colored::*;
use itertools::Itertools; use itertools::Itertools;
use crate::language::{ProgrammingLanguageInterface, EvalOptions, ComputationRequest, ComputationResponse}; use crate::language::{ProgrammingLanguageInterface, EvalOptions, ComputationRequest, ComputationResponse};
mod command_tree; mod command_tree;
use self::command_tree::CommandTree; use self::command_tree::{CommandTree, BoxedCommandFunction};
const HISTORY_SAVE_FILE: &'static str = ".schala_history"; const HISTORY_SAVE_FILE: &'static str = ".schala_history";
const OPTIONS_SAVE_FILE: &'static str = ".schala_repl"; 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<String> { fn handle_interpreter_directive(&mut self, input: &str) -> Option<String> {
let mut iter = input.chars(); let mut iter = input.chars();
iter.next(); iter.next();
@ -105,21 +131,11 @@ impl Repl {
} }
let directives = self.get_directives(); let directives = self.get_directives();
let result: Result<&BoxedCommandFunction, String> = Repl::get_function_from_directives(&directives, &commands);
let mut dir_pointer: &CommandTree = &directives; match result {
for command in commands.iter() { Ok(f) => f(self, commands),
match dir_pointer { Err(err) => Some(err.red().to_string())
CommandTree::Top(subcommands) | CommandTree::NonTerminal { children: subcommands, .. } => {
let q = subcommands;
},
CommandTree::Terminal { name, .. } => {
}
}
} }
Some(format!("you typed {:?}", commands))
} }
fn get_cur_language_state(&mut self) -> &mut Box<ProgrammingLanguageInterface> { fn get_cur_language_state(&mut self) -> &mut Box<ProgrammingLanguageInterface> {
@ -167,11 +183,11 @@ impl Repl {
*/ */
CommandTree::Top(vec![ CommandTree::Top(vec![
CommandTree::term_with_function("exit", Some("exit the REPL"), Box::new(|repl: &mut Repl, cmds: Vec<String>| { CommandTree::term_with_function("exit", Some("exit the REPL"), Box::new(|repl: &mut Repl, _cmds: Vec<&str>| {
repl.save_before_exit(); repl.save_before_exit();
::std::process::exit(0) ::std::process::exit(0)
})), })),
CommandTree::term_with_function("quit", Some("exit the REPL"), Box::new(|repl: &mut Repl, cmds: Vec<String>| { CommandTree::term_with_function("quit", Some("exit the REPL"), Box::new(|repl: &mut Repl, _cmds: Vec<&str>| {
repl.save_before_exit(); repl.save_before_exit();
::std::process::exit(0) ::std::process::exit(0)
})), })),