Make REPL interpreter return a value
This commit is contained in:
parent
0b2e2cf68b
commit
7f21b70e3f
@ -20,6 +20,7 @@ use std::fs::File;
|
|||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
|
use std::fmt::Write as FmtWrite;
|
||||||
|
|
||||||
use rustyline::error::ReadlineError;
|
use rustyline::error::ReadlineError;
|
||||||
use rustyline::Editor;
|
use rustyline::Editor;
|
||||||
@ -181,12 +182,13 @@ impl Repl {
|
|||||||
println!("Terminal read error: {}", e);
|
println!("Terminal read error: {}", e);
|
||||||
},
|
},
|
||||||
Ok(ref input) => {
|
Ok(ref input) => {
|
||||||
self.console.add_history_entry(input);
|
let output = match input.chars().nth(0) {
|
||||||
if self.handle_interpreter_directive(input) {
|
Some(ch) if ch == self.interpreter_directive_sigil => self.handle_interpreter_directive(input),
|
||||||
continue;
|
_ => 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()
|
interpreter_output.to_repl()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_interpreter_directive(&mut self, input: &str) -> bool {
|
fn handle_interpreter_directive(&mut self, input: &str) -> Option<String> {
|
||||||
match input.chars().nth(0) {
|
|
||||||
Some(ch) if ch == self.interpreter_directive_sigil => (),
|
|
||||||
_ => return false
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut iter = input.chars();
|
let mut iter = input.chars();
|
||||||
iter.next();
|
iter.next();
|
||||||
let trimmed_sigil: &str = iter.as_str();
|
let commands: Vec<&str> = iter
|
||||||
|
.as_str()
|
||||||
let commands: Vec<&str> = trimmed_sigil
|
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let cmd: &str = match commands.get(0).clone() {
|
let cmd: &str = match commands.get(0).clone() {
|
||||||
None => return true,
|
None => return None,
|
||||||
Some(s) => s
|
Some(s) => s
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -226,49 +222,46 @@ impl Repl {
|
|||||||
exit(0)
|
exit(0)
|
||||||
},
|
},
|
||||||
"help" => {
|
"help" => {
|
||||||
println!("Commands:");
|
Some(r#"Commands:
|
||||||
println!("exit | quit");
|
exit | quit
|
||||||
println!("lang(uage) [go|show|next|previous]");
|
lang(uage) [go|show|next|previous]
|
||||||
println!("set [show|hide] [tokens|parse|symbols|eval|llvm]");
|
set [show|hide] [tokens|parse|symbols|eval|llvm]
|
||||||
println!("options");
|
options"#.to_string())
|
||||||
}
|
}
|
||||||
"lang" | "language" => {
|
"lang" | "language" => {
|
||||||
match commands.get(1) {
|
match commands.get(1) {
|
||||||
Some(&"show") => {
|
Some(&"show") => {
|
||||||
|
let mut buf = String::new();
|
||||||
for (i, lang) in self.languages.iter().enumerate() {
|
for (i, lang) in self.languages.iter().enumerate() {
|
||||||
if i == self.current_language_index {
|
write!(buf, "{}{}\n", if i == self.current_language_index { "* "} else { "" }, lang.get_language_name()).unwrap();
|
||||||
println!("* {}", lang.get_language_name());
|
|
||||||
} else {
|
|
||||||
println!("{}", lang.get_language_name());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Some(buf)
|
||||||
},
|
},
|
||||||
Some(&"go") => {
|
Some(&"go") => {
|
||||||
match commands.get(2) {
|
match commands.get(2) {
|
||||||
None => println!("Must specify a language name"),
|
None => Some(format!("Must specify a language name")),
|
||||||
Some(&desired_name) => {
|
Some(&desired_name) => {
|
||||||
for (i, _) in self.languages.iter().enumerate() {
|
for (i, _) in self.languages.iter().enumerate() {
|
||||||
let lang_name = self.languages[i].get_language_name();
|
let lang_name = self.languages[i].get_language_name();
|
||||||
if lang_name.to_lowercase() == desired_name.to_lowercase() {
|
if lang_name.to_lowercase() == desired_name.to_lowercase() {
|
||||||
self.current_language_index = i;
|
self.current_language_index = i;
|
||||||
println!("Switching to {}", self.languages[self.current_language_index].get_language_name());
|
return Some(format!("Switching to {}", self.languages[self.current_language_index].get_language_name()));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!("Language {} not found", desired_name);
|
Some(format!("Language {} not found", desired_name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(&"next") => {
|
Some(&"next") => {
|
||||||
self.current_language_index = (self.current_language_index + 1) % self.languages.len();
|
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") => {
|
Some(&"prev") | Some(&"previous") => {
|
||||||
self.current_language_index = if self.current_language_index == 0 { self.languages.len() - 1 } else { self.current_language_index - 1 };
|
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),
|
Some(e) => Some(format!("Bad `lang` argument: {}", e)),
|
||||||
None => println!("`lang` - valid arguments `show`, `next`, `prev`|`previous`"),
|
None => Some(format!("`lang` - valid arguments `show`, `next`, `prev`|`previous`")),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"set" => {
|
"set" => {
|
||||||
@ -276,12 +269,10 @@ impl Repl {
|
|||||||
Some(&"show") => true,
|
Some(&"show") => true,
|
||||||
Some(&"hide") => false,
|
Some(&"hide") => false,
|
||||||
Some(e) => {
|
Some(e) => {
|
||||||
println!("Bad `set` argument: {}", e);
|
return Some(format!("Bad `set` argument: {}", e));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
println!("`set` - valid arguments `show {{option}}`, `hide {{option}}`");
|
return Some(format!("`set` - valid arguments `show {{option}}`, `hide {{option}}`"));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match commands.get(2) {
|
match commands.get(2) {
|
||||||
@ -290,15 +281,10 @@ impl Repl {
|
|||||||
Some(&"ast") => self.options.debug.ast = show,
|
Some(&"ast") => self.options.debug.ast = show,
|
||||||
Some(&"symbols") => self.options.debug.symbol_table = show,
|
Some(&"symbols") => self.options.debug.symbol_table = show,
|
||||||
Some(&"llvm") => self.options.debug.llvm_ir = show,
|
Some(&"llvm") => self.options.debug.llvm_ir = show,
|
||||||
Some(e) => {
|
Some(e) => return Some(format!("Bad `show`/`hide` argument: {}", e)),
|
||||||
println!("Bad `show`/`hide` argument: {}", e);
|
None => return Some(format!("`show`/`hide` requires an argument")),
|
||||||
return true;
|
};
|
||||||
}
|
None
|
||||||
None => {
|
|
||||||
println!("`show`/`hide` requires an argument");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"options" => {
|
"options" => {
|
||||||
let ref d = self.options.debug;
|
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 parse_tree = if d.parse_tree { "true".green() } else { "false".red() };
|
||||||
let ast = if d.ast { "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() };
|
let symbol_table = if d.symbol_table { "true".green() } else { "false".red() };
|
||||||
println!(r#"Debug:
|
Some(format!(r#"Debug:
|
||||||
tokens: {}, parse: {}, ast: {}, symbols: {}"#, tokens, parse_tree, ast, symbol_table);
|
tokens: {}, parse: {}, ast: {}, symbols: {}"#, tokens, parse_tree, ast, symbol_table))
|
||||||
},
|
},
|
||||||
e => println!("Unknown command: {}", e)
|
e => Some(format!("Unknown command: {}", e))
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user