improved REPL a bit

now uses rustyline for input
This commit is contained in:
Moritz Gmeiner 2024-09-02 03:10:35 +02:00
commit fb88595b6c
13 changed files with 560 additions and 100 deletions

View file

@ -15,6 +15,6 @@ pub use error::{LoxError, RuntimeError};
pub use function::LoxFunction;
pub use object::LoxReference;
pub use resolver::{resolve, ResolverError};
pub use run::{run, run_repl};
pub use run::run;
pub use runtime::Runtime;
pub use value::Value;

View file

@ -1,5 +1,3 @@
use std::io::Write;
use rlox2_frontend::lexer::{scan_tokens, Token};
use rlox2_frontend::parser::parse_tokens;
@ -9,61 +7,6 @@ use crate::resolver::resolve;
use super::Runtime;
pub fn run_repl(runtime: &mut Runtime) {
let stdin = std::io::stdin();
loop {
let mut input_buf = String::new();
print!("> ");
std::io::stdout().flush().unwrap();
'inner: loop {
stdin.read_line(&mut input_buf).unwrap_or_else(|err| {
eprintln!("Could not read from stdin: {err}");
std::process::exit(66);
});
let num_open_braces =
(input_buf.matches('{').count() as i64) - (input_buf.matches('}').count() as i64);
let num_open_parens =
(input_buf.matches('(').count() as i64) - (input_buf.matches(')').count() as i64);
let num_open_brackets =
(input_buf.matches('[').count() as i64) - (input_buf.matches(']').count() as i64);
// all braces/parens/brackets closed => break
if num_open_braces == 0 && num_open_parens == 0 && num_open_brackets == 0 {
break 'inner;
}
// any braces/parens/brackets more closing than opening => break (will be parse error)
if num_open_braces < 0 || num_open_parens < 0 || num_open_brackets < 0 {
break 'inner;
}
print!("< ");
// let indentation = " ".repeat((num_open_braces + num_open_brackets + num_open_parens) as usize);
// print!("{indentation}");
std::io::stdout().flush().unwrap();
}
if input_buf.is_empty() || input_buf == "exit\n" || input_buf == "quit\n" {
std::process::exit(0);
}
let input_buf = input_buf.trim();
match run(input_buf, runtime) {
Ok(()) => {}
Err(LoxError::Exit { exit_code }) => std::process::exit(exit_code),
Err(err) => eprintln!("{err}"),
}
}
}
pub fn run(source: &str, runtime: &mut Runtime) -> Result<(), LoxError> {
let tokens: Vec<Token> = scan_tokens(source)?;