aboutsummaryrefslogtreecommitdiff
path: root/boot/validation.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-05 01:03:55 +0200
committerEugen Wissner <belka@caraus.de>2026-08-05 21:27:36 +0200
commitb2dee14873402ee3d13d59ae5579593796ea862f (patch)
tree1f245eac1a23a73f45124498fc8274874e35750e /boot/validation.cc
parent1c2fb173ea3b674207badc721556ad72962b266e (diff)
downloadelna-b2dee14873402ee3d13d59ae5579593796ea862f.tar.gz
Check that constants are initialized
Diffstat (limited to 'boot/validation.cc')
-rw-r--r--boot/validation.cc69
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());