diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-09-27 11:23:17 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-09-27 11:23:17 +0200 |
| commit | c57a24b9fe37e233e7ec0e2e65405738d9c09c6e (patch) | |
| tree | 99b5f4dc22d27d8159c3ba76f2cf3a455ed37fb6 /boot | |
| parent | d048b633dd02014f8bff1b512ce4d5ae2b8b7903 (diff) | |
| download | elna-c57a24b9fe37e233e7ec0e2e65405738d9c09c6e.tar.gz | |
Reuse container visiting logic
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/ast.cc | 93 | ||||
| -rw-r--r-- | boot/materialization.cc | 20 | ||||
| -rw-r--r-- | boot/name_analysis.cc | 55 | ||||
| -rw-r--r-- | boot/type_check.cc | 25 | ||||
| -rw-r--r-- | boot/validation.cc | 27 |
5 files changed, 77 insertions, 143 deletions
diff --git a/boot/ast.cc b/boot/ast.cc index cd2ac55..87d6313 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -243,7 +243,11 @@ namespace elna::boot } if (declaration->body.has_value()) { - traverse_body(this, declaration->body.value()); + traverse_block(this, declaration->body.value()); + if (declaration->body.value().return_expression != nullptr) + { + declaration->body.value().return_expression->accept(this); + } } } @@ -253,66 +257,54 @@ namespace elna::boot statement->rvalue().accept(this); } - void walking_visitor::traverse_block(block& body) - { - for (variable_declaration *const variable : body.variables) - { - variable->accept(this); - } - for (statement *const body_statement : body.statements) - { - body_statement->accept(this); - } - } - void walking_visitor::visit(if_statement *statement) { statement->branch().prerequisite().accept(this); - traverse_block(statement->branch().body); + traverse_block(this, statement->branch().body); for (conditional_statements& branch : statement->branches) { branch.prerequisite().accept(this); - traverse_block(branch.body); + traverse_block(this, branch.body); } if (statement->alternative != nullptr) { - traverse_block(*statement->alternative); + traverse_block(this, *statement->alternative); } } void walking_visitor::visit(while_statement *statement) { statement->branch().prerequisite().accept(this); - traverse_block(statement->branch().body); + traverse_block(this, statement->branch().body); for (conditional_statements& branch : statement->branches) { branch.prerequisite().accept(this); - traverse_block(branch.body); + traverse_block(this, branch.body); } } void walking_visitor::visit(repeat_statement *statement) { statement->condition().accept(this); - traverse_block(statement->body); + traverse_block(this, statement->body); } void walking_visitor::visit(for_statement *statement) { statement->range().accept(this); - traverse_block(statement->body); + traverse_block(this, statement->body); } void walking_visitor::visit(defer_statement *statement) { - traverse_block(statement->body); + traverse_block(this, statement->body); } void walking_visitor::visit(block_statement *statement) { - traverse_block(statement->body); + traverse_block(this, statement->body); } void walking_visitor::visit(break_statement *) @@ -326,50 +318,30 @@ namespace elna::boot void walking_visitor::visit(case_statement *statement) { statement->condition().accept(this); - for (switch_case& case_block : statement->cases) + for (const switch_case& case_block : statement->cases) { - for (expression *case_label : case_block.labels) - { - case_label->accept(this); - } - traverse_block(case_block.body); + visit_all(this, case_block.labels); + traverse_block(this, case_block.body); } if (statement->alternative != nullptr) { - traverse_block(*statement->alternative); + traverse_block(this, *statement->alternative); } } void walking_visitor::visit(procedure_call *call) { call->callable().accept(this); - for (expression *argument : call->arguments) - { - argument->accept(this); - } + visit_all(this, call->arguments); } void walking_visitor::visit(unit *unit) { - for (import_declaration *_import : unit->imports) - { - _import->accept(this); - } - for (declaration *const unit_declaration : unit->declarations) - { - unit_declaration->accept(this); - } + visit_all(this, unit->imports); + visit_all(this, unit->declarations); if (unit->entry_point.has_value()) { - visit_entry_point(unit); - } - } - - void walking_visitor::visit_entry_point(unit *unit) - { - for (statement *body_statement : unit->entry_point.value()) - { - body_statement->accept(this); + visit_all(this, unit->entry_point.value()); } } @@ -452,10 +424,7 @@ namespace elna::boot void walking_visitor::visit(array_constructor_expression *expression) { - for (auto *element : expression->elements) - { - element->accept(this); - } + visit_all(this, expression->elements); } void walking_visitor::visit(slicing_expression *expression) @@ -1115,20 +1084,10 @@ namespace elna::boot delete this->return_expression; } - void traverse_body(parser_visitor *visitor, const procedure_body& body) + void traverse_block(parser_visitor *visitor, const block& body) { - for (variable_declaration *variable : body.variables) - { - variable->accept(visitor); - } - for (statement *body_statement : body.statements) - { - body_statement->accept(visitor); - } - if (body.return_expression != nullptr) - { - body.return_expression->accept(visitor); - } + visit_all(visitor, body.variables); + visit_all(visitor, body.statements); } unit::unit(const source_position position, diff --git a/boot/materialization.cc b/boot/materialization.cc index 0ca81aa..6eea0d1 100644 --- a/boot/materialization.cc +++ b/boot/materialization.cc @@ -48,6 +48,19 @@ namespace elna::boot { } + void materialization_visitor::visit(unit *unit) + { + visit_all(this, unit->imports); + visit_all(this, unit->declarations); + + this->in_global_scope = false; + if (unit->entry_point.has_value()) + { + visit_all(this, unit->entry_point.value()); + } + this->in_global_scope = true; + } + void materialization_visitor::visit(procedure_declaration *declaration) { this->in_global_scope = false; @@ -144,11 +157,4 @@ namespace elna::boot materialization_error::kind::real_overflow); } } - - void materialization_visitor::visit_entry_point(unit *unit) - { - this->in_global_scope = false; - walking_visitor::visit_entry_point(unit); - this->in_global_scope = true; - } } diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 2ee3da1..20f08ee 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -284,10 +284,7 @@ namespace elna::boot void forward_declaration_visitor::visit(unit *unit) { - for (auto *const unit_declaration: unit->declarations) - { - unit_declaration->accept(this); - } + visit_all(this, unit->declarations); } void forward_declaration_visitor::visit(type_declaration *declaration) @@ -733,22 +730,10 @@ namespace elna::boot statement->rvalue().accept(this); } - void resolving_visitor::traverse_block(block& body) - { - for (variable_declaration *const variable : body.variables) - { - variable->accept(this); - } - for (statement *const body_statement : body.statements) - { - body_statement->accept(this); - } - } - void resolving_visitor::visit_block(block& body) { body.symbols = this->bag.enter(); - traverse_block(body); + traverse_block(this, body); this->bag.leave(); } @@ -813,7 +798,7 @@ namespace elna::boot add_error<symbol_declaration_error>(statement->name.position(), label_name, original_definition); } - traverse_block(statement->body); + traverse_block(this, statement->body); this->bag.leave(); } @@ -852,10 +837,7 @@ namespace elna::boot statement->condition().accept(this); for (switch_case& case_block : statement->cases) { - for (expression *case_label : case_block.labels) - { - case_label->accept(this); - } + visit_all(this, case_block.labels); visit_block(case_block.body); } if (statement->alternative != nullptr) @@ -871,10 +853,7 @@ namespace elna::boot { call->type_decoration = procedure->return_type.proper_type; } - for (expression *const argument : call->arguments) - { - argument->accept(this); - } + visit_all(this, call->arguments); this->current_type = type(); } @@ -918,11 +897,9 @@ namespace elna::boot void resolving_visitor::visit(array_constructor_expression *expression) { - for (auto *const element : expression->elements) - { - element->accept(this); - } + visit_all(this, expression->elements); const type element_type = expression->elements.front()->type_decoration; + expression->type_decoration = type(std::make_shared<array_type>(element_type, expression->elements.size())); this->current_type = type(); @@ -1347,10 +1324,7 @@ namespace elna::boot void declaration_visitor::visit(unit *unit) { - for (declaration *const unit_declaration : unit->declarations) - { - unit_declaration->accept(this); - } + visit_all(this, unit->declarations); if (unit->entry_point.has_value()) { const type word8_primitive = lookup_primitive_type("Word8"); @@ -1540,10 +1514,7 @@ namespace elna::boot const std::shared_ptr<procedure_info> info = this->bag.lookup("")->is_procedure(); this->bag.enter(info->scope); - for (statement *body_statement : unit->entry_point.value()) - { - body_statement->accept(this); - } + visit_all(this, unit->entry_point.value()); this->bag.leave(); } } @@ -1590,7 +1561,11 @@ namespace elna::boot declaration->body->symbols = info->scope; this->bag.enter(info->scope); - traverse_body(this, declaration->body.value()); + traverse_block(this, declaration->body.value()); + if (declaration->body.value().return_expression != nullptr) + { + declaration->body.value().return_expression->accept(this); + } this->bag.leave(); } } @@ -1612,7 +1587,7 @@ namespace elna::boot register_variable(statement->counter->name(), lookup_primitive_type("Word"), statement->counter->position()); } - traverse_block(statement->body); + traverse_block(this, statement->body); this->bag.leave(); } } diff --git a/boot/type_check.cc b/boot/type_check.cc index 71fd8ab..15a01dc 100644 --- a/boot/type_check.cc +++ b/boot/type_check.cc @@ -800,13 +800,19 @@ namespace elna::boot } } - void type_analysis_visitor::visit_entry_point(unit *unit) + void type_analysis_visitor::visit(unit *unit) { - this->current_procedure = this->bag.lookup("")->is_procedure(); - this->bag.enter(this->current_procedure->scope); - walking_visitor::visit_entry_point(unit); - this->bag.leave(); - this->current_procedure.reset(); + visit_all(this, unit->imports); + visit_all(this, unit->declarations); + + if (unit->entry_point.has_value()) + { + this->current_procedure = this->bag.lookup("")->is_procedure(); + this->bag.enter(this->current_procedure->scope); + visit_all(this, unit->entry_point.value()); + this->bag.leave(); + this->current_procedure.reset(); + } } void type_analysis_visitor::visit(variable_declaration *declaration) @@ -885,7 +891,7 @@ namespace elna::boot void type_analysis_visitor::traverse_block(block& body) { this->bag.enter(body.symbols); - walking_visitor::traverse_block(body); + boot::traverse_block(this, body); this->bag.leave(); } @@ -1409,10 +1415,7 @@ namespace elna::boot { // Inference reads the argument types, so they are decorated // before the parameter types they will be checked against exist. - for (expression *const argument : call->arguments) - { - argument->accept(this); - } + visit_all(this, call->arguments); inferred = procedure; callable_type = infer_call(*call, *reference, *procedure); diff --git a/boot/validation.cc b/boot/validation.cc index 0c9259e..4539633 100644 --- a/boot/validation.cc +++ b/boot/validation.cc @@ -41,34 +41,27 @@ namespace elna::boot { } - void validation_visitor::visit_statements(const std::vector<statement *>& statements) + void validation_visitor::visit_statements(const std::vector<statement *>& statements, + const std::shared_ptr<symbol_table>& scope) { - for (statement *const body_statement : statements) - { - body_statement->accept(this); - } + this->bag.enter(scope); + visit_all(this, statements); + this->bag.leave(); } void validation_visitor::visit_block(const block& body) { - this->bag.enter(body.symbols); - visit_statements(body.statements); - this->bag.leave(); + visit_statements(body.statements, body.symbols); } void validation_visitor::visit(unit *unit) { - for (declaration *unit_declaration : unit->declarations) - { - unit_declaration->accept(this); - } + visit_all(this, unit->declarations); if (unit->entry_point.has_value()) { const std::shared_ptr<procedure_info> entry_point = this->bag.lookup("")->is_procedure(); - this->bag.enter(entry_point->scope); - visit_statements(unit->entry_point.value()); - this->bag.leave(); + visit_statements(unit->entry_point.value(), entry_point->scope); } } @@ -87,9 +80,7 @@ namespace elna::boot const std::shared_ptr<procedure_info> procedure = this->bag.lookup(declaration->identifier.name())->is_procedure(); - this->bag.enter(procedure->scope); - visit_statements(declaration->body.value().statements); - this->bag.leave(); + visit_statements(declaration->body.value().statements, procedure->scope); } } |
