use tree_sitter::{Parser, Tree as TSTree};
use crate::{language, AbstractTree, Error, Map, Result, Root, Value};
pub fn interpret(source: &str) -> Result<Value> {
let mut context = Map::new();
interpret_with_context(source, &mut context)
}
pub fn interpret_with_context(source: &str, context: &mut Map) -> Result<Value> {
let mut parser = Parser::new();
parser.set_language(language())?;
let mut interpreter = Interpreter::new(context, source)?;
let value = interpreter.run()?;
Ok(value)
}
pub struct Interpreter<'c, 's> {
parser: Parser,
context: &'c mut Map,
source: &'s str,
syntax_tree: Option<TSTree>,
abstract_tree: Option<Root>,
}
impl<'c, 's> Interpreter<'c, 's> {
pub fn new(context: &'c mut Map, source: &'s str) -> Result<Self> {
let mut parser = Parser::new();
parser.set_language(language())?;
Ok(Interpreter {
parser,
context,
source,
syntax_tree: None,
abstract_tree: None,
})
}
pub fn set_source(&mut self, source: &'s str) {
self.source = source;
}
pub fn parse_only(&mut self) {
self.syntax_tree = self.parser.parse(self.source, self.syntax_tree.as_ref());
}
pub fn run(&mut self) -> Result<Value> {
self.syntax_tree = self.parser.parse(self.source, self.syntax_tree.as_ref());
self.abstract_tree = if let Some(syntax_tree) = &self.syntax_tree {
Some(Root::from_syntax_node(
self.source,
syntax_tree.root_node(),
&self.context,
)?)
} else {
return Err(Error::ParserCancelled);
};
if let Some(abstract_tree) = &self.abstract_tree {
abstract_tree.run(self.source, &self.context)
} else {
Ok(Value::Option(None))
}
}
pub fn syntax_tree(&self) -> Result<String> {
if let Some(syntax_tree) = &self.syntax_tree {
Ok(syntax_tree.root_node().to_sexp())
} else {
Err(Error::ParserCancelled)
}
}
}