diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-08-05 01:03:55 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-08-05 21:27:36 +0200 |
| commit | b2dee14873402ee3d13d59ae5579593796ea862f (patch) | |
| tree | 1f245eac1a23a73f45124498fc8274874e35750e /boot/validation.cc | |
| parent | 1c2fb173ea3b674207badc721556ad72962b266e (diff) | |
| download | elna-b2dee14873402ee3d13d59ae5579593796ea862f.tar.gz | |
Check that constants are initialized
Diffstat (limited to 'boot/validation.cc')
| -rw-r--r-- | boot/validation.cc | 69 |
1 files changed, 11 insertions, 58 deletions
diff --git a/boot/validation.cc b/boot/validation.cc index dc4b5b0..b29381a 100644 --- a/boot/validation.cc +++ b/boot/validation.cc @@ -17,14 +17,12 @@ along with GCC; see the file COPYING3. If not see #include "elna/boot/validation.h" -#include <algorithm> -#include <numeric> #include <unordered_map> namespace elna::boot { validation_error::validation_error(const source_position position, payload_type payload) - : error(position), payload(std::move(payload)) + : error(position), payload(payload) { } @@ -33,18 +31,10 @@ namespace elna::boot return std::visit([](const auto& payload) -> std::string { using T = std::decay_t<decltype(payload)>; - if constexpr (std::is_same_v<T, non_constant_initializer>) - { - return "Variable initializers must be constant expressions"; - } - else if constexpr (std::is_same_v<T, duplicate_case>) + if constexpr (std::is_same_v<T, duplicate_case>) { return "Duplicate case label"; } - else if constexpr (std::is_same_v<T, non_constant_case_label>) - { - return "Case label must be a constant expression"; - } }, this->payload); } @@ -53,64 +43,27 @@ namespace elna::boot return std::visit([](const auto& payload) -> std::optional<std::pair<std::string, source_position>> { using T = std::decay_t<decltype(payload)>; - if constexpr (std::is_same_v<T, non_constant_initializer>) - { - std::string identifier_list = std::accumulate( - std::next(payload.identifiers.begin()), payload.identifiers.end(), - payload.identifiers.front().name(), - [](const std::string& accumulator, const identifier& next) -> std::string { - return accumulator + ", " + next.name(); - }); - auto position_span = source_position(payload.identifiers.front().position().start(), - payload.identifiers.back().position().end()); - return std::make_pair(std::move(identifier_list), position_span); - } - else if constexpr (std::is_same_v<T, duplicate_case>) + if constexpr (std::is_same_v<T, duplicate_case>) { return std::make_pair("Previous label here", payload.first); } - else if constexpr (std::is_same_v<T, non_constant_case_label>) - { - return std::nullopt; - } }, this->payload); } - validation_error validation_error::non_constant_initializer_error(const source_position position, - const std::vector<identifier_definition>& identifiers) - { - non_constant_initializer payload; - payload.identifiers.reserve(identifiers.size()); - - std::ranges::transform(identifiers, std::back_inserter(payload.identifiers), - [](const auto& identifier) { return identifier.id(); }); - - return validation_error(position, std::move(payload)); - } - validation_visitor::validation_visitor(symbol_bag& bag, const target_info& target) - : bag(bag), target(target), constant_evaluator(this->bag, this->target) + : bag(bag), constant_evaluator(this->bag, target) { } - void validation_visitor::visit(variable_declaration* declaration) + void validation_visitor::visit(unit *unit) { - if (declaration->initializer == nullptr || has_errors()) - { - return; - } - auto computed = this->constant_evaluator.evaluate(*declaration->initializer); - if (!computed) + for (procedure_declaration *procedure : unit->procedures) { - auto non_constant_initializer_error = validation_error::non_constant_initializer_error( - declaration->initializer->position(), declaration->identifiers); - add_error<validation_error>(non_constant_initializer_error); - return; + procedure->accept(this); } - for (const auto& identifier : declaration->identifiers) + for (auto *entry_statement : unit->entry_point) { - auto variable_symbol = this->bag.lookup(identifier.name())->is_variable(); - variable_symbol->value = computed; + entry_statement->accept(this); } } @@ -139,8 +92,8 @@ namespace elna::boot auto value = this->constant_evaluator.evaluate(*label); if (!value.has_value()) { - add_error<validation_error>(label->position(), - validation_error::non_constant_case_label{}); + add_error<non_constant_expression_error>(label->position(), + non_constant_expression_error::case_label{}); continue; } auto [case_position, inserted] = seen.try_emplace(value.value(), label->position()); |
