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/name_analysis.cc | 98 +++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 54 deletions(-) (limited to 'boot/name_analysis.cc') diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index f932a5d..0d25039 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -21,31 +21,32 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { - symbol_error::symbol_error(const source_position position, payload_type payload) + declaration_error::declaration_error(const source_position position, payload_type payload) : error(position), payload(std::move(payload)) { } - std::string symbol_error::what() const + std::string declaration_error::what() const { - return std::visit([](const auto& pay) -> std::string { - using T = std::decay_t; + return std::visit([](const auto& payload) -> std::string { + using T = std::decay_t; + if constexpr (std::is_same_v) { - return "Type '" + pay.name + "' not declared"; + return "Type '" + payload.name + "' not declared"; } else if constexpr (std::is_same_v) { - return "Local symbol '" + pay.name + "' cannot be exported"; + return "Local symbol '" + payload.name + "' cannot be exported"; } else if constexpr (std::is_same_v) { - return "Symbol '" + pay.name + "' has been already defined"; + return "Symbol '" + payload.name + "' has been already defined"; } - }, payload); + }, this->payload); } - std::optional> symbol_error::note() const + std::optional> declaration_error::note() const { if (const auto *redef = std::get_if(&payload)) { @@ -240,16 +241,9 @@ namespace elna::boot return lookup_field(record->base, field_name); } } - else if (auto array = resolved_type.get()) - { - if (auto field = lookup_pointer_like_field(field_name, array->base)) - { - return field.value(); - } - } - else if (auto slice = resolved_type.get()) + else if (auto range_base = get_range_base_type(resolved_type)) { - if (auto field = lookup_pointer_like_field(field_name, slice->base)) + if (auto field = lookup_pointer_like_field(field_name, range_base)) { return field.value(); } @@ -388,8 +382,8 @@ namespace elna::boot } else { - add_error(expression->base.value().position(), - symbol_error::undeclared{.name = expression->base.value().name()}); + add_error(expression->base.value().position(), + declaration_error::undeclared{.name = expression->base.value().name()}); this->current_type = type(); return; } @@ -417,8 +411,8 @@ namespace elna::boot } else { - add_error(expression->type_name.position(), - symbol_error::undeclared{.name = expression->type_name.name()}); + add_error(expression->type_name.position(), + declaration_error::undeclared{.name = expression->type_name.name()}); } for (const field_initializer& initializer : expression->field_initializers) { @@ -426,8 +420,8 @@ namespace elna::boot if (!expression->type_decoration.empty() && lookup_field(expression->type_decoration, initializer.name()).empty()) { - add_error(initializer.id().position(), - symbol_error::undeclared{.name = initializer.id().name()}); + add_error(initializer.id().position(), + declaration_error::undeclared{.name = initializer.id().name()}); } } } @@ -509,8 +503,8 @@ for (const auto& member : expression->members) if (!this->bag.enter(name, variable_symbol)) { auto original = this->bag.lookup(name); - add_error(position, - symbol_error::redefinition{.name = name, .original = original->position}); + add_error(position, + declaration_error::redefinition{.name = name, .original = original->position}); } return variable_symbol; } @@ -654,8 +648,8 @@ for (const auto& member : expression->members) } else { - add_error(trait->name.position(), - symbol_error::undeclared{.name = trait->name.name()}); + add_error(trait->name.position(), + declaration_error::undeclared{.name = trait->name.name()}); } } @@ -711,18 +705,12 @@ for (const auto& member : expression->members) walking_visitor::visit(expression); auto resolved_base = resolve_underlying_type(expression->base().type_decoration); - if (auto array = resolved_base.get()) - { - expression->type_decoration = array->base; - } - else if (auto slice = resolved_base.get()) - { - expression->type_decoration = slice->base; - } - // Elements of a constant array are constant themselves since a static - // array is a holistic type. - if (!expression->type_decoration.empty()) + if (auto range_base = get_range_base_type(resolved_base)) { + expression->type_decoration = range_base; + + // Elements of a constant array are constant themselves since a static + // array is a holistic type. expression->type_decoration = qualify_member_type(expression->type_decoration, expression->base().type_decoration); } @@ -763,18 +751,20 @@ for (const auto& member : expression->members) void name_analysis_visitor::visit(for_statement *statement) { - statement->initial_value().accept(this); - const type control_variable_type = type(std::make_shared(this->current_type)); - auto initial_value_info = std::make_shared(control_variable_type, false); + statement->range().accept(this); + auto resolved_range = resolve_underlying_type(statement->range().type_decoration); + const type control_variable_base_type = get_range_base_type(resolved_range); + const type control_variable_pointer_type = type(std::make_shared(control_variable_base_type)); + this->current_type = type(std::make_shared(control_variable_pointer_type)); - statement->final_value().accept(this); - if (statement->step != nullptr) - { - statement->step->accept(this); - } statement->symbols = this->bag.enter(); - this->bag.enter(statement->control_variable.name(), initial_value_info); + register_variable(statement->control_variable.name(), false, statement->control_variable.position()); + if (statement->counter != nullptr) + { + this->current_type = lookup_primitive_type("Word"); + register_variable(statement->counter->name(), false, statement->counter->position()); + } for (auto *body_statement : statement->body) { body_statement->accept(this); @@ -813,8 +803,8 @@ for (const auto& member : expression->members) } else { - add_error(expression->position(), - symbol_error::undeclared{.name = expression->name}); + add_error(expression->position(), + declaration_error::undeclared{.name = expression->name}); } } @@ -890,8 +880,8 @@ for (const auto& member : expression->members) if (!this->unresolved.insert({ type_identifier, std::make_shared(type_identifier) }).second) { - add_error(declaration->identifier.id().position(), - symbol_error::redefinition{.name = declaration->identifier.id().name(), + add_error(declaration->identifier.id().position(), + declaration_error::redefinition{.name = declaration->identifier.id().name(), .original = declaration->position()}); } } @@ -914,8 +904,8 @@ for (const auto& member : expression->members) { if (variable_identifier.exported()) { - add_error(variable_identifier.id().position(), - symbol_error::local_export{.name = variable_identifier.id().name()}); + add_error(variable_identifier.id().position(), + declaration_error::local_export{.name = variable_identifier.id().name()}); } } } -- cgit v1.2.3