1
0

99 lines
3.1 KiB
Rust
Raw Normal View History

2023-10-06 22:45:36 -04:00
//! Abstract, executable representations of corresponding items found in Dust
//! source code. The types that implement [AbstractTree] are inteded to be
//! created by an [Evaluator].
//!
//! When adding new lanugage features, first extend the grammar to recognize new
//! syntax nodes. Then add a new AbstractTree type using the existing types as
//! examples.
2023-10-06 13:32:58 -04:00
pub mod assignment;
2023-10-31 13:04:22 -04:00
pub mod block;
2023-10-06 13:32:58 -04:00
pub mod expression;
2023-10-17 14:06:02 -04:00
pub mod r#for;
2023-10-06 13:32:58 -04:00
pub mod function_call;
pub mod function_expression;
2023-10-06 13:32:58 -04:00
pub mod identifier;
pub mod if_else;
2023-10-29 19:31:06 -04:00
pub mod index;
2023-11-14 20:41:57 -05:00
pub mod index_assignment;
pub mod index_expression;
2023-10-06 13:32:58 -04:00
pub mod logic;
pub mod r#match;
pub mod math;
pub mod statement;
pub mod type_definition;
2023-10-10 14:12:07 -04:00
pub mod value_node;
2023-10-06 22:45:36 -04:00
pub mod r#while;
pub mod r#yield;
2023-10-06 13:32:58 -04:00
pub use {
assignment::*, block::*, expression::*, function_call::*, function_expression::*,
identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, index_expression::*,
logic::*, math::*, r#for::*, r#match::*, r#while::*, r#yield::*, statement::*,
type_definition::*, value_node::*,
2023-10-06 13:32:58 -04:00
};
use tree_sitter::Node;
2023-11-29 19:23:42 -05:00
use crate::{Error, Map, Result, Value};
pub struct Root {
statements: Vec<Statement>,
}
impl AbstractTree for Root {
2023-11-29 22:54:46 -05:00
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self> {
2023-11-29 19:23:42 -05:00
Error::expect_syntax_node(source, "root", node)?;
let statement_count = node.child_count();
let mut statements = Vec::with_capacity(statement_count);
for index in 0..statement_count {
let statement_node = node.child(index).unwrap();
2023-11-29 22:54:46 -05:00
let statement = Statement::from_syntax_node(source, statement_node, context)?;
2023-11-29 19:23:42 -05:00
statements.push(statement);
}
Ok(Root { statements })
}
fn run(&self, source: &str, context: &Map) -> Result<Value> {
2023-12-31 09:14:43 -05:00
let mut value = Value::none();
2023-11-29 19:23:42 -05:00
for statement in &self.statements {
if let Statement::Return(inner_statement) = statement {
return inner_statement.run(source, context);
} else {
value = statement.run(source, context)?;
}
2023-11-29 19:23:42 -05:00
}
Ok(value)
}
2023-12-05 17:08:22 -05:00
fn expected_type(&self, context: &Map) -> Result<Type> {
2023-11-29 19:23:42 -05:00
self.statements.last().unwrap().expected_type(context)
}
}
2023-10-06 13:32:58 -04:00
/// This trait is implemented by the Evaluator's internal types to form an
/// executable tree that resolves to a single value.
pub trait AbstractTree: Sized {
/// Interpret the syntax tree at the given node and return the abstraction.
///
/// This function is used to convert nodes in the Tree Sitter concrete
/// syntax tree into executable nodes in an abstract tree. This function is
/// where the tree should be traversed by accessing sibling and child nodes.
/// Each node in the CST should be traversed only once.
///
/// If necessary, the source code can be accessed directly by getting the
/// node's byte range.
2023-11-29 22:54:46 -05:00
fn from_syntax_node(source: &str, node: Node, context: &Map) -> Result<Self>;
2023-10-06 13:32:58 -04:00
2023-11-16 02:57:50 -05:00
/// Execute dust code by traversing the tree.
2023-11-29 19:23:42 -05:00
fn run(&self, source: &str, context: &Map) -> Result<Value>;
2023-12-05 17:08:22 -05:00
fn expected_type(&self, context: &Map) -> Result<Type>;
2023-10-06 13:32:58 -04:00
}