1
0
dust/src/interpret.rs

103 lines
2.8 KiB
Rust
Raw Normal View History

2023-12-29 19:01:54 +00:00
//! The top level of Dust's API with functions to interpret Dust code.
//!
//! You can use this library externally by calling either of the "eval"
//! functions or by constructing your own Evaluator.
use tree_sitter::{Parser, Tree as TSTree};
2023-12-29 19:35:52 +00:00
use crate::{language, AbstractTree, Error, Map, Result, Root, Value};
2023-12-29 19:01:54 +00:00
/// Interpret the given source code.
///
/// Returns a vector of results from evaluating the source code. Each comment
/// and statemtent will have its own result.
///
/// # Examples
///
/// ```rust
/// # use dust_lang::*;
/// assert_eq!(interpret("1 + 2 + 3"), Ok(Value::Integer(6)));
/// ```
pub fn interpret(source: &str) -> Result<Value> {
2023-12-29 19:52:51 +00:00
interpret_with_context(source, Map::new())
2023-12-29 19:01:54 +00:00
}
/// Interpret the given source code with the given context.
///
/// # Examples
///
/// ```rust
/// # use dust_lang::*;
2023-12-29 19:52:51 +00:00
/// let context = Map::new();
2023-12-29 19:01:54 +00:00
///
/// context.set("one".into(), 1.into(), None);
/// context.set("two".into(), 2.into(), None);
/// context.set("three".into(), 3.into(), None);
///
/// let dust_code = "four = 4 one + two + three + four";
///
/// assert_eq!(
2023-12-29 19:52:51 +00:00
/// interpret_with_context(dust_code, context),
2023-12-29 19:01:54 +00:00
/// Ok(Value::Integer(10))
/// );
/// ```
2023-12-29 19:52:51 +00:00
pub fn interpret_with_context(source: &str, context: Map) -> Result<Value> {
2023-12-29 21:27:13 +00:00
let mut interpreter = Interpreter::new(context)?;
let value = interpreter.run(source)?;
2023-12-29 19:01:54 +00:00
Ok(value)
}
/// A source code interpreter for the Dust language.
2023-12-29 21:27:13 +00:00
pub struct Interpreter {
2023-12-29 19:35:52 +00:00
parser: Parser,
2023-12-29 19:52:51 +00:00
context: Map,
2023-12-29 19:01:54 +00:00
syntax_tree: Option<TSTree>,
abstract_tree: Option<Root>,
}
2023-12-29 21:27:13 +00:00
impl Interpreter {
pub fn new(context: Map) -> Result<Self> {
2023-12-29 19:01:54 +00:00
let mut parser = Parser::new();
parser.set_language(language())?;
Ok(Interpreter {
2023-12-29 19:35:52 +00:00
parser,
2023-12-29 19:01:54 +00:00
context,
syntax_tree: None,
abstract_tree: None,
})
}
2023-12-29 21:27:13 +00:00
pub fn parse_only(&mut self, source: &str) {
self.syntax_tree = self.parser.parse(source, self.syntax_tree.as_ref());
2023-12-29 19:01:54 +00:00
}
2023-12-29 21:27:13 +00:00
pub fn run(&mut self, source: &str) -> Result<Value> {
self.syntax_tree = self.parser.parse(source, self.syntax_tree.as_ref());
2023-12-29 19:01:54 +00:00
self.abstract_tree = if let Some(syntax_tree) = &self.syntax_tree {
Some(Root::from_syntax_node(
2023-12-29 21:27:13 +00:00
source,
2023-12-29 19:01:54 +00:00
syntax_tree.root_node(),
&self.context,
)?)
} else {
2023-12-29 19:35:52 +00:00
return Err(Error::ParserCancelled);
2023-12-29 19:01:54 +00:00
};
if let Some(abstract_tree) = &self.abstract_tree {
2023-12-29 21:27:13 +00:00
abstract_tree.run(source, &self.context)
2023-12-29 19:01:54 +00:00
} else {
2023-12-30 14:29:33 +00:00
Ok(Value::none())
2023-12-29 19:01:54 +00:00
}
}
2023-12-29 19:35:52 +00:00
pub fn syntax_tree(&self) -> Result<String> {
2023-12-29 19:01:54 +00:00
if let Some(syntax_tree) = &self.syntax_tree {
2023-12-29 19:35:52 +00:00
Ok(syntax_tree.root_node().to_sexp())
2023-12-29 19:01:54 +00:00
} else {
2023-12-29 19:35:52 +00:00
Err(Error::ParserCancelled)
2023-12-29 19:01:54 +00:00
}
}
}