diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-07-03 08:53:03 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-07-03 08:53:03 +0200 |
| commit | 4ad6052aa2816f8296e62569272e99fc0d2fd3c1 (patch) | |
| tree | e1002f3fc1d51929b6f7b77f4769eb84be4e9e82 /frontend/semantic.cc | |
| parent | 453332311ac2d569093f9ef62d41d13b0ce024c8 (diff) | |
| download | elna-4ad6052aa2816f8296e62569272e99fc0d2fd3c1.tar.gz | |
Merge variable_expression and named_type_expression
Diffstat (limited to 'frontend/semantic.cc')
| -rw-r--r-- | frontend/semantic.cc | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/frontend/semantic.cc b/frontend/semantic.cc index 36c75b8..ee18492 100644 --- a/frontend/semantic.cc +++ b/frontend/semantic.cc @@ -223,10 +223,20 @@ namespace elna::frontend { visit(static_cast<unit *>(program)); + this->bag.enter(); + auto variable_type = this->bag.lookup("Int")->is_type()->symbol; + this->bag.enter("count", std::make_shared<variable_info>(variable_type, false)); + + variable_type = this->bag.lookup("Char")->is_type()->symbol; + variable_type = type(std::make_shared<pointer_type>(variable_type)); + variable_type = type(std::make_shared<pointer_type>(variable_type)); + this->bag.enter("parameters", std::make_shared<variable_info>(variable_type, false)); + for (statement *const statement : program->body) { statement->accept(this); } + this->bag.leave(); } void name_analysis_visitor::visit(type_declaration *definition) @@ -239,23 +249,8 @@ namespace elna::frontend this->bag.enter(definition->identifier.name, info); } - void name_analysis_visitor::visit(named_type_expression *type_expression) + void name_analysis_visitor::visit(type_expression *) { - auto unresolved_alias = this->bag.declared(type_expression->name); - - if (unresolved_alias != nullptr) - { - this->current_type = type(unresolved_alias); - } - else if (auto from_symbol_table = this->bag.lookup(type_expression->name)) - { - this->current_type = from_symbol_table->is_type()->symbol; - } - else - { - add_error<undeclared_error>(type_expression->name, this->input_file, type_expression->position()); - this->current_type = type(); - } } void name_analysis_visitor::visit(pointer_type_expression *type_expression) @@ -267,7 +262,9 @@ namespace elna::frontend void name_analysis_visitor::visit(array_type_expression *type_expression) { type_expression->base().accept(this); - this->current_type = type(std::make_shared<array_type>(this->current_type, type_expression->size)); + auto result_type{ std::make_shared<array_type>(this->current_type, type_expression->size) }; + + this->current_type = type(result_type); } std::vector<type_field> name_analysis_visitor::build_composite_type(const std::vector<field_declaration>& fields) @@ -324,20 +321,27 @@ namespace elna::frontend this->current_type = type(result_type); } + std::shared_ptr<variable_info> name_analysis_visitor::register_variable(const std::string& name, + const bool is_extern, const struct position position) + { + auto variable_symbol = std::make_shared<variable_info>(this->current_type, is_extern); + + if (!this->bag.enter(name, variable_symbol)) + { + add_error<already_declared_error>(name, this->input_file, position); + } + return variable_symbol; + } + void name_analysis_visitor::visit(variable_declaration *declaration) { declaration->variable_type().accept(this); for (const auto& variable_identifier : declaration->identifiers) { - auto variable_symbol = std::make_shared<variable_info>(this->current_type, declaration->is_extern); - + auto variable_symbol = register_variable(variable_identifier.name, declaration->is_extern, + declaration->position()); variable_symbol->exported = variable_identifier.exported; - if (!this->bag.enter(variable_identifier.name, variable_symbol)) - { - add_error<already_declared_error>(variable_identifier.name, this->input_file, - declaration->position()); - } } } @@ -358,7 +362,19 @@ namespace elna::frontend if (definition->body.has_value()) { info = std::make_shared<procedure_info>(heading, definition->parameter_names, this->bag.enter()); + auto name_iterator = std::cbegin(definition->parameter_names); + auto type_iterator = std::cbegin(heading.parameters); + while (name_iterator != std::cend(definition->parameter_names) + && type_iterator != std::cend(heading.parameters)) + { + this->current_type = *type_iterator; + auto variable_symbol = register_variable(*name_iterator, false, definition->heading().position()); + variable_symbol->exported = false; + + ++name_iterator; + ++type_iterator; + } for (constant_declaration *const constant : definition->body.value().constants()) { constant->accept(this); @@ -489,6 +505,10 @@ namespace elna::frontend { variable->accept(this); } + for (constant_declaration *const constant : unit->constants) + { + constant->accept(this); + } for (procedure_declaration *const procedure : unit->procedures) { procedure->accept(this); @@ -522,8 +542,26 @@ namespace elna::frontend expression->operand().accept(this); } - void name_analysis_visitor::visit(variable_expression *) + void name_analysis_visitor::visit(named_expression *type_expression) { + auto unresolved_alias = this->bag.declared(type_expression->name); + + if (unresolved_alias != nullptr) + { + this->current_type = type(unresolved_alias); + } + else if (auto from_symbol_table = this->bag.lookup(type_expression->name)) + { + if (auto type_symbol = from_symbol_table->is_type()) + { + this->current_type = type_symbol->symbol; + } + } + else + { + add_error<undeclared_error>(type_expression->name, this->input_file, type_expression->position()); + this->current_type = type(); + } } void name_analysis_visitor::visit(array_access_expression *expression) |
