From 8539c10542a4be1e1127daea60bf1b1e4c37e092 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 1 Aug 2026 09:30:39 +0200 Subject: Fix compile-time negation and array access --- include/elna/boot/ast.h | 5 +---- include/elna/boot/evaluator.h | 1 + include/elna/boot/name_analysis.h | 1 - include/elna/boot/result.h | 42 ++++++++++++++++++++++++++++----------- include/elna/gcc/elna-generic.h | 1 - 5 files changed, 32 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index 0eda1a3..996c58a 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -138,7 +138,6 @@ namespace elna::boot virtual void visit(array_access_expression *) = 0; virtual void visit(field_access_expression *) = 0; virtual void visit(dereference_expression *) = 0; - virtual void visit(literal *) = 0; virtual void visit(literal *) = 0; virtual void visit(literal *) = 0; virtual void visit(literal *) = 0; @@ -188,7 +187,6 @@ namespace elna::boot [[noreturn]] void visit(array_access_expression *) override; [[noreturn]] void visit(field_access_expression *) override; [[noreturn]] void visit(dereference_expression *) override; - [[noreturn]] void visit(literal *) override; [[noreturn]] void visit(literal *) override; [[noreturn]] void visit(literal *) override; [[noreturn]] void visit(literal *) override; @@ -236,7 +234,6 @@ namespace elna::boot void visit(array_access_expression *expression) override; void visit(field_access_expression *expression) override; void visit(dereference_expression *expression) override; - void visit(literal *) override; void visit(literal *) override; void visit(literal *) override; void visit(literal *) override; @@ -521,7 +518,7 @@ namespace elna::boot std::vector&& entry_point, expression *return_expression = nullptr); procedure_body(const procedure_body&) = delete; - procedure_body(procedure_body&& that); + procedure_body(procedure_body&& that) noexcept; procedure_body& operator=(const procedure_body&) = delete; diff --git a/include/elna/boot/evaluator.h b/include/elna/boot/evaluator.h index 8b36e1b..84bd5ab 100644 --- a/include/elna/boot/evaluator.h +++ b/include/elna/boot/evaluator.h @@ -53,6 +53,7 @@ namespace elna::boot std::optional evaluate_named(named_expression& subject); std::optional evaluate_array_access(array_access_expression& subject); std::optional evaluate_field_access(field_access_expression& subject); + std::optional evaluate_index(expression& subject); std::optional evaluate_slicing(slicing_expression& subject); std::optional evaluate_unary(unary_expression& subject); std::optional evaluate_binary(binary_expression& subject); diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h index 5d43f67..ab86a44 100644 --- a/include/elna/boot/name_analysis.h +++ b/include/elna/boot/name_analysis.h @@ -157,7 +157,6 @@ namespace elna::boot void visit(for_statement *statement) override; - void visit(literal *literal) override; void visit(literal *literal) override; void visit(literal *literal) override; void visit(literal *literal) override; diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h index 3e8dfdf..4c6046d 100644 --- a/include/elna/boot/result.h +++ b/include/elna/boot/result.h @@ -216,16 +216,6 @@ namespace elna::boot template inline constexpr bool is_integral = is_signed || is_unsigned; - /** - * Checks whether \p T is an integral or floating point type. - * - * \tparam T The examined type. - * - * \see is_integral - */ - template - inline constexpr bool is_arithmetic = is_integral || std::is_floating_point_v; - struct integer_literal { integer_literal(integer_literal&& that) noexcept; @@ -283,13 +273,27 @@ namespace elna::boot T to() const requires is_integral { - T result; + T result{}; mpz_export(&result, nullptr, 1, sizeof(T), 0, 0, this->raw); return result; } + /** + * Exports the stored value as a host \c std::ptrdiff_t. + * + * \return The converted value, or \c std::nullopt if out of range. + */ + std::optional to_signed() const; + + /** + * Exports the stored value as a host \c std::size_t. + * + * \return The converted value, or \c std::nullopt if out of range. + */ + std::optional to_unsigned() const; + template static integer_literal from(T initial) requires is_integral @@ -301,6 +305,8 @@ namespace elna::boot return result; } + friend void swap(integer_literal& lhs, integer_literal& rhs) noexcept; + private: bool m_signed; std::size_t m_size; @@ -308,8 +314,21 @@ namespace elna::boot integer_literal(bool is_signed, std::size_t size); std::optional check() &&; + bool is_negative_minimum(const std::size_t bits) const; bool is_negative_minimum() const; std::size_t bits() const; + + template + std::pair export_to_words() const + { + constexpr std::size_t word_count = std::max(1U, 8 / sizeof(T)); + std::array rop{}; + std::size_t written{ 0 }; + + mpz_export(rop.data(), &written, 1, sizeof(T), 0, 0, this->raw); + + return { written, rop[0] }; + } }; /** @@ -503,7 +522,6 @@ namespace elna::boot * array constructors as a vector of elements. */ using constant_value = std::variant< - std::int32_t, integer_literal, double, bool, diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index 944c4d0..097a660 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -73,7 +73,6 @@ namespace elna::gcc void visit(boot::procedure_declaration *declaration) override; void visit(boot::procedure_call *call) override; void visit(boot::cast_expression *expression) override; - void visit(boot::literal *literal) override; void visit(boot::literal *literal) override; void visit(boot::literal *literal) override; void visit(boot::literal *boolean) override; -- cgit v1.2.3