diff options
Diffstat (limited to 'boot/name_analysis.cc')
| -rw-r--r-- | boot/name_analysis.cc | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 9b3dec4..36faee1 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -317,6 +317,10 @@ namespace elna::boot { } + void forward_declaration_visitor::visit(constant_declaration *) + { + } + void forward_declaration_visitor::visit(procedure_declaration *) { } @@ -449,6 +453,26 @@ namespace elna::boot return variable_symbol; } + std::shared_ptr<constant_info> resolving_visitor::register_constant(const std::string& name, + const type& constant_type, const constant_value& value, const source_position position) + { + const std::shared_ptr<constant_info> constant_symbol = + std::make_shared<constant_info>(constant_type, value); + constant_symbol->position.emplace(position); + constant_symbol->file = this->module_file; + + if (!this->bag.enter(name, constant_symbol)) + { + const std::shared_ptr<info> original = this->bag.lookup(name); + symbol_declaration_error::redefinition original_definition{ + .original = original->position, + .file = this->redefinition_file(original) + }; + add_error<symbol_declaration_error>(position, name, original_definition); + } + return constant_symbol; + } + std::optional<type> resolving_visitor::lookup_pointer_like_field( const std::string& field_name, const type& element_type) { @@ -1063,6 +1087,10 @@ namespace elna::boot { expression->type_decoration = variable_symbol->symbol; } + else if (const auto constant_symbol = from_symbol_table->is_constant()) + { + expression->type_decoration = constant_symbol->symbol; + } else if (const auto procedure_symbol = from_symbol_table->is_procedure()) { type procedure = type(std::make_shared<procedure_type>(procedure_symbol->symbol)); @@ -1502,6 +1530,25 @@ namespace elna::boot } } + void declaration_visitor::visit(constant_declaration *declaration) + { + declaration->initializer->accept(this); + const std::optional<constant_value> computed = + this->constant_evaluator.evaluate(*declaration->initializer); + if (!computed.has_value()) + { + const non_constant_expression_error::initializer payload{ { declaration->identifier.id() } }; + add_error<non_constant_expression_error>(declaration->initializer->position(), payload); + return; + } + const type constant_type = declaration->initializer->type_decoration; + const source_position position = declaration->position(); + const std::string name = declaration->identifier.name(); + const std::shared_ptr<constant_info> constant_symbol = + register_constant(name, constant_type, computed.value(), position); + constant_symbol->exported = declaration->identifier.exported(); + } + void declaration_visitor::visit(procedure_declaration *declaration) { // The scope is opened before the heading is built so that the type @@ -1633,6 +1680,28 @@ namespace elna::boot } } + void name_analysis_visitor::visit(constant_declaration *declaration) + { + if (!this->bag.is_global()) + { + declaration->initializer->accept(this); + const std::optional<constant_value> computed = + this->constant_evaluator.evaluate(*declaration->initializer); + if (!computed.has_value()) + { + const non_constant_expression_error::initializer payload{ { declaration->identifier.id() } }; + add_error<non_constant_expression_error>(declaration->initializer->position(), payload); + return; + } + const type constant_type = declaration->initializer->type_decoration; + const source_position position = declaration->position(); + const std::string name = declaration->identifier.name(); + const std::shared_ptr<constant_info> constant_symbol = + register_constant(name, constant_type, computed.value(), position); + constant_symbol->exported = declaration->identifier.exported(); + } + } + void name_analysis_visitor::visit(procedure_declaration *declaration) { if (declaration->body.has_value()) |
