From bb4f474cb2247e0e314beab5d7d72e673ff4e8b6 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 24 Jul 2026 03:11:32 +0200 Subject: Implement a repeat loop --- boot/type_check.cc | 63 +++++++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 41 deletions(-) (limited to 'boot/type_check.cc') diff --git a/boot/type_check.cc b/boot/type_check.cc index 1689e65..761c4b2 100644 --- a/boot/type_check.cc +++ b/boot/type_check.cc @@ -93,14 +93,23 @@ namespace elna::boot + "' is expected to return, but does not have a return statement"; } - base_type_error::base_type_error(type actual, const source_position position) - : error(position), actual(std::move(actual)) + type_kind_error::type_kind_error(const source_position position, kind type_kind, const type& actual) + : error(position), type_kind(type_kind), actual(actual) { } - std::string base_type_error::what() const + std::string type_kind_error::what() const { - return "'" + actual.to_string() + "' is not a record type"; + switch (this->type_kind) + { + case kind::record_base: + return "'" + this->actual.to_string() + "' is not a record type"; + case kind::for_loop: + return "for-loop variable must be an array or a slice, got '" + + this->actual.to_string() + "'"; + default: + __builtin_unreachable(); + } } argument_count_error::argument_count_error(std::size_t expected, std::size_t actual, @@ -467,31 +476,13 @@ 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); + statement->range().accept(this); + auto resolved_range = resolve_underlying_type(statement->range().type_decoration); - if (!is_integral_type(initial_type)) - { - add_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( - statement->final_value().position(), - initial_type, statement->final_value().type_decoration); - } - if (statement->step != nullptr) + if (!get_range_base_type(resolved_range)) { - statement->step->accept(this); - if (!is_assignable_from(initial_type, statement->step->type_decoration)) - { - add_error( - statement->step->position(), - initial_type, statement->step->type_decoration); - } + add_error(statement->range().position(), type_kind_error::kind::for_loop, + statement->range().type_decoration); } this->bag.enter(statement->symbols); for (auto *body_statement : statement->body) @@ -523,14 +514,16 @@ namespace elna::boot auto const base_symbol = this->bag.lookup(expression->base.value().name()); if (base_symbol == nullptr || base_symbol->is_type() == nullptr) { - add_error(type(), expression->position()); + add_error(expression->position(), + type_kind_error::kind::record_base, type()); } else { type const base_type = resolve_underlying_type(base_symbol->is_type()->symbol); if (base_type.get() == nullptr) { - add_error(base_type, expression->position()); + add_error(expression->position(), + type_kind_error::kind::record_base, base_type); } } } @@ -685,18 +678,6 @@ 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) -- cgit v1.2.3