Fix if/else bug
This commit is contained in:
parent
fbcb28ce24
commit
b6b7a61727
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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(())
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user