aboutsummaryrefslogtreecommitdiff
path: root/boot/evaluator.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-08-21 00:05:03 +0200
committerEugen Wissner <belka@caraus.de>2026-08-21 00:05:03 +0200
commit39269cc68a32f6e1a7524b00da36a1fe4cc7fb8b (patch)
tree9558cd6107d60e22127faeddbdeac5031ee2fdbe /boot/evaluator.cc
parent4f77ad5d019618893c59a0f8d5bfa6b98e50a3be (diff)
downloadelna-39269cc68a32f6e1a7524b00da36a1fe4cc7fb8b.tar.gz
Implement Single and Double floats
Diffstat (limited to 'boot/evaluator.cc')
-rw-r--r--boot/evaluator.cc112
1 files changed, 58 insertions, 54 deletions
diff --git a/boot/evaluator.cc b/boot/evaluator.cc
index d43ef11..1d10346 100644
--- a/boot/evaluator.cc
+++ b/boot/evaluator.cc
@@ -237,9 +237,9 @@ namespace elna::boot
{
return constant_value{ integer_subject->value };
}
- else if (auto *double_subject = subject.is_a<double>())
+ else if (auto *float_subject = subject.is_a<float_literal>())
{
- return constant_value{ double_subject->value };
+ return constant_value{ float_subject->value };
}
else if (auto *boolean_subject = subject.is_a<bool>())
{
@@ -395,7 +395,7 @@ namespace elna::boot
}
return std::nullopt;
}
- if constexpr (std::is_same_v<T, double>)
+ if constexpr (std::is_same_v<T, float_literal>)
{
return constant_value{ -value };
}
@@ -433,7 +433,7 @@ namespace elna::boot
template<typename T>
static std::optional<T> add_overflow(T lhs, T rhs)
{
- if constexpr (is_integral<T>)
+ if constexpr (is_integral_v<T>)
{
T result;
return __builtin_add_overflow(lhs, rhs, &result)
@@ -446,7 +446,7 @@ namespace elna::boot
template<typename T>
static std::optional<T> sub_overflow(T lhs, T rhs)
{
- if constexpr (is_integral<T>)
+ if constexpr (is_integral_v<T>)
{
T result;
return __builtin_sub_overflow(lhs, rhs, &result)
@@ -459,7 +459,7 @@ namespace elna::boot
template<typename T>
static std::optional<T> mul_overflow(T lhs, T rhs)
{
- if constexpr (is_integral<T>)
+ if constexpr (is_integral_v<T>)
{
T result;
return __builtin_mul_overflow(lhs, rhs, &result)
@@ -498,7 +498,7 @@ namespace elna::boot
return constant_value{ result.value() };
}
}
- else if constexpr (std::is_floating_point_v<T>)
+ else if constexpr (std::is_same_v<T, float_literal>)
{
if (auto result = add_overflow(lhs, rhs))
{
@@ -514,7 +514,7 @@ namespace elna::boot
return constant_value{ result.value() };
}
}
- else if constexpr (std::is_floating_point_v<T>)
+ else if constexpr (std::is_same_v<T, float_literal>)
{
if (auto result = sub_overflow(lhs, rhs))
{
@@ -530,7 +530,7 @@ namespace elna::boot
return constant_value{ result.value() };
}
}
- else if constexpr (std::is_floating_point_v<T>)
+ else if constexpr (std::is_same_v<T, float_literal>)
{
if (auto result = mul_overflow(lhs, rhs))
{
@@ -546,12 +546,9 @@ namespace elna::boot
return constant_value{ result.value() };
}
}
- else if constexpr (std::is_floating_point_v<T>)
+ else if constexpr (std::is_same_v<T, float_literal>)
{
- if (rhs != static_cast<T>(0))
- {
- return constant_value{ lhs / rhs };
- }
+ return constant_value{ lhs / rhs };
}
return std::nullopt;
case remainder:
@@ -625,25 +622,25 @@ namespace elna::boot
case not_equals:
return constant_value{ lhs != rhs };
case less:
- if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
{
return constant_value{ lhs < rhs };
}
return std::nullopt;
case greater:
- if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
{
return constant_value{ lhs > rhs };
}
return std::nullopt;
case less_equal:
- if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
{
return constant_value{ lhs <= rhs };
}
return std::nullopt;
case greater_equal:
- if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, integer_literal>)
+ if constexpr (std::is_same_v<T, float_literal> || std::is_same_v<T, integer_literal>)
{
return constant_value{ lhs >= rhs };
}
@@ -789,23 +786,23 @@ namespace elna::boot
{
type const resolved = resolve_underlying_type(subject.types.front());
- if (auto resolved_primitive = resolved.get<primitive_type>())
+ if (is_integer_type(resolved))
{
- if (resolved_primitive->identifier.starts_with("Int"))
- {
- const std::size_t bits = resolved_primitive->properties.size * CHAR_BIT;
- const integer_literal one = integer_literal::from<std::ptrdiff_t>(
- resolved_primitive->properties.size, 1U).value();
+ const std::shared_ptr<primitive_type> resolved_primitive = resolved.get<primitive_type>();
+ const std::size_t bits = resolved_primitive->properties.size * CHAR_BIT;
+ const integer_literal one = integer_literal::from<std::ptrdiff_t>(
+ resolved_primitive->properties.size, 1U).value();
- return constant_value{
- one.shl(integer_literal::from<std::size_t>(bits - 1U)).value()
- };
- }
- if (resolved_primitive->identifier.starts_with("Word"))
- {
- return constant_value{ integer_literal::from<std::size_t>(
- resolved_primitive->properties.size, 0U).value() };
- }
+ return constant_value{
+ one.shl(integer_literal::from<std::size_t>(bits - 1U)).value()
+ };
+ }
+ if (is_word_type(resolved))
+ {
+ const std::shared_ptr<primitive_type> resolved_primitive = resolved.get<primitive_type>();
+
+ return constant_value{ integer_literal::from<std::size_t>(
+ resolved_primitive->properties.size, 0U).value() };
}
if (is_primitive_type(resolved, "Char"))
{
@@ -815,9 +812,13 @@ namespace elna::boot
{
return constant_value{ false };
}
- if (is_primitive_type(resolved, "Float"))
+ if (is_primitive_type(resolved, "Single"))
{
- return constant_value{ -std::numeric_limits<double>::max() };
+ return constant_value{ float_literal::from(std::numeric_limits<float>::min()) };
+ }
+ if (is_primitive_type(resolved, "Double"))
+ {
+ return constant_value{ float_literal::from(std::numeric_limits<double>::min()) };
}
if (auto enumeration = resolved.get<enumeration_type>())
{
@@ -828,26 +829,25 @@ namespace elna::boot
{
type const resolved = resolve_underlying_type(subject.types.front());
- if (auto resolved_primitive = resolved.get<primitive_type>())
+ if (is_integer_type(resolved))
{
- if (resolved_primitive->identifier.starts_with("Int"))
- {
- const std::size_t bits = resolved_primitive->properties.size * CHAR_BIT;
- const integer_literal one = integer_literal::from<std::ptrdiff_t>(
- resolved_primitive->properties.size, 1U).value();
- const std::optional<integer_literal> minimum = one.shl(
- integer_literal::from<std::size_t>(bits - 1U));
+ const std::shared_ptr<primitive_type> resolved_primitive = resolved.get<primitive_type>();
+ const std::size_t bits = resolved_primitive->properties.size * CHAR_BIT;
+ const integer_literal one = integer_literal::from<std::ptrdiff_t>(
+ resolved_primitive->properties.size, 1U).value();
+ const std::optional<integer_literal> minimum = one.shl(
+ integer_literal::from<std::size_t>(bits - 1U));
- return constant_value{ ~minimum.value() };
- }
- if (resolved_primitive->identifier.starts_with("Word"))
- {
- // All bits set.
- std::optional<integer_literal> zero = integer_literal::from<std::size_t>(
- resolved_primitive->properties.size, 0U);
+ return constant_value{ ~minimum.value() };
+ }
+ if (is_word_type(resolved))
+ {
+ const std::shared_ptr<primitive_type> resolved_primitive = resolved.get<primitive_type>();
+ // All bits set.
+ std::optional<integer_literal> zero = integer_literal::from<std::size_t>(
+ resolved_primitive->properties.size, 0U);
- return constant_value{ ~zero.value() };
- }
+ return constant_value{ ~zero.value() };
}
if (is_primitive_type(resolved, "Char"))
{
@@ -857,9 +857,13 @@ namespace elna::boot
{
return constant_value{ true };
}
- if (is_primitive_type(resolved, "Float"))
+ if (is_primitive_type(resolved, "Single"))
+ {
+ return constant_value{ float_literal::from(std::numeric_limits<float>::max()) };
+ }
+ if (is_primitive_type(resolved, "Double"))
{
- return constant_value{ std::numeric_limits<double>::max() };
+ return constant_value{ float_literal::from(std::numeric_limits<double>::max()) };
}
if (auto enumeration = resolved.get<enumeration_type>())
{