Refactor abstract tree traits
This commit is contained in:
parent
578cb6ad16
commit
a28ac297c1
@ -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,
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)),
|
||||||
)
|
)?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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())))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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(
|
||||||
|
@ -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,
|
||||||
|
@ -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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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>;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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}.");
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user