diff options
author | Dominick Allen <dominick.allen1989@gmail.com> | 2020-06-20 13:38:03 -0500 |
---|---|---|
committer | Dominick Allen <dominick.allen1989@gmail.com> | 2020-06-20 13:38:03 -0500 |
commit | 36e1bf722a3d366cea20ab7315d63d588d23dc48 (patch) | |
tree | 84ef440e398978bfd4467a99d375d7710f016031 /src/main.rs |
Working on a simple LISP/scheme interpreter.
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 71 |
1 files changed, 71 insertions, 0 deletions
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<T: rustyline::Helper>(rl: &mut Editor<T>) -> Option<String> { + 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(); +} |