Fix if/else bug
This commit is contained in:
parent
fbcb28ce24
commit
b6b7a61727
@ -195,7 +195,6 @@ where
|
|||||||
manage_memory: bool,
|
manage_memory: bool,
|
||||||
) -> Result<Option<Evaluation>, RuntimeError> {
|
) -> Result<Option<Evaluation>, RuntimeError> {
|
||||||
self.context.set_parent(context.clone())?;
|
self.context.set_parent(context.clone())?;
|
||||||
|
|
||||||
self.function.call(&self.context, manage_memory)
|
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() {
|
if let Some(type_parameters) = function.type_parameters() {
|
||||||
for identifier in type_parameters {
|
for identifier in type_parameters {
|
||||||
|
@ -62,36 +62,7 @@ impl AbstractNode for IfElse {
|
|||||||
self.if_expression.position(),
|
self.if_expression.position(),
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
let expected_type = if let Some(r#type) = self.if_block.node.expected_type(context)? {
|
let if_block_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(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(else_ifs) = &self.else_ifs {
|
if let Some(else_ifs) = &self.else_ifs {
|
||||||
for (expression, block) in else_ifs {
|
for (expression, block) in else_ifs {
|
||||||
@ -100,19 +71,17 @@ impl AbstractNode for IfElse {
|
|||||||
if let Some(Type::Boolean) = expression_type {
|
if let Some(Type::Boolean) = expression_type {
|
||||||
block.node.validate(context, manage_memory)?;
|
block.node.validate(context, manage_memory)?;
|
||||||
|
|
||||||
let actual_type = if let Some(r#type) = block.node.expected_type(context)? {
|
let else_if_block_type = block.node.expected_type(context)?;
|
||||||
r#type
|
|
||||||
} else {
|
|
||||||
return Err(ValidationError::ExpectedExpression(block.position));
|
|
||||||
};
|
|
||||||
|
|
||||||
expected_type.check(&actual_type).map_err(|conflict| {
|
if let (Some(expected), Some(actual)) = (&if_block_type, else_if_block_type) {
|
||||||
ValidationError::TypeCheck {
|
expected
|
||||||
|
.check(&actual)
|
||||||
|
.map_err(|conflict| ValidationError::TypeCheck {
|
||||||
conflict,
|
conflict,
|
||||||
actual_position: self.if_block.node.last_statement().position(),
|
actual_position: self.if_block.node.last_statement().position(),
|
||||||
expected_position: Some(self.if_expression.position()),
|
expected_position: Some(self.if_expression.position()),
|
||||||
}
|
|
||||||
})?;
|
})?;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return Err(ValidationError::ExpectedBoolean {
|
return Err(ValidationError::ExpectedBoolean {
|
||||||
actual: if_expression_type,
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,6 +83,8 @@ impl AbstractNode for ValueNode {
|
|||||||
context_template,
|
context_template,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
|
context_template.set_parent(outer_context.clone())?;
|
||||||
|
|
||||||
if let Some(type_parameters) = type_parameters {
|
if let Some(type_parameters) = type_parameters {
|
||||||
for identifier in type_parameters {
|
for identifier in type_parameters {
|
||||||
context_template.set_type(
|
context_template.set_type(
|
||||||
|
Loading…
Reference in New Issue
Block a user