diff --git a/dust-lang/src/abstract_tree/as.rs b/dust-lang/src/abstract_tree/as.rs index cc170bd..616910e 100644 --- a/dust-lang/src/abstract_tree/as.rs +++ b/dust-lang/src/abstract_tree/as.rs @@ -33,7 +33,7 @@ impl Evaluate for As { _manage_memory: bool, ) -> Result<(), ValidationError> { match self.constructor { - TypeConstructor::Type(_) => {} + TypeConstructor::Raw(_) => {} _ => todo!("Create an error for this occurence."), }; diff --git a/dust-lang/src/abstract_tree/assignment.rs b/dust-lang/src/abstract_tree/assignment.rs index 92ac574..7a48d0b 100644 --- a/dust-lang/src/abstract_tree/assignment.rs +++ b/dust-lang/src/abstract_tree/assignment.rs @@ -8,7 +8,8 @@ use crate::{ }; use super::{ - Evaluate, Evaluation, ExpectedType, Expression, Statement, Type, TypeConstructor, WithPosition, + type_constructor::TypeInvokationConstructor, Evaluate, Evaluation, ExpectedType, Expression, + Statement, Type, TypeConstructor, WithPosition, }; #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] @@ -44,21 +45,66 @@ impl Assignment { impl Evaluate for Assignment { fn validate(&self, context: &mut Context, manage_memory: bool) -> Result<(), ValidationError> { - let statement_type = self.statement.expected_type(context)?; + if let Some(TypeConstructor::Raw(WithPosition { + node: Type::None, + position, + })) = &self.constructor + { + return Err(ValidationError::CannotAssignToNone(position.clone())); + } - if let Type::None = statement_type { + let relevant_statement = self.statement.last_child_statement(); + let statement_type = relevant_statement.expected_type(context)?; + + if let Type::None = &statement_type { return Err(ValidationError::CannotAssignToNone( self.statement.position(), )); } - let statement = self - .statement - .last_child_statement() - .unwrap_or(&self.statement); + if let Some(constructor) = &self.constructor { + let r#type = constructor.clone().construct(&context)?; + + r#type + .check(&statement_type) + .map_err(|conflict| ValidationError::TypeCheck { + conflict, + actual_position: self.statement.position(), + expected_position: Some(constructor.position()), + })?; + + context.set_type(self.identifier.node.clone(), r#type.clone())?; + } else { + context.set_type(self.identifier.node.clone(), statement_type.clone())?; + } + + self.statement.validate(context, manage_memory)?; + + if let ( + Some(TypeConstructor::Invokation(TypeInvokationConstructor { + identifier, + type_arguments, + })), + Statement::Expression(Expression::Value(_)), + Type::Enum { + type_parameters, .. + }, + ) = (&self.constructor, relevant_statement, &statement_type) + { + if let (Some(parameters), Some(arguments)) = (type_parameters, type_arguments) { + if parameters.len() != arguments.len() { + return Err(ValidationError::FullTypeNotKnown { + identifier: identifier.node.clone(), + position: self.constructor.clone().unwrap().position(), + }); + } + } + + return Ok(()); + } if let (Some(constructor), Statement::Expression(Expression::FunctionCall(function_call))) = - (&self.constructor, statement) + (&self.constructor, relevant_statement) { let declared_type = constructor.clone().construct(context)?; let function_type = function_call.node.function().expected_type(context)?; @@ -76,6 +122,8 @@ impl Evaluate for Assignment { if let Some(parameter) = returned_parameter { context.set_type(parameter, declared_type)?; + + return Ok(()); } } } else { @@ -84,24 +132,8 @@ impl Evaluate for Assignment { position: function_call.position, }); } - } else if let Some(constructor) = &self.constructor { - let r#type = constructor.clone().construct(&context)?; - - r#type - .check(&statement_type) - .map_err(|conflict| ValidationError::TypeCheck { - conflict, - actual_position: self.statement.position(), - expected_position: Some(constructor.position()), - })?; - - context.set_type(self.identifier.node.clone(), r#type.clone())?; - } else { - context.set_type(self.identifier.node.clone(), statement_type)?; } - self.statement.validate(context, manage_memory)?; - Ok(()) } diff --git a/dust-lang/src/abstract_tree/statement.rs b/dust-lang/src/abstract_tree/statement.rs index 7ed2f24..37fb201 100644 --- a/dust-lang/src/abstract_tree/statement.rs +++ b/dust-lang/src/abstract_tree/statement.rs @@ -40,11 +40,11 @@ impl Statement { } } - pub fn last_child_statement(&self) -> Option<&Self> { + pub fn last_child_statement(&self) -> &Self { match self { - Statement::Block(block) => Some(block.node.last_statement()), - Statement::Loop(r#loop) => Some(r#loop.node.last_statement()), - _ => None, + Statement::Block(inner) => inner.node.last_statement(), + Statement::Loop(inner) => inner.node.last_statement(), + statement => statement, } } } diff --git a/dust-lang/src/abstract_tree/type.rs b/dust-lang/src/abstract_tree/type.rs index 11a9261..0faeb32 100644 --- a/dust-lang/src/abstract_tree/type.rs +++ b/dust-lang/src/abstract_tree/type.rs @@ -16,7 +16,8 @@ pub enum Type { Any, Boolean, Enum { - variants: Vec<(Identifier, Vec)>, + type_parameters: Option>, + variants: Vec<(Identifier, Option>)>, }, Float, Function { @@ -229,14 +230,20 @@ impl Display for Type { match self { Type::Any => write!(f, "any"), Type::Boolean => write!(f, "bool"), - Type::Enum { variants } => { - write!(f, "enum {{")?; + Type::Enum { variants, .. } => { + write!(f, "enum ")?; + + write!(f, " {{")?; for (identifier, types) in variants { - writeln!(f, "{identifier}(")?; + writeln!(f, "{identifier}")?; - for r#type in types { - write!(f, "{}", r#type)? + if let Some(types) = types { + write!(f, "(")?; + + for r#type in types { + write!(f, "{}", r#type)?; + } } write!(f, ")")?; diff --git a/dust-lang/src/abstract_tree/type_constructor.rs b/dust-lang/src/abstract_tree/type_constructor.rs index 7ffca38..e78e7b6 100644 --- a/dust-lang/src/abstract_tree/type_constructor.rs +++ b/dust-lang/src/abstract_tree/type_constructor.rs @@ -10,10 +10,10 @@ use super::{SourcePosition, Type, WithPosition}; pub enum TypeConstructor { Enum(WithPosition), Function(WithPosition), - Identifier(WithPosition), + Invokation(TypeInvokationConstructor), List(WithPosition), ListOf(WithPosition>), - Type(WithPosition), + Raw(WithPosition), } impl TypeConstructor { @@ -21,17 +21,61 @@ impl TypeConstructor { match self { TypeConstructor::Enum(WithPosition { position, .. }) => *position, TypeConstructor::Function(WithPosition { position, .. }) => *position, - TypeConstructor::Identifier(WithPosition { position, .. }) => *position, + TypeConstructor::Invokation(TypeInvokationConstructor { + identifier, + type_arguments, + }) => { + if let Some(arguments) = type_arguments { + SourcePosition( + identifier.position.0, + arguments.last().unwrap().position().1, + ) + } else { + SourcePosition(identifier.position.0, identifier.position.1) + } + } TypeConstructor::List(WithPosition { position, .. }) => *position, TypeConstructor::ListOf(WithPosition { position, .. }) => *position, - TypeConstructor::Type(WithPosition { position, .. }) => *position, + TypeConstructor::Raw(WithPosition { position, .. }) => *position, } } pub fn construct(self, context: &Context) -> Result { let r#type = match self { + TypeConstructor::Invokation(TypeInvokationConstructor { identifier, .. }) => { + let invoked_type = if let Some(r#type) = context.get_type(&identifier.node)? { + r#type + } else { + return Err(ValidationError::VariableNotFound { + identifier: identifier.node, + position: identifier.position, + }); + }; + + if let Type::Enum { + type_parameters, + variants, + } = invoked_type + { + let mut mapped_variants = Vec::with_capacity(variants.len()); + + for (variant_name, content) in variants { + mapped_variants.push((variant_name.clone(), content.clone())); + } + + Type::Enum { + type_parameters: type_parameters.clone(), + variants: mapped_variants, + } + } else { + invoked_type + } + } TypeConstructor::Enum(enum_type_constructor) => { - let EnumTypeConstructor { variants, .. } = enum_type_constructor.node; + let EnumTypeConstructor { + type_parameters, + variants, + } = enum_type_constructor.node; let mut type_variants = Vec::with_capacity(variants.len()); for (variant_name, constructors) in variants { @@ -44,11 +88,22 @@ impl TypeConstructor { types.push(r#type); } - type_variants.push((variant_name.node, types)); + type_variants.push((variant_name.node, Some(types))); + } else { + type_variants.push((variant_name.node, None)) } } Type::Enum { + type_parameters: type_parameters.map(|identifiers| { + identifiers + .into_iter() + .map(|identifier| Type::Generic { + identifier: identifier.node, + concrete_type: None, + }) + .collect() + }), variants: type_variants, } } @@ -81,21 +136,6 @@ impl TypeConstructor { return_type, } } - TypeConstructor::Identifier(WithPosition { - node: identifier, .. - }) => { - if let Some(r#type) = context.get_type(&identifier)? { - Type::Generic { - identifier, - concrete_type: Some(Box::new(r#type)), - } - } else { - Type::Generic { - identifier, - concrete_type: None, - } - } - } TypeConstructor::List(positioned_constructor) => { let ListTypeConstructor { length, item_type } = positioned_constructor.node; let constructed_type = item_type.construct(context)?; @@ -110,7 +150,7 @@ impl TypeConstructor { Type::ListOf(Box::new(item_type)) } - TypeConstructor::Type(r#type) => r#type.node, + TypeConstructor::Raw(r#type) => r#type.node, }; Ok(r#type) @@ -141,3 +181,9 @@ pub struct ListTypeConstructor { pub length: usize, pub item_type: Box, } + +#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] +pub struct TypeInvokationConstructor { + pub identifier: WithPosition, + pub type_arguments: Option>, +} diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index 55d1788..4dcadf2 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -41,12 +41,26 @@ pub enum ValueNode { impl Evaluate for ValueNode { fn validate(&self, context: &mut Context, _manage_memory: bool) -> Result<(), ValidationError> { - if let ValueNode::EnumInstance { type_name, .. } = self { - if let Some(_) = context.get_type(&type_name.node)? { + if let ValueNode::EnumInstance { + type_name, variant, .. + } = self + { + if let Some(Type::Enum { variants, .. }) = context.get_type(&type_name.node)? { + if variants + .iter() + .find(|(identifier, _)| identifier == &variant.node) + .is_none() + { + return Err(ValidationError::EnumVariantNotFound { + identifier: variant.node.clone(), + position: variant.position, + }); + } } else { - return Err(ValidationError::EnumDefinitionNotFound( - type_name.node.clone(), - )); + return Err(ValidationError::EnumDefinitionNotFound { + identifier: type_name.node.clone(), + position: Some(type_name.position), + }); } } @@ -231,17 +245,28 @@ impl Evaluate for ValueNode { return_type, body, } => { - let type_parameters = - type_parameters.map(|parameter_list| parameter_list.into_iter().collect()); + let function_context = context.create_child(); let mut value_parameters = Vec::with_capacity(constructors.len()); for (identifier, constructor) in constructors { - let r#type = constructor.construct(&context)?; + let r#type = constructor.construct(&function_context)?; value_parameters.push((identifier, r#type)); } - let return_type = return_type.construct(&context)?; + if let Some(identifiers) = &type_parameters { + for identifier in identifiers { + function_context.set_type( + identifier.clone(), + Type::Generic { + identifier: identifier.clone(), + concrete_type: None, + }, + )?; + } + } + + let return_type = return_type.construct(&function_context)?; Value::function(type_parameters, value_parameters, return_type, body.node) } @@ -401,9 +426,10 @@ impl ExpectedType for ValueNode { if let Some(r#type) = context.get_type(&type_name.node)? { r#type } else { - return Err(ValidationError::EnumDefinitionNotFound( - type_name.node.clone(), - )); + return Err(ValidationError::EnumDefinitionNotFound { + identifier: type_name.node.clone(), + position: Some(type_name.position), + }); } } ValueNode::Float(_) => Type::Float, diff --git a/dust-lang/src/error.rs b/dust-lang/src/error.rs index 923e5c9..b8a03c1 100644 --- a/dust-lang/src/error.rs +++ b/dust-lang/src/error.rs @@ -132,6 +132,10 @@ pub enum ValidationError { position: SourcePosition, }, ExpectedValue(SourcePosition), + FullTypeNotKnown { + identifier: Identifier, + position: SourcePosition, + }, InterpreterExpectedReturn(SourcePosition), RwLockPoison(RwLockPoisonError), TypeCheck { @@ -160,7 +164,14 @@ pub enum ValidationError { identifier: Identifier, position: SourcePosition, }, - EnumDefinitionNotFound(Identifier), + EnumDefinitionNotFound { + identifier: Identifier, + position: Option, + }, + EnumVariantNotFound { + identifier: Identifier, + position: SourcePosition, + }, } impl From for ValidationError { diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index 7cff0ba..aa7d33b 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -335,6 +335,17 @@ impl InterpreterError { )), ); } + ValidationError::FullTypeNotKnown { + identifier, + position, + } => builder.add_label( + Label::new((self.source_id.clone(), position.0..position.1)).with_message( + format!( + "The full type for {} must be known.", + identifier.fg(identifier_color) + ), + ), + ), ValidationError::RwLockPoison(_) => todo!(), ValidationError::TypeCheck { conflict, @@ -425,7 +436,25 @@ impl InterpreterError { ) } ValidationError::ExpectedString { .. } => todo!(), - ValidationError::EnumDefinitionNotFound(_) => todo!(), + ValidationError::EnumDefinitionNotFound { + identifier, + position, + } => { + let message = format!( + "The enum {} does not exist in this context.", + identifier.fg(identifier_color), + ); + + if let Some(position) = position { + builder.add_label( + Label::new((self.source_id.clone(), position.0..position.1)) + .with_message(message), + ) + } else { + builder = builder.with_message(message); + } + } + ValidationError::EnumVariantNotFound { .. } => todo!(), } } diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 4973b8b..4c3f396 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -9,6 +9,8 @@ use crate::{ lexer::{Control, Keyword, Operator, Token}, }; +use self::type_constructor::TypeInvokationConstructor; + pub type ParserInput<'src> = SpannedInput, SimpleSpan, &'src [(Token<'src>, SimpleSpan)]>; @@ -79,7 +81,7 @@ pub fn parser<'src>( just(Token::Keyword(Keyword::Range)).to(Type::Range), just(Token::Keyword(Keyword::Str)).to(Type::String), )) - .map_with(|r#type, state| TypeConstructor::Type(r#type.with_position(state.span()))); + .map_with(|r#type, state| TypeConstructor::Raw(r#type.with_position(state.span()))); let function_type = just(Token::Keyword(Keyword::Fn)) .ignore_then( @@ -147,10 +149,6 @@ pub fn parser<'src>( TypeConstructor::ListOf(Box::new(item_type).with_position(state.span())) }); - let identifier_type = positioned_identifier - .clone() - .map(|identifier| TypeConstructor::Identifier(identifier)); - let enum_variant = positioned_identifier.clone().then( type_constructor .clone() @@ -196,12 +194,34 @@ pub fn parser<'src>( ) }); + let type_invokation = positioned_identifier + .clone() + .then( + type_constructor + .clone() + .separated_by(just(Token::Control(Control::Comma))) + .at_least(1) + .allow_trailing() + .collect() + .delimited_by( + just(Token::Control(Control::ParenOpen)), + just(Token::Control(Control::ParenClose)), + ) + .or_not(), + ) + .map(|(identifier, type_arguments)| { + TypeConstructor::Invokation(TypeInvokationConstructor { + identifier, + type_arguments, + }) + }); + choice(( + type_invokation, function_type, list_type, list_of_type, primitive_type, - identifier_type, enum_type, )) }); @@ -703,10 +723,10 @@ pub fn parser<'src>( .repeated() .or_not() .ignore_then(choice(( - async_block, - if_else, assignment, expression_statement, + async_block, + if_else, r#break, block_statement, r#loop, @@ -725,6 +745,53 @@ mod tests { use super::*; + #[test] + fn type_invokation() { + assert_eq!( + parse(&lex("x: Foo(int) = Foo::Bar(42)").unwrap()).unwrap()[0], + Statement::Assignment( + Assignment::new( + Identifier::new("x").with_position((0, 1)), + Some(TypeConstructor::Invokation(TypeInvokationConstructor { + identifier: Identifier::new("Foo").with_position((3, 6)), + type_arguments: Some(vec![TypeConstructor::Raw( + Type::Integer.with_position((7, 10)) + )]), + })), + AssignmentOperator::Assign, + Statement::Expression(Expression::Value( + ValueNode::EnumInstance { + type_name: Identifier::new("Foo").with_position((14, 17)), + variant: Identifier::new("Bar").with_position((19, 22)), + content: Some(vec![Expression::Value( + ValueNode::Integer(42).with_position((23, 25)) + )]) + } + .with_position((14, 26)) + )) + ) + .with_position((0, 26)) + ) + ); + } + + #[test] + fn enum_instance() { + assert_eq!( + parse(&lex("Foo::Bar(42)").unwrap()).unwrap()[0], + Statement::Expression(Expression::Value( + ValueNode::EnumInstance { + type_name: Identifier::new("Foo").with_position((0, 3)), + variant: Identifier::new("Bar").with_position((5, 8)), + content: Some(vec![Expression::Value( + ValueNode::Integer(42).with_position((9, 11)) + )]) + } + .with_position((0, 12)) + )) + ); + } + #[test] fn enum_type_empty() { assert_eq!( @@ -762,15 +829,13 @@ mod tests { ( Identifier::new("X").with_position((21, 22)), Some(vec![ - TypeConstructor::Type(Type::String.with_position((23, 26))), - TypeConstructor::Type( - Type::Integer.with_position((28, 31)) - ) + TypeConstructor::Raw(Type::String.with_position((23, 26))), + TypeConstructor::Raw(Type::Integer.with_position((28, 31))) ]) ), ( Identifier::new("Y").with_position((34, 35)), - Some(vec![TypeConstructor::Type( + Some(vec![TypeConstructor::Raw( Type::Integer.with_position((36, 39)) )]) ) @@ -800,14 +865,22 @@ mod tests { variants: vec![ ( Identifier::new("X").with_position((28, 29)), - Some(vec![TypeConstructor::Identifier( - Identifier::new("T").with_position((30, 31)) + Some(vec![TypeConstructor::Invokation( + TypeInvokationConstructor { + identifier: Identifier::new("T") + .with_position((30, 31)), + type_arguments: None, + } )]) ), ( Identifier::new("Y").with_position((34, 35)), - Some(vec![TypeConstructor::Identifier( - Identifier::new("U").with_position((36, 37)) + Some(vec![TypeConstructor::Invokation( + TypeInvokationConstructor { + identifier: Identifier::new("U") + .with_position((36, 37)), + type_arguments: None, + } )]) ), ], @@ -894,7 +967,7 @@ mod tests { Statement::TypeAssignment( TypeAssignment::new( Identifier::new("MyType").with_position((5, 11)), - TypeConstructor::Type(Type::String.with_position((14, 17))) + TypeConstructor::Raw(Type::String.with_position((14, 17))) ) .with_position((0, 17)) ) @@ -908,7 +981,7 @@ mod tests { Statement::Expression(Expression::As( Box::new(As::new( Expression::Value(ValueNode::Integer(1).with_position((0, 1))), - TypeConstructor::Type(Type::String.with_position((5, 8))) + TypeConstructor::Raw(Type::String.with_position((5, 8))) )) .with_position((0, 8)) )) @@ -1053,7 +1126,7 @@ mod tests { Statement::Assignment( Assignment::new( Identifier::new("foobar").with_position((0, 6)), - Some(TypeConstructor::Type(Type::Boolean.with_position((9, 13)))), + Some(TypeConstructor::Raw(Type::Boolean.with_position((9, 13)))), AssignmentOperator::Assign, Statement::Expression(Expression::Value( ValueNode::Boolean(true).with_position((16, 20)) @@ -1074,7 +1147,7 @@ mod tests { Some(TypeConstructor::List( ListTypeConstructor { length: 2, - item_type: Box::new(TypeConstructor::Type( + item_type: Box::new(TypeConstructor::Raw( Type::Integer.with_position((9, 12)) )) } @@ -1098,7 +1171,7 @@ mod tests { Assignment::new( Identifier::new("foobar").with_position((0, 6)), Some(TypeConstructor::ListOf( - Box::new(TypeConstructor::Type(Type::Boolean.with_position((10, 14)))) + Box::new(TypeConstructor::Raw(Type::Boolean.with_position((10, 14)))) .with_position((9, 15)) )), AssignmentOperator::Assign, @@ -1126,11 +1199,14 @@ mod tests { type_parameters: Some(vec![ Identifier::new("T").with_position((15, 16)) ]), - value_parameters: vec![TypeConstructor::Type( + value_parameters: vec![TypeConstructor::Raw( Type::Integer.with_position((19, 22)) )], - return_type: Box::new(TypeConstructor::Identifier( - Identifier::new("T").with_position((27, 28)) + return_type: Box::new(TypeConstructor::Invokation( + TypeInvokationConstructor { + identifier: Identifier::new("T").with_position((27, 28)), + type_arguments: None, + } )), } .with_position((11, 28)) @@ -1163,7 +1239,7 @@ mod tests { Statement::Expression(Expression::FunctionCall( FunctionCall::new( Expression::Identifier(Identifier::new("foobar").with_position((0, 6))), - Some(vec![TypeConstructor::Type( + Some(vec![TypeConstructor::Raw( Type::String.with_position((9, 12)) )]), vec![Expression::Value( @@ -1193,7 +1269,7 @@ mod tests { ValueNode::Function { type_parameters: None, value_parameters: vec![], - return_type: TypeConstructor::Type(Type::Integer.with_position((9, 12))), + return_type: TypeConstructor::Raw(Type::Integer.with_position((9, 12))), body: Block::new(vec![Statement::Expression(Expression::Value( ValueNode::Integer(0).with_position((15, 16)) ))]) @@ -1210,9 +1286,9 @@ mod tests { type_parameters: None, value_parameters: vec![( Identifier::new("x"), - TypeConstructor::Type(Type::Integer.with_position((7, 10))) + TypeConstructor::Raw(Type::Integer.with_position((7, 10))) )], - return_type: TypeConstructor::Type(Type::Integer.with_position((15, 18))), + return_type: TypeConstructor::Raw(Type::Integer.with_position((15, 18))), body: Block::new(vec![Statement::Expression(Expression::Identifier( Identifier::new("x").with_position((21, 22)) ))]) @@ -1233,20 +1309,23 @@ mod tests { value_parameters: vec![ ( Identifier::new("x"), - TypeConstructor::Identifier( - Identifier::new("T").with_position((14, 15)) - ) + TypeConstructor::Invokation(TypeInvokationConstructor { + identifier: Identifier::new("T").with_position((14, 15)), + type_arguments: None, + }) ), ( Identifier::new("y"), - TypeConstructor::Identifier( - Identifier::new("U").with_position((20, 21)) - ) + TypeConstructor::Invokation(TypeInvokationConstructor { + identifier: Identifier::new("U").with_position((20, 21)), + type_arguments: None, + }) ) ], - return_type: TypeConstructor::Identifier( - Identifier::new("T").with_position((26, 27)) - ), + return_type: TypeConstructor::Invokation(TypeInvokationConstructor { + identifier: Identifier::new("T").with_position((26, 27)), + type_arguments: None, + }), body: Block::new(vec![Statement::Expression(Expression::Identifier( Identifier::new("x").with_position((30, 31)) ))]) @@ -1531,7 +1610,7 @@ mod tests { Statement::Assignment( Assignment::new( Identifier::new("foobar").with_position((0, 6)), - Some(TypeConstructor::Type(Type::Integer.with_position((8, 11)))), + Some(TypeConstructor::Raw(Type::Integer.with_position((8, 11)))), AssignmentOperator::Assign, Statement::Expression(Expression::Value( ValueNode::Integer(1).with_position((14, 15)) diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index 1d1df04..d7d11fd 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -564,7 +564,10 @@ impl ValueInner { if let Some(r#type) = context.get_type(type_name)? { r#type } else { - return Err(ValidationError::EnumDefinitionNotFound(type_name.clone())); + return Err(ValidationError::EnumDefinitionNotFound { + identifier: type_name.clone(), + position: None, + }); } } ValueInner::Float(_) => Type::Float, @@ -720,11 +723,14 @@ impl Function { pub fn call( self, - arguments: Vec, + value_arguments: Vec, context: &mut Context, clear_variables: bool, ) -> Result { - for ((identifier, _), value) in self.value_parameters.into_iter().zip(arguments.into_iter()) + for ((identifier, _), value) in self + .value_parameters + .into_iter() + .zip(value_arguments.into_iter()) { context.set_value(identifier.clone(), value)?; }