aboutsummaryrefslogtreecommitdiff
path: root/boot/evaluator.cc
diff options
context:
space:
mode:
Diffstat (limited to 'boot/evaluator.cc')
-rw-r--r--boot/evaluator.cc66
1 files changed, 20 insertions, 46 deletions
diff --git a/boot/evaluator.cc b/boot/evaluator.cc
index 18633ba..78eb4cd 100644
--- a/boot/evaluator.cc
+++ b/boot/evaluator.cc
@@ -280,10 +280,6 @@ namespace elna::boot
{
return constant_value{ character_subject->value };
}
- else if (auto *pointer_subject = subject.is_a<std::nullptr_t>())
- {
- return constant_value{ pointer_subject->value };
- }
else if (auto *string_subject = subject.is_a<std::string>())
{
return constant_value{ string_subject->value };
@@ -517,25 +513,10 @@ namespace elna::boot
template<typename T>
static std::optional<constant_value> evaluate_operation(binary_operator operation, const T& lhs, const T& rhs)
{
- if constexpr (std::is_same_v<T, std::nullptr_t>)
- {
- switch (operation)
- {
- using enum binary_operator;
- case equals:
- return constant_value{ true };
- case not_equals:
- return constant_value{ false };
- default:
- return std::nullopt;
- }
- }
- else
+ switch (operation)
{
- switch (operation)
- {
- using enum binary_operator;
- case sum:
+ using enum binary_operator;
+ case sum:
if constexpr (std::is_same_v<T, integer_literal>)
{
if (auto result = lhs.add(rhs))
@@ -667,25 +648,29 @@ namespace elna::boot
case not_equals:
return constant_value{ lhs != rhs };
case less:
- if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>
+ || std::is_same_v<T, pointer_literal>)
{
return constant_value{ lhs < rhs };
}
return std::nullopt;
case greater:
- if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>
+ || std::is_same_v<T, pointer_literal>)
{
return constant_value{ lhs > rhs };
}
return std::nullopt;
case less_equal:
- if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>
+ || std::is_same_v<T, pointer_literal>)
{
return constant_value{ lhs <= rhs };
}
return std::nullopt;
case greater_equal:
- if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>
+ || std::is_same_v<T, pointer_literal>)
{
return constant_value{ lhs >= rhs };
}
@@ -693,7 +678,6 @@ namespace elna::boot
default:
return std::nullopt;
}
- }
}
std::optional<constant_value> evaluator::evaluate_binary(binary_expression& subject)
@@ -799,9 +783,9 @@ namespace elna::boot
{
return integer_constant(target_signed, target_size, static_cast<double>(source_value));
}
- else if constexpr (std::is_same_v<T, std::nullptr_t>)
+ else if constexpr (std::is_same_v<T, pointer_literal>)
{
- return integer_constant(target_signed, target_size, 0.0);
+ return constant_value{ source_value.address.cast_to(target_signed, target_size) };
}
else
{
@@ -834,10 +818,6 @@ namespace elna::boot
return constant_value{ widened.cast_to(target_format) };
}
- else if constexpr (std::is_same_v<T, std::nullptr_t>)
- {
- return constant_value{ float_literal::from(0.0).cast_to(target_format) };
- }
else
{
return std::nullopt;
@@ -866,9 +846,9 @@ namespace elna::boot
{
return constant_value{ source_value != 0U };
}
- else if constexpr (std::is_same_v<T, std::nullptr_t>)
+ else if constexpr (std::is_same_v<T, pointer_literal>)
{
- return constant_value{ false };
+ return constant_value{ !(source_value.address == std::size_t{ 0 }) };
}
else
{
@@ -906,10 +886,6 @@ namespace elna::boot
{
return constant_value{ static_cast<std::uint32_t>(source_value) };
}
- else if constexpr (std::is_same_v<T, std::nullptr_t>)
- {
- return constant_value{ std::uint32_t{ 0 } };
- }
else
{
return std::nullopt;
@@ -935,17 +911,15 @@ namespace elna::boot
return value;
}
- std::optional<constant_value> evaluator::cast_to_pointer(const constant_value& source_expression)
+ std::optional<constant_value> evaluator::cast_to_pointer(const constant_value& source_expression) const
{
- if (std::holds_alternative<std::nullptr_t>(source_expression))
+ if (const auto *address = std::get_if<integer_literal>(&source_expression))
{
- return source_expression;
+ return constant_value{ pointer_literal{ address->cast_to(false, this->target.pointer_properties.size) } };
}
- // Only the null pointer has a constant representation.
- else if (const auto *address = std::get_if<integer_literal>(&source_expression);
- *address == std::ptrdiff_t{ 0 })
+ else if (std::holds_alternative<pointer_literal>(source_expression))
{
- return constant_value{ nullptr };
+ return source_expression;
}
return std::nullopt;
}