aboutsummaryrefslogtreecommitdiff
path: root/boot/type_check.cc
diff options
context:
space:
mode:
Diffstat (limited to 'boot/type_check.cc')
-rw-r--r--boot/type_check.cc28
1 files changed, 18 insertions, 10 deletions
diff --git a/boot/type_check.cc b/boot/type_check.cc
index 9bab537..c88a7d1 100644
--- a/boot/type_check.cc
+++ b/boot/type_check.cc
@@ -199,6 +199,18 @@ namespace elna::boot
return false;
}
+ bool type_analysis_visitor::is_equality_compatible(const type& left, const type& right)
+ {
+ auto resolved_left = resolve_underlying_type(left);
+ auto resolved_right = resolve_underlying_type(right);
+
+ return resolved_left == resolved_right
+ || (is_primitive_type(resolved_left, "Pointer") && is_any_pointer_type(resolved_right))
+ || (is_any_pointer_type(resolved_left) && is_primitive_type(resolved_right, "Pointer"))
+ || (resolved_left.get<slice_type>() && resolved_right.get<slice_type>())
+ || (resolved_left.get<record_type>() && resolved_right.get<record_type>());
+ }
+
bool type_analysis_visitor::check_unresolved_symbol(const std::shared_ptr<alias_type>& alias,
std::vector<std::string>& alias_path)
{
@@ -462,8 +474,7 @@ namespace elna::boot
auto variable_symbol = this->bag.lookup(variable_identifier.name())->is_variable();
if (!is_assignable_from(variable_symbol->symbol, declaration->initializer->type_decoration))
{
- add_error<type_mismatch_error>(
- declaration->initializer->position(),
+ add_error<type_mismatch_error>(declaration->initializer->position(),
variable_symbol->symbol, declaration->initializer->type_decoration);
}
}
@@ -478,10 +489,11 @@ namespace elna::boot
{
for (const expression *case_label : case_block.labels)
{
- if (!is_assignable_from(condition_type, case_label->type_decoration))
+ if (!is_equality_compatible(condition_type, case_label->type_decoration))
{
- add_error<type_mismatch_error>(
- case_label->position(), condition_type, case_label->type_decoration);
+ add_error<binary_operation_error>(
+ case_label->position(), condition_type,
+ case_label->type_decoration, binary_operator::equals);
}
}
}
@@ -836,11 +848,7 @@ namespace elna::boot
break;
case equals:
case not_equals:
- valid = lhs_resolved == rhs_resolved
- || (is_primitive_type(lhs_resolved, "Pointer") && is_any_pointer_type(rhs_resolved))
- || (is_any_pointer_type(lhs_resolved) && is_primitive_type(rhs_resolved, "Pointer"))
- || (lhs_resolved.get<slice_type>() && rhs_resolved.get<slice_type>())
- || (lhs_resolved.get<record_type>() && rhs_resolved.get<record_type>());
+ valid = is_equality_compatible(lhs_resolved, rhs_resolved);
break;
case shift_left:
case shift_right: