diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-07-14 01:45:58 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-07-14 01:45:58 +0200 |
| commit | 51e2f98e33ae10fc3052335cc6847bc93d0784fa (patch) | |
| tree | 7588effe2778d38d19adbf83cf23b5429df93691 /boot | |
| parent | 8ceb48a4e60b8ff89f28372da4f66cd152e2e0fe (diff) | |
| download | elna-51e2f98e33ae10fc3052335cc6847bc93d0784fa.tar.gz | |
Add static array initializer
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/ast.cc | 35 | ||||
| -rw-r--r-- | boot/parser.yy | 4 | ||||
| -rw-r--r-- | boot/semantic.cc | 45 |
3 files changed, 82 insertions, 2 deletions
diff --git a/boot/ast.cc b/boot/ast.cc index 36215c1..4af906f 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -119,6 +119,11 @@ namespace elna::boot __builtin_unreachable(); } + void empty_visitor::visit(array_constructor_expression *) + { + __builtin_unreachable(); + } + void empty_visitor::visit(traits_expression *) { __builtin_unreachable(); @@ -416,6 +421,15 @@ namespace elna::boot } } + void walking_visitor::visit(array_constructor_expression *expression) + { + expression->m_element_type->accept(this); + for (auto element : expression->elements) + { + element->accept(this); + } + } + void walking_visitor::visit(traits_expression *trait) { if (!trait->parameters.empty()) @@ -656,6 +670,27 @@ namespace elna::boot } } + array_constructor_expression::array_constructor_expression(const struct position position, + std::uint32_t size, type_expression *element_type, + std::vector<expression *>&& elements) + : node(position), size(size), m_element_type(element_type), elements(std::move(elements)) + { + } + + void array_constructor_expression::accept(parser_visitor *visitor) + { + visitor->visit(this); + } + + array_constructor_expression::~array_constructor_expression() + { + delete m_element_type; + for (expression *const element : elements) + { + delete element; + } + } + variable_declaration::variable_declaration(const struct position position, std::vector<identifier_definition>&& identifier, std::shared_ptr<type_expression> variable_type, expression *initializer) diff --git a/boot/parser.yy b/boot/parser.yy index ae2e5a8..4ef2de4 100644 --- a/boot/parser.yy +++ b/boot/parser.yy @@ -265,6 +265,10 @@ simple_expression: { $$ = new boot::record_constructor_expression(boot::make_position(@1), std::move($1), std::move($3)); } + | "[" INTEGER "]" type_expression "{" expressions "}" + { + $$ = new boot::array_constructor_expression(boot::make_position(@1), $2, $4, std::move($6)); + } operand: unary_expression { $$ = $1; } | simple_expression { $$ = $1; } diff --git a/boot/semantic.cc b/boot/semantic.cc index f46dce9..f42b094 100644 --- a/boot/semantic.cc +++ b/boot/semantic.cc @@ -343,6 +343,31 @@ namespace elna::boot } } + void type_analysis_visitor::visit(array_constructor_expression *expression) + { + auto array = inner_aliased_type(expression->type_decoration).get<array_type>(); + + if (array == nullptr) + { + add_error<type_expectation_error>(type_expectation_error::kind::result, expression->position()); + return; + } + if (expression->elements.size() > array->size) + { + add_error<argument_count_error>(array->size, expression->elements.size(), + expression->position()); + return; + } + for (auto element : expression->elements) + { + if (!is_assignable_from(array->base, element->type_decoration)) + { + add_error<type_expectation_error>(type_expectation_error::kind::argument, + element->position()); + } + } + } + name_analysis_visitor::name_analysis_visitor(symbol_bag bag) : error_container(), bag(bag) { @@ -588,6 +613,17 @@ namespace elna::boot } } + void name_analysis_visitor::visit(array_constructor_expression *expression) + { + expression->m_element_type->accept(this); + auto element_type = this->current_type; + for (auto element : expression->elements) + { + element->accept(this); + } + expression->type_decoration = type(std::make_shared<array_type>(element_type, expression->size)); + } + void name_analysis_visitor::visit(procedure_type_expression *expression) { std::shared_ptr<procedure_type> result_type = @@ -617,8 +653,13 @@ namespace elna::boot void name_analysis_visitor::visit(variable_declaration *declaration) { - walking_visitor::visit(declaration); - + declaration->variable_type().accept(this); + auto variable_type = this->current_type; + if (declaration->initializer != nullptr) + { + declaration->initializer->accept(this); + this->current_type = variable_type; + } for (const identifier_definition& variable_identifier : declaration->identifiers) { auto variable_symbol = register_variable(variable_identifier.name, declaration->is_extern, |
