2024-05-21 21:07:12 +00:00
|
|
|
pub mod r#as;
|
2024-02-25 18:49:26 +00:00
|
|
|
pub mod assignment;
|
2024-03-20 21:05:37 +00:00
|
|
|
pub mod async_block;
|
2024-02-25 18:49:26 +00:00
|
|
|
pub mod block;
|
2024-04-21 21:00:08 +00:00
|
|
|
pub mod built_in_function_call;
|
2024-06-17 21:38:24 +00:00
|
|
|
pub mod expression;
|
2024-03-09 12:34:34 +00:00
|
|
|
pub mod function_call;
|
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;
|
2024-02-29 02:04:38 +00:00
|
|
|
pub mod r#type;
|
2024-06-16 01:13:11 +00:00
|
|
|
pub mod type_alias;
|
2024-06-17 14:10:06 +00:00
|
|
|
pub mod type_constructor;
|
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
|
|
|
|
2024-03-21 02:58:13 +00:00
|
|
|
use std::{cmp::Ordering, ops::Index};
|
2024-03-20 04:28:28 +00:00
|
|
|
|
2024-03-17 06:51:33 +00:00
|
|
|
use chumsky::span::{SimpleSpan, Span};
|
2024-06-04 18:47:15 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2024-03-17 06:51:33 +00:00
|
|
|
|
2024-02-25 18:49:26 +00:00
|
|
|
pub use self::{
|
2024-03-08 17:39:35 +00:00
|
|
|
assignment::{Assignment, AssignmentOperator},
|
2024-03-20 21:05:37 +00:00
|
|
|
async_block::AsyncBlock,
|
2024-03-08 17:39:35 +00:00
|
|
|
block::Block,
|
2024-04-21 21:00:08 +00:00
|
|
|
built_in_function_call::BuiltInFunctionCall,
|
2024-06-17 21:38:24 +00:00
|
|
|
expression::Expression,
|
2024-03-09 12:34:34 +00:00
|
|
|
function_call::FunctionCall,
|
2024-03-08 19:01:05 +00:00
|
|
|
if_else::IfElse,
|
2024-03-18 01:07:03 +00:00
|
|
|
list_index::ListIndex,
|
2024-03-08 17:39:35 +00:00
|
|
|
logic::Logic,
|
2024-03-18 01:07:03 +00:00
|
|
|
map_index::MapIndex,
|
2024-03-08 17:39:35 +00:00
|
|
|
math::Math,
|
2024-05-21 21:07:12 +00:00
|
|
|
r#as::As,
|
2024-03-08 17:39:35 +00:00
|
|
|
r#loop::Loop,
|
|
|
|
r#type::Type,
|
2024-03-11 21:58:26 +00:00
|
|
|
r#while::While,
|
2024-03-08 17:39:35 +00:00
|
|
|
statement::Statement,
|
2024-03-19 21:49:24 +00:00
|
|
|
structure_definition::StructureDefinition,
|
2024-06-16 07:12:04 +00:00
|
|
|
type_alias::TypeAssignment,
|
2024-06-19 13:48:01 +00:00
|
|
|
type_constructor::{
|
|
|
|
EnumTypeConstructor, FunctionTypeConstructor, ListTypeConstructor, TypeConstructor,
|
|
|
|
},
|
2024-03-07 11:33:54 +00:00
|
|
|
value_node::ValueNode,
|
2024-02-25 18:49:26 +00:00
|
|
|
};
|
|
|
|
|
2024-02-29 02:04:38 +00:00
|
|
|
use crate::{
|
|
|
|
context::Context,
|
2024-06-18 23:42:04 +00:00
|
|
|
error::{DustError, RuntimeError, ValidationError},
|
2024-02-29 02:04:38 +00:00
|
|
|
Value,
|
|
|
|
};
|
2024-02-25 18:49:26 +00:00
|
|
|
|
2024-06-04 18:47:15 +00:00
|
|
|
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
2024-03-17 11:31:45 +00:00
|
|
|
pub struct WithPosition<T> {
|
2024-06-16 07:12:04 +00:00
|
|
|
pub node: T,
|
2024-03-17 11:48:06 +00:00
|
|
|
pub position: SourcePosition,
|
|
|
|
}
|
|
|
|
|
2024-03-24 16:21:08 +00:00
|
|
|
pub trait WithPos: Sized {
|
|
|
|
fn with_position<T: Into<SourcePosition>>(self, span: T) -> WithPosition<Self> {
|
|
|
|
WithPosition {
|
2024-06-16 07:12:04 +00:00
|
|
|
node: self,
|
2024-03-24 16:21:08 +00:00
|
|
|
position: span.into(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T> WithPos for T {}
|
|
|
|
|
2024-06-04 18:47:15 +00:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
|
2024-03-17 11:48:06 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2024-03-20 04:28:28 +00:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
|
2024-06-17 14:10:06 +00:00
|
|
|
pub enum Evaluation {
|
2024-03-20 04:28:28 +00:00
|
|
|
Return(Value),
|
|
|
|
Break,
|
|
|
|
None,
|
|
|
|
}
|
|
|
|
|
2024-06-04 18:47:15 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2024-03-25 04:16:55 +00:00
|
|
|
pub struct AbstractTree(Vec<Statement>);
|
2024-03-20 04:28:28 +00:00
|
|
|
|
|
|
|
impl AbstractTree {
|
2024-03-25 04:16:55 +00:00
|
|
|
pub fn new(mut statements: Vec<Statement>) -> Self {
|
|
|
|
statements.sort_by(|left, right| match (&left, &right) {
|
2024-03-21 02:58:13 +00:00
|
|
|
(Statement::StructureDefinition(_), _) => Ordering::Less,
|
|
|
|
(_, Statement::StructureDefinition(_)) => Ordering::Greater,
|
|
|
|
(_, _) => Ordering::Equal,
|
|
|
|
});
|
|
|
|
|
2024-03-20 04:28:28 +00:00
|
|
|
AbstractTree(statements)
|
|
|
|
}
|
|
|
|
|
2024-04-22 05:51:34 +00:00
|
|
|
pub fn run(
|
|
|
|
self,
|
|
|
|
context: &mut Context,
|
2024-04-22 11:56:03 +00:00
|
|
|
manage_memory: bool,
|
2024-06-18 23:42:04 +00:00
|
|
|
) -> Result<Option<Value>, Vec<DustError>> {
|
2024-04-22 11:56:03 +00:00
|
|
|
let valid_statements = self.validate(context, manage_memory)?;
|
2024-03-21 03:13:21 +00:00
|
|
|
let mut previous_value = None;
|
|
|
|
|
|
|
|
for statement in valid_statements {
|
2024-03-25 04:16:55 +00:00
|
|
|
let position = statement.position();
|
2024-06-17 14:10:06 +00:00
|
|
|
let run = statement.evaluate(context, manage_memory);
|
2024-03-21 03:13:21 +00:00
|
|
|
|
|
|
|
match run {
|
|
|
|
Ok(action) => match action {
|
2024-06-17 14:10:06 +00:00
|
|
|
Evaluation::Return(value) => previous_value = Some(value),
|
|
|
|
Evaluation::None => previous_value = None,
|
2024-03-21 03:13:21 +00:00
|
|
|
_ => {}
|
|
|
|
},
|
|
|
|
Err(runtime_error) => {
|
2024-06-18 23:42:04 +00:00
|
|
|
return Err(vec![DustError::Runtime {
|
2024-03-21 03:13:21 +00:00
|
|
|
error: runtime_error,
|
2024-03-25 04:16:55 +00:00
|
|
|
position,
|
2024-03-21 03:13:21 +00:00
|
|
|
}]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(previous_value)
|
|
|
|
}
|
|
|
|
|
2024-04-22 11:56:03 +00:00
|
|
|
fn validate(
|
|
|
|
self,
|
|
|
|
context: &mut Context,
|
2024-06-17 22:00:42 +00:00
|
|
|
manage_memory: bool,
|
2024-06-18 23:42:04 +00:00
|
|
|
) -> Result<Vec<Statement>, Vec<DustError>> {
|
2024-03-20 04:28:28 +00:00
|
|
|
let mut errors = Vec::new();
|
2024-03-21 02:58:13 +00:00
|
|
|
let mut valid_statements = Vec::new();
|
2024-03-20 04:28:28 +00:00
|
|
|
|
|
|
|
for statement in self.0 {
|
2024-06-17 22:00:42 +00:00
|
|
|
let validation = statement.validate(context, manage_memory);
|
2024-03-20 04:28:28 +00:00
|
|
|
|
2024-03-21 02:58:13 +00:00
|
|
|
if let Err(validation_error) = validation {
|
2024-06-18 23:42:04 +00:00
|
|
|
errors.push(DustError::Validation {
|
2024-03-21 02:58:13 +00:00
|
|
|
error: validation_error,
|
2024-03-25 04:16:55 +00:00
|
|
|
position: statement.position(),
|
2024-03-21 02:58:13 +00:00
|
|
|
})
|
|
|
|
} else if errors.is_empty() {
|
2024-03-25 04:16:55 +00:00
|
|
|
if let Statement::StructureDefinition(_) = statement {
|
|
|
|
let position = statement.position();
|
2024-06-17 14:10:06 +00:00
|
|
|
let run = statement.evaluate(context, true);
|
2024-03-21 02:58:13 +00:00
|
|
|
|
|
|
|
if let Err(runtime_error) = run {
|
2024-06-18 23:42:04 +00:00
|
|
|
errors.push(DustError::Runtime {
|
2024-03-21 02:58:13 +00:00
|
|
|
error: runtime_error,
|
2024-03-25 04:16:55 +00:00
|
|
|
position,
|
2024-03-21 02:58:13 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return Err(errors);
|
2024-03-20 04:28:28 +00:00
|
|
|
}
|
2024-03-21 02:58:13 +00:00
|
|
|
} else {
|
|
|
|
valid_statements.push(statement)
|
2024-03-20 04:28:28 +00:00
|
|
|
}
|
2024-04-22 01:33:21 +00:00
|
|
|
} else {
|
|
|
|
continue;
|
2024-03-20 04:28:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-21 03:13:21 +00:00
|
|
|
if errors.is_empty() {
|
|
|
|
Ok(valid_statements)
|
|
|
|
} else {
|
|
|
|
Err(errors)
|
2024-03-20 04:28:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Index<usize> for AbstractTree {
|
2024-03-25 04:16:55 +00:00
|
|
|
type Output = Statement;
|
2024-03-20 04:28:28 +00:00
|
|
|
|
|
|
|
fn index(&self, index: usize) -> &Self::Output {
|
|
|
|
&self.0[index]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-19 09:08:10 +00:00
|
|
|
pub trait Evaluate: Sized {
|
2024-04-22 12:25:20 +00:00
|
|
|
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError>;
|
2024-06-17 14:10:06 +00:00
|
|
|
fn evaluate(
|
|
|
|
self,
|
|
|
|
context: &mut Context,
|
|
|
|
manage_memory: bool,
|
|
|
|
) -> Result<Evaluation, RuntimeError>;
|
2024-03-08 17:24:11 +00:00
|
|
|
}
|
2024-06-16 07:12:04 +00:00
|
|
|
|
|
|
|
pub trait ExpectedType {
|
|
|
|
fn expected_type(&self, context: &mut Context) -> Result<Type, ValidationError>;
|
|
|
|
}
|