Fix if/else bug

This commit is contained in:
Jeff 2024-06-24 02:18:58 -04:00
parent fbcb28ce24
commit b6b7a61727
4 changed files with 30 additions and 44 deletions

View File

@ -195,7 +195,6 @@ where
manage_memory: bool,
) -> Result<Option<Evaluation>, RuntimeError> {
self.context.set_parent(context.clone())?;
self.function.call(&self.context, manage_memory)
}

View File

@ -116,7 +116,7 @@ impl AbstractNode for FunctionCall {
));
};
let function_context = Context::new(None);
let function_context = Context::new(Some(context.clone()));
if let Some(type_parameters) = function.type_parameters() {
for identifier in type_parameters {

View File

@ -62,36 +62,7 @@ impl AbstractNode for IfElse {
self.if_expression.position(),
));
};
let expected_type = if let Some(r#type) = self.if_block.node.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(self.if_block.position));
};
if let Type::Boolean = if_expression_type {
if let Some(else_block) = &self.else_block {
else_block.node.validate(context, manage_memory)?;
let actual_type = if let Some(r#type) = else_block.node.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(else_block.position));
};
expected_type.check(&actual_type).map_err(|conflict| {
ValidationError::TypeCheck {
conflict,
actual_position: else_block.node.last_statement().position(),
expected_position: Some(self.if_block.node.first_statement().position()),
}
})?;
}
} else {
return Err(ValidationError::ExpectedBoolean {
actual: if_expression_type,
position: self.if_expression.position(),
});
}
let if_block_type = self.if_block.node.expected_type(context)?;
if let Some(else_ifs) = &self.else_ifs {
for (expression, block) in else_ifs {
@ -100,19 +71,17 @@ impl AbstractNode for IfElse {
if let Some(Type::Boolean) = expression_type {
block.node.validate(context, manage_memory)?;
let actual_type = if let Some(r#type) = block.node.expected_type(context)? {
r#type
} else {
return Err(ValidationError::ExpectedExpression(block.position));
};
let else_if_block_type = block.node.expected_type(context)?;
expected_type.check(&actual_type).map_err(|conflict| {
ValidationError::TypeCheck {
if let (Some(expected), Some(actual)) = (&if_block_type, else_if_block_type) {
expected
.check(&actual)
.map_err(|conflict| ValidationError::TypeCheck {
conflict,
actual_position: self.if_block.node.last_statement().position(),
expected_position: Some(self.if_expression.position()),
}
})?;
}
} else {
return Err(ValidationError::ExpectedBoolean {
actual: if_expression_type,
@ -122,6 +91,22 @@ impl AbstractNode for IfElse {
}
}
if let Some(block) = &self.else_block {
block.node.validate(context, manage_memory)?;
let else_if_block_type = block.node.expected_type(context)?;
if let (Some(expected), Some(actual)) = (if_block_type, else_if_block_type) {
expected
.check(&actual)
.map_err(|conflict| ValidationError::TypeCheck {
conflict,
actual_position: self.if_block.node.last_statement().position(),
expected_position: Some(self.if_expression.position()),
})?;
}
}
Ok(())
}

View File

@ -83,6 +83,8 @@ impl AbstractNode for ValueNode {
context_template,
..
}) => {
context_template.set_parent(outer_context.clone())?;
if let Some(type_parameters) = type_parameters {
for identifier in type_parameters {
context_template.set_type(