diff --git a/dust-lang/src/abstract_tree/assignment.rs b/dust-lang/src/abstract_tree/assignment.rs index 0d6e2db..963b78e 100644 --- a/dust-lang/src/abstract_tree/assignment.rs +++ b/dust-lang/src/abstract_tree/assignment.rs @@ -47,7 +47,7 @@ impl AbstractNode for Assignment { let statement_type = self.statement.expected_type(context)?; if let Some(WithPosition { - node: expected_type, + item: expected_type, position: expected_position, }) = &self.r#type { @@ -59,9 +59,9 @@ impl AbstractNode for Assignment { } })?; - context.set_type(self.identifier.node.clone(), expected_type.clone())?; + context.set_type(self.identifier.item.clone(), expected_type.clone())?; } else { - context.set_type(self.identifier.node.clone(), statement_type)?; + context.set_type(self.identifier.item.clone(), statement_type)?; } self.statement.validate(context)?; @@ -78,10 +78,10 @@ impl AbstractNode for Assignment { match self.operator { AssignmentOperator::Assign => { - context.set_value(self.identifier.node, right)?; + context.set_value(self.identifier.item, right)?; } AssignmentOperator::AddAssign => { - if let Some(left) = context.use_value(&self.identifier.node)? { + if let Some(left) = context.use_value(&self.identifier.item)? { let new_value = match (left.inner().as_ref(), right.inner().as_ref()) { (ValueInner::Integer(left), ValueInner::Integer(right)) => { let sum = left.saturating_add(*right); @@ -109,18 +109,18 @@ impl AbstractNode for Assignment { )) } }; - context.set_value(self.identifier.node, new_value)?; + context.set_value(self.identifier.item, new_value)?; } else { return Err(RuntimeError::ValidationFailure( ValidationError::VariableNotFound { - identifier: self.identifier.node, + identifier: self.identifier.item, position: self.identifier.position, }, )); } } AssignmentOperator::SubAssign => { - if let Some(left) = context.use_value(&self.identifier.node)? { + if let Some(left) = context.use_value(&self.identifier.item)? { let new_value = match (left.inner().as_ref(), right.inner().as_ref()) { (ValueInner::Integer(left), ValueInner::Integer(right)) => { let difference = left.saturating_sub(*right); @@ -148,11 +148,11 @@ impl AbstractNode for Assignment { )) } }; - context.set_value(self.identifier.node, new_value)?; + context.set_value(self.identifier.item, new_value)?; } else { return Err(RuntimeError::ValidationFailure( ValidationError::VariableNotFound { - identifier: self.identifier.node, + identifier: self.identifier.item, position: self.identifier.position, }, )); @@ -249,7 +249,7 @@ mod tests { let validation = Assignment::new( Identifier::new("foobar").with_position((0, 0)), Some(WithPosition { - node: Type::Boolean, + item: Type::Boolean, position: (0, 0).into(), }), AssignmentOperator::Assign, diff --git a/dust-lang/src/abstract_tree/expression.rs b/dust-lang/src/abstract_tree/expression.rs index 1e76262..6631522 100644 --- a/dust-lang/src/abstract_tree/expression.rs +++ b/dust-lang/src/abstract_tree/expression.rs @@ -39,50 +39,50 @@ impl Expression { impl AbstractNode for Expression { fn expected_type(&self, _context: &Context) -> Result { match self { - Expression::FunctionCall(function_call) => function_call.node.expected_type(_context), + Expression::FunctionCall(function_call) => function_call.item.expected_type(_context), Expression::Identifier(identifier) => { - if let Some(r#type) = _context.get_type(&identifier.node)? { + if let Some(r#type) = _context.get_type(&identifier.item)? { Ok(r#type) } else { Err(ValidationError::VariableNotFound { - identifier: identifier.node.clone(), + identifier: identifier.item.clone(), position: identifier.position, }) } } - Expression::MapIndex(map_index) => map_index.node.expected_type(_context), - Expression::ListIndex(list_index) => list_index.node.expected_type(_context), - Expression::Logic(logic) => logic.node.expected_type(_context), - Expression::Math(math) => math.node.expected_type(_context), - Expression::Value(value_node) => value_node.node.expected_type(_context), + Expression::MapIndex(map_index) => map_index.item.expected_type(_context), + Expression::ListIndex(list_index) => list_index.item.expected_type(_context), + Expression::Logic(logic) => logic.item.expected_type(_context), + Expression::Math(math) => math.item.expected_type(_context), + Expression::Value(value_node) => value_node.item.expected_type(_context), Expression::BuiltInFunctionCall(built_in_function_call) => { - built_in_function_call.node.expected_type(_context) + built_in_function_call.item.expected_type(_context) } } } fn validate(&self, context: &Context) -> Result<(), ValidationError> { match self { - Expression::FunctionCall(function_call) => function_call.node.validate(context), + Expression::FunctionCall(function_call) => function_call.item.validate(context), Expression::Identifier(identifier) => { - let found = context.add_expected_use(&identifier.node)?; + let found = context.add_expected_use(&identifier.item)?; if found { Ok(()) } else { Err(ValidationError::VariableNotFound { - identifier: identifier.node.clone(), + identifier: identifier.item.clone(), position: identifier.position, }) } } - Expression::MapIndex(map_index) => map_index.node.validate(context), - Expression::ListIndex(list_index) => list_index.node.validate(context), - Expression::Logic(logic) => logic.node.validate(context), - Expression::Math(math) => math.node.validate(context), - Expression::Value(value_node) => value_node.node.validate(context), + Expression::MapIndex(map_index) => map_index.item.validate(context), + Expression::ListIndex(list_index) => list_index.item.validate(context), + Expression::Logic(logic) => logic.item.validate(context), + Expression::Math(math) => math.item.validate(context), + Expression::Value(value_node) => value_node.item.validate(context), Expression::BuiltInFunctionCall(built_in_function_call) => { - built_in_function_call.node.validate(context) + built_in_function_call.item.validate(context) } } } @@ -90,27 +90,27 @@ impl AbstractNode for Expression { fn run(self, context: &mut Context, _clear_variables: bool) -> Result { match self { Expression::FunctionCall(function_call) => { - function_call.node.run(context, _clear_variables) + function_call.item.run(context, _clear_variables) } Expression::Identifier(identifier) => { - if let Some(value) = context.use_value(&identifier.node)? { + if let Some(value) = context.use_value(&identifier.item)? { Ok(Action::Return(value)) } else { Err(RuntimeError::ValidationFailure( ValidationError::VariableNotFound { - identifier: identifier.node.clone(), + identifier: identifier.item.clone(), position: identifier.position, }, )) } } - Expression::MapIndex(map_index) => map_index.node.run(context, _clear_variables), - Expression::ListIndex(list_index) => list_index.node.run(context, _clear_variables), - Expression::Logic(logic) => logic.node.run(context, _clear_variables), - Expression::Math(math) => math.node.run(context, _clear_variables), - Expression::Value(value_node) => value_node.node.run(context, _clear_variables), + Expression::MapIndex(map_index) => map_index.item.run(context, _clear_variables), + Expression::ListIndex(list_index) => list_index.item.run(context, _clear_variables), + Expression::Logic(logic) => logic.item.run(context, _clear_variables), + Expression::Math(math) => math.item.run(context, _clear_variables), + Expression::Value(value_node) => value_node.item.run(context, _clear_variables), Expression::BuiltInFunctionCall(built_in_function_call) => { - built_in_function_call.node.run(context, _clear_variables) + built_in_function_call.item.run(context, _clear_variables) } } } diff --git a/dust-lang/src/abstract_tree/function_call.rs b/dust-lang/src/abstract_tree/function_call.rs index eb0826b..36cd862 100644 --- a/dust-lang/src/abstract_tree/function_call.rs +++ b/dust-lang/src/abstract_tree/function_call.rs @@ -32,7 +32,7 @@ impl AbstractNode for FunctionCall { let function_node_type = self.function.expected_type(_context)?; if let Type::Function { return_type, .. } = function_node_type { - Ok(return_type.node) + Ok(return_type.item) } else { Err(ValidationError::ExpectedFunction { actual: function_node_type, @@ -58,13 +58,13 @@ impl AbstractNode for FunctionCall { for (type_parameter, type_argument) in parameter_types.iter().zip(self.type_arguments.iter()) { - if let Type::Argument(_) = type_parameter.node { + if let Type::Argument(_) = type_parameter.item { continue; } type_parameter - .node - .check(&type_argument.node) + .item + .check(&type_argument.item) .map_err(|conflict| ValidationError::TypeCheck { conflict, actual_position: type_argument.position, @@ -73,13 +73,13 @@ impl AbstractNode for FunctionCall { } for (type_parameter, expression) in parameter_types.iter().zip(self.arguments.iter()) { - if let Type::Argument(_) = type_parameter.node { + if let Type::Argument(_) = type_parameter.item { continue; } let actual = expression.expected_type(context)?; - type_parameter.node.check(&actual).map_err(|conflict| { + type_parameter.item.check(&actual).map_err(|conflict| { ValidationError::TypeCheck { conflict, actual_position: expression.position(), @@ -97,9 +97,9 @@ impl AbstractNode for FunctionCall { } } - fn run(self, context: &mut Context, _clear_variables: bool) -> Result { + fn run(self, context: &mut Context, clear_variables: bool) -> Result { let function_position = self.function.position(); - let action = self.function.run(context, _clear_variables)?; + let action = self.function.run(context, clear_variables)?; let value = if let Action::Return(value) = action { value } else { @@ -121,7 +121,7 @@ impl AbstractNode for FunctionCall { for expression in self.arguments { let expression_position = expression.position(); - let action = expression.run(context, _clear_variables)?; + let action = expression.run(context, clear_variables)?; let value = if let Action::Return(value) = action { value } else { @@ -138,8 +138,8 @@ impl AbstractNode for FunctionCall { for (type_parameter, type_argument) in function .type_parameters() .iter() - .map(|r#type| r#type.node.clone()) - .zip(self.type_arguments.into_iter().map(|r#type| r#type.node)) + .map(|r#type| r#type.item.clone()) + .zip(self.type_arguments.into_iter().map(|r#type| r#type.item)) { if let Type::Argument(identifier) = type_parameter { function_context.set_type(identifier, type_argument)?; @@ -147,6 +147,8 @@ impl AbstractNode for FunctionCall { } function_context.inherit_data_from(&context)?; - function.clone().call(arguments, &mut function_context) + function + .clone() + .call(arguments, &mut function_context, clear_variables) } } diff --git a/dust-lang/src/abstract_tree/if_else.rs b/dust-lang/src/abstract_tree/if_else.rs index 559d8e7..10ade52 100644 --- a/dust-lang/src/abstract_tree/if_else.rs +++ b/dust-lang/src/abstract_tree/if_else.rs @@ -32,27 +32,27 @@ impl IfElse { impl AbstractNode for IfElse { fn expected_type(&self, _context: &Context) -> Result { - self.if_block.node.expected_type(_context) + self.if_block.item.expected_type(_context) } fn validate(&self, context: &Context) -> Result<(), ValidationError> { self.if_expression.validate(context)?; - self.if_block.node.validate(context)?; + self.if_block.item.validate(context)?; - let expected_type = self.if_block.node.expected_type(context)?; + let expected_type = self.if_block.item.expected_type(context)?; let if_expression_type = self.if_expression.expected_type(context)?; if let Type::Boolean = if_expression_type { if let Some(else_block) = &self.else_block { - else_block.node.validate(context)?; + else_block.item.validate(context)?; - let actual = else_block.node.expected_type(context)?; + let actual = else_block.item.expected_type(context)?; expected_type .check(&actual) .map_err(|conflict| ValidationError::TypeCheck { conflict, - actual_position: self.if_block.node.last_statement().position(), + actual_position: self.if_block.item.last_statement().position(), expected_position: self.if_expression.position(), })?; } @@ -67,15 +67,15 @@ impl AbstractNode for IfElse { let expression_type = expression.expected_type(context)?; if let Type::Boolean = expression_type { - block.node.validate(context)?; + block.item.validate(context)?; - let actual = block.node.expected_type(context)?; + let actual = block.item.expected_type(context)?; expected_type .check(&actual) .map_err(|conflict| ValidationError::TypeCheck { conflict, - actual_position: self.if_block.node.last_statement().position(), + actual_position: self.if_block.item.last_statement().position(), expected_position: self.if_expression.position(), })?; } else { @@ -102,7 +102,7 @@ impl AbstractNode for IfElse { if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() { if *if_boolean { - self.if_block.node.run(context, _clear_variables) + self.if_block.item.run(context, _clear_variables) } else { for (expression, block) in self.else_ifs { let expression_position = expression.position(); @@ -117,7 +117,7 @@ impl AbstractNode for IfElse { if let ValueInner::Boolean(else_if_boolean) = value.inner().as_ref() { if *else_if_boolean { - return block.node.run(context, _clear_variables); + return block.item.run(context, _clear_variables); } } else { return Err(RuntimeError::ValidationFailure( @@ -130,7 +130,7 @@ impl AbstractNode for IfElse { } if let Some(else_statement) = self.else_block { - else_statement.node.run(context, _clear_variables) + else_statement.item.run(context, _clear_variables) } else { Ok(Action::None) } diff --git a/dust-lang/src/abstract_tree/list_index.rs b/dust-lang/src/abstract_tree/list_index.rs index 5fb7ed1..225bcdd 100644 --- a/dust-lang/src/abstract_tree/list_index.rs +++ b/dust-lang/src/abstract_tree/list_index.rs @@ -23,11 +23,11 @@ impl AbstractNode for ListIndex { if let ( Expression::Value(WithPosition { - node: ValueNode::List(expression_list), + item: ValueNode::List(expression_list), .. }), Expression::Value(WithPosition { - node: ValueNode::Integer(index), + item: ValueNode::Integer(index), .. }), ) = (&self.left, &self.right) @@ -98,7 +98,7 @@ impl AbstractNode for ListIndex { let found_item = list.get(index as usize); if let Some(item) = found_item { - Ok(Action::Return(item.node.clone())) + Ok(Action::Return(item.item.clone())) } else { Ok(Action::None) } diff --git a/dust-lang/src/abstract_tree/map_index.rs b/dust-lang/src/abstract_tree/map_index.rs index ae5989b..d6560e3 100644 --- a/dust-lang/src/abstract_tree/map_index.rs +++ b/dust-lang/src/abstract_tree/map_index.rs @@ -28,21 +28,21 @@ impl AbstractNode for MapIndex { (&self.collection, &self.index) { let collection = - if let Some(collection) = context.use_value(&collection_identifier.node)? { + if let Some(collection) = context.use_value(&collection_identifier.item)? { collection } else { return Err(ValidationError::VariableNotFound { - identifier: collection_identifier.node.clone(), + identifier: collection_identifier.item.clone(), position: collection_identifier.position, }); }; if let ValueInner::Map(map) = collection.inner().as_ref() { - return if let Some(value) = map.get(&index.node) { + return if let Some(value) = map.get(&index.item) { Ok(value.r#type(context)?) } else { Err(ValidationError::PropertyNotFound { - identifier: index.node.clone(), + identifier: index.item.clone(), position: index.position, }) }; @@ -51,7 +51,7 @@ impl AbstractNode for MapIndex { if let ( Expression::Value(WithPosition { - node: ValueNode::Map(properties), + item: ValueNode::Map(properties), .. }), index, @@ -61,9 +61,9 @@ impl AbstractNode for MapIndex { properties .iter() .find_map(|(property, type_option, expression)| { - if property == &index.node { + if property == &index.item { if let Some(r#type) = type_option { - Some(r#type.node.expected_type(context)) + Some(r#type.item.expected_type(context)) } else { Some(expression.expected_type(context)) } @@ -80,14 +80,14 @@ impl AbstractNode for MapIndex { if let ( Expression::Value(WithPosition { - node: ValueNode::Structure { fields, .. }, + item: ValueNode::Structure { fields, .. }, .. }), index, ) = (&self.collection, &self.index) { return if let Some(type_result) = fields.iter().find_map(|(property, expression)| { - if property == &index.node { + if property == &index.item { Some(expression.expected_type(context)) } else { None @@ -122,7 +122,7 @@ impl AbstractNode for MapIndex { if let ValueInner::Map(map) = collection.inner().as_ref() { let action = map - .get(&self.index.node) + .get(&self.index.item) .map(|value| Action::Return(value.clone())) .unwrap_or(Action::None); diff --git a/dust-lang/src/abstract_tree/mod.rs b/dust-lang/src/abstract_tree/mod.rs index f98d601..12f1ee5 100644 --- a/dust-lang/src/abstract_tree/mod.rs +++ b/dust-lang/src/abstract_tree/mod.rs @@ -48,14 +48,14 @@ use crate::{ #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] pub struct WithPosition { - pub node: T, + pub item: T, pub position: SourcePosition, } pub trait WithPos: Sized { fn with_position>(self, span: T) -> WithPosition { WithPosition { - node: self, + item: self, position: span.into(), } } diff --git a/dust-lang/src/abstract_tree/statement.rs b/dust-lang/src/abstract_tree/statement.rs index b38acf1..4725ad2 100644 --- a/dust-lang/src/abstract_tree/statement.rs +++ b/dust-lang/src/abstract_tree/statement.rs @@ -40,48 +40,48 @@ impl Statement { impl AbstractNode for Statement { fn expected_type(&self, _context: &Context) -> Result { match self { - Statement::Assignment(assignment) => assignment.node.expected_type(_context), - Statement::AsyncBlock(async_block) => async_block.node.expected_type(_context), - Statement::Block(block) => block.node.expected_type(_context), + Statement::Assignment(assignment) => assignment.item.expected_type(_context), + Statement::AsyncBlock(async_block) => async_block.item.expected_type(_context), + Statement::Block(block) => block.item.expected_type(_context), Statement::Break(_) => Ok(Type::None), Statement::Expression(expression) => expression.expected_type(_context), - Statement::IfElse(if_else) => if_else.node.expected_type(_context), - Statement::Loop(r#loop) => r#loop.node.expected_type(_context), - Statement::While(r#while) => r#while.node.expected_type(_context), + Statement::IfElse(if_else) => if_else.item.expected_type(_context), + Statement::Loop(r#loop) => r#loop.item.expected_type(_context), + Statement::While(r#while) => r#while.item.expected_type(_context), Statement::StructureDefinition(structure_definition) => { - structure_definition.node.expected_type(_context) + structure_definition.item.expected_type(_context) } } } fn validate(&self, _context: &Context) -> Result<(), ValidationError> { match self { - Statement::Assignment(assignment) => assignment.node.validate(_context), - Statement::AsyncBlock(async_block) => async_block.node.validate(_context), - Statement::Block(block) => block.node.validate(_context), + Statement::Assignment(assignment) => assignment.item.validate(_context), + Statement::AsyncBlock(async_block) => async_block.item.validate(_context), + Statement::Block(block) => block.item.validate(_context), Statement::Break(_) => Ok(()), Statement::Expression(expression) => expression.validate(_context), - Statement::IfElse(if_else) => if_else.node.validate(_context), - Statement::Loop(r#loop) => r#loop.node.validate(_context), - Statement::While(r#while) => r#while.node.validate(_context), + Statement::IfElse(if_else) => if_else.item.validate(_context), + Statement::Loop(r#loop) => r#loop.item.validate(_context), + Statement::While(r#while) => r#while.item.validate(_context), Statement::StructureDefinition(structure_definition) => { - structure_definition.node.validate(_context) + structure_definition.item.validate(_context) } } } fn run(self, context: &mut Context, clear_variables: bool) -> Result { let result = match self { - Statement::Assignment(assignment) => assignment.node.run(context, clear_variables), - Statement::AsyncBlock(async_block) => async_block.node.run(context, clear_variables), - Statement::Block(block) => block.node.run(context, clear_variables), + Statement::Assignment(assignment) => assignment.item.run(context, clear_variables), + Statement::AsyncBlock(async_block) => async_block.item.run(context, clear_variables), + Statement::Block(block) => block.item.run(context, clear_variables), Statement::Break(_) => Ok(Action::Break), Statement::Expression(expression) => expression.run(context, clear_variables), - Statement::IfElse(if_else) => if_else.node.run(context, clear_variables), - Statement::Loop(r#loop) => r#loop.node.run(context, clear_variables), - Statement::While(r#while) => r#while.node.run(context, clear_variables), + Statement::IfElse(if_else) => if_else.item.run(context, clear_variables), + Statement::Loop(r#loop) => r#loop.item.run(context, clear_variables), + Statement::While(r#while) => r#while.item.run(context, clear_variables), Statement::StructureDefinition(structure_definition) => { - structure_definition.node.run(context, clear_variables) + structure_definition.item.run(context, clear_variables) } }; diff --git a/dust-lang/src/abstract_tree/type.rs b/dust-lang/src/abstract_tree/type.rs index fccc719..0d35e19 100644 --- a/dust-lang/src/abstract_tree/type.rs +++ b/dust-lang/src/abstract_tree/type.rs @@ -57,27 +57,27 @@ impl Type { } } (Type::ListOf(left), Type::ListOf(right)) => { - if let Ok(()) = left.node.check(&right.node) { + if let Ok(()) = left.item.check(&right.item) { return Ok(()); } } (Type::ListOf(list_of), Type::ListExact(list_exact)) => { for r#type in list_exact { - list_of.node.check(&r#type.node)?; + list_of.item.check(&r#type.item)?; } return Ok(()); } (Type::ListExact(list_exact), Type::ListOf(list_of)) => { for r#type in list_exact { - r#type.node.check(&list_of.node)?; + r#type.item.check(&list_of.item)?; } return Ok(()); } (Type::ListExact(left), Type::ListExact(right)) => { for (left, right) in left.iter().zip(right.iter()) { - left.node.check(&right.node)?; + left.item.check(&right.item)?; } return Ok(()); @@ -96,7 +96,7 @@ impl Type { for ((left_field_name, left_type), (right_field_name, right_type)) in left_fields.iter().zip(right_fields.iter()) { - if left_field_name != right_field_name || left_type.node != right_type.node + if left_field_name != right_field_name || left_type.item != right_type.item { return Err(TypeConflict { actual: other.clone(), @@ -118,11 +118,11 @@ impl Type { return_type: right_return, }, ) => { - if left_return.node == right_return.node { + if left_return.item == right_return.item { for (left_parameter, right_parameter) in left_parameters.iter().zip(right_parameters.iter()) { - if left_parameter.node != right_parameter.node { + if left_parameter.item != right_parameter.item { return Err(TypeConflict { actual: other.clone(), expected: self.clone(), @@ -165,15 +165,15 @@ impl Display for Type { Type::Float => write!(f, "float"), Type::Integer => write!(f, "int"), Type::List => write!(f, "list"), - Type::ListOf(item_type) => write!(f, "list({})", item_type.node), + Type::ListOf(item_type) => write!(f, "list({})", item_type.item), Type::ListExact(item_types) => { write!(f, "[")?; for (index, item_type) in item_types.into_iter().enumerate() { if index == item_types.len() - 1 { - write!(f, "{}", item_type.node)?; + write!(f, "{}", item_type.item)?; } else { - write!(f, "{}, ", item_type.node)?; + write!(f, "{}, ", item_type.item)?; } } @@ -190,10 +190,10 @@ impl Display for Type { write!(f, "(")?; for r#type in parameter_types { - write!(f, "{} ", r#type.node)?; + write!(f, "{} ", r#type.item)?; } - write!(f, ") : {}", return_type.node) + write!(f, ") : {}", return_type.item) } Type::Structure { name, .. } => write!(f, "{name}"), Type::Argument(identifier) => write!(f, "{identifier}"), diff --git a/dust-lang/src/abstract_tree/value_node.rs b/dust-lang/src/abstract_tree/value_node.rs index f855ebf..645b289 100644 --- a/dust-lang/src/abstract_tree/value_node.rs +++ b/dust-lang/src/abstract_tree/value_node.rs @@ -75,14 +75,14 @@ impl AbstractNode for ValueNode { types.push(( identifier.clone(), WithPosition { - node: r#type, + item: r#type, position: expression.position(), }, )); } Type::Structure { - name: name.node.clone(), + name: name.item.clone(), fields: types, } } @@ -97,7 +97,7 @@ impl AbstractNode for ValueNode { if let Some(expected_type) = r#type { let actual_type = expression.expected_type(context)?; - expected_type.node.check(&actual_type).map_err(|conflict| { + expected_type.item.check(&actual_type).map_err(|conflict| { ValidationError::TypeCheck { conflict, actual_position: expression.position(), @@ -122,21 +122,21 @@ impl AbstractNode for ValueNode { function_context.inherit_types_from(context)?; for r#type in type_arguments { - if let Type::Argument(identifier) = &r#type.node { - function_context.set_type(identifier.clone(), r#type.node.clone())?; + if let Type::Argument(identifier) = &r#type.item { + function_context.set_type(identifier.clone(), r#type.item.clone())?; } } for (identifier, r#type) in parameters { - function_context.set_type(identifier.clone(), r#type.node.clone())?; + function_context.set_type(identifier.clone(), r#type.item.clone())?; } - body.node.validate(&function_context)?; + body.item.validate(&function_context)?; - let actual_return_type = body.node.expected_type(&function_context)?; + let actual_return_type = body.item.expected_type(&function_context)?; return_type - .node + .item .check(&actual_return_type) .map_err(|conflict| ValidationError::TypeCheck { conflict, @@ -152,9 +152,9 @@ impl AbstractNode for ValueNode { fields: expressions, } = self { - if !context.contains(&name.node)? { + if !context.contains(&name.item)? { return Err(ValidationError::VariableNotFound { - identifier: name.node.clone(), + identifier: name.item.clone(), position: name.position, }); } @@ -162,12 +162,12 @@ impl AbstractNode for ValueNode { if let Some(Type::Structure { name: _, fields: types, - }) = context.get_type(&name.node)? + }) = context.get_type(&name.item)? { for ((_, expression), (_, expected_type)) in expressions.iter().zip(types.iter()) { let actual_type = expression.expected_type(context)?; - expected_type.node.check(&actual_type).map_err(|conflict| { + expected_type.item.check(&actual_type).map_err(|conflict| { ValidationError::TypeCheck { conflict, actual_position: expression.position(), @@ -194,7 +194,7 @@ impl AbstractNode for ValueNode { let action = expression.run(_context, _clear_variables)?; let value = if let Action::Return(value) = action { WithPosition { - node: value, + item: value, position: expression_position, } } else { diff --git a/dust-lang/src/context.rs b/dust-lang/src/context.rs index af095bf..2a131af 100644 --- a/dust-lang/src/context.rs +++ b/dust-lang/src/context.rs @@ -3,8 +3,6 @@ use std::{ sync::{Arc, RwLock, RwLockReadGuard}, }; -use rayon::iter::{IntoParallelIterator, ParallelIterator}; - use crate::{ abstract_tree::Type, error::{RwLockPoisonError, ValidationError}, @@ -14,19 +12,19 @@ use crate::{ #[derive(Clone, Debug)] pub struct Context { - inner: Arc>>, + variables: Arc>>, } impl Context { pub fn new() -> Self { Self { - inner: Arc::new(RwLock::new(BTreeMap::new())), + variables: Arc::new(RwLock::new(BTreeMap::new())), } } pub fn with_data(data: BTreeMap) -> Self { Self { - inner: Arc::new(RwLock::new(data)), + variables: Arc::new(RwLock::new(data)), } } @@ -34,14 +32,16 @@ impl Context { &self, ) -> Result>, RwLockPoisonError> { - Ok(self.inner.read()?) + Ok(self.variables.read()?) } pub fn inherit_types_from(&self, other: &Context) -> Result<(), RwLockPoisonError> { - let mut self_data = self.inner.write()?; + let mut self_data = self.variables.write()?; - for (identifier, (value_data, usage_data)) in other.inner.read()?.iter() { + for (identifier, (value_data, usage_data)) in other.variables.read()?.iter() { if let ValueData::Type(Type::Function { .. }) = value_data { + log::trace!("Inheriting type of variable {identifier}."); + self_data.insert(identifier.clone(), (value_data.clone(), usage_data.clone())); } } @@ -50,9 +50,11 @@ impl Context { } pub fn inherit_data_from(&self, other: &Context) -> Result<(), RwLockPoisonError> { - let mut self_data = self.inner.write()?; + let mut self_data = self.variables.write()?; + + for (identifier, (value_data, usage_data)) in other.variables.read()?.iter() { + log::trace!("Inheriting variable {identifier}."); - for (identifier, (value_data, usage_data)) in other.inner.read()?.iter() { self_data.insert(identifier.clone(), (value_data.clone(), usage_data.clone())); } @@ -60,11 +62,13 @@ impl Context { } pub fn contains(&self, identifier: &Identifier) -> Result { - Ok(self.inner.read()?.contains_key(identifier)) + log::trace!("Checking that {identifier} exists."); + + Ok(self.variables.read()?.contains_key(identifier)) } pub fn get_type(&self, identifier: &Identifier) -> Result, ValidationError> { - if let Some((value_data, _)) = self.inner.read()?.get(identifier) { + if let Some((value_data, _)) = self.variables.read()?.get(identifier) { log::trace!("Using {identifier}'s type."); let r#type = match value_data { @@ -79,7 +83,8 @@ impl Context { } pub fn use_value(&self, identifier: &Identifier) -> Result, RwLockPoisonError> { - if let Some((ValueData::Value(value), usage_data)) = self.inner.write()?.get_mut(identifier) + if let Some((ValueData::Value(value), usage_data)) = + self.variables.write()?.get_mut(identifier) { log::trace!("Using {identifier}'s value."); @@ -92,9 +97,9 @@ impl Context { } pub fn set_type(&self, identifier: Identifier, r#type: Type) -> Result<(), RwLockPoisonError> { - log::info!("Setting {identifier} to type {}.", r#type); + log::debug!("Setting {identifier} to type {}.", r#type); - self.inner + self.variables .write()? .insert(identifier, (ValueData::Type(r#type), UsageData::new())); @@ -102,15 +107,17 @@ impl Context { } pub fn set_value(&self, identifier: Identifier, value: Value) -> Result<(), RwLockPoisonError> { - log::info!("Setting {identifier} to value {value}."); + log::debug!("Setting {identifier} to value {value}."); - let mut inner = self.inner.write()?; - let old_usage_data = inner.remove(&identifier).map(|(_, usage_data)| usage_data); + let mut variables = self.variables.write()?; + let old_usage_data = variables + .remove(&identifier) + .map(|(_, usage_data)| usage_data); if let Some(usage_data) = old_usage_data { - inner.insert(identifier, (ValueData::Value(value), usage_data)); + variables.insert(identifier, (ValueData::Value(value), usage_data)); } else { - inner.insert(identifier, (ValueData::Value(value), UsageData::new())); + variables.insert(identifier, (ValueData::Value(value), UsageData::new())); } Ok(()) @@ -118,7 +125,7 @@ impl Context { pub fn remove(&self, identifier: &Identifier) -> Result, RwLockPoisonError> { let removed = self - .inner + .variables .write()? .remove(identifier) .map(|(value_data, _)| value_data); @@ -127,31 +134,25 @@ impl Context { } pub fn clean(&mut self) -> Result<(), RwLockPoisonError> { - let clean_variables = self - .inner + self.variables .write()? - .clone() - .into_par_iter() - .filter(|(identifier, (_, usage_data))| { + .retain(|identifier, (_, usage_data)| { if usage_data.actual < usage_data.expected { true } else { - log::debug!("Removing variable {identifier}."); + log::trace!("Removing variable {identifier}."); false } - }) - .collect(); - - self.inner = Arc::new(RwLock::new(clean_variables)); + }); Ok(()) } pub fn add_expected_use(&self, identifier: &Identifier) -> Result { - let mut inner = self.inner.write()?; + let mut variables = self.variables.write()?; - if let Some((_, usage_data)) = inner.get_mut(identifier) { + if let Some((_, usage_data)) = variables.get_mut(identifier) { log::trace!("Adding expected use for variable {identifier}."); usage_data.expected += 1; diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index ad1d593..a2a3f5f 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -1520,7 +1520,7 @@ mod tests { ); if let Statement::Expression(Expression::Value(WithPosition { - node: ValueNode::Float(float), + item: ValueNode::Float(float), .. })) = &parse(&lex("NaN").unwrap()).unwrap()[0] { diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index d46bece..8de39a2 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -107,9 +107,9 @@ impl Display for Value { for (index, value) in list.into_iter().enumerate() { if index == list.len() - 1 { - write!(f, "{}", value.node)?; + write!(f, "{}", value.item)?; } else { - write!(f, "{}, ", value.node)?; + write!(f, "{}, ", value.item)?; } } @@ -137,9 +137,9 @@ impl Display for Value { for (index, r#type) in type_arguments.into_iter().enumerate() { if index == type_arguments.len() - 1 { - write!(f, "{}", r#type.node)?; + write!(f, "{}", r#type.item)?; } else { - write!(f, "{} ", r#type.node)?; + write!(f, "{} ", r#type.item)?; } } @@ -149,13 +149,13 @@ impl Display for Value { write!(f, "(")?; for (identifier, r#type) in parameters { - write!(f, "{identifier}: {}", r#type.node)?; + write!(f, "{identifier}: {}", r#type.item)?; } - write!(f, "): {} {:?}", return_type.node, body.node) + write!(f, "): {} {:?}", return_type.item, body.item) } ValueInner::Structure { name, fields } => { - write!(f, "{}\n{{", name.node)?; + write!(f, "{}\n{{", name.item)?; for (key, value) in fields { writeln!(f, "{key} = {value},")?; @@ -207,7 +207,7 @@ impl ValueInner { let mut types = Vec::with_capacity(values.len()); for value in values { - types.push(value.node.r#type(context)?.with_position(value.position)); + types.push(value.item.r#type(context)?.with_position(value.position)); } Type::ListExact(types) @@ -224,11 +224,11 @@ impl ValueInner { return_type: Box::new(function.return_type.clone()), }, ValueInner::Structure { name, .. } => { - if let Some(r#type) = context.get_type(&name.node)? { + if let Some(r#type) = context.get_type(&name.item)? { r#type } else { return Err(ValidationError::VariableNotFound { - identifier: name.node.clone(), + identifier: name.item.clone(), position: name.position, }); } @@ -316,11 +316,12 @@ impl Function { self, arguments: Vec, context: &mut Context, + clear_variables: bool, ) -> Result { for ((identifier, _), value) in self.parameters.into_iter().zip(arguments.into_iter()) { context.set_value(identifier.clone(), value)?; } - self.body.node.run(context, true) + self.body.item.run(context, clear_variables) } }