Make new CommandTree paradigm work
This commit is contained in:
parent
57f3d39ea1
commit
712da62d35
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
})),
|
})),
|
||||||
|
Loading…
Reference in New Issue
Block a user