diff --git a/schala-repl/src/language.rs b/schala-repl/src/language.rs index b242221..ce2bedd 100644 --- a/schala-repl/src/language.rs +++ b/schala-repl/src/language.rs @@ -171,3 +171,5 @@ pub trait ProgrammingLanguageInterface { None } } + + diff --git a/schala-repl/src/lib.rs b/schala-repl/src/lib.rs index 08bd239..c6aa30f 100644 --- a/schala-repl/src/lib.rs +++ b/schala-repl/src/lib.rs @@ -25,6 +25,11 @@ mod repl; mod language; mod webapp; +pub fn start_repl() { + let mut repl = repl::NewRepl::new(); + repl.run_repl(); +} + const VERSION_STRING: &'static str = "0.1.0"; include!(concat!(env!("OUT_DIR"), "/static.rs")); diff --git a/schala-repl/src/repl/mod.rs b/schala-repl/src/repl/mod.rs index 56e85bb..7f9d0ad 100644 --- a/schala-repl/src/repl/mod.rs +++ b/schala-repl/src/repl/mod.rs @@ -13,6 +13,94 @@ use self::command_tree::CommandTree; const HISTORY_SAVE_FILE: &'static str = ".schala_history"; const OPTIONS_SAVE_FILE: &'static str = ".schala_repl"; +pub struct NewRepl { + interpreter_directive_sigil: char, + line_reader: ::linefeed::interface::Interface<::linefeed::terminal::DefaultTerminal>, +} + +impl NewRepl { + pub fn new() -> NewRepl { + use linefeed::Interface; + let line_reader = Interface::new("schala-repl").unwrap(); + let interpreter_directive_sigil = ':'; + + NewRepl { + interpreter_directive_sigil, line_reader, + } + } + + pub fn run_repl(&mut self) { + println!("Schala MetaInterpreter version {}", ::VERSION_STRING); + println!("Type {}help for help with the REPL", self.interpreter_directive_sigil); + + self.line_reader.load_history(HISTORY_SAVE_FILE).unwrap_or(()); + self.handle_repl_loop(); + self.line_reader.save_history(HISTORY_SAVE_FILE).unwrap_or(()); + self.save_options(); + println!("Exiting..."); + } + + fn handle_repl_loop(&mut self) { + use linefeed::ReadResult::*; + + loop { + self.update_line_reader(); + match self.line_reader.read_line() { + Err(e) => { + println!("readline IO Error: {}", e); + break; + }, + Ok(Eof) => break, + Ok(Signal(_)) => break, + Ok(Input(ref input)) => { + self.line_reader.add_history_unique(input.to_string()); + let output = match input.chars().nth(0) { + Some(ch) if ch == self.interpreter_directive_sigil => self.handle_interpreter_directive(input), + _ => Some(self.handle_input(input)), + }; + if let Some(o) = output { + println!("=> {}", o); + } + } + } + } + } + + fn update_line_reader(&mut self) { + let tab_complete_handler = TabCompleteHandler::new(self.interpreter_directive_sigil, self.get_directives()); + self.line_reader.set_completer(Arc::new(tab_complete_handler)); + let prompt_str = format!(" >> "); + self.line_reader.set_prompt(&prompt_str).unwrap(); + } + + fn save_options(&self) { + /* + let ref options = self.options; + let read = File::create(OPTIONS_SAVE_FILE) + .and_then(|mut file| { + let buf = ::serde_json::to_string(options).unwrap(); + file.write_all(buf.as_bytes()) + }); + + if let Err(err) = read { + println!("Error saving {} file {}", OPTIONS_SAVE_FILE, err); + } + */ + } + + fn get_directives(&self) -> CommandTree { + CommandTree::Top(vec![]) + } + + fn handle_interpreter_directive(&mut self, input: &str) -> Option { + None + } + + fn handle_input(&mut self, input: &str) -> String { + format!("") + } +} + pub struct Repl { options: EvalOptions, languages: Vec>, diff --git a/src/main.rs b/src/main.rs index 70b8351..0448f3f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ extern crate maaru_lang; extern crate rukka_lang; extern crate robo_lang; extern crate schala_lang; -use schala_repl::{PLIGenerator, repl_main}; +use schala_repl::{PLIGenerator, repl_main, start_repl}; extern { } @@ -15,6 +15,7 @@ fn main() { Box::new(|| { Box::new(robo_lang::Robo::new())}), Box::new(|| { Box::new(rukka_lang::Rukka::new())}), ]; - repl_main(generators); + //repl_main(generators); + start_repl(); }