use tree_sitter::{Parser, Tree as SyntaxTree};
use crate::{language, AbstractTree, Context, ContextMode, Error, Format, Root, Value};
pub fn interpret(source: &str) -> Result<Value, Error> {
interpret_with_context(source, Context::new(ContextMode::RemoveGarbage))
}
pub fn interpret_with_context(source: &str, context: Context) -> Result<Value, Error> {
let mut interpreter = Interpreter::new(context);
let value = interpreter.run(source)?;
Ok(value)
}
pub struct Interpreter {
parser: Parser,
context: Context,
}
impl Interpreter {
pub fn new(context: Context) -> Self {
let mut parser = Parser::new();
parser
.set_language(language())
.expect("Language version is incompatible with tree sitter version.");
parser.set_logger(Some(Box::new(|_log_type, message| {
log::trace!("{}", message)
})));
Interpreter { parser, context }
}
pub fn parse(&mut self, source: &str) -> Result<SyntaxTree, Error> {
if let Some(tree) = self.parser.parse(source, None) {
Ok(tree)
} else {
Err(Error::ParserCancelled)
}
}
pub fn validate(&mut self, source: &str) -> Result<Root, Error> {
let syntax_tree = self.parse(source)?;
let abstract_tree = Root::from_syntax(syntax_tree.root_node(), source, &self.context)?;
abstract_tree.validate(source, &self.context)?;
Ok(abstract_tree)
}
pub fn run(&mut self, source: &str) -> Result<Value, Error> {
let final_value = self.validate(source)?.run(source, &self.context)?;
Ok(final_value)
}
pub fn syntax_tree(&mut self, source: &str) -> Result<String, Error> {
Ok(self.parse(source)?.root_node().to_sexp())
}
pub fn format(&mut self, source: &str) -> Result<String, Error> {
let mut formatted_output = String::new();
self.validate(source)?.format(&mut formatted_output, 0);
Ok(formatted_output)
}
}
impl Default for Interpreter {
fn default() -> Self {
Interpreter::new(Context::default())
}
}