Refactor abstract tree traits

This commit is contained in:
Jeff 2024-06-21 18:28:12 -04:00
parent 578cb6ad16
commit a28ac297c1
24 changed files with 227 additions and 241 deletions

View File

@ -9,7 +9,7 @@ use crate::{
Value, Value,
}; };
use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, TypeConstructor}; use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, TypeConstructor, Validate};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct As { pub struct As {
@ -26,7 +26,7 @@ impl As {
} }
} }
impl Evaluate for As { impl Validate for As {
fn validate( fn validate(
&self, &self,
_context: &mut Context, _context: &mut Context,
@ -44,7 +44,9 @@ impl Evaluate for As {
Ok(()) Ok(())
} }
}
impl Evaluate for As {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,

View File

@ -9,7 +9,8 @@ use crate::{
use super::{ use super::{
type_constructor::{RawTypeConstructor, TypeInvokationConstructor}, type_constructor::{RawTypeConstructor, TypeInvokationConstructor},
Evaluate, Evaluation, ExpectedType, Expression, Statement, Type, TypeConstructor, WithPosition, Evaluation, ExpectedType, Expression, Run, Statement, Type, TypeConstructor, Validate,
WithPosition,
}; };
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
@ -43,7 +44,7 @@ impl Assignment {
} }
} }
impl Evaluate for Assignment { impl Validate for Assignment {
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
if let Some(TypeConstructor::Raw(WithPosition { if let Some(TypeConstructor::Raw(WithPosition {
node: RawTypeConstructor::None, node: RawTypeConstructor::None,
@ -136,16 +137,18 @@ impl Evaluate for Assignment {
Ok(()) Ok(())
} }
}
fn evaluate( impl Run for Assignment {
fn run(
self, self,
context: &mut Context, context: &mut Context,
manage_memory: bool, manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let evaluation = self.statement.evaluate(context, manage_memory)?; let evaluation = self.statement.run(context, manage_memory)?;
let right = match evaluation { let right = match evaluation {
Evaluation::Return(value) => value, Some(Evaluation::Return(value)) => value,
r#break => return Ok(r#break), evaluation => return Ok(evaluation),
}; };
match self.operator { match self.operator {
@ -244,6 +247,6 @@ impl Evaluate for Assignment {
} }
} }
Ok(Evaluation::None) Ok(Some(Evaluation::Void))
} }
} }

View File

@ -1,14 +1,14 @@
use std::sync::RwLock; use std::sync::Mutex;
use rayon::prelude::*; use rayon::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
context::Context, context::Context,
error::{RuntimeError, RwLockPoisonError, ValidationError}, error::{PoisonError, RuntimeError, ValidationError},
}; };
use super::{Evaluate, Evaluation, ExpectedType, Statement, Type}; use super::{Evaluation, ExpectedType, Run, Statement, Type, Validate};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct AsyncBlock { pub struct AsyncBlock {
@ -21,7 +21,7 @@ impl AsyncBlock {
} }
} }
impl Evaluate for AsyncBlock { impl Validate for AsyncBlock {
fn validate(&self, _context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, _context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
for statement in &self.statements { for statement in &self.statements {
statement.validate(_context, manage_memory)?; statement.validate(_context, manage_memory)?;
@ -29,30 +29,32 @@ impl Evaluate for AsyncBlock {
Ok(()) Ok(())
} }
}
fn evaluate( impl Run for AsyncBlock {
fn run(
self, self,
_context: &mut Context, _context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let statement_count = self.statements.len(); let statement_count = self.statements.len();
let final_result = RwLock::new(Ok(Evaluation::None)); let final_result = Mutex::new(Ok(None));
self.statements self.statements
.into_par_iter() .into_par_iter()
.enumerate() .enumerate()
.find_map_first(|(index, statement)| { .find_map_any(|(index, statement)| {
let result = statement.evaluate(&mut _context.clone(), false); let result = statement.run(&mut _context.clone(), false);
if index == statement_count - 1 { if index == statement_count - 1 {
let get_write_lock = final_result.write(); let get_write_lock = final_result.lock();
match get_write_lock { match get_write_lock {
Ok(mut final_result) => { Ok(mut final_result) => {
*final_result = result; *final_result = result;
None None
} }
Err(_error) => Some(Err(RuntimeError::RwLockPoison(RwLockPoisonError))), Err(_error) => Some(Err(RuntimeError::RwLockPoison(PoisonError))),
} }
} else { } else {
None None
@ -61,8 +63,8 @@ impl Evaluate for AsyncBlock {
.unwrap_or( .unwrap_or(
final_result final_result
.into_inner() .into_inner()
.map_err(|_| RuntimeError::RwLockPoison(RwLockPoisonError))?, .map_err(|_| RuntimeError::RwLockPoison(PoisonError)),
) )?
} }
} }

View File

@ -5,7 +5,7 @@ use crate::{
error::{RuntimeError, ValidationError}, error::{RuntimeError, ValidationError},
}; };
use super::{Evaluate, Evaluation, ExpectedType, Statement, Type}; use super::{Evaluation, ExpectedType, Run, Statement, Type, Validate};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Block { pub struct Block {
@ -26,7 +26,7 @@ impl Block {
} }
} }
impl Evaluate for Block { impl Validate for Block {
fn validate( fn validate(
&self, &self,
_context: &mut Context, _context: &mut Context,
@ -38,16 +38,18 @@ impl Evaluate for Block {
Ok(()) Ok(())
} }
}
fn evaluate( impl Run for Block {
fn run(
self, self,
_context: &mut Context, _context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let mut previous = Evaluation::None; let mut previous = None;
for statement in self.statements { for statement in self.statements {
previous = statement.evaluate(_context, _manage_memory)?; previous = statement.run(_context, _manage_memory)?;
} }
Ok(previous) Ok(previous)
@ -84,8 +86,8 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
block.evaluate(&mut Context::new(None), true).unwrap(), block.run(&mut Context::new(None), true).unwrap(),
Evaluation::Return(Value::integer(42)) Some(Evaluation::Return(Value::integer(42)))
) )
} }

View File

@ -14,7 +14,7 @@ use crate::{
Value, Value,
}; };
use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, TypeConstructor}; use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, TypeConstructor, Validate};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum BuiltInFunctionCall { pub enum BuiltInFunctionCall {
@ -26,7 +26,7 @@ pub enum BuiltInFunctionCall {
WriteLine(Expression), WriteLine(Expression),
} }
impl Evaluate for BuiltInFunctionCall { impl Validate for BuiltInFunctionCall {
fn validate( fn validate(
&self, &self,
_context: &mut Context, _context: &mut Context,
@ -49,7 +49,9 @@ impl Evaluate for BuiltInFunctionCall {
} }
} }
} }
}
impl Evaluate for BuiltInFunctionCall {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,
@ -136,7 +138,7 @@ impl Evaluate for BuiltInFunctionCall {
thread::sleep(Duration::from_millis(*milliseconds as u64)); thread::sleep(Duration::from_millis(*milliseconds as u64));
} }
Ok(Evaluation::None) Ok(Evaluation::Void)
} }
BuiltInFunctionCall::WriteLine(expression) => { BuiltInFunctionCall::WriteLine(expression) => {
let action = expression.clone().evaluate(context, _manage_memory)?; let action = expression.clone().evaluate(context, _manage_memory)?;
@ -156,7 +158,7 @@ impl Evaluate for BuiltInFunctionCall {
stdout.flush()?; stdout.flush()?;
} }
Ok(Evaluation::None) Ok(Evaluation::Void)
} }
} }
} }

