diff --git a/dust-lang/src/abstract_tree/as.rs b/dust-lang/src/abstract_tree/as.rs index 5535b31..6858112 100644 --- a/dust-lang/src/abstract_tree/as.rs +++ b/dust-lang/src/abstract_tree/as.rs @@ -56,7 +56,7 @@ impl AbstractNode for As { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(expression_position), )); }; let r#type = self.constructor.construct(&context)?; diff --git a/dust-lang/src/abstract_tree/assignment.rs b/dust-lang/src/abstract_tree/assignment.rs index 205760e..f3182b7 100644 --- a/dust-lang/src/abstract_tree/assignment.rs +++ b/dust-lang/src/abstract_tree/assignment.rs @@ -46,13 +46,13 @@ impl Assignment { impl AbstractNode for Assignment { fn define_types(&self, context: &Context) -> Result<(), ValidationError> { let relevant_statement = self.statement.last_evaluated_statement(); - let statement_type = relevant_statement.expected_type(context)?; - - if let Type::Void = &statement_type { + let statement_type = if let Some(r#type) = relevant_statement.expected_type(context)? { + r#type + } else { return Err(ValidationError::CannotAssignToNone( self.statement.position(), )); - } + }; if let Some(constructor) = &self.constructor { let r#type = constructor.clone().construct(&context)?; @@ -83,13 +83,13 @@ impl AbstractNode for Assignment { } let relevant_statement = self.statement.last_evaluated_statement(); - let statement_type = relevant_statement.expected_type(context)?; - - if let Type::Void = &statement_type { + let statement_type = if let Some(r#type) = relevant_statement.expected_type(context)? { + r#type + } else { return Err(ValidationError::CannotAssignToNone( self.statement.position(), )); - } + }; if let Some(constructor) = &self.constructor { let r#type = constructor.clone().construct(&context)?; @@ -138,11 +138,11 @@ impl AbstractNode for Assignment { let declared_type = constructor.clone().construct(context)?; let function_type = function_call.node.function().expected_type(context)?; - if let Type::Function { + if let Some(Type::Function { return_type, type_parameters: Some(type_parameters), .. - } = function_type + }) = function_type { if let Type::Generic { identifier, .. } = *return_type { let returned_parameter = type_parameters @@ -157,7 +157,7 @@ impl AbstractNode for Assignment { } } else { return Err(ValidationError::ExpectedFunction { - actual: function_type, + actual: function_type.unwrap(), position: function_call.position, }); } @@ -171,7 +171,7 @@ impl AbstractNode for Assignment { context: &Context, manage_memory: bool, ) -> Result, RuntimeError> { - let evaluation = self.statement.run(context, manage_memory)?; + let evaluation = self.statement.evaluate(context, manage_memory)?; let right = match evaluation { Some(Evaluation::Return(value)) => value, evaluation => return Ok(evaluation), @@ -273,10 +273,10 @@ impl AbstractNode for Assignment { } } - Ok(Some(Evaluation::Void)) + Ok(None) } - fn expected_type(&self, context: &Context) -> Result, ValidationError> { + fn expected_type(&self, _: &Context) -> Result, ValidationError> { Ok(None) } } diff --git a/dust-lang/src/abstract_tree/async_block.rs b/dust-lang/src/abstract_tree/async_block.rs index de66b6c..d7734aa 100644 --- a/dust-lang/src/abstract_tree/async_block.rs +++ b/dust-lang/src/abstract_tree/async_block.rs @@ -38,11 +38,7 @@ impl AbstractNode for AsyncBlock { Ok(()) } - fn evaluate( - self, - _context: &Context, - _manage_memory: bool, - ) -> Result, RuntimeError> { + fn evaluate(self, _context: &Context, _: bool) -> Result, RuntimeError> { let statement_count = self.statements.len(); let final_result = Mutex::new(Ok(None)); @@ -51,7 +47,7 @@ impl AbstractNode for AsyncBlock { .enumerate() .find_map_any( |(index, statement)| -> Option, RuntimeError>> { - let result = statement.run(&mut _context.clone(), false); + let result = statement.evaluate(&_context, false); if result.is_err() { return Some(result); diff --git a/dust-lang/src/abstract_tree/block.rs b/dust-lang/src/abstract_tree/block.rs index 12f691c..25e2fc4 100644 --- a/dust-lang/src/abstract_tree/block.rs +++ b/dust-lang/src/abstract_tree/block.rs @@ -51,7 +51,7 @@ impl AbstractNode for Block { let mut previous = None; for statement in self.statements { - previous = statement.run(_context, _manage_memory)?; + previous = statement.evaluate(_context, _manage_memory)?; } Ok(previous) @@ -86,7 +86,7 @@ mod tests { ]); assert_eq!( - block.run(&mut Context::new(None), true).unwrap(), + block.evaluate(&Context::new(None), true).unwrap(), Some(Evaluation::Return(Value::integer(42))) ) } @@ -103,8 +103,8 @@ mod tests { ]); assert_eq!( - block.expected_type(&mut Context::new(None)), - Ok(Type::Integer) + block.expected_type(&Context::new(None)), + Ok(Some(Type::Integer)) ) } } diff --git a/dust-lang/src/abstract_tree/built_in_function_call.rs b/dust-lang/src/abstract_tree/built_in_function_call.rs index 4c257b0..e9ce9c4 100644 --- a/dust-lang/src/abstract_tree/built_in_function_call.rs +++ b/dust-lang/src/abstract_tree/built_in_function_call.rs @@ -26,8 +26,15 @@ pub enum BuiltInFunctionCall { WriteLine(Expression), } impl AbstractNode for BuiltInFunctionCall { - fn define_types(&self, context: &Context) -> Result<(), ValidationError> { - Ok(()) + fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { + match self { + BuiltInFunctionCall::JsonParse(_, expression) => expression.define_types(_context), + BuiltInFunctionCall::Length(expression) => expression.define_types(_context), + BuiltInFunctionCall::ReadFile(expression) => expression.define_types(_context), + BuiltInFunctionCall::ReadLine => Ok(()), + BuiltInFunctionCall::Sleep(expression) => expression.define_types(_context), + BuiltInFunctionCall::WriteLine(expression) => expression.define_types(_context), + } } fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { @@ -54,56 +61,53 @@ impl AbstractNode for BuiltInFunctionCall { context: &Context, _manage_memory: bool, ) -> Result, RuntimeError> { + fn evaluate_expression( + expression: Expression, + context: &Context, + _manage_memory: bool, + ) -> Result { + let position = expression.position(); + let evaluation = expression.evaluate(context, _manage_memory)?; + + if let Some(Evaluation::Return(value)) = evaluation { + Ok(value) + } else { + Err(RuntimeError::ValidationFailure( + ValidationError::ExpectedExpression(position), + )) + } + } + match self { BuiltInFunctionCall::JsonParse(_type, expression) => { - let action = expression.clone().evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { - value - } else { - return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression.position()), - )); - }; + let position = expression.position(); + let value = evaluate_expression(expression, context, _manage_memory)?; if let ValueInner::String(string) = value.inner().as_ref() { - let deserialized = serde_json::from_str(string)?; + let deserialized = serde_json::from_str(&string)?; Ok(Some(Evaluation::Return(deserialized))) } else { Err(RuntimeError::ValidationFailure( ValidationError::ExpectedString { actual: value.r#type(context)?, - position: expression.position(), + position, }, )) } } BuiltInFunctionCall::Length(expression) => { - let action = expression.clone().evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { - value - } else { - return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression.position()), - )); - }; + let value = evaluate_expression(expression, context, _manage_memory)?; let length = if let ValueInner::List(list) = value.inner().as_ref() { list.len() as i64 } else { - 0 + todo!("Create an error for this occurence.") }; Ok(Some(Evaluation::Return(Value::integer(length)))) } BuiltInFunctionCall::ReadFile(expression) => { - let action = expression.clone().evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { - value - } else { - return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression.position()), - )); - }; + let value = evaluate_expression(expression, context, _manage_memory)?; let file_contents = if let ValueInner::String(path) = value.inner().as_ref() { read_to_string(path)? } else { @@ -122,30 +126,16 @@ impl AbstractNode for BuiltInFunctionCall { )))) } BuiltInFunctionCall::Sleep(expression) => { - let action = expression.clone().evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { - value - } else { - return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression.position()), - )); - }; + let value = evaluate_expression(expression, context, _manage_memory)?; if let ValueInner::Integer(milliseconds) = value.inner().as_ref() { thread::sleep(Duration::from_millis(*milliseconds as u64)); } - Ok(Evaluation::Void) + Ok(None) } BuiltInFunctionCall::WriteLine(expression) => { - let action = expression.clone().evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { - value - } else { - return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression.position()), - )); - }; + let value = evaluate_expression(expression, context, _manage_memory)?; if let ValueInner::String(output) = value.inner().as_ref() { let mut stdout = stdout(); @@ -155,7 +145,7 @@ impl AbstractNode for BuiltInFunctionCall { stdout.flush()?; } - Ok(Evaluation::Void) + Ok(None) } } } diff --git a/dust-lang/src/abstract_tree/enum_declaration.rs b/dust-lang/src/abstract_tree/enum_declaration.rs index 2680e62..116f60f 100644 --- a/dust-lang/src/abstract_tree/enum_declaration.rs +++ b/dust-lang/src/abstract_tree/enum_declaration.rs @@ -63,7 +63,7 @@ impl AbstractNode for EnumDeclaration { None }; - type_variants.push((name.node, types)); + type_variants.push((name.node.clone(), types)); } let r#type = Type::Enum { @@ -72,31 +72,20 @@ impl AbstractNode for EnumDeclaration { variants: type_variants, }; - context.set_type(name.node, r#type)?; + context.set_type(name.node.clone(), r#type)?; Ok(()) } - fn validate( - &self, - context: &Context, - manage_memory: bool, - ) -> Result<(), crate::error::ValidationError> { + fn validate(&self, _: &Context, _: bool) -> Result<(), ValidationError> { Ok(()) } - fn evaluate( - self, - context: &Context, - _manage_memory: bool, - ) -> Result, RuntimeError> { + fn evaluate(self, _: &Context, _: bool) -> Result, RuntimeError> { Ok(None) } - fn expected_type( - &self, - context: &Context, - ) -> Result, crate::error::ValidationError> { + fn expected_type(&self, _: &Context) -> Result, ValidationError> { Ok(None) } } diff --git a/dust-lang/src/abstract_tree/expression.rs b/dust-lang/src/abstract_tree/expression.rs index 2c9a3ca..a344b2a 100644 --- a/dust-lang/src/abstract_tree/expression.rs +++ b/dust-lang/src/abstract_tree/expression.rs @@ -46,7 +46,7 @@ impl AbstractNode for Expression { Expression::As(inner) => inner.node.define_types(_context), Expression::BuiltInFunctionCall(inner) => inner.node.define_types(_context), Expression::FunctionCall(inner) => inner.node.define_types(_context), - Expression::Identifier(inner) => inner.node.define_types(_context), + Expression::Identifier(_) => Ok(()), Expression::MapIndex(inner) => inner.node.define_types(_context), Expression::ListIndex(inner) => inner.node.define_types(_context), Expression::Logic(inner) => inner.node.define_types(_context), @@ -132,7 +132,7 @@ impl AbstractNode for Expression { Expression::As(r#as) => r#as.node.expected_type(_context), Expression::FunctionCall(function_call) => function_call.node.expected_type(_context), Expression::Identifier(identifier) => { - let get_type = _context.get_type(identifier)?; + let get_type = _context.get_type(&identifier.node)?; if get_type.is_none() { Err(ValidationError::VariableNotFound { diff --git a/dust-lang/src/abstract_tree/function_call.rs b/dust-lang/src/abstract_tree/function_call.rs index f4d45e0..d7811f8 100644 --- a/dust-lang/src/abstract_tree/function_call.rs +++ b/dust-lang/src/abstract_tree/function_call.rs @@ -35,7 +35,7 @@ impl FunctionCall { impl AbstractNode for FunctionCall { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { - self.function.define_ypes(_context)?; + self.function.define_types(_context)?; let mut previous = (); @@ -53,7 +53,13 @@ impl AbstractNode for FunctionCall { expression.validate(context, manage_memory)?; } - let function_node_type = self.function.expected_type(context)?; + let function_node_type = if let Some(r#type) = self.function.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression( + self.function.position(), + )); + }; if let Type::Function { type_parameters, @@ -88,12 +94,12 @@ impl AbstractNode for FunctionCall { clear_variables: bool, ) -> Result, RuntimeError> { let function_position = self.function.position(); - let action = self.function.evaluate(context, clear_variables)?; - let value = if let Evaluation::Return(value) = action { + let evaluation = self.function.evaluate(context, clear_variables)?; + let value = if let Some(Evaluation::Return(value)) = evaluation { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(function_position), + ValidationError::ExpectedExpression(function_position), )); }; let function = if let ValueInner::Function(function) = value.inner().as_ref() { @@ -111,15 +117,15 @@ impl AbstractNode for FunctionCall { for expression in self.value_arguments { let expression_position = expression.position(); let action = expression.evaluate(context, clear_variables)?; - let value = if let Evaluation::Return(value) = action { + let evalution = if let Some(Evaluation::Return(value)) = action { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(expression_position), )); }; - arguments.push(value); + arguments.push(evalution); } let mut function_context = Context::new(Some(&context)); @@ -143,13 +149,19 @@ impl AbstractNode for FunctionCall { } fn expected_type(&self, context: &Context) -> Result, ValidationError> { - let function_node_type = self.function.expected_type(context)?; + let function_type = if let Some(r#type) = self.function.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression( + self.function.position(), + )); + }; if let Type::Function { return_type, type_parameters, .. - } = function_node_type + } = function_type { if let Type::Generic { identifier: return_identifier, @@ -179,7 +191,14 @@ impl AbstractNode for FunctionCall { .zip(type_parameters.into_iter()) { if identifier == return_identifier { - let concrete_type = expression.expected_type(context)?; + let concrete_type = + if let Some(r#type) = expression.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression( + expression.position(), + )); + }; return Ok(Some(Type::Generic { identifier, @@ -193,7 +212,7 @@ impl AbstractNode for FunctionCall { Ok(Some(*return_type)) } else { Err(ValidationError::ExpectedFunction { - actual: function_node_type, + actual: function_type, position: self.function.position(), }) } diff --git a/dust-lang/src/abstract_tree/if_else.rs b/dust-lang/src/abstract_tree/if_else.rs index fa8511b..3c0d4b8 100644 --- a/dust-lang/src/abstract_tree/if_else.rs +++ b/dust-lang/src/abstract_tree/if_else.rs @@ -35,16 +35,16 @@ impl IfElse { impl AbstractNode for IfElse { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { self.if_expression.define_types(_context)?; - self.if_block.define_type(_context)?; + self.if_block.node.define_types(_context)?; - if let Some(else_ifs) = self.else_ifs { + if let Some(else_ifs) = &self.else_ifs { for (expression, block) in else_ifs { expression.define_types(_context)?; block.node.define_types(_context)?; } } - if let Some(else_block) = self.else_block { + if let Some(else_block) = &self.else_block { else_block.node.define_types(_context)?; } @@ -55,22 +55,36 @@ impl AbstractNode for IfElse { self.if_expression.validate(context, manage_memory)?; self.if_block.node.validate(context, manage_memory)?; - let expected_type = self.if_block.node.expected_type(context)?; - let if_expression_type = self.if_expression.expected_type(context)?; + let if_expression_type = if let Some(r#type) = self.if_expression.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression( + self.if_expression.position(), + )); + }; + let expected_type = if let Some(r#type) = self.if_block.node.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression(self.if_block.position)); + }; if let Type::Boolean = if_expression_type { if let Some(else_block) = &self.else_block { else_block.node.validate(context, manage_memory)?; - let actual = else_block.node.expected_type(context)?; + let actual_type = if let Some(r#type) = else_block.node.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression(else_block.position)); + }; - expected_type - .check(&actual) - .map_err(|conflict| ValidationError::TypeCheck { + expected_type.check(&actual_type).map_err(|conflict| { + ValidationError::TypeCheck { conflict, actual_position: else_block.node.last_statement().position(), expected_position: Some(self.if_block.node.first_statement().position()), - })?; + } + })?; } } else { return Err(ValidationError::ExpectedBoolean { @@ -83,12 +97,16 @@ impl AbstractNode for IfElse { for (expression, block) in else_ifs { let expression_type = expression.expected_type(context)?; - if let Type::Boolean = expression_type { + if let Some(Type::Boolean) = expression_type { block.node.validate(context, manage_memory)?; - let actual = block.node.expected_type(context)?; + let actual_type = if let Some(r#type) = block.node.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression(block.position)); + }; - expected_type.check(&actual).map_err(|conflict| { + expected_type.check(&actual_type).map_err(|conflict| { ValidationError::TypeCheck { conflict, actual_position: self.if_block.node.last_statement().position(), @@ -113,35 +131,35 @@ impl AbstractNode for IfElse { _manage_memory: bool, ) -> Result, RuntimeError> { let if_position = self.if_expression.position(); - let action = self.if_expression.evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { + let evaluation = self.if_expression.evaluate(context, _manage_memory)?; + let value = if let Some(Evaluation::Return(value)) = evaluation { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(if_position), + ValidationError::ExpectedExpression(if_position), )); }; if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() { if *if_boolean { - return self.if_block.node.run(context, _manage_memory); + return self.if_block.node.evaluate(context, _manage_memory); } if let Some(else_ifs) = self.else_ifs { for (expression, block) in else_ifs { let expression_position = expression.position(); - let action = expression.evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { + let evaluation = expression.evaluate(context, _manage_memory)?; + let value = if let Some(Evaluation::Return(value)) = evaluation { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(expression_position), )); }; if let ValueInner::Boolean(else_if_boolean) = value.inner().as_ref() { if *else_if_boolean { - return block.node.run(context, _manage_memory); + return block.node.evaluate(context, _manage_memory); } } else { return Err(RuntimeError::ValidationFailure( @@ -155,7 +173,7 @@ impl AbstractNode for IfElse { } if let Some(else_statement) = self.else_block { - else_statement.node.run(context, _manage_memory) + else_statement.node.evaluate(context, _manage_memory) } else { Ok(None) } @@ -195,7 +213,7 @@ mod tests { Some(Vec::with_capacity(0)), None ) - .run(&mut Context::new(None), true) + .evaluate(&Context::new(None), true) .unwrap(), Some(Evaluation::Return(Value::string("foo".to_string()))) ) diff --git a/dust-lang/src/abstract_tree/list_index.rs b/dust-lang/src/abstract_tree/list_index.rs index 0843be1..084f7f5 100644 --- a/dust-lang/src/abstract_tree/list_index.rs +++ b/dust-lang/src/abstract_tree/list_index.rs @@ -5,7 +5,7 @@ use crate::{ error::{RuntimeError, ValidationError}, }; -use super::{AbstractNode, Evaluation, Expression, Type, Validate, ValueNode, WithPosition}; +use super::{AbstractNode, Evaluation, Expression, Type, ValueNode, WithPosition}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct ListIndex { @@ -22,8 +22,13 @@ impl ListIndex { } } -impl Validate for ListIndex { - fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { +impl AbstractNode for ListIndex { + fn define_types(&self, context: &Context) -> Result<(), ValidationError> { + self.collection.define_types(context)?; + self.index.define_types(context) + } + + fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { self.collection.validate(context, _manage_memory)?; self.index.validate(context, _manage_memory)?; @@ -57,12 +62,10 @@ impl Validate for ListIndex { }), } } -} -impl AbstractNode for ListIndex { fn evaluate( self, - context: &mut Context, + context: &Context, _clear_variables: bool, ) -> Result, RuntimeError> { let left_position = self.collection.position(); @@ -71,7 +74,7 @@ impl AbstractNode for ListIndex { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(left_position), + ValidationError::ExpectedExpression(left_position), )); }; let right_position = self.index.position(); @@ -80,7 +83,7 @@ impl AbstractNode for ListIndex { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(right_position), + ValidationError::ExpectedExpression(right_position), )); }; @@ -104,7 +107,7 @@ impl AbstractNode for ListIndex { } } - fn expected_type(&self, _context: &mut Context) -> Result, ValidationError> { + fn expected_type(&self, _context: &Context) -> Result, ValidationError> { let left_type = self.collection.expected_type(_context)?; if let ( diff --git a/dust-lang/src/abstract_tree/logic.rs b/dust-lang/src/abstract_tree/logic.rs index 14c73d3..04d4a83 100644 --- a/dust-lang/src/abstract_tree/logic.rs +++ b/dust-lang/src/abstract_tree/logic.rs @@ -7,7 +7,7 @@ use crate::{ Value, }; -use super::{AbstractNode, Evaluation, Expression, Type, Validate}; +use super::{AbstractNode, Evaluation, Expression, Type}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub enum Logic { @@ -22,8 +22,46 @@ pub enum Logic { Not(Expression), } -impl Validate for Logic { - fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { +impl AbstractNode for Logic { + fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { + match self { + Logic::Equal(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Logic::NotEqual(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Logic::Greater(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Logic::Less(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Logic::GreaterOrEqual(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Logic::LessOrEqual(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Logic::And(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Logic::Or(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Logic::Not(expression) => expression.define_types(_context), + } + } + + fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { match self { Logic::Equal(left, right) | Logic::NotEqual(left, right) @@ -88,12 +126,10 @@ impl Validate for Logic { } } } -} -impl AbstractNode for Logic { fn evaluate( self, - context: &mut Context, + context: &Context, _manage_memory: bool, ) -> Result, RuntimeError> { let run_and_expect_value = |expression: Expression| -> Result { @@ -103,7 +139,7 @@ impl AbstractNode for Logic { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(expression_position), )); }; @@ -117,7 +153,7 @@ impl AbstractNode for Logic { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(expression_position), )); }; @@ -196,7 +232,7 @@ impl AbstractNode for Logic { Ok(Some(Evaluation::Return(Value::boolean(boolean)))) } - fn expected_type(&self, _context: &mut Context) -> Result, ValidationError> { + fn expected_type(&self, _context: &Context) -> Result, ValidationError> { Ok(Some(Type::Boolean)) } } diff --git a/dust-lang/src/abstract_tree/loop.rs b/dust-lang/src/abstract_tree/loop.rs index 9d61262..9d33909 100644 --- a/dust-lang/src/abstract_tree/loop.rs +++ b/dust-lang/src/abstract_tree/loop.rs @@ -5,7 +5,7 @@ use crate::{ error::{RuntimeError, ValidationError}, }; -use super::{AbstractNode, Evaluation, Statement, Validate}; +use super::{AbstractNode, Evaluation, Statement, Type}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct Loop { @@ -21,25 +21,26 @@ impl Loop { self.statements.last().unwrap() } } +impl AbstractNode for Loop { + fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { + for statement in &self.statements { + statement.define_types(_context)?; + } -impl Validate for Loop { - fn validate( - &self, - _context: &mut Context, - _manage_memory: bool, - ) -> Result<(), ValidationError> { + Ok(()) + } + + fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { for statement in &self.statements { statement.validate(_context, false)?; } Ok(()) } -} -impl AbstractNode for Loop { fn evaluate( self, - _context: &mut Context, + _context: &Context, _manage_memory: bool, ) -> Result, RuntimeError> { loop { @@ -53,10 +54,7 @@ impl AbstractNode for Loop { } } - fn expected_type( - &self, - _context: &mut Context, - ) -> Result, ValidationError> { + fn expected_type(&self, _context: &Context) -> Result, ValidationError> { self.last_statement().expected_type(_context) } } diff --git a/dust-lang/src/abstract_tree/map_index.rs b/dust-lang/src/abstract_tree/map_index.rs index 94e65c7..eb67db6 100644 --- a/dust-lang/src/abstract_tree/map_index.rs +++ b/dust-lang/src/abstract_tree/map_index.rs @@ -6,7 +6,7 @@ use crate::{ value::ValueInner, }; -use super::{AbstractNode, Evaluation, Expression, Type, Validate, ValueNode, WithPosition}; +use super::{AbstractNode, Evaluation, Expression, Type, ValueNode, WithPosition}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct MapIndex { @@ -23,20 +23,19 @@ impl MapIndex { } } -impl Validate for MapIndex { - fn validate( - &self, - _context: &mut Context, - _manage_memory: bool, - ) -> Result<(), ValidationError> { +impl AbstractNode for MapIndex { + fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { + self.collection.define_types(_context)?; + self.index.define_types(_context) + } + + fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { self.collection.validate(_context, _manage_memory) } -} -impl AbstractNode for MapIndex { fn evaluate( self, - context: &mut Context, + context: &Context, _manage_memory: bool, ) -> Result, RuntimeError> { let collection_position = self.collection.position(); @@ -45,7 +44,7 @@ impl AbstractNode for MapIndex { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(collection_position), + ValidationError::ExpectedExpression(collection_position), )); }; @@ -67,7 +66,7 @@ impl AbstractNode for MapIndex { } } - fn expected_type(&self, context: &mut Context) -> Result, ValidationError> { + fn expected_type(&self, context: &Context) -> Result, ValidationError> { if let (Expression::Identifier(collection), Expression::Identifier(index)) = (&self.collection, &self.index) { diff --git a/dust-lang/src/abstract_tree/math.rs b/dust-lang/src/abstract_tree/math.rs index 84dac74..9b828a0 100644 --- a/dust-lang/src/abstract_tree/math.rs +++ b/dust-lang/src/abstract_tree/math.rs @@ -7,7 +7,7 @@ use crate::{ Value, }; -use super::{AbstractNode, Evaluation, Expression, SourcePosition, Type, Validate}; +use super::{AbstractNode, Evaluation, Expression, SourcePosition, Type}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub enum Math { @@ -18,8 +18,33 @@ pub enum Math { Modulo(Expression, Expression), } -impl Validate for Math { - fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { +impl AbstractNode for Math { + fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { + match self { + Math::Add(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Math::Subtract(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Math::Multiply(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Math::Divide(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + Math::Modulo(left, right) => { + left.define_types(_context)?; + right.define_types(_context) + } + } + } + + fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { match self { Math::Add(left, right) => { let left_position = left.position(); @@ -66,12 +91,10 @@ impl Validate for Math { } } } -} -impl AbstractNode for Math { fn evaluate( self, - _context: &mut Context, + _context: &Context, _clear_variables: bool, ) -> Result, RuntimeError> { let run_and_expect_value = @@ -81,7 +104,7 @@ impl AbstractNode for Math { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(position), + ValidationError::ExpectedExpression(position), )); }; @@ -296,7 +319,7 @@ impl AbstractNode for Math { Ok(Some(Evaluation::Return(value))) } - fn expected_type(&self, _context: &mut Context) -> Result, ValidationError> { + fn expected_type(&self, _context: &Context) -> Result, ValidationError> { match self { Math::Add(left, right) | Math::Subtract(left, right) diff --git a/dust-lang/src/abstract_tree/statement.rs b/dust-lang/src/abstract_tree/statement.rs index 43b4119..2e1daae 100644 --- a/dust-lang/src/abstract_tree/statement.rs +++ b/dust-lang/src/abstract_tree/statement.rs @@ -6,9 +6,8 @@ use crate::{ }; use super::{ - AbstractNode, Assignment, AsyncBlock, Block, DefineTypes, EnumDeclaration, Evaluation, - Expression, IfElse, Loop, SourcePosition, StructureDefinition, Type, TypeAlias, Validate, - While, WithPosition, + AbstractNode, Assignment, AsyncBlock, Block, EnumDeclaration, Evaluation, Expression, IfElse, + Loop, SourcePosition, StructureDefinition, Type, TypeAlias, While, WithPosition, }; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] @@ -52,7 +51,7 @@ impl Statement { } } -impl DefineTypes for Statement { +impl AbstractNode for Statement { fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { match self { Statement::Expression(expression) => expression.define_types(_context), @@ -72,12 +71,26 @@ impl DefineTypes for Statement { Statement::While(r#while) => r#while.node.define_types(_context), } } -} -impl AbstractNode for Statement { + fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { + match self { + Statement::Assignment(assignment) => assignment.node.validate(_context, _manage_memory), + Statement::AsyncBlock(async_block) => { + async_block.node.validate(_context, _manage_memory) + } + Statement::Block(block) => block.node.validate(_context, _manage_memory), + Statement::Break(_) => Ok(()), + Statement::Expression(expression) => expression.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::While(r#while) => r#while.node.validate(_context, _manage_memory), + _ => Ok(()), + } + } + fn evaluate( self, - context: &mut Context, + context: &Context, manage_memory: bool, ) -> Result, RuntimeError> { let result = match self { @@ -105,7 +118,7 @@ impl AbstractNode for Statement { result } - fn expected_type(&self, _context: &mut Context) -> Result, ValidationError> { + fn expected_type(&self, _context: &Context) -> Result, ValidationError> { match self { Statement::Expression(expression) => expression.expected_type(_context), Statement::IfElse(if_else) => if_else.node.expected_type(_context), @@ -125,25 +138,3 @@ impl AbstractNode for Statement { } } } - -impl Validate for Statement { - fn validate( - &self, - _context: &mut Context, - _manage_memory: bool, - ) -> Result<(), ValidationError> { - match self { - Statement::Assignment(assignment) => assignment.node.validate(_context, _manage_memory), - Statement::AsyncBlock(async_block) => { - async_block.node.validate(_context, _manage_memory) - } - Statement::Block(block) => block.node.validate(_context, _manage_memory), - Statement::Break(_) => Ok(()), - Statement::Expression(expression) => expression.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::While(r#while) => r#while.node.validate(_context, _manage_memory), - _ => Ok(()), - } - } -} diff --git a/dust-lang/src/abstract_tree/structure_definition.rs b/dust-lang/src/abstract_tree/structure_definition.rs index d198307..81606c2 100644 --- a/dust-lang/src/abstract_tree/structure_definition.rs +++ b/dust-lang/src/abstract_tree/structure_definition.rs @@ -1,6 +1,10 @@ use serde::{Deserialize, Serialize}; -use crate::{context::Context, error::RuntimeError, identifier::Identifier}; +use crate::{ + context::Context, + error::{RuntimeError, ValidationError}, + identifier::Identifier, +}; use super::{AbstractNode, Evaluation, Type, TypeConstructor}; @@ -17,9 +21,32 @@ impl StructureDefinition { } impl AbstractNode for StructureDefinition { + fn define_types(&self, context: &Context) -> Result<(), ValidationError> { + let mut fields = Vec::with_capacity(self.fields.len()); + + for (identifier, constructor) in self.fields { + let r#type = constructor.construct(&context)?; + + fields.push((identifier, r#type)); + } + + let struct_type = Type::Structure { + name: self.name.clone(), + fields, + }; + + context.set_type(self.name, struct_type)?; + + Ok(None) + } + + fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> { + Ok(()) + } + fn evaluate( self, - context: &mut Context, + context: &Context, _manage_memory: bool, ) -> Result, RuntimeError> { let mut fields = Vec::with_capacity(self.fields.len()); @@ -40,10 +67,7 @@ impl AbstractNode for StructureDefinition { Ok(None) } - fn expected_type( - &self, - context: &mut Context, - ) -> Result, crate::error::ValidationError> { + fn expected_type(&self, context: &Context) -> Result, ValidationError> { Ok(None) } } diff --git a/dust-lang/src/abstract_tree/type_alias.rs b/dust-lang/src/abstract_tree/type_alias.rs index 9107390..40dbe8d 100644 --- a/dust-lang/src/abstract_tree/type_alias.rs +++ b/dust-lang/src/abstract_tree/type_alias.rs @@ -6,7 +6,7 @@ use crate::{ identifier::Identifier, }; -use super::{AbstractNode, DefineTypes, Evaluation, Type, TypeConstructor, WithPosition}; +use super::{AbstractNode, Evaluation, Type, TypeConstructor, WithPosition}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct TypeAlias { @@ -24,20 +24,6 @@ impl TypeAlias { } impl AbstractNode for TypeAlias { - fn evaluate( - self, - context: &mut Context, - manage_memory: bool, - ) -> Result, RuntimeError> { - Ok(None) - } - - fn expected_type(&self, context: &mut Context) -> Result, ValidationError> { - Ok(None) - } -} - -impl DefineTypes for TypeAlias { fn define_types(&self, context: &Context) -> Result<(), ValidationError> { let r#type = self.constructor.construct(&context)?; @@ -45,4 +31,20 @@ impl DefineTypes for TypeAlias { Ok(()) } + + fn validate(&self, context: &Context, manage_memory: bool) -> Result<(), ValidationError> { + Ok(()) + } + + fn evaluate( + self, + context: &Context, + manage_memory: bool, + ) -> Result, RuntimeError> { + Ok(None) + } + + fn expected_type(&self, context: &Context) -> Result, ValidationError> { + Ok(None) + } } diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index 9efe521..acd3f81 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -10,7 +10,7 @@ use crate::{ }; use super::{ - AbstractNode, Block, Evaluation, Expression, Type, TypeConstructor, Validate, WithPosition, + AbstractNode, Block, Evaluation, Expression, Type, TypeConstructor, WithPos, WithPosition, }; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] @@ -39,8 +39,46 @@ pub enum ValueNode { }, } -impl Validate for ValueNode { - fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { +impl AbstractNode for ValueNode { + fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { + match self { + ValueNode::EnumInstance { content, .. } => { + if let Some(expressions) = content { + for expression in expressions { + expression.define_types(_context)?; + } + } + } + ValueNode::List(expressions) => { + for expression in expressions { + expression.define_types(_context)?; + } + } + ValueNode::Map(fields) => { + for (_, _, expression) in fields { + expression.define_types(_context)?; + } + } + ValueNode::Structure { fields, .. } => { + for (_, expression) in fields { + expression.define_types(_context)?; + } + } + ValueNode::Function { + type_parameters, + value_parameters, + return_type, + body, + } => { + body.node.define_types(_context)?; + } + _ => {} + } + + Ok(()) + } + + fn validate(&self, context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { if let ValueNode::EnumInstance { type_name, variant, .. } = self @@ -69,7 +107,11 @@ impl Validate for ValueNode { expression.validate(context, _manage_memory)?; if let Some(constructor) = constructor_option { - let actual_type = expression.expected_type(context)?; + let actual_type = if let Some(r#type) = expression.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression(expression.position())); + }; let exprected_type = constructor.clone().construct(&context)?; exprected_type.check(&actual_type).map_err(|conflict| { @@ -114,7 +156,11 @@ impl Validate for ValueNode { body.node.validate(&mut function_context, _manage_memory)?; - let actual_return_type = body.node.expected_type(&mut function_context)?; + let actual_return_type = if let Some(r#type) = body.node.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression(body.position)); + }; return_type .clone() @@ -147,7 +193,11 @@ impl Validate for ValueNode { }) = context.get_type(&name.node)? { for ((_, expression), (_, expected_type)) in expressions.iter().zip(types.iter()) { - let actual_type = expression.expected_type(context)?; + let actual_type = if let Some(r#type) = expression.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression(expression.position())); + }; expected_type.check(&actual_type).map_err(|conflict| { ValidationError::TypeCheck { @@ -162,12 +212,10 @@ impl Validate for ValueNode { Ok(()) } -} -impl AbstractNode for ValueNode { fn evaluate( self, - context: &mut Context, + context: &Context, _manage_memory: bool, ) -> Result, RuntimeError> { let value = match self { @@ -184,11 +232,11 @@ impl AbstractNode for ValueNode { let position = expression.position(); let evaluation = expression.evaluate(context, _manage_memory)?; - if let Evaluation::Return(value) = evaluation { + if let Some(Evaluation::Return(value)) = evaluation { values.push(value); } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(position), + ValidationError::ExpectedExpression(position), )); } } @@ -205,13 +253,13 @@ impl AbstractNode for ValueNode { let mut value_list = Vec::with_capacity(expression_list.len()); for expression in expression_list { - let expression_position = expression.position(); + let position = expression.position(); let evaluation = expression.evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = evaluation { + let value = if let Some(Evaluation::Return(value)) = evaluation { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(position), )); }; @@ -224,13 +272,13 @@ impl AbstractNode for ValueNode { let mut property_map = BTreeMap::new(); for (identifier, _type, expression) in property_list { - let expression_position = expression.position(); - let action = expression.evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { + let position = expression.position(); + let evaluation = expression.evaluate(context, _manage_memory)?; + let value = if let Some(Evaluation::Return(value)) = evaluation { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(position), )); }; @@ -279,13 +327,13 @@ impl AbstractNode for ValueNode { let mut fields = Vec::with_capacity(expressions.len()); for (identifier, expression) in expressions { - let expression_position = expression.position(); - let action = expression.evaluate(context, _manage_memory)?; - let value = if let Evaluation::Return(value) = action { + let position = expression.position(); + let evaluation = expression.evaluate(context, _manage_memory)?; + let value = if let Some(Evaluation::Return(value)) = evaluation { value } else { return Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(position), )); }; @@ -299,7 +347,7 @@ impl AbstractNode for ValueNode { Ok(Some(Evaluation::Return(value))) } - fn expected_type(&self, context: &mut Context) -> Result, ValidationError> { + fn expected_type(&self, context: &Context) -> Result, ValidationError> { let r#type = match self { ValueNode::Boolean(_) => Type::Boolean, ValueNode::EnumInstance { type_name, .. } => { @@ -314,11 +362,16 @@ impl AbstractNode for ValueNode { } ValueNode::Float(_) => Type::Float, ValueNode::Integer(_) => Type::Integer, - ValueNode::List(items) => { - let item_type = items.first().unwrap().expected_type(context)?; + ValueNode::List(expressions) => { + let first_item = expressions.first().unwrap(); + let item_type = if let Some(r#type) = first_item.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression(first_item.position())); + }; Type::List { - length: items.len(), + length: expressions.len(), item_type: Box::new(item_type), } } @@ -360,14 +413,15 @@ impl AbstractNode for ValueNode { let mut types = Vec::with_capacity(expressions.len()); for (identifier, expression) in expressions { - let r#type = expression.expected_type(context)?; + let r#type = if let Some(r#type) = expression.expected_type(context)? { + r#type + } else { + return Err(ValidationError::ExpectedExpression(expression.position())); + }; types.push(( identifier.clone(), - WithPosition { - node: r#type, - position: expression.position(), - }, + r#type.with_position(expression.position()), )); } diff --git a/dust-lang/src/abstract_tree/while.rs b/dust-lang/src/abstract_tree/while.rs index ddbf0b5..cc50120 100644 --- a/dust-lang/src/abstract_tree/while.rs +++ b/dust-lang/src/abstract_tree/while.rs @@ -7,7 +7,7 @@ use crate::{ Value, }; -use super::{AbstractNode, Evaluation, Expression, Statement, Type, Validate}; +use super::{AbstractNode, Evaluation, Expression, Statement, Type}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct While { @@ -24,12 +24,18 @@ impl While { } } -impl Validate for While { - fn validate( - &self, - _context: &mut Context, - _manage_memory: bool, - ) -> Result<(), ValidationError> { +impl AbstractNode for While { + fn define_types(&self, _context: &Context) -> Result<(), ValidationError> { + self.expression.define_types(_context)?; + + for statement in &self.statements { + statement.define_types(_context)?; + } + + Ok(()) + } + + fn validate(&self, _context: &Context, _manage_memory: bool) -> Result<(), ValidationError> { self.expression.validate(_context, false)?; for statement in &self.statements { @@ -38,12 +44,10 @@ impl Validate for While { Ok(()) } -} -impl AbstractNode for While { fn evaluate( self, - _context: &mut Context, + _context: &Context, _manage_memory: bool, ) -> Result, RuntimeError> { let get_boolean = || -> Result { @@ -57,7 +61,7 @@ impl AbstractNode for While { Ok(value) } else { Err(RuntimeError::ValidationFailure( - ValidationError::InterpreterExpectedReturn(expression_position), + ValidationError::ExpectedExpression(expression_position), )) } }; @@ -75,7 +79,7 @@ impl AbstractNode for While { Ok(None) } - fn expected_type(&self, _context: &mut Context) -> Result, ValidationError> { + fn expected_type(&self, _context: &Context) -> Result, ValidationError> { self.statements.last().unwrap().expected_type(_context) } } diff --git a/dust-lang/src/context.rs b/dust-lang/src/context.rs index 8433b2b..355c3c3 100644 --- a/dust-lang/src/context.rs +++ b/dust-lang/src/context.rs @@ -119,7 +119,7 @@ impl<'a> Context<'a> { Ok(()) } - pub fn set_value(&mut self, identifier: Identifier, value: Value) -> Result<(), PoisonError> { + pub fn set_value(&self, identifier: Identifier, value: Value) -> Result<(), PoisonError> { log::debug!("Setting {identifier} to value {value}."); let mut variables = self.variables.write()?; @@ -136,7 +136,7 @@ impl<'a> Context<'a> { Ok(()) } - pub fn clean(&mut self) -> Result<(), PoisonError> { + pub fn clean(&self) -> Result<(), PoisonError> { if *self.is_clean.read()? { return Ok(()); } diff --git a/dust-lang/src/error.rs b/dust-lang/src/error.rs index db695ef..c6229c7 100644 --- a/dust-lang/src/error.rs +++ b/dust-lang/src/error.rs @@ -114,7 +114,6 @@ pub enum ValidationError { index_type: Type, index_position: SourcePosition, }, - CannotIndexWithVoid(SourcePosition), ExpectedString { actual: Type, position: SourcePosition, @@ -137,7 +136,7 @@ pub enum ValidationError { identifier: Identifier, position: SourcePosition, }, - InterpreterExpectedReturn(SourcePosition), + ExpectedExpression(SourcePosition), RwLockPoison(PoisonError), TypeCheck { /// The mismatch that caused the error. diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index aa7d33b..2bfd02a 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -416,7 +416,7 @@ impl InterpreterError { .with_message(format!("This has type {}.", index_type.fg(type_color),)), ]) } - ValidationError::InterpreterExpectedReturn(_) => todo!(), + ValidationError::ExpectedExpression(_) => todo!(), ValidationError::ExpectedFunction { .. } => todo!(), ValidationError::ExpectedValue(_) => todo!(), ValidationError::PropertyNotFound { .. } => todo!(), @@ -455,6 +455,7 @@ impl InterpreterError { } } ValidationError::EnumVariantNotFound { .. } => todo!(), + ValidationError::CannotIndexWithVoid(_) => todo!(), } } diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index 798c03e..4c22596 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -14,7 +14,7 @@ use serde::{ }; use crate::{ - abstract_tree::{Block, Evaluation, Type, WithPosition}, + abstract_tree::{AbstractNode, Block, Evaluation, Type, WithPosition}, context::Context, error::{RuntimeError, ValidationError}, identifier::Identifier, @@ -725,8 +725,8 @@ impl Function { self, value_arguments: Vec, context: &mut Context, - clear_variables: bool, - ) -> Result { + manage_memory: bool, + ) -> Result, RuntimeError> { for ((identifier, _), value) in self .value_parameters .into_iter() @@ -735,12 +735,6 @@ impl Function { context.set_value(identifier.clone(), value)?; } - self.body.run(context, clear_variables).map(|eval_option| { - if let Some(evaluation) = eval_option { - evaluation - } else { - Evaluation::Void - } - }) + self.body.evaluate(context, manage_memory) } }