aboutsummaryrefslogtreecommitdiff
path: root/boot/name_analysis.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-24 03:11:32 +0200
committerEugen Wissner <belka@caraus.de>2026-07-24 03:11:32 +0200
commitbb4f474cb2247e0e314beab5d7d72e673ff4e8b6 (patch)
tree4809b414bffa8d422ef8c1b6fe65dcdd4dce65d8 /boot/name_analysis.cc
parent275fa4bff6d153019b6914fed7127a7d919ca177 (diff)
downloadelna-bb4f474cb2247e0e314beab5d7d72e673ff4e8b6.tar.gz
Implement a repeat loop
Diffstat (limited to 'boot/name_analysis.cc')
-rw-r--r--boot/name_analysis.cc98
1 files changed, 44 insertions, 54 deletions
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<decltype(pay)>;
+ return std::visit([](const auto& payload) -> std::string {
+ using T = std::decay_t<decltype(payload)>;
+
if constexpr (std::is_same_v<T, undeclared>)
{
- return "Type '" + pay.name + "' not declared";
+ return "Type '" + payload.name + "' not declared";
}
else if constexpr (std::is_same_v<T, local_export>)
{
- return "Local symbol '" + pay.name + "' cannot be exported";
+ return "Local symbol '" + payload.name + "' cannot be exported";
}
else if constexpr (std::is_same_v<T, redefinition>)
{
- return "Symbol '" + pay.name + "' has been already defined";
+ return "Symbol '" + payload.name + "' has been already defined";
}
- }, payload);
+ }, this->payload);
}
- std::optional<std::pair<std::string, source_position>> symbol_error::note() const
+ std::optional<std::pair<std::string, source_position>> declaration_error::note() const
{
if (const auto *redef = std::get_if<redefinition>(&payload))
{
@@ -240,16 +241,9 @@ namespace elna::boot
return lookup_field(record->base, field_name);
}
}
- else if (auto array = resolved_type.get<array_type>())
- {
- if (auto field = lookup_pointer_like_field(field_name, array->base))
- {
- return field.value();
- }
- }
- else if (auto slice = resolved_type.get<slice_type>())
+ 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<symbol_error>(expression->base.value().position(),
- symbol_error::undeclared{.name = expression->base.value().name()});
+ add_error<declaration_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<symbol_error>(expression->type_name.position(),
- symbol_error::undeclared{.name = expression->type_name.name()});
+ add_error<declaration_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<symbol_error>(initializer.id().position(),
- symbol_error::undeclared{.name = initializer.id().name()});
+ add_error<declaration_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<symbol_error>(position,
- symbol_error::redefinition{.name = name, .original = original->position});
+ add_error<declaration_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<symbol_error>(trait->name.position(),
- symbol_error::undeclared{.name = trait->name.name()});
+ add_error<declaration_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<array_type>())
- {
- expression->type_decoration = array->base;
- }
- else if (auto slice = resolved_base.get<slice_type>())
- {
- 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<constant_type>(this->current_type));
- auto initial_value_info = std::make_shared<variable_info>(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<pointer_type>(control_variable_base_type));
+ this->current_type = type(std::make_shared<constant_type>(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<symbol_error>(expression->position(),
- symbol_error::undeclared{.name = expression->name});
+ add_error<declaration_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<alias_type>(type_identifier) }).second)
{
- add_error<symbol_error>(declaration->identifier.id().position(),
- symbol_error::redefinition{.name = declaration->identifier.id().name(),
+ add_error<declaration_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<symbol_error>(variable_identifier.id().position(),
- symbol_error::local_export{.name = variable_identifier.id().name()});
+ add_error<declaration_error>(variable_identifier.id().position(),
+ declaration_error::local_export{.name = variable_identifier.id().name()});
}
}
}