diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-10-15 14:46:38 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-10-15 14:46:38 +0200 |
| commit | 56a1244380133ab400f98d2da15353e080ffb360 (patch) | |
| tree | f4e0aef02c8d356fc2c67bfdb2f1c490858c24cf /boot/name_analysis.cc | |
| parent | de6ecae0f072bb32be95382c536a517eabe4b1f1 (diff) | |
| download | elna-56a1244380133ab400f98d2da15353e080ffb360.tar.gz | |
Diffstat (limited to 'boot/name_analysis.cc')
| -rw-r--r-- | boot/name_analysis.cc | 50 |
1 files changed, 47 insertions, 3 deletions
diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 36faee1..9305cd2 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -144,6 +144,11 @@ namespace elna::boot { return "All constants should be initialized"; } + else if constexpr (std::is_same_v<T, array_dimension_type>) + { + return "Array dimension must be of type 'Word' or 'Int', but got '" + + payload.actual.to_string() + "'"; + } else if constexpr (std::is_same_v<T, kind>) { switch (payload) @@ -162,6 +167,8 @@ namespace elna::boot case enumeration_values: return "Enumeration values should be omitted, given for the first member only," " or given for all members"; + case array_dimension_size: + return "Array dimension must be greater than zero"; default: __builtin_unreachable(); } @@ -327,7 +334,7 @@ namespace elna::boot resolving_visitor::resolving_visitor(symbol_bag& bag, const target_info& target, const std::filesystem::path& module_path) - : bag(bag), constant_evaluator(this->bag, target), module_file(module_path) + : bag(bag), target(target), constant_evaluator(this->bag, target), module_file(module_path) { } @@ -580,15 +587,52 @@ namespace elna::boot this->current_type = type(); return; } - const auto size_constant = this->constant_evaluator.evaluate_index(expression->dimensions()); - if (!size_constant.has_value()) + if (!is_index_type(expression->dimensions().type_decoration, this->target)) + { + add_error<declaration_format_error>(expression->dimensions().position(), + declaration_format_error::array_dimension_type{ expression->dimensions().type_decoration }); + this->current_type = type(); + return; + } + + const std::optional<constant_value> evaluated = + this->constant_evaluator.evaluate(expression->dimensions()); + + if (!evaluated.has_value()) + { + add_error<non_constant_expression_error>(expression->position(), + non_constant_expression_error::array_dimensions{ array_base }); + this->current_type = type(); + return; + } + + const auto *literal = std::get_if<integer_literal>(&evaluated.value()); + + if (literal == nullptr) { add_error<non_constant_expression_error>(expression->position(), non_constant_expression_error::array_dimensions{ array_base }); this->current_type = type(); return; } + if (*literal <= 0) + { + add_error<declaration_format_error>(expression->dimensions().position(), + declaration_format_error::kind::array_dimension_size); + this->current_type = type(); + return; + } + + const std::optional<std::uint64_t> size_constant = literal->try_to<std::uint64_t>(); + + if (!size_constant.has_value()) + { + add_error<declaration_format_error>(expression->dimensions().position(), + declaration_format_error::kind::array_dimension_size); + this->current_type = type(); + return; + } this->current_type = type(std::make_shared<array_type>(array_base, size_constant.value())); } |
