From b0d80ab867aef5928a40ee3e91729f073536fcec Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 17 Jun 2024 18:00:42 -0400 Subject: [PATCH] Clean up; Add error for assignment without a value --- dust-lang/src/abstract_tree/assignment.rs | 10 +++++++++- dust-lang/src/abstract_tree/mod.rs | 4 ++-- dust-lang/src/abstract_tree/value_node.rs | 2 +- dust-lang/src/error.rs | 1 + dust-lang/src/lib.rs | 10 +++++++++- 5 files changed, 22 insertions(+), 5 deletions(-) diff --git a/dust-lang/src/abstract_tree/assignment.rs b/dust-lang/src/abstract_tree/assignment.rs index 8d746df..55eb79e 100644 --- a/dust-lang/src/abstract_tree/assignment.rs +++ b/dust-lang/src/abstract_tree/assignment.rs @@ -7,7 +7,9 @@ use crate::{ Context, Value, }; -use super::{AbstractNode, Evaluation, ExpectedType, Statement, TypeConstructor, WithPosition}; +use super::{ + AbstractNode, Evaluation, ExpectedType, Statement, Type, TypeConstructor, WithPosition, +}; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] pub struct Assignment { @@ -44,6 +46,12 @@ impl AbstractNode for Assignment { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { let statement_type = self.statement.expected_type(context)?; + if let Type::None = statement_type { + return Err(ValidationError::CannotAssignToNone( + self.statement.position(), + )); + } + if let Some(constructor) = &self.constructor { let r#type = constructor.clone().construct(&context)?; diff --git a/dust-lang/src/abstract_tree/mod.rs b/dust-lang/src/abstract_tree/mod.rs index 8d48637..74b2330 100644 --- a/dust-lang/src/abstract_tree/mod.rs +++ b/dust-lang/src/abstract_tree/mod.rs @@ -139,13 +139,13 @@ impl AbstractTree { fn validate( self, context: &mut Context, - add_variable_uses: bool, + manage_memory: bool, ) -> Result, Vec> { let mut errors = Vec::new(); let mut valid_statements = Vec::new(); for statement in self.0 { - let validation = statement.validate(context, add_variable_uses); + let validation = statement.validate(context, manage_memory); if let Err(validation_error) = validation { errors.push(Error::Validation { diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index b872595..949c73e 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -64,7 +64,7 @@ impl AbstractNode for ValueNode { body, } = self { - let mut function_context = Context::new(Some(&context)); + let mut function_context = context.create_child(); if let Some(type_parameters) = type_parameters { for identifier in type_parameters { diff --git a/dust-lang/src/error.rs b/dust-lang/src/error.rs index d4a1926..2bea4cb 100644 --- a/dust-lang/src/error.rs +++ b/dust-lang/src/error.rs @@ -103,6 +103,7 @@ impl PartialEq for RuntimeError { #[derive(Debug, PartialEq)] pub enum ValidationError { + CannotAssignToNone(SourcePosition), CannotIndex { r#type: Type, position: SourcePosition, diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index dd94a2a..6756dc7 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -150,7 +150,6 @@ impl<'a> Interpreter<'a> { Ok(tokens) => tokens, Err(error) => return Some(error), }; - let parse_result = parser(true) .parse(tokens.spanned((tokens.len()..tokens.len()).into())) .into_result() @@ -293,6 +292,15 @@ impl InterpreterError { if let Some(validation_error) = validation_error { match validation_error { + + ValidationError::CannotAssignToNone(postion) => { + builder.add_label( + Label::new((self.source_id.clone(), postion.0..postion.1)) + .with_message(format!( + "This statement does not yield a value, you cannot assign a variable to it." + )), + ); + } ValidationError::ExpectedBoolean { actual, position } => { builder.add_label( Label::new((self.source_id.clone(), position.0..position.1))