use std::io::{self, Write};
use callisp::ast::Ast;
use callisp::env;
use callisp::error::LispError;
use callisp::eval;
use callisp::parser;
fn read() -> Result<Ast, LispError> {
print!("callisp> ");
io::stdout().flush().map_err(|_| LispError::IO)?;
let mut buf = String::new();
io::stdin().read_line(&mut buf).map_err(|_| LispError::IO)?;
let buf = buf.trim_end().to_string();
let expr = parser::parse_expr(&buf).map_err(|_| LispError::Parse)?.1;
Ok(expr)
}
fn eval(input: Ast, env: &mut env::Environment) -> Result<Ast, LispError> {
eval::eval_expr(input, env)
}
fn print(input: Ast) {
if !matches!(input, Ast::Unspecified) {
println!("{}", input);
}
}
fn main() {
let mut env = env::Environment::outer_new();
loop {
let input = read().unwrap();
let result = eval(input, &mut env).unwrap();
print(result);
}
}