From 39269cc68a32f6e1a7524b00da36a1fe4cc7fb8b Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Fri, 21 Aug 2026 00:05:03 +0200 Subject: Implement Single and Double floats --- boot/evaluator.cc | 112 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 58 insertions(+), 54 deletions(-) (limited to 'boot/evaluator.cc') 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()) + else if (auto *float_subject = subject.is_a()) { - return constant_value{ double_subject->value }; + return constant_value{ float_subject->value }; } else if (auto *boolean_subject = subject.is_a()) { @@ -395,7 +395,7 @@ namespace elna::boot } return std::nullopt; } - if constexpr (std::is_same_v) + if constexpr (std::is_same_v) { return constant_value{ -value }; } @@ -433,7 +433,7 @@ namespace elna::boot template static std::optional add_overflow(T lhs, T rhs) { - if constexpr (is_integral) + if constexpr (is_integral_v) { T result; return __builtin_add_overflow(lhs, rhs, &result) @@ -446,7 +446,7 @@ namespace elna::boot template static std::optional sub_overflow(T lhs, T rhs) { - if constexpr (is_integral) + if constexpr (is_integral_v) { T result; return __builtin_sub_overflow(lhs, rhs, &result) @@ -459,7 +459,7 @@ namespace elna::boot template static std::optional mul_overflow(T lhs, T rhs) { - if constexpr (is_integral) + if constexpr (is_integral_v) { 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) + else if constexpr (std::is_same_v) { 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) + else if constexpr (std::is_same_v) { 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) + else if constexpr (std::is_same_v) { 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) + else if constexpr (std::is_same_v) { - if (rhs != static_cast(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 || std::is_same_v) + if constexpr (std::is_same_v || std::is_same_v) { return constant_value{ lhs < rhs }; } return std::nullopt; case greater: - if constexpr (std::is_floating_point_v || std::is_same_v) + if constexpr (std::is_same_v || std::is_same_v) { return constant_value{ lhs > rhs }; } return std::nullopt; case less_equal: - if constexpr (std::is_floating_point_v || std::is_same_v) + if constexpr (std::is_same_v || std::is_same_v) { return constant_value{ lhs <= rhs }; } return std::nullopt; case greater_equal: - if constexpr (std::is_floating_point_v || std::is_same_v) + if constexpr (std::is_same_v || std::is_same_v) { 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()) + 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( - resolved_primitive->properties.size, 1U).value(); + const std::shared_ptr resolved_primitive = resolved.get(); + const std::size_t bits = resolved_primitive->properties.size * CHAR_BIT; + const integer_literal one = integer_literal::from( + resolved_primitive->properties.size, 1U).value(); - return constant_value{ - one.shl(integer_literal::from(bits - 1U)).value() - }; - } - if (resolved_primitive->identifier.starts_with("Word")) - { - return constant_value{ integer_literal::from( - resolved_primitive->properties.size, 0U).value() }; - } + return constant_value{ + one.shl(integer_literal::from(bits - 1U)).value() + }; + } + if (is_word_type(resolved)) + { + const std::shared_ptr resolved_primitive = resolved.get(); + + return constant_value{ integer_literal::from( + 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::max() }; + return constant_value{ float_literal::from(std::numeric_limits::min()) }; + } + if (is_primitive_type(resolved, "Double")) + { + return constant_value{ float_literal::from(std::numeric_limits::min()) }; } if (auto enumeration = resolved.get()) { @@ -828,26 +829,25 @@ namespace elna::boot { type const resolved = resolve_underlying_type(subject.types.front()); - if (auto resolved_primitive = resolved.get()) + 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( - resolved_primitive->properties.size, 1U).value(); - const std::optional minimum = one.shl( - integer_literal::from(bits - 1U)); + const std::shared_ptr resolved_primitive = resolved.get(); + const std::size_t bits = resolved_primitive->properties.size * CHAR_BIT; + const integer_literal one = integer_literal::from( + resolved_primitive->properties.size, 1U).value(); + const std::optional minimum = one.shl( + integer_literal::from(bits - 1U)); - return constant_value{ ~minimum.value() }; - } - if (resolved_primitive->identifier.starts_with("Word")) - { - // All bits set. - std::optional zero = integer_literal::from( - resolved_primitive->properties.size, 0U); + return constant_value{ ~minimum.value() }; + } + if (is_word_type(resolved)) + { + const std::shared_ptr resolved_primitive = resolved.get(); + // All bits set. + std::optional zero = integer_literal::from( + 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::max()) }; + } + if (is_primitive_type(resolved, "Double")) { - return constant_value{ std::numeric_limits::max() }; + return constant_value{ float_literal::from(std::numeric_limits::max()) }; } if (auto enumeration = resolved.get()) { -- cgit v1.2.3