1
0
dust/dust-lang/src/abstract_tree/mod.rs

167 lines
4.5 KiB
Rust
Raw Normal View History

2024-02-25 18:49:26 +00:00
pub mod assignment;
pub mod block;
2024-02-26 21:27:01 +00:00
pub mod expression;
2024-03-09 12:34:34 +00:00
pub mod function_call;
2024-02-25 18:49:26 +00:00
pub mod identifier;
2024-03-08 19:01:05 +00:00
pub mod if_else;
2024-03-18 01:07:03 +00:00
pub mod list_index;
2024-02-25 18:49:26 +00:00
pub mod logic;
pub mod r#loop;
2024-03-18 01:07:03 +00:00
pub mod map_index;
2024-03-07 11:33:54 +00:00
pub mod math;
2024-02-25 18:49:26 +00:00
pub mod statement;
2024-03-19 21:49:24 +00:00
pub mod structure_definition;
pub mod r#type;
2024-02-26 21:27:01 +00:00
pub mod value_node;
2024-03-11 21:58:26 +00:00
pub mod r#while;
2024-02-25 18:49:26 +00:00
use std::ops::Index;
2024-03-17 06:51:33 +00:00
use chumsky::span::{SimpleSpan, Span};
2024-02-25 18:49:26 +00:00
pub use self::{
assignment::{Assignment, AssignmentOperator},
block::Block,
expression::Expression,
2024-03-09 12:34:34 +00:00
function_call::FunctionCall,
identifier::Identifier,
2024-03-08 19:01:05 +00:00
if_else::IfElse,
2024-03-18 01:07:03 +00:00
list_index::ListIndex,
logic::Logic,
2024-03-18 01:07:03 +00:00
map_index::MapIndex,
math::Math,
r#loop::Loop,
r#type::Type,
2024-03-11 21:58:26 +00:00
r#while::While,
statement::Statement,
2024-03-19 21:49:24 +00:00
structure_definition::StructureDefinition,
2024-03-07 11:33:54 +00:00
value_node::ValueNode,
2024-02-25 18:49:26 +00:00
};
use crate::{
context::Context,
error::{Error, RuntimeError, ValidationError},
Value,
};
2024-02-25 18:49:26 +00:00
2024-03-17 04:49:01 +00:00
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
2024-03-17 11:31:45 +00:00
pub struct WithPosition<T> {
2024-03-17 04:49:01 +00:00
pub node: T,
2024-03-17 11:48:06 +00:00
pub position: SourcePosition,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct SourcePosition(pub usize, pub usize);
impl From<SimpleSpan> for SourcePosition {
fn from(span: SimpleSpan) -> Self {
SourcePosition(span.start(), span.end())
}
}
impl From<(usize, usize)> for SourcePosition {
fn from((start, end): (usize, usize)) -> Self {
SourcePosition(start, end)
}
2024-03-17 04:49:01 +00:00
}
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub enum Action {
Return(Value),
Break,
None,
}
pub struct AbstractTree(Vec<WithPosition<Statement>>);
impl AbstractTree {
pub fn new(statements: Vec<WithPosition<Statement>>) -> Self {
AbstractTree(statements)
}
pub fn run(self, context: &Context) -> Result<Option<Value>, Vec<Error>> {
let mut valid_statements = Vec::with_capacity(self.0.len());
let mut errors = Vec::new();
for statement in self.0 {
let validation = statement.node.validate(context);
if let Statement::StructureDefinition(_) = statement.node {
match validation {
Ok(_) => {
let run_result = statement.node.run(context);
match run_result {
Ok(_) => {}
Err(runtime_error) => {
return Err(vec![Error::Runtime {
error: runtime_error,
position: statement.position,
}]);
}
}
}
Err(validation_error) => errors.push(Error::Validation {
error: validation_error,
position: statement.position,
}),
}
} else {
match validation {
Ok(_) => valid_statements.push(statement),
Err(validation_error) => errors.push(Error::Validation {
error: validation_error,
position: statement.position,
}),
}
}
}
if !errors.is_empty() {
return Err(errors);
}
let mut previous = None;
for statement in valid_statements {
let run_result = statement.node.run(context);
match run_result {
Ok(action) => match action {
Action::Return(value) => previous = Some(value),
_ => {}
},
Err(runtime_error) => {
return Err(vec![Error::Runtime {
error: runtime_error,
position: statement.position,
}]);
}
}
}
Ok(previous)
}
}
impl Index<usize> for AbstractTree {
type Output = WithPosition<Statement>;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
}
}
pub trait AbstractNode: Sized {
fn expected_type(&self, context: &Context) -> Result<Type, ValidationError>;
fn validate(&self, context: &Context) -> Result<(), ValidationError>;
2024-03-08 17:24:11 +00:00
fn run(self, context: &Context) -> Result<Action, RuntimeError>;
2024-03-17 04:49:01 +00:00
2024-03-17 11:48:06 +00:00
fn with_position<T: Into<SourcePosition>>(self, span: T) -> WithPosition<Self> {
2024-03-17 11:31:45 +00:00
WithPosition {
2024-03-17 04:49:01 +00:00
node: self,
2024-03-17 11:48:06 +00:00
position: span.into(),
2024-03-17 04:49:01 +00:00
}
}
2024-03-08 17:24:11 +00:00
}