From 36e1bf722a3d366cea20ab7315d63d588d23dc48 Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Sat, 20 Jun 2020 13:38:03 -0500 Subject: Working on a simple LISP/scheme interpreter. --- src/main.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/main.rs (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..15cf60b --- /dev/null +++ b/src/main.rs @@ -0,0 +1,71 @@ +#[cfg(test)] +pub mod tests; + +pub mod lib; + +use rustyline::error::ReadlineError; +use rustyline::Editor; + +fn read(rl: &mut Editor) -> Option { + let readline = rl.readline(">> "); + match readline { + Ok(line) => { + rl.add_history_entry(line.as_str()); + Some(line) + }, + Err(ReadlineError::Interrupted) => { + println!("CTRL-C"); + None + }, + Err(ReadlineError::Eof) => { + println!("CTRL-D"); + None + }, + Err(err) => { + println!("Error: {:?}", err); + None + } + } +} + +fn means_exit(input: &str) -> bool { + match input { + "exit" | "quit" | ",q" => true, + _ => false + } +} + +fn eval(env: &mut lib::eval::Env, input: &str) -> String { + let sexp = match lib::parse::parse(input) { + Ok(x) => x, + Err(f) => return f + }; + + println!("{:?}", sexp); + let res = lib::eval::eval(&sexp, env); + match res { + Ok(x) => format!("{:?}", x), + Err(f) => f + } +} + +fn main() { + let mut env = lib::eval::Env::new(); + let hist_file = "history.txt"; + + // `()` can be used when no completer is required + let mut rl = Editor::<()>::new(); + if rl.load_history(hist_file).is_err() { + println!("No previous history."); + } + loop { + let input_line = read(&mut rl); + let line = match input_line { + None => break, + Some(expr) if means_exit(&expr) => break, + Some(expr) => expr + }; + println!("{}", eval(&mut env, &line)); + } + rl.save_history(hist_file).unwrap(); +} -- cgit v1.2.3