View File

@ -1,12 +1,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{context::Context, error::RuntimeError, identifier::Identifier};
context::Context,
error::{RuntimeError, ValidationError},
identifier::Identifier,
};
use super::{Evaluate, Evaluation, Type, TypeConstructor, WithPosition}; use super::{Evaluation, Run, Type, TypeConstructor, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct EnumDeclaration { pub struct EnumDeclaration {
@ -29,20 +25,12 @@ impl EnumDeclaration {
} }
} }
impl Evaluate for EnumDeclaration { impl Run for EnumDeclaration {
fn validate( fn run(
&self,
_context: &mut Context,
_manage_memory: bool,
) -> Result<(), ValidationError> {
Ok(())
}
fn evaluate(
self, self,
context: &mut Context, context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let EnumDeclaration { let EnumDeclaration {
name, name,
type_parameters, type_parameters,
@ -86,7 +74,7 @@ impl Evaluate for EnumDeclaration {
context.set_type(name.node, r#type)?; context.set_type(name.node, r#type)?;
Ok(Evaluation::None) Ok(None)
} }
} }

View File

@ -8,7 +8,7 @@ use crate::{
use super::{ use super::{
As, BuiltInFunctionCall, Evaluate, Evaluation, ExpectedType, FunctionCall, ListIndex, Logic, As, BuiltInFunctionCall, Evaluate, Evaluation, ExpectedType, FunctionCall, ListIndex, Logic,
MapIndex, Math, SourcePosition, Type, ValueNode, WithPosition, MapIndex, Math, SourcePosition, Type, Validate, ValueNode, WithPosition,
}; };
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
@ -40,7 +40,7 @@ impl Expression {
} }
} }
impl Evaluate for Expression { impl Validate for Expression {
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
match self { match self {
Expression::As(r#as) => r#as.node.validate(context, manage_memory), Expression::As(r#as) => r#as.node.validate(context, manage_memory),
@ -73,7 +73,9 @@ impl Evaluate for Expression {
Expression::Value(value_node) => value_node.node.validate(context, manage_memory), Expression::Value(value_node) => value_node.node.validate(context, manage_memory),
} }
} }
}
impl Evaluate for Expression {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,

View File

@ -6,7 +6,7 @@ use crate::{
value::ValueInner, value::ValueInner,
}; };
use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, TypeConstructor}; use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, TypeConstructor, Validate};
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct FunctionCall { pub struct FunctionCall {
@ -33,7 +33,7 @@ impl FunctionCall {
} }
} }
impl Evaluate for FunctionCall { impl Validate for FunctionCall {
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
self.function.validate(context, manage_memory)?; self.function.validate(context, manage_memory)?;
@ -69,7 +69,9 @@ impl Evaluate for FunctionCall {
}) })
} }
} }
}
impl Evaluate for FunctionCall {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,

View File

@ -6,7 +6,9 @@ use crate::{
value::ValueInner, value::ValueInner,
}; };
use super::{Block, Evaluate, Evaluation, ExpectedType, Expression, Type, WithPosition}; use super::{
Block, Evaluate, Evaluation, ExpectedType, Expression, Run, Type, Validate, WithPosition,
};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct IfElse { pub struct IfElse {
@ -32,7 +34,7 @@ impl IfElse {
} }
} }
impl Evaluate for IfElse { impl Validate for IfElse {
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> {
self.if_expression.validate(context, manage_memory)?; self.if_expression.validate(context, manage_memory)?;
self.if_block.node.validate(context, manage_memory)?; self.if_block.node.validate(context, manage_memory)?;
@ -88,12 +90,14 @@ impl Evaluate for IfElse {
Ok(()) Ok(())
} }
}
fn evaluate( impl Run for IfElse {
fn run(
self, self,
context: &mut Context, context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let if_position = self.if_expression.position(); let if_position = self.if_expression.position();
let action = self.if_expression.evaluate(context, _manage_memory)?; let action = self.if_expression.evaluate(context, _manage_memory)?;
let value = if let Evaluation::Return(value) = action { let value = if let Evaluation::Return(value) = action {
@ -106,7 +110,7 @@ impl Evaluate for IfElse {
if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() { if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() {
if *if_boolean { if *if_boolean {
return self.if_block.node.evaluate(context, _manage_memory); return self.if_block.node.run(context, _manage_memory);
} }
if let Some(else_ifs) = self.else_ifs { if let Some(else_ifs) = self.else_ifs {
@ -123,7 +127,7 @@ impl Evaluate for IfElse {
if let ValueInner::Boolean(else_if_boolean) = value.inner().as_ref() { if let ValueInner::Boolean(else_if_boolean) = value.inner().as_ref() {
if *else_if_boolean { if *else_if_boolean {
return block.node.evaluate(context, _manage_memory); return block.node.run(context, _manage_memory);
} }
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
@ -137,9 +141,9 @@ impl Evaluate for IfElse {
} }
if let Some(else_statement) = self.else_block { if let Some(else_statement) = self.else_block {
else_statement.node.evaluate(context, _manage_memory) else_statement.node.run(context, _manage_memory)
} else { } else {
Ok(Evaluation::None) Ok(None)
} }
} else { } else {
Err(RuntimeError::ValidationFailure( Err(RuntimeError::ValidationFailure(
@ -179,9 +183,9 @@ mod tests {
Some(Vec::with_capacity(0)), Some(Vec::with_capacity(0)),
None None
) )
.evaluate(&mut Context::new(None), true) .run(&mut Context::new(None), true)
.unwrap(), .unwrap(),
Evaluation::Return(Value::string("foo".to_string())) Some(Evaluation::Return(Value::string("foo".to_string())))
) )
} }
} }

View File

@ -5,7 +5,9 @@ use crate::{
error::{RuntimeError, ValidationError}, error::{RuntimeError, ValidationError},
}; };
use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, ValueNode, WithPosition}; use super::{
Evaluate, Evaluation, ExpectedType, Expression, Type, Validate, ValueNode, WithPosition,
};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ListIndex { pub struct ListIndex {
@ -22,7 +24,7 @@ impl ListIndex {
} }
} }
impl Evaluate for ListIndex { impl Validate for ListIndex {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
self.collection.validate(context, _manage_memory)?; self.collection.validate(context, _manage_memory)?;
self.index.validate(context, _manage_memory)?; self.index.validate(context, _manage_memory)?;
@ -53,7 +55,9 @@ impl Evaluate for ListIndex {
}), }),
} }
} }
}
impl Evaluate for ListIndex {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,
@ -84,7 +88,7 @@ impl Evaluate for ListIndex {
if let Some(item) = found_item { if let Some(item) = found_item {
Ok(Evaluation::Return(item.clone())) Ok(Evaluation::Return(item.clone()))
} else { } else {
Ok(Evaluation::None) Ok(Evaluation::Void)
} }
} else { } else {
Err(RuntimeError::ValidationFailure( Err(RuntimeError::ValidationFailure(

View File

@ -7,7 +7,7 @@ use crate::{
Value, Value,
}; };
use super::{Evaluate, Evaluation, ExpectedType, Expression, Type}; use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, Validate};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Logic { pub enum Logic {
@ -22,7 +22,7 @@ pub enum Logic {
Not(Expression), Not(Expression),
} }
impl Evaluate for Logic { impl Validate for Logic {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
match self { match self {
Logic::Equal(left, right) Logic::Equal(left, right)
@ -88,7 +88,9 @@ impl Evaluate for Logic {
} }
} }
} }
}
impl Evaluate for Logic {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,

View File

@ -5,7 +5,7 @@ use crate::{
error::{RuntimeError, ValidationError}, error::{RuntimeError, ValidationError},
}; };
use super::{Evaluate, Evaluation, Statement}; use super::{Evaluation, Run, Statement, Validate};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct Loop { pub struct Loop {
@ -22,7 +22,7 @@ impl Loop {
} }
} }
impl Evaluate for Loop { impl Validate for Loop {
fn validate( fn validate(
&self, &self,
_context: &mut Context, _context: &mut Context,
@ -34,20 +34,20 @@ impl Evaluate for Loop {
Ok(()) Ok(())
} }
}
fn evaluate( impl Run for Loop {
fn run(
self, self,
_context: &mut Context, _context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
loop { loop {
for statement in &self.statements { for statement in &self.statements {
let action = statement.clone().evaluate(_context, false)?; let run = statement.clone().run(_context, false)?;
match action { if let Some(Evaluation::Break) = run {
Evaluation::Return(_) => {} return Ok(run);
Evaluation::None => {}
Evaluation::Break => return Ok(Evaluation::Break),
} }
} }
} }

View File

@ -6,7 +6,9 @@ use crate::{
value::ValueInner, value::ValueInner,
}; };
use super::{Evaluate, Evaluation, ExpectedType, Expression, Type, ValueNode, WithPosition}; use super::{
Evaluate, Evaluation, ExpectedType, Expression, Type, Validate, ValueNode, WithPosition,
};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct MapIndex { pub struct MapIndex {
@ -23,7 +25,7 @@ impl MapIndex {
} }
} }
impl Evaluate for MapIndex { impl Validate for MapIndex {
fn validate( fn validate(
&self, &self,
_context: &mut Context, _context: &mut Context,
@ -31,7 +33,9 @@ impl Evaluate for MapIndex {
) -> Result<(), ValidationError> { ) -> Result<(), ValidationError> {
self.collection.validate(_context, _manage_memory) self.collection.validate(_context, _manage_memory)
} }
}
impl Evaluate for MapIndex {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,
@ -53,7 +57,7 @@ impl Evaluate for MapIndex {
let action = map let action = map
.get(&index.node) .get(&index.node)
.map(|value| Evaluation::Return(value.clone())) .map(|value| Evaluation::Return(value.clone()))
.unwrap_or(Evaluation::None); .unwrap_or(Evaluation::Void);
Ok(action) Ok(action)
} else { } else {

View File

@ -7,7 +7,7 @@ use crate::{
Value, Value,
}; };
use super::{Evaluate, Evaluation, ExpectedType, Expression, SourcePosition, Type}; use super::{Evaluate, Evaluation, ExpectedType, Expression, SourcePosition, Type, Validate};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Math { pub enum Math {
@ -18,7 +18,7 @@ pub enum Math {
Modulo(Expression, Expression), Modulo(Expression, Expression),
} }
impl Evaluate for Math { impl Validate for Math {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
match self { match self {
Math::Add(left, right) => { Math::Add(left, right) => {
@ -66,7 +66,9 @@ impl Evaluate for Math {
} }
} }
} }
}
impl Evaluate for Math {
fn evaluate( fn evaluate(
self, self,
_context: &mut Context, _context: &mut Context,

View File

@ -91,9 +91,10 @@ impl From<(usize, usize)> for SourcePosition {
#[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub enum Evaluation { pub enum Evaluation {
Return(Value),
Break, Break,
None, Continue,
Return(Value),
Void,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -120,12 +121,12 @@ impl AbstractTree {
for statement in valid_statements { for statement in valid_statements {
let position = statement.position(); let position = statement.position();
let run = statement.evaluate(context, manage_memory); let run = statement.run(context, manage_memory);
match run { match run {
Ok(action) => match action { Ok(evaluation) => match evaluation {
Evaluation::Return(value) => previous_value = Some(value), Some(Evaluation::Return(value)) => previous_value = Some(value),
Evaluation::None => previous_value = None, Some(Evaluation::Void) | None => previous_value = None,
_ => {} _ => {}
}, },
Err(runtime_error) => { Err(runtime_error) => {
@ -159,7 +160,7 @@ impl AbstractTree {
} else if errors.is_empty() { } else if errors.is_empty() {
if let Statement::StructureDefinition(_) = statement { if let Statement::StructureDefinition(_) = statement {
let position = statement.position(); let position = statement.position();
let run = statement.evaluate(context, true); let run = statement.run(context, true);
if let Err(runtime_error) = run { if let Err(runtime_error) = run {
errors.push(DustError::Runtime { errors.push(DustError::Runtime {
@ -193,8 +194,11 @@ impl Index<usize> for AbstractTree {
} }
} }
pub trait Evaluate: Sized { pub trait Validate {
fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError>; fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError>;
}
pub trait Evaluate: ExpectedType {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,
@ -202,6 +206,14 @@ pub trait Evaluate: Sized {
) -> Result<Evaluation, RuntimeError>; ) -> Result<Evaluation, RuntimeError>;
} }
pub trait Run {
fn run(
self,
context: &mut Context,
manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError>;
}
pub trait ExpectedType { pub trait ExpectedType {
fn expected_type(&self, context: &mut Context) -> Result<Type, ValidationError>; fn expected_type(&self, context: &mut Context) -> Result<Type, ValidationError>;
} }

View File

@ -7,7 +7,8 @@ use crate::{
use super::{ use super::{
Assignment, AsyncBlock, Block, EnumDeclaration, Evaluate, Evaluation, ExpectedType, Expression, Assignment, AsyncBlock, Block, EnumDeclaration, Evaluate, Evaluation, ExpectedType, Expression,
IfElse, Loop, SourcePosition, StructureDefinition, Type, TypeAlias, While, WithPosition, IfElse, Loop, Run, SourcePosition, StructureDefinition, Type, TypeAlias, Validate, While,
WithPosition,
}; };
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
@ -51,7 +52,41 @@ impl Statement {
} }
} }
impl Evaluate for Statement { impl Run for Statement {
fn run(
self,
context: &mut Context,
manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
let result = match self {
Statement::Assignment(assignment) => assignment.node.run(context, manage_memory),
Statement::AsyncBlock(async_block) => async_block.node.run(context, manage_memory),
Statement::Block(block) => block.node.run(context, manage_memory),
Statement::Break(_) => Ok(Some(Evaluation::Break)),
Statement::Expression(expression) => {
let evaluation = expression.evaluate(context, manage_memory)?;
Ok(Some(evaluation))
}
Statement::IfElse(if_else) => if_else.node.run(context, manage_memory),
Statement::Loop(r#loop) => r#loop.node.run(context, manage_memory),
Statement::StructureDefinition(structure_definition) => {
structure_definition.node.run(context, manage_memory)
}
Statement::TypeAlias(type_alias) => type_alias.node.run(context, manage_memory),
Statement::EnumDeclaration(type_alias) => type_alias.node.run(context, manage_memory),
Statement::While(r#while) => r#while.node.run(context, manage_memory),
};
if manage_memory {
context.clean()?;
}
result
}
}
impl Validate for Statement {
fn validate( fn validate(
&self, &self,
_context: &mut Context, _context: &mut Context,
@ -67,46 +102,10 @@ impl Evaluate for Statement {
Statement::Expression(expression) => expression.validate(_context, _manage_memory), Statement::Expression(expression) => expression.validate(_context, _manage_memory),
Statement::IfElse(if_else) => if_else.node.validate(_context, _manage_memory), Statement::IfElse(if_else) => if_else.node.validate(_context, _manage_memory),
Statement::Loop(r#loop) => r#loop.node.validate(_context, _manage_memory), Statement::Loop(r#loop) => r#loop.node.validate(_context, _manage_memory),
Statement::StructureDefinition(structure_definition) => {
structure_definition.node.validate(_context, _manage_memory)
}
Statement::TypeAlias(type_alias) => type_alias.node.validate(_context, _manage_memory),
Statement::EnumDeclaration(type_declaration) => {
type_declaration.node.validate(_context, _manage_memory)
}
Statement::While(r#while) => r#while.node.validate(_context, _manage_memory), Statement::While(r#while) => r#while.node.validate(_context, _manage_memory),
_ => Ok(()),
} }
} }
fn evaluate(
self,
context: &mut Context,
manage_memory: bool,
) -> Result<Evaluation, RuntimeError> {
let result = match self {
Statement::Assignment(assignment) => assignment.node.evaluate(context, manage_memory),
Statement::AsyncBlock(async_block) => async_block.node.evaluate(context, manage_memory),
Statement::Block(block) => block.node.evaluate(context, manage_memory),
Statement::Break(_) => Ok(Evaluation::Break),
Statement::Expression(expression) => expression.evaluate(context, manage_memory),
Statement::IfElse(if_else) => if_else.node.evaluate(context, manage_memory),
Statement::Loop(r#loop) => r#loop.node.evaluate(context, manage_memory),
Statement::StructureDefinition(structure_definition) => {
structure_definition.node.evaluate(context, manage_memory)
}
Statement::TypeAlias(type_alias) => type_alias.node.evaluate(context, manage_memory),
Statement::EnumDeclaration(type_alias) => {
type_alias.node.evaluate(context, manage_memory)
}
Statement::While(r#while) => r#while.node.evaluate(context, manage_memory),
};
if manage_memory {
context.clean()?;
}
result
}
} }
impl ExpectedType for Statement { impl ExpectedType for Statement {

View File

@ -1,12 +1,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{context::Context, error::RuntimeError, identifier::Identifier};
context::Context,
error::{RuntimeError, ValidationError},
identifier::Identifier,
};
use super::{Evaluate, Evaluation, Type, TypeConstructor}; use super::{Evaluation, Run, Type, TypeConstructor};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct StructureDefinition { pub struct StructureDefinition {
@ -20,20 +16,12 @@ impl StructureDefinition {
} }
} }
impl Evaluate for StructureDefinition { impl Run for StructureDefinition {
fn validate( fn run(
&self,
_context: &mut Context,
_manage_memory: bool,
) -> Result<(), ValidationError> {
Ok(())
}
fn evaluate(
self, self,
context: &mut Context, context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let mut fields = Vec::with_capacity(self.fields.len()); let mut fields = Vec::with_capacity(self.fields.len());
for (identifier, constructor) in self.fields { for (identifier, constructor) in self.fields {
@ -49,6 +37,6 @@ impl Evaluate for StructureDefinition {
context.set_type(self.name, struct_type)?; context.set_type(self.name, struct_type)?;
Ok(Evaluation::None) Ok(None)
} }
} }

View File

@ -3,13 +3,7 @@ use std::fmt::{self, Display, Formatter};
use clap::error::Result; use clap::error::Result;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{error::TypeConflict, identifier::Identifier};
context::Context,
error::{RuntimeError, TypeConflict, ValidationError},
identifier::Identifier,
};
use super::{Evaluate, Evaluation};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum Type { pub enum Type {
@ -208,24 +202,6 @@ impl Type {
} }
} }
impl Evaluate for Type {
fn validate(
&self,
_context: &mut Context,
_manage_memory: bool,
) -> Result<(), ValidationError> {
Ok(())
}
fn evaluate(
self,
_context: &mut Context,
_manage_memory: bool,
) -> Result<Evaluation, RuntimeError> {
Ok(Evaluation::None)
}
}
impl Display for Type { impl Display for Type {
fn fmt(&self, f: &mut Formatter) -> fmt::Result { fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self { match self {

View File

@ -1,12 +1,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::{context::Context, error::RuntimeError, identifier::Identifier};
context::Context,
error::{RuntimeError, ValidationError},
identifier::Identifier,
};
use super::{Evaluate, Evaluation, TypeConstructor, WithPosition}; use super::{Evaluation, Run, TypeConstructor, WithPosition};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct TypeAlias { pub struct TypeAlias {
@ -23,24 +19,16 @@ impl TypeAlias {
} }
} }
impl Evaluate for TypeAlias { impl Run for TypeAlias {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { fn run(
let r#type = self.constructor.clone().construct(&context)?;
context.set_type(self.identifier.node.clone(), r#type)?;
Ok(())
}
fn evaluate(
self, self,
context: &mut Context, context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let r#type = self.constructor.construct(&context)?; let r#type = self.constructor.construct(&context)?;
context.set_type(self.identifier.node, r#type)?; context.set_type(self.identifier.node, r#type)?;
Ok(Evaluation::None) Ok(None)
} }
} }

View File

@ -10,7 +10,8 @@ use crate::{
}; };
use super::{ use super::{
Block, Evaluate, Evaluation, ExpectedType, Expression, Type, TypeConstructor, WithPosition, Block, Evaluate, Evaluation, ExpectedType, Expression, Type, TypeConstructor, Validate,
WithPosition,
}; };
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -39,7 +40,7 @@ pub enum ValueNode {
}, },
} }
impl Evaluate for ValueNode { impl Validate for ValueNode {
fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> {
if let ValueNode::EnumInstance { if let ValueNode::EnumInstance {
type_name, variant, .. type_name, variant, ..
@ -162,7 +163,9 @@ impl Evaluate for ValueNode {
Ok(()) Ok(())
} }
}
impl Evaluate for ValueNode {
fn evaluate( fn evaluate(
self, self,
context: &mut Context, context: &mut Context,

View File

@ -7,7 +7,7 @@ use crate::{
Value, Value,
}; };
use super::{Evaluate, Evaluation, Expression, Statement}; use super::{Evaluate, Evaluation, Expression, Run, Statement, Validate};
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct While { pub struct While {
@ -24,7 +24,7 @@ impl While {
} }
} }
impl Evaluate for While { impl Validate for While {
fn validate( fn validate(
&self, &self,
_context: &mut Context, _context: &mut Context,
@ -38,12 +38,14 @@ impl Evaluate for While {
Ok(()) Ok(())
} }
}
fn evaluate( impl Run for While {
fn run(
self, self,
_context: &mut Context, _context: &mut Context,
_manage_memory: bool, _manage_memory: bool,
) -> Result<Evaluation, RuntimeError> { ) -> Result<Option<Evaluation>, RuntimeError> {
let get_boolean = || -> Result<Value, RuntimeError> { let get_boolean = || -> Result<Value, RuntimeError> {
let expression_position = self.expression.position(); let expression_position = self.expression.position();
let action = self let action = self
@ -62,16 +64,14 @@ impl Evaluate for While {
while let ValueInner::Boolean(true) = get_boolean()?.inner().as_ref() { while let ValueInner::Boolean(true) = get_boolean()?.inner().as_ref() {
for statement in &self.statements { for statement in &self.statements {
let action = statement.clone().evaluate(&mut _context.clone(), false)?; let evaluation = statement.clone().run(&mut _context.clone(), false)?;
match action { if let Some(Evaluation::Break) = evaluation {
Evaluation::Return(_) => {} return Ok(evaluation);
Evaluation::None => {}
Evaluation::Break => return Ok(Evaluation::Break),
} }
} }
} }
Ok(Evaluation::None) Ok(None)
} }
} }

View File

@ -5,7 +5,7 @@ use std::{
use crate::{ use crate::{
abstract_tree::Type, abstract_tree::Type,
error::{RwLockPoisonError, ValidationError}, error::{PoisonError, ValidationError},
identifier::Identifier, identifier::Identifier,
Value, Value,
}; };
@ -32,12 +32,11 @@ impl<'a> Context<'a> {
pub fn inner( pub fn inner(
&self, &self,
) -> Result<RwLockReadGuard<HashMap<Identifier, (VariableData, UsageData)>>, RwLockPoisonError> ) -> Result<RwLockReadGuard<HashMap<Identifier, (VariableData, UsageData)>>, PoisonError> {
{
Ok(self.variables.read()?) Ok(self.variables.read()?)
} }
pub fn contains(&self, identifier: &Identifier) -> Result<bool, RwLockPoisonError> { pub fn contains(&self, identifier: &Identifier) -> Result<bool, PoisonError> {
log::trace!("Checking that {identifier} exists."); log::trace!("Checking that {identifier} exists.");
if self.variables.read()?.contains_key(identifier) { if self.variables.read()?.contains_key(identifier) {
@ -66,7 +65,7 @@ impl<'a> Context<'a> {
} }
} }
pub fn use_value(&self, identifier: &Identifier) -> Result<Option<Value>, RwLockPoisonError> { pub fn use_value(&self, identifier: &Identifier) -> Result<Option<Value>, PoisonError> {
if let Some((VariableData::Value(value), usage_data)) = if let Some((VariableData::Value(value), usage_data)) =
self.variables.read()?.get(identifier) self.variables.read()?.get(identifier)
{ {
@ -83,7 +82,7 @@ impl<'a> Context<'a> {
} }
} }
pub fn get_value(&self, identifier: &Identifier) -> Result<Option<Value>, RwLockPoisonError> { pub fn get_value(&self, identifier: &Identifier) -> Result<Option<Value>, PoisonError> {
if let Some((VariableData::Value(value), _)) = self.variables.read()?.get(identifier) { if let Some((VariableData::Value(value), _)) = self.variables.read()?.get(identifier) {
log::trace!("Getting {identifier}'s value."); log::trace!("Getting {identifier}'s value.");
@ -98,7 +97,7 @@ impl<'a> Context<'a> {
pub fn get_data( pub fn get_data(
&self, &self,
identifier: &Identifier, identifier: &Identifier,
) -> Result<Option<(VariableData, UsageData)>, RwLockPoisonError> { ) -> Result<Option<(VariableData, UsageData)>, PoisonError> {
if let Some(full_data) = self.variables.read()?.get(identifier) { if let Some(full_data) = self.variables.read()?.get(identifier) {
log::trace!("Getting {identifier}'s value."); log::trace!("Getting {identifier}'s value.");
@ -110,7 +109,7 @@ impl<'a> Context<'a> {
} }
} }
pub fn set_type(&self, identifier: Identifier, r#type: Type) -> Result<(), RwLockPoisonError> { pub fn set_type(&self, identifier: Identifier, r#type: Type) -> Result<(), PoisonError> {
log::debug!("Setting {identifier} to type {}.", r#type); log::debug!("Setting {identifier} to type {}.", r#type);
self.variables self.variables
@ -120,11 +119,7 @@ impl<'a> Context<'a> {
Ok(()) Ok(())
} }
pub fn set_value( pub fn set_value(&mut self, identifier: Identifier, value: Value) -> Result<(), PoisonError> {
&mut self,
identifier: Identifier,
value: Value,
) -> Result<(), RwLockPoisonError> {
log::debug!("Setting {identifier} to value {value}."); log::debug!("Setting {identifier} to value {value}.");
let mut variables = self.variables.write()?; let mut variables = self.variables.write()?;
@ -141,7 +136,7 @@ impl<'a> Context<'a> {
Ok(()) Ok(())
} }
pub fn clean(&mut self) -> Result<(), RwLockPoisonError> { pub fn clean(&mut self) -> Result<(), PoisonError> {
if *self.is_clean.read()? { if *self.is_clean.read()? {
return Ok(()); return Ok(());
} }
@ -169,7 +164,7 @@ impl<'a> Context<'a> {
Ok(()) Ok(())
} }
pub fn is_clean(&mut self) -> Result<bool, RwLockPoisonError> { pub fn is_clean(&mut self) -> Result<bool, PoisonError> {
if *self.is_clean.read()? { if *self.is_clean.read()? {
Ok(true) Ok(true)
} else { } else {
@ -185,7 +180,7 @@ impl<'a> Context<'a> {
} }
} }
pub fn add_expected_use(&self, identifier: &Identifier) -> Result<bool, RwLockPoisonError> { pub fn add_expected_use(&self, identifier: &Identifier) -> Result<bool, PoisonError> {
if let Some((_, usage_data)) = self.variables.read()?.get(identifier) { if let Some((_, usage_data)) = self.variables.read()?.get(identifier) {
log::trace!("Adding expected use for variable {identifier}."); log::trace!("Adding expected use for variable {identifier}.");

View File

@ -1,4 +1,4 @@
use std::{io, sync::PoisonError}; use std::{io, sync::PoisonError as StdPoisonError};
use chumsky::{prelude::Rich, span::Span}; use chumsky::{prelude::Rich, span::Span};
@ -53,20 +53,20 @@ impl<'src> From<Rich<'_, Token<'src>>> for DustError {
#[derive(Debug)] #[derive(Debug)]
pub enum RuntimeError { pub enum RuntimeError {
Io(io::Error), Io(io::Error),
RwLockPoison(RwLockPoisonError), RwLockPoison(PoisonError),
ValidationFailure(ValidationError), ValidationFailure(ValidationError),
SerdeJson(serde_json::Error), SerdeJson(serde_json::Error),
} }
impl From<RwLockPoisonError> for RuntimeError { impl From<PoisonError> for RuntimeError {
fn from(error: RwLockPoisonError) -> Self { fn from(error: PoisonError) -> Self {
RuntimeError::RwLockPoison(error) RuntimeError::RwLockPoison(error)
} }
} }
impl<T> From<PoisonError<T>> for RuntimeError { impl<T> From<StdPoisonError<T>> for RuntimeError {
fn from(_: PoisonError<T>) -> Self { fn from(_: StdPoisonError<T>) -> Self {
RuntimeError::RwLockPoison(RwLockPoisonError) RuntimeError::RwLockPoison(PoisonError)
} }
} }
@ -137,7 +137,7 @@ pub enum ValidationError {
position: SourcePosition, position: SourcePosition,
}, },
InterpreterExpectedReturn(SourcePosition), InterpreterExpectedReturn(SourcePosition),
RwLockPoison(RwLockPoisonError), RwLockPoison(PoisonError),
TypeCheck { TypeCheck {
/// The mismatch that caused the error. /// The mismatch that caused the error.
conflict: TypeConflict, conflict: TypeConflict,
@ -174,24 +174,24 @@ pub enum ValidationError {
}, },
} }
impl From<RwLockPoisonError> for ValidationError { impl From<PoisonError> for ValidationError {
fn from(error: RwLockPoisonError) -> Self { fn from(error: PoisonError) -> Self {
ValidationError::RwLockPoison(error) ValidationError::RwLockPoison(error)
} }
} }
impl<T> From<PoisonError<T>> for ValidationError { impl<T> From<StdPoisonError<T>> for ValidationError {
fn from(_: PoisonError<T>) -> Self { fn from(_: StdPoisonError<T>) -> Self {
ValidationError::RwLockPoison(RwLockPoisonError) ValidationError::RwLockPoison(PoisonError)
} }
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct RwLockPoisonError; pub struct PoisonError;
impl<T> From<PoisonError<T>> for RwLockPoisonError { impl<T> From<StdPoisonError<T>> for PoisonError {
fn from(_: PoisonError<T>) -> Self { fn from(_: StdPoisonError<T>) -> Self {
RwLockPoisonError PoisonError
} }
} }

View File

@ -14,7 +14,7 @@ use serde::{
}; };
use crate::{ use crate::{
abstract_tree::{Block, Evaluate, Evaluation, Type, WithPosition}, abstract_tree::{Block, Evaluation, Run, Type, WithPosition},
context::Context, context::Context,
error::{RuntimeError, ValidationError}, error::{RuntimeError, ValidationError},
identifier::Identifier, identifier::Identifier,
@ -735,6 +735,12 @@ impl Function {
context.set_value(identifier.clone(), value)?; context.set_value(identifier.clone(), value)?;
} }
self.body.evaluate(context, clear_variables) self.body.run(context, clear_variables).map(|eval_option| {
if let Some(evaluation) = eval_option {
evaluation
} else {
Evaluation::Void
}
})
} }
} }