From d01d280452d3ee62c86651a187fc2cf00f3950d9 Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Wed, 13 Oct 2021 01:41:45 -0700 Subject: [PATCH] Various REPL refactoring --- schala-repl/src/language.rs | 8 +----- schala-repl/src/repl/help.rs | 3 +- schala-repl/src/repl/mod.rs | 42 ++++++++++++++-------------- schala-repl/src/repl/repl_options.rs | 7 ++--- 4 files changed, 26 insertions(+), 34 deletions(-) diff --git a/schala-repl/src/language.rs b/schala-repl/src/language.rs index da7f13d..754f065 100644 --- a/schala-repl/src/language.rs +++ b/schala-repl/src/language.rs @@ -5,13 +5,7 @@ pub trait ProgrammingLanguageInterface { fn language_name(&self) -> String; fn source_file_suffix(&self) -> String; - fn run_computation(&mut self, _request: ComputationRequest) -> ComputationResponse { - ComputationResponse { - main_output: Err(format!("Computation pipeline not implemented")), - global_output_stats: GlobalOutputStats::default(), - debug_responses: vec![], - } - } + fn run_computation(&mut self, _request: ComputationRequest) -> ComputationResponse; fn request_meta(&mut self, _request: LangMetaRequest) -> LangMetaResponse { LangMetaResponse::Custom { diff --git a/schala-repl/src/repl/help.rs b/schala-repl/src/repl/help.rs index a8c1040..3e69bc5 100644 --- a/schala-repl/src/repl/help.rs +++ b/schala-repl/src/repl/help.rs @@ -48,7 +48,6 @@ fn get_directive_from_commands<'a>( fn global_help(repl: &mut Repl) -> InterpreterDirectiveOutput { let mut buf = String::new(); - let sigil = repl.interpreter_directive_sigil; writeln!( buf, @@ -63,7 +62,7 @@ fn global_help(repl: &mut Repl) -> InterpreterDirectiveOutput { writeln!( buf, "{}{} - {}", - sigil, + repl.sigil, directive.get_cmd(), directive.get_help() ) diff --git a/schala-repl/src/repl/mod.rs b/schala-repl/src/repl/mod.rs index b10906f..d578548 100644 --- a/schala-repl/src/repl/mod.rs +++ b/schala-repl/src/repl/mod.rs @@ -1,5 +1,6 @@ use std::collections::HashSet; use std::sync::Arc; +use colored::*; use crate::language::{ ComputationRequest, LangMetaRequest, LangMetaResponse, ProgrammingLanguageInterface, @@ -22,7 +23,10 @@ const OPTIONS_SAVE_FILE: &'static str = ".schala_repl"; type InterpreterDirectiveOutput = Option; pub struct Repl { - pub interpreter_directive_sigil: char, + /// If this is the first character typed by a user into the repl, the following + /// will be interpreted as a directive to the REPL rather than a command in the + /// running programming language. + sigil: char, line_reader: ::linefeed::interface::Interface<::linefeed::terminal::DefaultTerminal>, language_states: Vec>, options: ReplOptions, @@ -38,10 +42,10 @@ impl Repl { pub fn new(initial_states: Vec>) -> Repl { use linefeed::Interface; let line_reader = Interface::new("schala-repl").unwrap(); - let interpreter_directive_sigil = ':'; + let sigil = ':'; Repl { - interpreter_directive_sigil, + sigil, line_reader, language_states: initial_states, options: ReplOptions::new(), @@ -49,10 +53,9 @@ impl Repl { } pub fn run_repl(&mut self) { - println!("Schala MetaInterpreter version {}", crate::VERSION_STRING); + println!("Schala meta-interpeter version {}", crate::VERSION_STRING); println!( - "Type {}help for help with the REPL", - self.interpreter_directive_sigil + "Type {} for help with the REPL", format!("{}help", self.sigil).bright_green().bold() ); self.load_options(); self.handle_repl_loop(); @@ -65,16 +68,15 @@ impl Repl { .load_history(HISTORY_SAVE_FILE) .unwrap_or(()); match ReplOptions::load_from_file(OPTIONS_SAVE_FILE) { - Ok(options) => { - self.options = options; - } - Err(()) => (), - }; + Ok(options) => { + self.options = options; + } + Err(e) => eprintln!("{}",e) + } } fn handle_repl_loop(&mut self) { use linefeed::ReadResult::*; - let sigil = self.interpreter_directive_sigil; 'main: loop { macro_rules! match_or_break { @@ -96,7 +98,7 @@ impl Repl { self.line_reader.add_history_unique(input.to_string()); let mut chars = input.chars().peekable(); let repl_responses = match chars.nth(0) { - Some(ch) if ch == sigil => { + Some(ch) if ch == self.sigil => { if chars.peek() == Some(&'{') { let mut buf = String::new(); buf.push_str(input.get(2..).unwrap()); @@ -113,8 +115,8 @@ impl Repl { } self.handle_input(&buf) } else { - match self.handle_interpreter_directive(input) { - Some(directive_output) => println!("<> {}", directive_output), + match self.handle_interpreter_directive(input.get(1..).unwrap()) { + Some(directive_output) => println!("{}", directive_output), None => (), } continue; @@ -131,7 +133,7 @@ impl Repl { fn update_line_reader(&mut self) { let tab_complete_handler = - TabCompleteHandler::new(self.interpreter_directive_sigil, self.get_directives()); + TabCompleteHandler::new(self.sigil, self.get_directives()); self.line_reader .set_completer(Arc::new(tab_complete_handler)); //TODO fix this here self.set_prompt(PromptStyle::Normal); @@ -139,8 +141,8 @@ impl Repl { fn set_prompt(&mut self, prompt_style: PromptStyle) { let prompt_str = match prompt_style { - PromptStyle::Normal => ">> ".to_string(), - PromptStyle::Multiline => ">| ".to_string(), + PromptStyle::Normal => ">> ", + PromptStyle::Multiline => ">| ", }; self.line_reader.set_prompt(&prompt_str).unwrap(); @@ -154,9 +156,7 @@ impl Repl { } fn handle_interpreter_directive(&mut self, input: &str) -> InterpreterDirectiveOutput { - let mut iter = input.chars(); - iter.next(); - let arguments: Vec<&str> = iter.as_str().split_whitespace().collect(); + let arguments: Vec<&str> = input.split_whitespace().collect(); if arguments.len() < 1 { return None; diff --git a/schala-repl/src/repl/repl_options.rs b/schala-repl/src/repl/repl_options.rs index 2dc8626..e1f20fd 100644 --- a/schala-repl/src/repl/repl_options.rs +++ b/schala-repl/src/repl/repl_options.rs @@ -2,7 +2,7 @@ use crate::language::DebugAsk; use std::collections::HashSet; use std::fs::File; -use std::io::{Read, Write}; +use std::io::{self, Read, Write}; #[derive(Serialize, Deserialize)] pub struct ReplOptions { @@ -26,11 +26,11 @@ impl ReplOptions { file.write_all(buf.as_bytes()) }); if let Err(err) = res { - println!("Error saving {} file {}", filename, err); + eprintln!("Error saving {} file {}", filename, err); } } - pub fn load_from_file(filename: &str) -> Result { + pub fn load_from_file(filename: &str) -> Result { File::open(filename) .and_then(|mut file| { let mut contents = String::new(); @@ -41,6 +41,5 @@ impl ReplOptions { let output: ReplOptions = crate::serde_json::from_str(&contents)?; Ok(output) }) - .map_err(|_| ()) } }