From eb987bb5b0fb1e8d7c5fb142297161980b8a5036 Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 25 Mar 2018 00:09:51 -0700 Subject: [PATCH] Make REPL interpreter return a value --- schala-repl/src/lib.rs | 85 +++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 50 deletions(-) diff --git a/schala-repl/src/lib.rs b/schala-repl/src/lib.rs index c201b7b..7342eb9 100644 --- a/schala-repl/src/lib.rs +++ b/schala-repl/src/lib.rs @@ -20,6 +20,7 @@ use std::fs::File; use std::io::{Read, Write}; use std::process::exit; use std::default::Default; +use std::fmt::Write as FmtWrite; use rustyline::error::ReadlineError; use rustyline::Editor; @@ -181,12 +182,13 @@ impl Repl { println!("Terminal read error: {}", e); }, Ok(ref input) => { - self.console.add_history_entry(input); - if self.handle_interpreter_directive(input) { - continue; + let output = match input.chars().nth(0) { + Some(ch) if ch == self.interpreter_directive_sigil => self.handle_interpreter_directive(input), + _ => Some(self.input_handler(input)), + }; + if let Some(o) = output { + println!("=> {}", o); } - let output = self.input_handler(input); - println!("=> {}", output); } } } @@ -201,22 +203,16 @@ impl Repl { interpreter_output.to_repl() } - fn handle_interpreter_directive(&mut self, input: &str) -> bool { - match input.chars().nth(0) { - Some(ch) if ch == self.interpreter_directive_sigil => (), - _ => return false - } - + fn handle_interpreter_directive(&mut self, input: &str) -> Option { let mut iter = input.chars(); iter.next(); - let trimmed_sigil: &str = iter.as_str(); - - let commands: Vec<&str> = trimmed_sigil + let commands: Vec<&str> = iter + .as_str() .split_whitespace() .collect(); let cmd: &str = match commands.get(0).clone() { - None => return true, + None => return None, Some(s) => s }; @@ -226,49 +222,46 @@ impl Repl { exit(0) }, "help" => { - println!("Commands:"); - println!("exit | quit"); - println!("lang(uage) [go|show|next|previous]"); - println!("set [show|hide] [tokens|parse|symbols|eval|llvm]"); - println!("options"); + Some(r#"Commands: +exit | quit +lang(uage) [go|show|next|previous] +set [show|hide] [tokens|parse|symbols|eval|llvm] +options"#.to_string()) } "lang" | "language" => { match commands.get(1) { Some(&"show") => { + let mut buf = String::new(); for (i, lang) in self.languages.iter().enumerate() { - if i == self.current_language_index { - println!("* {}", lang.get_language_name()); - } else { - println!("{}", lang.get_language_name()); - } + write!(buf, "{}{}\n", if i == self.current_language_index { "* "} else { "" }, lang.get_language_name()).unwrap(); } + Some(buf) }, Some(&"go") => { match commands.get(2) { - None => println!("Must specify a language name"), + None => Some(format!("Must specify a language name")), Some(&desired_name) => { for (i, _) in self.languages.iter().enumerate() { let lang_name = self.languages[i].get_language_name(); if lang_name.to_lowercase() == desired_name.to_lowercase() { self.current_language_index = i; - println!("Switching to {}", self.languages[self.current_language_index].get_language_name()); - return true; + return Some(format!("Switching to {}", self.languages[self.current_language_index].get_language_name())); } } - println!("Language {} not found", desired_name); + Some(format!("Language {} not found", desired_name)) } } }, Some(&"next") => { self.current_language_index = (self.current_language_index + 1) % self.languages.len(); - println!("Switching to {}", self.languages[self.current_language_index].get_language_name()); + Some(format!("Switching to {}", self.languages[self.current_language_index].get_language_name())) } Some(&"prev") | Some(&"previous") => { self.current_language_index = if self.current_language_index == 0 { self.languages.len() - 1 } else { self.current_language_index - 1 }; - println!("Switching to {}", self.languages[self.current_language_index].get_language_name()); + Some(format!("Switching to {}", self.languages[self.current_language_index].get_language_name())) }, - Some(e) => println!("Bad `lang` argument: {}", e), - None => println!("`lang` - valid arguments `show`, `next`, `prev`|`previous`"), + Some(e) => Some(format!("Bad `lang` argument: {}", e)), + None => Some(format!("`lang` - valid arguments `show`, `next`, `prev`|`previous`")), } }, "set" => { @@ -276,12 +269,10 @@ impl Repl { Some(&"show") => true, Some(&"hide") => false, Some(e) => { - println!("Bad `set` argument: {}", e); - return true; + return Some(format!("Bad `set` argument: {}", e)); } None => { - println!("`set` - valid arguments `show {{option}}`, `hide {{option}}`"); - return true; + return Some(format!("`set` - valid arguments `show {{option}}`, `hide {{option}}`")); } }; match commands.get(2) { @@ -290,15 +281,10 @@ impl Repl { Some(&"ast") => self.options.debug.ast = show, Some(&"symbols") => self.options.debug.symbol_table = show, Some(&"llvm") => self.options.debug.llvm_ir = show, - Some(e) => { - println!("Bad `show`/`hide` argument: {}", e); - return true; - } - None => { - println!("`show`/`hide` requires an argument"); - return true; - } - } + Some(e) => return Some(format!("Bad `show`/`hide` argument: {}", e)), + None => return Some(format!("`show`/`hide` requires an argument")), + }; + None }, "options" => { let ref d = self.options.debug; @@ -306,12 +292,11 @@ impl Repl { let parse_tree = if d.parse_tree { "true".green() } else { "false".red() }; let ast = if d.ast { "true".green() } else { "false".red() }; let symbol_table = if d.symbol_table { "true".green() } else { "false".red() }; - println!(r#"Debug: -tokens: {}, parse: {}, ast: {}, symbols: {}"#, tokens, parse_tree, ast, symbol_table); + Some(format!(r#"Debug: +tokens: {}, parse: {}, ast: {}, symbols: {}"#, tokens, parse_tree, ast, symbol_table)) }, - e => println!("Unknown command: {}", e) + e => Some(format!("Unknown command: {}", e)) } - return true; } }