1
0

Refine memory management

This commit is contained in:
Jeff 2024-04-22 03:41:21 -04:00
parent 70face6765
commit 8478d59000
13 changed files with 173 additions and 169 deletions

View File

@ -47,7 +47,7 @@ impl AbstractNode for Assignment {
let statement_type = self.statement.expected_type(context)?; let statement_type = self.statement.expected_type(context)?;
if let Some(WithPosition { if let Some(WithPosition {
node: expected_type, item: expected_type,
position: expected_position, position: expected_position,
}) = &self.r#type }) = &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 { } else {
context.set_type(self.identifier.node.clone(), statement_type)?; context.set_type(self.identifier.item.clone(), statement_type)?;
} }
self.statement.validate(context)?; self.statement.validate(context)?;
@ -78,10 +78,10 @@ impl AbstractNode for Assignment {
match self.operator { match self.operator {
AssignmentOperator::Assign => { AssignmentOperator::Assign => {
context.set_value(self.identifier.node, right)?; context.set_value(self.identifier.item, right)?;
} }
AssignmentOperator::AddAssign => { 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()) { let new_value = match (left.inner().as_ref(), right.inner().as_ref()) {
(ValueInner::Integer(left), ValueInner::Integer(right)) => { (ValueInner::Integer(left), ValueInner::Integer(right)) => {
let sum = left.saturating_add(*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 { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::VariableNotFound { ValidationError::VariableNotFound {
identifier: self.identifier.node, identifier: self.identifier.item,
position: self.identifier.position, position: self.identifier.position,
}, },
)); ));
} }
} }
AssignmentOperator::SubAssign => { 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()) { let new_value = match (left.inner().as_ref(), right.inner().as_ref()) {
(ValueInner::Integer(left), ValueInner::Integer(right)) => { (ValueInner::Integer(left), ValueInner::Integer(right)) => {
let difference = left.saturating_sub(*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 { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
ValidationError::VariableNotFound { ValidationError::VariableNotFound {
identifier: self.identifier.node, identifier: self.identifier.item,
position: self.identifier.position, position: self.identifier.position,
}, },
)); ));
@ -249,7 +249,7 @@ mod tests {
let validation = Assignment::new( let validation = Assignment::new(
Identifier::new("foobar").with_position((0, 0)), Identifier::new("foobar").with_position((0, 0)),
Some(WithPosition { Some(WithPosition {
node: Type::Boolean, item: Type::Boolean,
position: (0, 0).into(), position: (0, 0).into(),
}), }),
AssignmentOperator::Assign, AssignmentOperator::Assign,

View File

@ -39,50 +39,50 @@ impl Expression {
impl AbstractNode for Expression { impl AbstractNode for Expression {
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
match self { 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) => { 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) Ok(r#type)
} else { } else {
Err(ValidationError::VariableNotFound { Err(ValidationError::VariableNotFound {
identifier: identifier.node.clone(), identifier: identifier.item.clone(),
position: identifier.position, position: identifier.position,
}) })
} }
} }
Expression::MapIndex(map_index) => map_index.node.expected_type(_context), Expression::MapIndex(map_index) => map_index.item.expected_type(_context),
Expression::ListIndex(list_index) => list_index.node.expected_type(_context), Expression::ListIndex(list_index) => list_index.item.expected_type(_context),
Expression::Logic(logic) => logic.node.expected_type(_context), Expression::Logic(logic) => logic.item.expected_type(_context),
Expression::Math(math) => math.node.expected_type(_context), Expression::Math(math) => math.item.expected_type(_context),
Expression::Value(value_node) => value_node.node.expected_type(_context), Expression::Value(value_node) => value_node.item.expected_type(_context),
Expression::BuiltInFunctionCall(built_in_function_call) => { 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> { fn validate(&self, context: &Context) -> Result<(), ValidationError> {
match self { match self {
Expression::FunctionCall(function_call) => function_call.node.validate(context), Expression::FunctionCall(function_call) => function_call.item.validate(context),
Expression::Identifier(identifier) => { Expression::Identifier(identifier) => {
let found = context.add_expected_use(&identifier.node)?; let found = context.add_expected_use(&identifier.item)?;
if found { if found {
Ok(()) Ok(())
} else { } else {
Err(ValidationError::VariableNotFound { Err(ValidationError::VariableNotFound {
identifier: identifier.node.clone(), identifier: identifier.item.clone(),
position: identifier.position, position: identifier.position,
}) })
} }
} }
Expression::MapIndex(map_index) => map_index.node.validate(context), Expression::MapIndex(map_index) => map_index.item.validate(context),
Expression::ListIndex(list_index) => list_index.node.validate(context), Expression::ListIndex(list_index) => list_index.item.validate(context),
Expression::Logic(logic) => logic.node.validate(context), Expression::Logic(logic) => logic.item.validate(context),
Expression::Math(math) => math.node.validate(context), Expression::Math(math) => math.item.validate(context),
Expression::Value(value_node) => value_node.node.validate(context), Expression::Value(value_node) => value_node.item.validate(context),
Expression::BuiltInFunctionCall(built_in_function_call) => { 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<Action, RuntimeError> { fn run(self, context: &mut Context, _clear_variables: bool) -> Result<Action, RuntimeError> {
match self { match self {
Expression::FunctionCall(function_call) => { Expression::FunctionCall(function_call) => {
function_call.node.run(context, _clear_variables) function_call.item.run(context, _clear_variables)
} }
Expression::Identifier(identifier) => { 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)) Ok(Action::Return(value))
} else { } else {
Err(RuntimeError::ValidationFailure( Err(RuntimeError::ValidationFailure(
ValidationError::VariableNotFound { ValidationError::VariableNotFound {
identifier: identifier.node.clone(), identifier: identifier.item.clone(),
position: identifier.position, position: identifier.position,
}, },
)) ))
} }
} }
Expression::MapIndex(map_index) => map_index.node.run(context, _clear_variables), Expression::MapIndex(map_index) => map_index.item.run(context, _clear_variables),
Expression::ListIndex(list_index) => list_index.node.run(context, _clear_variables), Expression::ListIndex(list_index) => list_index.item.run(context, _clear_variables),
Expression::Logic(logic) => logic.node.run(context, _clear_variables), Expression::Logic(logic) => logic.item.run(context, _clear_variables),
Expression::Math(math) => math.node.run(context, _clear_variables), Expression::Math(math) => math.item.run(context, _clear_variables),
Expression::Value(value_node) => value_node.node.run(context, _clear_variables), Expression::Value(value_node) => value_node.item.run(context, _clear_variables),
Expression::BuiltInFunctionCall(built_in_function_call) => { Expression::BuiltInFunctionCall(built_in_function_call) => {
built_in_function_call.node.run(context, _clear_variables) built_in_function_call.item.run(context, _clear_variables)
} }
} }
} }

View File

@ -32,7 +32,7 @@ impl AbstractNode for FunctionCall {
let function_node_type = self.function.expected_type(_context)?; let function_node_type = self.function.expected_type(_context)?;
if let Type::Function { return_type, .. } = function_node_type { if let Type::Function { return_type, .. } = function_node_type {
Ok(return_type.node) Ok(return_type.item)
} else { } else {
Err(ValidationError::ExpectedFunction { Err(ValidationError::ExpectedFunction {
actual: function_node_type, actual: function_node_type,
@ -58,13 +58,13 @@ impl AbstractNode for FunctionCall {
for (type_parameter, type_argument) in for (type_parameter, type_argument) in
parameter_types.iter().zip(self.type_arguments.iter()) parameter_types.iter().zip(self.type_arguments.iter())
{ {
if let Type::Argument(_) = type_parameter.node { if let Type::Argument(_) = type_parameter.item {
continue; continue;
} }
type_parameter type_parameter
.node .item
.check(&type_argument.node) .check(&type_argument.item)
.map_err(|conflict| ValidationError::TypeCheck { .map_err(|conflict| ValidationError::TypeCheck {
conflict, conflict,
actual_position: type_argument.position, 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()) { 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; continue;
} }
let actual = expression.expected_type(context)?; let actual = expression.expected_type(context)?;
type_parameter.node.check(&actual).map_err(|conflict| { type_parameter.item.check(&actual).map_err(|conflict| {
ValidationError::TypeCheck { ValidationError::TypeCheck {
conflict, conflict,
actual_position: expression.position(), actual_position: expression.position(),
@ -97,9 +97,9 @@ impl AbstractNode for FunctionCall {
} }
} }
fn run(self, context: &mut Context, _clear_variables: bool) -> Result<Action, RuntimeError> { fn run(self, context: &mut Context, clear_variables: bool) -> Result<Action, RuntimeError> {
let function_position = self.function.position(); 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 { let value = if let Action::Return(value) = action {
value value
} else { } else {
@ -121,7 +121,7 @@ impl AbstractNode for FunctionCall {
for expression in self.arguments { for expression in self.arguments {
let expression_position = expression.position(); 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 { let value = if let Action::Return(value) = action {
value value
} else { } else {
@ -138,8 +138,8 @@ impl AbstractNode for FunctionCall {
for (type_parameter, type_argument) in function for (type_parameter, type_argument) in function
.type_parameters() .type_parameters()
.iter() .iter()
.map(|r#type| r#type.node.clone()) .map(|r#type| r#type.item.clone())
.zip(self.type_arguments.into_iter().map(|r#type| r#type.node)) .zip(self.type_arguments.into_iter().map(|r#type| r#type.item))
{ {
if let Type::Argument(identifier) = type_parameter { if let Type::Argument(identifier) = type_parameter {
function_context.set_type(identifier, type_argument)?; function_context.set_type(identifier, type_argument)?;
@ -147,6 +147,8 @@ impl AbstractNode for FunctionCall {
} }
function_context.inherit_data_from(&context)?; function_context.inherit_data_from(&context)?;
function.clone().call(arguments, &mut function_context) function
.clone()
.call(arguments, &mut function_context, clear_variables)
} }
} }

View File

@ -32,27 +32,27 @@ impl IfElse {
impl AbstractNode for IfElse { impl AbstractNode for IfElse {
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
self.if_block.node.expected_type(_context) self.if_block.item.expected_type(_context)
} }
fn validate(&self, context: &Context) -> Result<(), ValidationError> { fn validate(&self, context: &Context) -> Result<(), ValidationError> {
self.if_expression.validate(context)?; 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)?; let if_expression_type = self.if_expression.expected_type(context)?;
if let Type::Boolean = if_expression_type { if let Type::Boolean = if_expression_type {
if let Some(else_block) = &self.else_block { 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 expected_type
.check(&actual) .check(&actual)
.map_err(|conflict| ValidationError::TypeCheck { .map_err(|conflict| ValidationError::TypeCheck {
conflict, 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(), expected_position: self.if_expression.position(),
})?; })?;
} }
@ -67,15 +67,15 @@ impl AbstractNode for IfElse {
let expression_type = expression.expected_type(context)?; let expression_type = expression.expected_type(context)?;
if let Type::Boolean = expression_type { 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 expected_type
.check(&actual) .check(&actual)
.map_err(|conflict| ValidationError::TypeCheck { .map_err(|conflict| ValidationError::TypeCheck {
conflict, 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(), expected_position: self.if_expression.position(),
})?; })?;
} else { } else {
@ -102,7 +102,7 @@ impl AbstractNode for IfElse {
if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() { if let ValueInner::Boolean(if_boolean) = value.inner().as_ref() {
if *if_boolean { if *if_boolean {
self.if_block.node.run(context, _clear_variables) self.if_block.item.run(context, _clear_variables)
} else { } else {
for (expression, block) in self.else_ifs { for (expression, block) in self.else_ifs {
let expression_position = expression.position(); 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 let ValueInner::Boolean(else_if_boolean) = value.inner().as_ref() {
if *else_if_boolean { if *else_if_boolean {
return block.node.run(context, _clear_variables); return block.item.run(context, _clear_variables);
} }
} else { } else {
return Err(RuntimeError::ValidationFailure( return Err(RuntimeError::ValidationFailure(
@ -130,7 +130,7 @@ impl AbstractNode for IfElse {
} }
if let Some(else_statement) = self.else_block { if let Some(else_statement) = self.else_block {
else_statement.node.run(context, _clear_variables) else_statement.item.run(context, _clear_variables)
} else { } else {
Ok(Action::None) Ok(Action::None)
} }

View File

@ -23,11 +23,11 @@ impl AbstractNode for ListIndex {
if let ( if let (
Expression::Value(WithPosition { Expression::Value(WithPosition {
node: ValueNode::List(expression_list), item: ValueNode::List(expression_list),
.. ..
}), }),
Expression::Value(WithPosition { Expression::Value(WithPosition {
node: ValueNode::Integer(index), item: ValueNode::Integer(index),
.. ..
}), }),
) = (&self.left, &self.right) ) = (&self.left, &self.right)
@ -98,7 +98,7 @@ impl AbstractNode for ListIndex {
let found_item = list.get(index as usize); let found_item = list.get(index as usize);
if let Some(item) = found_item { if let Some(item) = found_item {
Ok(Action::Return(item.node.clone())) Ok(Action::Return(item.item.clone()))
} else { } else {
Ok(Action::None) Ok(Action::None)
} }

View File

@ -28,21 +28,21 @@ impl AbstractNode for MapIndex {
(&self.collection, &self.index) (&self.collection, &self.index)
{ {
let collection = let collection =
if let Some(collection) = context.use_value(&collection_identifier.node)? { if let Some(collection) = context.use_value(&collection_identifier.item)? {
collection collection
} else { } else {
return Err(ValidationError::VariableNotFound { return Err(ValidationError::VariableNotFound {
identifier: collection_identifier.node.clone(), identifier: collection_identifier.item.clone(),
position: collection_identifier.position, position: collection_identifier.position,
}); });
}; };
if let ValueInner::Map(map) = collection.inner().as_ref() { 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)?) Ok(value.r#type(context)?)
} else { } else {
Err(ValidationError::PropertyNotFound { Err(ValidationError::PropertyNotFound {
identifier: index.node.clone(), identifier: index.item.clone(),
position: index.position, position: index.position,
}) })
}; };
@ -51,7 +51,7 @@ impl AbstractNode for MapIndex {
if let ( if let (
Expression::Value(WithPosition { Expression::Value(WithPosition {
node: ValueNode::Map(properties), item: ValueNode::Map(properties),
.. ..
}), }),
index, index,
@ -61,9 +61,9 @@ impl AbstractNode for MapIndex {
properties properties
.iter() .iter()
.find_map(|(property, type_option, expression)| { .find_map(|(property, type_option, expression)| {
if property == &index.node { if property == &index.item {
if let Some(r#type) = type_option { if let Some(r#type) = type_option {
Some(r#type.node.expected_type(context)) Some(r#type.item.expected_type(context))
} else { } else {
Some(expression.expected_type(context)) Some(expression.expected_type(context))
} }
@ -80,14 +80,14 @@ impl AbstractNode for MapIndex {
if let ( if let (
Expression::Value(WithPosition { Expression::Value(WithPosition {
node: ValueNode::Structure { fields, .. }, item: ValueNode::Structure { fields, .. },
.. ..
}), }),
index, index,
) = (&self.collection, &self.index) ) = (&self.collection, &self.index)
{ {
return if let Some(type_result) = fields.iter().find_map(|(property, expression)| { 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)) Some(expression.expected_type(context))
} else { } else {
None None
@ -122,7 +122,7 @@ impl AbstractNode for MapIndex {
if let ValueInner::Map(map) = collection.inner().as_ref() { if let ValueInner::Map(map) = collection.inner().as_ref() {
let action = map let action = map
.get(&self.index.node) .get(&self.index.item)
.map(|value| Action::Return(value.clone())) .map(|value| Action::Return(value.clone()))
.unwrap_or(Action::None); .unwrap_or(Action::None);

View File

@ -48,14 +48,14 @@ use crate::{
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub struct WithPosition<T> { pub struct WithPosition<T> {
pub node: T, pub item: T,
pub position: SourcePosition, pub position: SourcePosition,
} }
pub trait WithPos: Sized { pub trait WithPos: Sized {
fn with_position<T: Into<SourcePosition>>(self, span: T) -> WithPosition<Self> { fn with_position<T: Into<SourcePosition>>(self, span: T) -> WithPosition<Self> {
WithPosition { WithPosition {
node: self, item: self,
position: span.into(), position: span.into(),
} }
} }

View File

@ -40,48 +40,48 @@ impl Statement {
impl AbstractNode for Statement { impl AbstractNode for Statement {
fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> { fn expected_type(&self, _context: &Context) -> Result<Type, ValidationError> {
match self { match self {
Statement::Assignment(assignment) => assignment.node.expected_type(_context), Statement::Assignment(assignment) => assignment.item.expected_type(_context),
Statement::AsyncBlock(async_block) => async_block.node.expected_type(_context), Statement::AsyncBlock(async_block) => async_block.item.expected_type(_context),
Statement::Block(block) => block.node.expected_type(_context), Statement::Block(block) => block.item.expected_type(_context),
Statement::Break(_) => Ok(Type::None), Statement::Break(_) => Ok(Type::None),
Statement::Expression(expression) => expression.expected_type(_context), Statement::Expression(expression) => expression.expected_type(_context),
Statement::IfElse(if_else) => if_else.node.expected_type(_context), Statement::IfElse(if_else) => if_else.item.expected_type(_context),
Statement::Loop(r#loop) => r#loop.node.expected_type(_context), Statement::Loop(r#loop) => r#loop.item.expected_type(_context),
Statement::While(r#while) => r#while.node.expected_type(_context), Statement::While(r#while) => r#while.item.expected_type(_context),
Statement::StructureDefinition(structure_definition) => { Statement::StructureDefinition(structure_definition) => {
structure_definition.node.expected_type(_context) structure_definition.item.expected_type(_context)
} }
} }
} }
fn validate(&self, _context: &Context) -> Result<(), ValidationError> { fn validate(&self, _context: &Context) -> Result<(), ValidationError> {
match self { match self {
Statement::Assignment(assignment) => assignment.node.validate(_context), Statement::Assignment(assignment) => assignment.item.validate(_context),
Statement::AsyncBlock(async_block) => async_block.node.validate(_context), Statement::AsyncBlock(async_block) => async_block.item.validate(_context),
Statement::Block(block) => block.node.validate(_context), Statement::Block(block) => block.item.validate(_context),
Statement::Break(_) => Ok(()), Statement::Break(_) => Ok(()),
Statement::Expression(expression) => expression.validate(_context), Statement::Expression(expression) => expression.validate(_context),
Statement::IfElse(if_else) => if_else.node.validate(_context), Statement::IfElse(if_else) => if_else.item.validate(_context),
Statement::Loop(r#loop) => r#loop.node.validate(_context), Statement::Loop(r#loop) => r#loop.item.validate(_context),
Statement::While(r#while) => r#while.node.validate(_context), Statement::While(r#while) => r#while.item.validate(_context),
Statement::StructureDefinition(structure_definition) => { Statement::StructureDefinition(structure_definition) => {
structure_definition.node.validate(_context) structure_definition.item.validate(_context)
} }
} }
} }
fn run(self, context: &mut Context, clear_variables: bool) -> Result<Action, RuntimeError> { fn run(self, context: &mut Context, clear_variables: bool) -> Result<Action, RuntimeError> {
let result = match self { let result = match self {
Statement::Assignment(assignment) => assignment.node.run(context, clear_variables), Statement::Assignment(assignment) => assignment.item.run(context, clear_variables),
Statement::AsyncBlock(async_block) => async_block.node.run(context, clear_variables), Statement::AsyncBlock(async_block) => async_block.item.run(context, clear_variables),
Statement::Block(block) => block.node.run(context, clear_variables), Statement::Block(block) => block.item.run(context, clear_variables),
Statement::Break(_) => Ok(Action::Break), Statement::Break(_) => Ok(Action::Break),
Statement::Expression(expression) => expression.run(context, clear_variables), Statement::Expression(expression) => expression.run(context, clear_variables),
Statement::IfElse(if_else) => if_else.node.run(context, clear_variables), Statement::IfElse(if_else) => if_else.item.run(context, clear_variables),
Statement::Loop(r#loop) => r#loop.node.run(context, clear_variables), Statement::Loop(r#loop) => r#loop.item.run(context, clear_variables),
Statement::While(r#while) => r#while.node.run(context, clear_variables), Statement::While(r#while) => r#while.item.run(context, clear_variables),
Statement::StructureDefinition(structure_definition) => { Statement::StructureDefinition(structure_definition) => {
structure_definition.node.run(context, clear_variables) structure_definition.item.run(context, clear_variables)
} }
}; };

View File

@ -57,27 +57,27 @@ impl Type {
} }
} }
(Type::ListOf(left), Type::ListOf(right)) => { (Type::ListOf(left), Type::ListOf(right)) => {
if let Ok(()) = left.node.check(&right.node) { if let Ok(()) = left.item.check(&right.item) {
return Ok(()); return Ok(());
} }
} }
(Type::ListOf(list_of), Type::ListExact(list_exact)) => { (Type::ListOf(list_of), Type::ListExact(list_exact)) => {
for r#type in list_exact { for r#type in list_exact {
list_of.node.check(&r#type.node)?; list_of.item.check(&r#type.item)?;
} }
return Ok(()); return Ok(());
} }
(Type::ListExact(list_exact), Type::ListOf(list_of)) => { (Type::ListExact(list_exact), Type::ListOf(list_of)) => {
for r#type in list_exact { for r#type in list_exact {
r#type.node.check(&list_of.node)?; r#type.item.check(&list_of.item)?;
} }
return Ok(()); return Ok(());
} }
(Type::ListExact(left), Type::ListExact(right)) => { (Type::ListExact(left), Type::ListExact(right)) => {
for (left, right) in left.iter().zip(right.iter()) { for (left, right) in left.iter().zip(right.iter()) {
left.node.check(&right.node)?; left.item.check(&right.item)?;
} }
return Ok(()); return Ok(());
@ -96,7 +96,7 @@ impl Type {
for ((left_field_name, left_type), (right_field_name, right_type)) in for ((left_field_name, left_type), (right_field_name, right_type)) in
left_fields.iter().zip(right_fields.iter()) 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 { return Err(TypeConflict {
actual: other.clone(), actual: other.clone(),
@ -118,11 +118,11 @@ impl Type {
return_type: right_return, return_type: right_return,
}, },
) => { ) => {
if left_return.node == right_return.node { if left_return.item == right_return.item {
for (left_parameter, right_parameter) in for (left_parameter, right_parameter) in
left_parameters.iter().zip(right_parameters.iter()) left_parameters.iter().zip(right_parameters.iter())
{ {
if left_parameter.node != right_parameter.node { if left_parameter.item != right_parameter.item {
return Err(TypeConflict { return Err(TypeConflict {
actual: other.clone(), actual: other.clone(),
expected: self.clone(), expected: self.clone(),
@ -165,15 +165,15 @@ impl Display for Type {
Type::Float => write!(f, "float"), Type::Float => write!(f, "float"),
Type::Integer => write!(f, "int"), Type::Integer => write!(f, "int"),
Type::List => write!(f, "list"), 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) => { Type::ListExact(item_types) => {
write!(f, "[")?; write!(f, "[")?;
for (index, item_type) in item_types.into_iter().enumerate() { for (index, item_type) in item_types.into_iter().enumerate() {
if index == item_types.len() - 1 { if index == item_types.len() - 1 {
write!(f, "{}", item_type.node)?; write!(f, "{}", item_type.item)?;
} else { } else {
write!(f, "{}, ", item_type.node)?; write!(f, "{}, ", item_type.item)?;
} }
} }
@ -190,10 +190,10 @@ impl Display for Type {
write!(f, "(")?; write!(f, "(")?;
for r#type in parameter_types { 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::Structure { name, .. } => write!(f, "{name}"),
Type::Argument(identifier) => write!(f, "{identifier}"), Type::Argument(identifier) => write!(f, "{identifier}"),

View File

@ -75,14 +75,14 @@ impl AbstractNode for ValueNode {
types.push(( types.push((
identifier.clone(), identifier.clone(),
WithPosition { WithPosition {
node: r#type, item: r#type,
position: expression.position(), position: expression.position(),
}, },
)); ));
} }
Type::Structure { Type::Structure {
name: name.node.clone(), name: name.item.clone(),
fields: types, fields: types,
} }
} }
@ -97,7 +97,7 @@ impl AbstractNode for ValueNode {
if let Some(expected_type) = r#type { if let Some(expected_type) = r#type {
let actual_type = expression.expected_type(context)?; 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 { ValidationError::TypeCheck {
conflict, conflict,
actual_position: expression.position(), actual_position: expression.position(),
@ -122,21 +122,21 @@ impl AbstractNode for ValueNode {
function_context.inherit_types_from(context)?; function_context.inherit_types_from(context)?;
for r#type in type_arguments { for r#type in type_arguments {
if let Type::Argument(identifier) = &r#type.node { if let Type::Argument(identifier) = &r#type.item {
function_context.set_type(identifier.clone(), r#type.node.clone())?; function_context.set_type(identifier.clone(), r#type.item.clone())?;
} }
} }
for (identifier, r#type) in parameters { 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 return_type
.node .item
.check(&actual_return_type) .check(&actual_return_type)
.map_err(|conflict| ValidationError::TypeCheck { .map_err(|conflict| ValidationError::TypeCheck {
conflict, conflict,
@ -152,9 +152,9 @@ impl AbstractNode for ValueNode {
fields: expressions, fields: expressions,
} = self } = self
{ {
if !context.contains(&name.node)? { if !context.contains(&name.item)? {
return Err(ValidationError::VariableNotFound { return Err(ValidationError::VariableNotFound {
identifier: name.node.clone(), identifier: name.item.clone(),
position: name.position, position: name.position,
}); });
} }
@ -162,12 +162,12 @@ impl AbstractNode for ValueNode {
if let Some(Type::Structure { if let Some(Type::Structure {
name: _, name: _,
fields: types, fields: types,
}) = context.get_type(&name.node)? }) = context.get_type(&name.item)?
{ {
for ((_, expression), (_, expected_type)) in expressions.iter().zip(types.iter()) { for ((_, expression), (_, expected_type)) in expressions.iter().zip(types.iter()) {
let actual_type = expression.expected_type(context)?; 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 { ValidationError::TypeCheck {
conflict, conflict,
actual_position: expression.position(), actual_position: expression.position(),
@ -194,7 +194,7 @@ impl AbstractNode for ValueNode {
let action = expression.run(_context, _clear_variables)?; let action = expression.run(_context, _clear_variables)?;
let value = if let Action::Return(value) = action { let value = if let Action::Return(value) = action {
WithPosition { WithPosition {
node: value, item: value,
position: expression_position, position: expression_position,
} }
} else { } else {

View File

@ -3,8 +3,6 @@ use std::{
sync::{Arc, RwLock, RwLockReadGuard}, sync::{Arc, RwLock, RwLockReadGuard},
}; };
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use crate::{ use crate::{
abstract_tree::Type, abstract_tree::Type,
error::{RwLockPoisonError, ValidationError}, error::{RwLockPoisonError, ValidationError},
@ -14,19 +12,19 @@ use crate::{
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Context { pub struct Context {
inner: Arc<RwLock<BTreeMap<Identifier, (ValueData, UsageData)>>>, variables: Arc<RwLock<BTreeMap<Identifier, (ValueData, UsageData)>>>,
} }
impl Context { impl Context {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
inner: Arc::new(RwLock::new(BTreeMap::new())), variables: Arc::new(RwLock::new(BTreeMap::new())),
} }
} }
pub fn with_data(data: BTreeMap<Identifier, (ValueData, UsageData)>) -> Self { pub fn with_data(data: BTreeMap<Identifier, (ValueData, UsageData)>) -> Self {
Self { Self {
inner: Arc::new(RwLock::new(data)), variables: Arc::new(RwLock::new(data)),
} }
} }
@ -34,14 +32,16 @@ impl Context {
&self, &self,
) -> Result<RwLockReadGuard<BTreeMap<Identifier, (ValueData, UsageData)>>, RwLockPoisonError> ) -> Result<RwLockReadGuard<BTreeMap<Identifier, (ValueData, UsageData)>>, RwLockPoisonError>
{ {
Ok(self.inner.read()?) Ok(self.variables.read()?)
} }
pub fn inherit_types_from(&self, other: &Context) -> Result<(), RwLockPoisonError> { 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 { 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())); 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> { 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())); self_data.insert(identifier.clone(), (value_data.clone(), usage_data.clone()));
} }
@ -60,11 +62,13 @@ impl Context {
} }
pub fn contains(&self, identifier: &Identifier) -> Result<bool, RwLockPoisonError> { pub fn contains(&self, identifier: &Identifier) -> Result<bool, RwLockPoisonError> {
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<Option<Type>, ValidationError> { pub fn get_type(&self, identifier: &Identifier) -> Result<Option<Type>, 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."); log::trace!("Using {identifier}'s type.");
let r#type = match value_data { let r#type = match value_data {
@ -79,7 +83,8 @@ impl Context {
} }
pub fn use_value(&self, identifier: &Identifier) -> Result<Option<Value>, RwLockPoisonError> { pub fn use_value(&self, identifier: &Identifier) -> Result<Option<Value>, 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."); log::trace!("Using {identifier}'s value.");
@ -92,9 +97,9 @@ impl Context {
} }
pub fn set_type(&self, identifier: Identifier, r#type: Type) -> Result<(), RwLockPoisonError> { 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()? .write()?
.insert(identifier, (ValueData::Type(r#type), UsageData::new())); .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> { 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 mut variables = self.variables.write()?;
let old_usage_data = inner.remove(&identifier).map(|(_, usage_data)| usage_data); let old_usage_data = variables
.remove(&identifier)
.map(|(_, usage_data)| usage_data);
if let Some(usage_data) = old_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 { } else {
inner.insert(identifier, (ValueData::Value(value), UsageData::new())); variables.insert(identifier, (ValueData::Value(value), UsageData::new()));
} }
Ok(()) Ok(())
@ -118,7 +125,7 @@ impl Context {
pub fn remove(&self, identifier: &Identifier) -> Result<Option<ValueData>, RwLockPoisonError> { pub fn remove(&self, identifier: &Identifier) -> Result<Option<ValueData>, RwLockPoisonError> {
let removed = self let removed = self
.inner .variables
.write()? .write()?
.remove(identifier) .remove(identifier)
.map(|(value_data, _)| value_data); .map(|(value_data, _)| value_data);
@ -127,31 +134,25 @@ impl Context {
} }
pub fn clean(&mut self) -> Result<(), RwLockPoisonError> { pub fn clean(&mut self) -> Result<(), RwLockPoisonError> {
let clean_variables = self self.variables
.inner
.write()? .write()?
.clone() .retain(|identifier, (_, usage_data)| {
.into_par_iter()
.filter(|(identifier, (_, usage_data))| {
if usage_data.actual < usage_data.expected { if usage_data.actual < usage_data.expected {
true true
} else { } else {
log::debug!("Removing variable {identifier}."); log::trace!("Removing variable {identifier}.");
false false
} }
}) });
.collect();
self.inner = Arc::new(RwLock::new(clean_variables));
Ok(()) Ok(())
} }
pub fn add_expected_use(&self, identifier: &Identifier) -> Result<bool, RwLockPoisonError> { pub fn add_expected_use(&self, identifier: &Identifier) -> Result<bool, RwLockPoisonError> {
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}."); log::trace!("Adding expected use for variable {identifier}.");
usage_data.expected += 1; usage_data.expected += 1;

View File

@ -1520,7 +1520,7 @@ mod tests {
); );
if let Statement::Expression(Expression::Value(WithPosition { if let Statement::Expression(Expression::Value(WithPosition {
node: ValueNode::Float(float), item: ValueNode::Float(float),
.. ..
})) = &parse(&lex("NaN").unwrap()).unwrap()[0] })) = &parse(&lex("NaN").unwrap()).unwrap()[0]
{ {

View File

@ -107,9 +107,9 @@ impl Display for Value {
for (index, value) in list.into_iter().enumerate() { for (index, value) in list.into_iter().enumerate() {
if index == list.len() - 1 { if index == list.len() - 1 {
write!(f, "{}", value.node)?; write!(f, "{}", value.item)?;
} else { } 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() { for (index, r#type) in type_arguments.into_iter().enumerate() {
if index == type_arguments.len() - 1 { if index == type_arguments.len() - 1 {
write!(f, "{}", r#type.node)?; write!(f, "{}", r#type.item)?;
} else { } else {
write!(f, "{} ", r#type.node)?; write!(f, "{} ", r#type.item)?;
} }
} }
@ -149,13 +149,13 @@ impl Display for Value {
write!(f, "(")?; write!(f, "(")?;
for (identifier, r#type) in parameters { 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 } => { ValueInner::Structure { name, fields } => {
write!(f, "{}\n{{", name.node)?; write!(f, "{}\n{{", name.item)?;
for (key, value) in fields { for (key, value) in fields {
writeln!(f, "{key} = {value},")?; writeln!(f, "{key} = {value},")?;
@ -207,7 +207,7 @@ impl ValueInner {
let mut types = Vec::with_capacity(values.len()); let mut types = Vec::with_capacity(values.len());
for value in values { 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) Type::ListExact(types)
@ -224,11 +224,11 @@ impl ValueInner {
return_type: Box::new(function.return_type.clone()), return_type: Box::new(function.return_type.clone()),
}, },
ValueInner::Structure { name, .. } => { 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 r#type
} else { } else {
return Err(ValidationError::VariableNotFound { return Err(ValidationError::VariableNotFound {
identifier: name.node.clone(), identifier: name.item.clone(),
position: name.position, position: name.position,
}); });
} }
@ -316,11 +316,12 @@ impl Function {
self, self,
arguments: Vec<Value>, arguments: Vec<Value>,
context: &mut Context, context: &mut Context,
clear_variables: bool,
) -> Result<Action, RuntimeError> { ) -> Result<Action, RuntimeError> {
for ((identifier, _), value) in self.parameters.into_iter().zip(arguments.into_iter()) { for ((identifier, _), value) in self.parameters.into_iter().zip(arguments.into_iter()) {
context.set_value(identifier.clone(), value)?; context.set_value(identifier.clone(), value)?;
} }
self.body.node.run(context, true) self.body.item.run(context, clear_variables)
} }
} }