From eaf5934f81dcd8ce5705f13b651d7b93ca8c459f Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Thu, 6 Aug 2026 23:12:01 +0200 Subject: Implement compile time castings for integers --- boot/evaluator.cc | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) (limited to 'boot/evaluator.cc') diff --git a/boot/evaluator.cc b/boot/evaluator.cc index 407370a..14ca889 100644 --- a/boot/evaluator.cc +++ b/boot/evaluator.cc @@ -370,7 +370,7 @@ namespace elna::boot } auto& index_literal = std::get(evaluated_index.value()); - return index_literal.is_negative() ? std::nullopt : index_literal.to_unsigned(); + return index_literal < 0 ? std::nullopt : index_literal.try_to(); } std::optional evaluator::evaluate_slicing(slicing_expression& subject) @@ -694,6 +694,66 @@ namespace elna::boot }, lhs.value()); } + std::optional evaluator::cast_to_int(const constant_value& source_expression) + { + return std::visit([](auto&& source_value) -> std::optional { + using T = std::decay_t; + + if constexpr (std::is_same_v) + { + std::optional signed_value = source_value.template try_to(); + + return signed_value.has_value() + ? std::optional(integer_literal::from(signed_value.value())) + : std::nullopt; + } + else if constexpr (std::is_same_v + || std::is_same_v + || std::is_same_v) + { + return integer_literal::from(static_cast(source_value)); + } + else if constexpr (std::is_same_v) + { + return integer_literal::from(0); + } + else + { + return std::nullopt; + } + }, source_expression); + } + + std::optional evaluator::cast_to_word(const constant_value& source_expression) + { + return std::visit([](auto&& source_value) -> std::optional { + using T = std::decay_t; + + if constexpr (std::is_same_v) + { + std::optional unsigned_value = source_value.template try_to(); + + return unsigned_value.has_value() + ? std::optional(integer_literal::from(unsigned_value.value())) + : std::nullopt; + } + else if constexpr (std::is_same_v + || std::is_same_v + || std::is_same_v) + { + return integer_literal::from(static_cast(source_value)); + } + else if constexpr (std::is_same_v) + { + return integer_literal::from(0U); + } + else + { + return std::nullopt; + } + }, source_expression); + } + std::optional evaluator::evaluate_cast(cast_expression& subject) { auto value = evaluate(subject.value()); @@ -702,6 +762,17 @@ namespace elna::boot { return std::nullopt; } + const type resolved = resolve_underlying_type(subject.type_decoration); + + if (is_primitive_type(resolved, "Int")) + { + return cast_to_int(value.value()); + } + else if (is_primitive_type(resolved, "Word")) + { + return cast_to_word(value.value()); + } + return constant_value{ value.value() }; } -- cgit v1.2.3