diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-07-20 16:09:24 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-07-20 16:09:24 +0200 |
| commit | 6b131c925dee7a5f97516edd581e051e08bb52d8 (patch) | |
| tree | 680ae83121442f777e03aa0a0d1299cc364b95dd | |
| parent | cbbe1593bb0893654bd71e611ca610df03bac768 (diff) | |
| download | elna-6b131c925dee7a5f97516edd581e051e08bb52d8.tar.gz | |
Implement min and max for booleans and floats
| -rw-r--r-- | boot/evaluator.cc | 16 | ||||
| -rw-r--r-- | boot/name_analysis.cc | 5 | ||||
| -rw-r--r-- | gcc/gcc/elna-generic.cc | 31 | ||||
| -rw-r--r-- | include/elna/boot/evaluator.h | 2 | ||||
| -rw-r--r-- | 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<unsigned char>(0) }; } + if (is_primitive_type(resolved, "Bool")) + { + return constant_value{ false }; + } + if (is_primitive_type(resolved, "Float")) + { + return constant_value{ -std::numeric_limits<double>::max() }; + } if (auto enumeration = resolved.get<enumeration_type>()) { return constant_value{ 1 }; @@ -555,6 +563,14 @@ namespace elna::boot { return constant_value{ std::numeric_limits<unsigned char>::max() }; } + if (is_primitive_type(resolved, "Bool")) + { + return constant_value{ true }; + } + if (is_primitive_type(resolved, "Float")) + { + return constant_value{ std::numeric_limits<double>::max() }; + } if (auto enumeration = resolved.get<enumeration_type>()) { return constant_value{ static_cast<std::int32_t>(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<enumeration_type>() != nullptr; - if (!is_enum && !is_discrete_type(resolved)) + if (resolved.get<enumeration_type>() == nullptr + && !is_primitive_type(resolved, "Float") + && !is_discrete_type(resolved)) { add_error<unsupported_trait_type_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> symbol_table, boot::symbol_bag bag, const boot::target_info& target) : bag(bag), symbols(symbol_table), target(target) + , const_evaluator(std::make_unique<boot::evaluator>(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<constant_value> evaluate_unary(unary_expression& subject); std::optional<constant_value> evaluate_binary(binary_expression& subject); std::optional<constant_value> evaluate_cast(cast_expression& subject); - std::optional<constant_value> evaluate_traits(traits_expression& subject); std::optional<std::size_t> evaluate_traits_size(const type& subject); std::optional<std::size_t> evaluate_traits_alignment(const type& subject); public: + std::optional<constant_value> evaluate_traits(traits_expression& subject); explicit evaluator(symbol_bag& bag, const target_info& target, const std::map<std::string, expression*>& 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 <map> +#include <memory> #include <string> #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<symbol_table> symbols; const elna::boot::target_info& target; + std::map<std::string, boot::expression *> evaluated_initializers; + std::unique_ptr<boot::evaluator> const_evaluator; void enter_scope(); tree leave_scope(); |
