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.cc50
1 files changed, 50 insertions, 0 deletions
diff --git a/boot/type_check.cc b/boot/type_check.cc
index 7989925..1689e65 100644
--- a/boot/type_check.cc
+++ b/boot/type_check.cc
@@ -465,6 +465,42 @@ namespace elna::boot
}
}
+ void type_analysis_visitor::visit(for_statement *statement)
+ {
+ statement->initial_value().accept(this);
+ type const initial_type = resolve_underlying_type(statement->initial_value().type_decoration);
+
+ if (!is_integral_type(initial_type))
+ {
+ add_error<for_loop_type_error>(
+ statement->initial_value().position(),
+ statement->initial_value().type_decoration);
+ }
+ statement->final_value().accept(this);
+ if (!is_assignable_from(initial_type, statement->final_value().type_decoration))
+ {
+ add_error<type_mismatch_error>(
+ statement->final_value().position(),
+ initial_type, statement->final_value().type_decoration);
+ }
+ if (statement->step != nullptr)
+ {
+ statement->step->accept(this);
+ if (!is_assignable_from(initial_type, statement->step->type_decoration))
+ {
+ add_error<type_mismatch_error>(
+ statement->step->position(),
+ initial_type, statement->step->type_decoration);
+ }
+ }
+ this->bag.enter(statement->symbols);
+ for (auto *body_statement : statement->body)
+ {
+ body_statement->accept(this);
+ }
+ this->bag.leave();
+ }
+
void type_analysis_visitor::visit(type_declaration *declaration)
{
std::vector<std::string> alias_path;
@@ -649,6 +685,18 @@ namespace elna::boot
}
}
+ for_loop_type_error::for_loop_type_error(const source_position position,
+ type actual)
+ : error(position), actual(std::move(actual))
+ {
+ }
+
+ std::string for_loop_type_error::what() const
+ {
+ return "for-loop variable must be Int or Word, but got '"
+ + actual.to_string() + "'";
+ }
+
binary_operation_error::binary_operation_error(const source_position position,
type left, type right, binary_operator operation)
: error(position), left(std::move(left)), right(std::move(right)), op(operation)
@@ -749,6 +797,8 @@ namespace elna::boot
valid = is_integral_type(lhs_resolved)
&& is_primitive_type(rhs_resolved, "Word");
break;
+ default:
+ __builtin_unreachable();
}
if (!valid)
{