aboutsummaryrefslogtreecommitdiff
path: root/boot/name_analysis.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-09-18 12:19:13 +0200
committerEugen Wissner <belka@caraus.de>2026-09-18 12:19:13 +0200
commitdc9d03915c4b169fec749081b45d56f722105813 (patch)
tree0a0719bc95f942b675fb52865d9c5bac9e105767 /boot/name_analysis.cc
parentb575036fe804f14b78da74897a74b010cc94f730 (diff)
downloadelna-dc9d03915c4b169fec749081b45d56f722105813.tar.gz
Allow block-local variables
Diffstat (limited to 'boot/name_analysis.cc')
-rw-r--r--boot/name_analysis.cc86
1 files changed, 37 insertions, 49 deletions
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc
index 9ba030c..18aaca2 100644
--- a/boot/name_analysis.cc
+++ b/boot/name_analysis.cc
@@ -733,65 +733,63 @@ namespace elna::boot
statement->rvalue().accept(this);
}
- void resolving_visitor::visit(if_statement *statement)
+ void resolving_visitor::traverse_block(block& body)
{
- statement->branch().prerequisite().accept(this);
- for (auto *branch_statement : statement->branch().statements)
+ for (variable_declaration *const variable : body.variables)
+ {
+ variable->accept(this);
+ }
+ for (statement *const body_statement : body.statements)
{
- branch_statement->accept(this);
+ body_statement->accept(this);
}
+ }
+
+ void resolving_visitor::visit_block(block& body)
+ {
+ body.symbols = this->bag.enter();
+ traverse_block(body);
+ this->bag.leave();
+ }
+
+ void resolving_visitor::visit(if_statement *statement)
+ {
+ statement->branch().prerequisite().accept(this);
+ visit_block(statement->branch().body);
+
for (conditional_statements *branch : statement->branches)
{
branch->prerequisite().accept(this);
-
- for (auto *branch_statement : branch->statements)
- {
- branch_statement->accept(this);
- }
+ visit_block(branch->body);
}
if (statement->alternative != nullptr)
{
- for (auto *branch_statement : *statement->alternative)
- {
- branch_statement->accept(this);
- }
+ visit_block(*statement->alternative);
}
}
void resolving_visitor::visit(while_statement *statement)
{
statement->branch().prerequisite().accept(this);
- for (auto *branch_statement : statement->branch().statements)
- {
- branch_statement->accept(this);
- }
+ visit_block(statement->branch().body);
+
for (conditional_statements *branch : statement->branches)
{
branch->prerequisite().accept(this);
-
- for (auto *branch_statement : branch->statements)
- {
- branch_statement->accept(this);
- }
+ visit_block(branch->body);
}
}
void resolving_visitor::visit(repeat_statement *statement)
{
statement->condition().accept(this);
- for (auto *body_statement : statement->body)
- {
- body_statement->accept(this);
- }
+ visit_block(statement->body);
}
void resolving_visitor::visit(defer_statement *statement)
{
++this->defer_depth;
- for (auto *body_statement : statement->statements)
- {
- body_statement->accept(this);
- }
+ visit_block(statement->body);
--this->defer_depth;
}
@@ -799,7 +797,7 @@ namespace elna::boot
{
const std::string& label_name = statement->name.name();
- this->bag.enter();
+ statement->body.symbols = this->bag.enter();
auto label_symbol = std::make_shared<label_info>(this->defer_depth);
label_symbol->position.emplace(statement->name.position());
@@ -815,10 +813,7 @@ namespace elna::boot
add_error<symbol_declaration_error>(statement->name.position(),
label_name, original_definition);
}
- for (auto *body_statement : statement->statements)
- {
- body_statement->accept(this);
- }
+ traverse_block(statement->body);
this->bag.leave();
}
@@ -855,23 +850,17 @@ namespace elna::boot
void resolving_visitor::visit(case_statement *statement)
{
statement->condition().accept(this);
- for (const switch_case& case_block : statement->cases)
+ for (switch_case& case_block : statement->cases)
{
for (expression *case_label : case_block.labels)
{
case_label->accept(this);
}
- for (auto *body_statement : case_block.statements)
- {
- body_statement->accept(this);
- }
+ visit_block(case_block.body);
}
if (statement->alternative != nullptr)
{
- for (auto *body_statement : *statement->alternative)
- {
- body_statement->accept(this);
- }
+ visit_block(*statement->alternative);
}
}
@@ -1552,6 +1541,7 @@ namespace elna::boot
{
const std::shared_ptr<procedure_info> info = this->bag.lookup("")->is_procedure();
+ unit->entry_point->symbols = info->scope;
this->bag.enter(info->scope);
traverse_body(this, unit->entry_point.value());
this->bag.leave();
@@ -1598,6 +1588,7 @@ namespace elna::boot
const std::shared_ptr<procedure_info> info =
this->bag.lookup(declaration->identifier.name())->is_procedure();
+ declaration->body->symbols = info->scope;
this->bag.enter(info->scope);
traverse_body(this, declaration->body.value());
this->bag.leave();
@@ -1612,7 +1603,7 @@ namespace elna::boot
const type control_variable_pointer_type = type(std::make_shared<pointer_type>(control_variable_base_type));
const type control_variable_const_type = type(std::make_shared<constant_type>(control_variable_pointer_type));
- statement->symbols = this->bag.enter();
+ statement->body.symbols = this->bag.enter();
register_variable(statement->control_variable.name(), control_variable_const_type,
statement->control_variable.position());
@@ -1621,10 +1612,7 @@ namespace elna::boot
register_variable(statement->counter->name(), lookup_primitive_type("Word"),
statement->counter->position());
}
- for (auto *body_statement : statement->body)
- {
- body_statement->accept(this);
- }
+ traverse_block(statement->body);
this->bag.leave();
}
}