use sindra::log::LogPriority;
use visitor::{self, State};
use value::Value;
use glue::pipeline;
use parse;
pub fn interpret_pipeline<T>(ast: &T, mut state: &mut State) -> Result<Value, String>
where T: visitor::symbol::SymbolDefineVisitor +
visitor::type_visitor::TypeComputationVisitor +
visitor::eval::EvaluateVisitor {
pipeline(ast, &mut state)?;
let final_val = {
match visitor::eval::EvaluateVisitor::visit(ast, &mut state) {
Ok(value) => {
if state.logger.flush() == Some(LogPriority::Error) {
return Err(format!("stopping due to previous error(s)"));
}
value
},
Err(e) => {
return Err(format!("fatal error during evaluation: {}", e));
}
}
};
Ok(final_val)
}
pub fn interpret_statement(line: &str, mut state: &mut State)
-> Result<Value, String> {
let statement_ast = match parse::statement(line) {
Ok(ast) => ast,
Err(e) => {
return Err(format!("failed to parse statement: {}", e));
}
};
interpret_pipeline(&statement_ast, &mut state)
}
pub fn interpret(program: &str) -> Result<Value, String> {
let ast = match parse::program(program) {
Ok(ast) => ast,
Err(e) => {
return Err(format!("failed to lex program: {}", e));
}
};
let mut state = State::default();
interpret_pipeline(&ast, &mut state)
}