#[cfg(test)] pub mod tests; pub mod lib; use rustyline::error::ReadlineError; use rustyline::Editor; use lib::environment::Environment; 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 Environment, input: &str) -> String { let sexp = match lib::tokenize::tokenize(input) { Ok(x) => x, Err(f) => return f }; let res = lib::eval::eval(&sexp, env); match res { Ok(x) => format!("{:?}", x), Err(f) => f } } fn main() { let mut env = Environment::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(); }