From 6b131c925dee7a5f97516edd581e051e08bb52d8 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 20 Jul 2026 16:09:24 +0200 Subject: Implement min and max for booleans and floats --- boot/evaluator.cc | 16 ++++++++++++++++ boot/name_analysis.cc | 5 +++-- gcc/gcc/elna-generic.cc | 31 ++++++------------------------- include/elna/boot/evaluator.h | 2 +- include/elna/gcc/elna-generic.h | 5 +++++ 5 files changed, 31 insertions(+), 28 deletions(-) diff --git a/boot/evaluator.cc b/boot/evaluator.cc index b7edd3a..7eb612b 100644 --- a/boot/evaluator.cc +++ b/boot/evaluator.cc @@ -534,6 +534,14 @@ namespace elna::boot { return constant_value{ static_cast(0) }; } + if (is_primitive_type(resolved, "Bool")) + { + return constant_value{ false }; + } + if (is_primitive_type(resolved, "Float")) + { + return constant_value{ -std::numeric_limits::max() }; + } if (auto enumeration = resolved.get()) { return constant_value{ 1 }; @@ -555,6 +563,14 @@ namespace elna::boot { return constant_value{ std::numeric_limits::max() }; } + if (is_primitive_type(resolved, "Bool")) + { + return constant_value{ true }; + } + if (is_primitive_type(resolved, "Float")) + { + return constant_value{ std::numeric_limits::max() }; + } if (auto enumeration = resolved.get()) { return constant_value{ static_cast(enumeration->members.size()) }; diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 22b7814..54a2d1a 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -539,9 +539,10 @@ for (const auto& member : expression->members) if (!trait->type_decoration.empty()) { type const resolved = resolve_underlying_type(trait->type_decoration); - bool const is_enum = resolved.get() != nullptr; - if (!is_enum && !is_discrete_type(resolved)) + if (resolved.get() == nullptr + && !is_primitive_type(resolved, "Float") + && !is_discrete_type(resolved)) { add_error(trait->name, trait->type_decoration); diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc index 79207cc..8561ac4 100644 --- a/gcc/gcc/elna-generic.cc +++ b/gcc/gcc/elna-generic.cc @@ -39,6 +39,8 @@ namespace elna::gcc generic_visitor::generic_visitor(std::shared_ptr symbol_table, boot::symbol_bag bag, const boot::target_info& target) : bag(bag), symbols(symbol_table), target(target) + , const_evaluator(std::make_unique(this->bag, this->target, + this->evaluated_initializers)) { } @@ -862,34 +864,13 @@ namespace elna::gcc { location_t trait_location = get_location(&trait->position()); - if (trait->name == "size") + if (trait->name == "size" || trait->name == "alignment" + || trait->name == "min" || trait->name == "max") { if (expect_trait_type_only(trait)) { - this->current_expression = fold_convert_loc(trait_location, elna_word_type_node, - size_in_bytes(this->current_expression)); - } - } - else if (trait->name == "alignment") - { - if (expect_trait_type_only(trait)) - { - this->current_expression = build_int_cstu(elna_word_type_node, - TYPE_ALIGN_UNIT(this->current_expression)); - } - } - else if (trait->name == "min") - { - if (expect_trait_type_only(trait)) - { - this->current_expression = TYPE_MIN_VALUE(this->current_expression); - } - } - else if (trait->name == "max") - { - if (expect_trait_type_only(trait)) - { - this->current_expression = TYPE_MAX_VALUE(this->current_expression); + this->current_expression = constant_to_tree( + *this->const_evaluator->evaluate_traits(*trait)); } } else if (trait->name == "offset") diff --git a/include/elna/boot/evaluator.h b/include/elna/boot/evaluator.h index f1a5437..08aec6b 100644 --- a/include/elna/boot/evaluator.h +++ b/include/elna/boot/evaluator.h @@ -80,11 +80,11 @@ namespace elna::boot std::optional evaluate_unary(unary_expression& subject); std::optional evaluate_binary(binary_expression& subject); std::optional evaluate_cast(cast_expression& subject); - std::optional evaluate_traits(traits_expression& subject); std::optional evaluate_traits_size(const type& subject); std::optional evaluate_traits_alignment(const type& subject); public: + std::optional evaluate_traits(traits_expression& subject); explicit evaluator(symbol_bag& bag, const target_info& target, const std::map& evaluated_initializers); diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index 9dea83b..aa4bde1 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -17,8 +17,11 @@ along with GCC; see the file COPYING3. If not see #pragma once +#include +#include #include #include "elna/boot/ast.h" +#include "elna/boot/evaluator.h" #include "elna/boot/symbol.h" #include "elna/gcc/elna-tree.h" @@ -36,6 +39,8 @@ namespace elna::gcc elna::boot::symbol_bag bag; std::shared_ptr symbols; const elna::boot::target_info& target; + std::map evaluated_initializers; + std::unique_ptr const_evaluator; void enter_scope(); tree leave_scope(); -- cgit v1.2.3