forked from AbleScript/ablescript
Add statement continuation in REPL in CLI
Typing ``` var foo = [ ``` into the REPL now causes it to prompt you to complete the statement rather than just printing an "unexpected EOF" error.
This commit is contained in:
parent
a3b6ae326e
commit
863d03575b
|
@ -1,12 +1,12 @@
|
|||
#![forbid(unsafe_code, clippy::unwrap_used)]
|
||||
|
||||
pub mod ast;
|
||||
pub mod error;
|
||||
pub mod interpret;
|
||||
pub mod parser;
|
||||
|
||||
mod base_55;
|
||||
mod brian;
|
||||
mod consts;
|
||||
mod error;
|
||||
mod lexer;
|
||||
mod variables;
|
||||
|
|
|
@ -6,39 +6,44 @@ use ablescript::parser::Parser;
|
|||
pub fn repl(ast_print: bool) {
|
||||
let mut rl = Editor::<()>::new();
|
||||
let mut env = ExecEnv::new();
|
||||
|
||||
// If this is `Some`, the user has previously entered an
|
||||
// incomplete statement and is now completing it; otherwise, the
|
||||
// user is entering a completely new statement.
|
||||
let mut partial: Option<String> = None;
|
||||
loop {
|
||||
let readline = rl.readline(":: ");
|
||||
match readline {
|
||||
Ok(line) => {
|
||||
// NOTE(Alex): `readline()` leaves a newline at the
|
||||
// end of the string if stdin is connected to a file
|
||||
// or unsupported terminal; this can interfere with
|
||||
// error printing.
|
||||
rl.add_history_entry(&line);
|
||||
let line = line.trim_end();
|
||||
match rl.readline(if partial.is_some() { ">> " } else { ":: " }) {
|
||||
Ok(readline) => {
|
||||
let readline = readline.trim_end();
|
||||
let partial_data = match partial {
|
||||
Some(line) => line + &readline,
|
||||
None => readline.to_owned(),
|
||||
};
|
||||
|
||||
if line == "exit" {
|
||||
println!("bye");
|
||||
break;
|
||||
}
|
||||
|
||||
let mut parser = Parser::new(line);
|
||||
let value = parser.init().and_then(|ast| {
|
||||
partial = match Parser::new(&partial_data).init().and_then(|ast| {
|
||||
if ast_print {
|
||||
println!("{:#?}", &ast);
|
||||
}
|
||||
env.eval_stmts(&ast)
|
||||
});
|
||||
|
||||
if let Err(e) = value {
|
||||
}) {
|
||||
Ok(_) => None,
|
||||
Err(ablescript::error::Error {
|
||||
// Treat "Unexpected EOF" errors as "we need
|
||||
// more data".
|
||||
kind: ablescript::error::ErrorKind::UnexpectedEof,
|
||||
..
|
||||
}) => Some(partial_data),
|
||||
Err(e) => {
|
||||
println!("{}", e);
|
||||
println!(" | {}", line);
|
||||
println!(" | {}", partial_data);
|
||||
println!(
|
||||
" {}{}",
|
||||
" ".repeat(e.span.start),
|
||||
"^".repeat((e.span.end - e.span.start).max(1))
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(rustyline::error::ReadlineError::Eof) => {
|
||||
println!("bye");
|
||||
|
|
Loading…
Reference in a new issue