aboutsummaryrefslogtreecommitdiff
path: root/boot/evaluator.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-01 20:03:34 +0200
committerEugen Wissner <belka@caraus.de>2026-08-01 20:03:34 +0200
commite9cd3e5d0157f145dc0c3fea59f434fdd5ae55c6 (patch)
tree90ba6af2fe70ab961cdf48b46caa669757cd11b7 /boot/evaluator.cc
parent71b3bbb7698b13b42c99a4ca66c27db4a6189ff8 (diff)
downloadelna-e9cd3e5d0157f145dc0c3fea59f434fdd5ae55c6.tar.gz
Evaluate strings at compile time
Diffstat (limited to 'boot/evaluator.cc')
-rw-r--r--boot/evaluator.cc93
1 files changed, 42 insertions, 51 deletions
diff --git a/boot/evaluator.cc b/boot/evaluator.cc
index 56ba270..afa72db 100644
--- a/boot/evaluator.cc
+++ b/boot/evaluator.cc
@@ -231,6 +231,10 @@ namespace elna::boot
{
return constant_value{ std::nullptr_t{} };
}
+ else if (is_string_type(decoration))
+ {
+ return constant_value{ static_cast<literal<std::string>&>(subject).value };
+ }
return std::nullopt;
}
@@ -356,72 +360,59 @@ namespace elna::boot
std::optional<constant_value> evaluator::evaluate_unary(unary_expression& subject)
{
- if (subject.operation() == unary_operator::reference)
- {
- if (auto *designator = subject.operand().is_designator())
- {
- if (auto *named = designator->is_named())
- {
- return constant_value{ global_address{ .name = named->name } };
- }
- }
- return std::nullopt;
- }
auto operand = evaluate(subject.operand());
if (!operand)
{
return std::nullopt;
}
- if (subject.operation() == unary_operator::minus)
+ switch (subject.operation())
{
- return std::visit([](auto&& value) -> std::optional<constant_value> {
- using T = std::decay_t<decltype(value)>;
+ using enum unary_operator;
+ case minus:
+ return std::visit([](auto&& value) -> std::optional<constant_value> {
+ using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, integer_literal>)
- {
- if (auto result = value.neg())
+ if constexpr (std::is_same_v<T, integer_literal>)
+ {
+ if (auto result = value.neg())
+ {
+ return constant_value{ result.value() };
+ }
+ return std::nullopt;
+ }
+ if constexpr (std::is_same_v<T, double>)
{
- return constant_value{ result.value() };
+ return constant_value{ -value };
}
return std::nullopt;
- }
- if constexpr (std::is_same_v<T, double>)
- {
- return constant_value{ -value };
- }
- return std::nullopt;
- }, operand.value());
- }
- if (subject.operation() == unary_operator::logical_negation)
- {
- return std::visit([](const auto& value) -> std::optional<constant_value> {
- using T = std::decay_t<decltype(value)>;
+ }, operand.value());
+ case logical_negation:
+ return std::visit([](const auto& value) -> std::optional<constant_value> {
+ using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, bool>)
- {
- return constant_value{ !value };
- }
- return std::nullopt;
- }, operand.value());
- }
- if (subject.operation() == unary_operator::bitwise_negation)
- {
- return std::visit([](const auto& value) -> std::optional<constant_value> {
- using T = std::decay_t<decltype(value)>;
+ if constexpr (std::is_same_v<T, bool>)
+ {
+ return constant_value{ !value };
+ }
+ return std::nullopt;
+ }, operand.value());
+ case bitwise_negation:
+ return std::visit([](const auto& value) -> std::optional<constant_value> {
+ using T = std::decay_t<decltype(value)>;
- if constexpr (std::is_same_v<T, integer_literal>)
- {
- return constant_value{ ~value };
- }
+ if constexpr (std::is_same_v<T, integer_literal>)
+ {
+ return constant_value{ ~value };
+ }
+ return std::nullopt;
+ }, operand.value());
+ case plus:
+ return operand;
+ case negation:
+ case reference:
return std::nullopt;
- }, operand.value());
}
- if (subject.operation() == unary_operator::plus)
- {
- return operand;
- }
- return std::nullopt;
}
template<typename T>