diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-10-07 17:33:40 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-10-07 17:45:20 +0200 |
| commit | 12e304fd56f054ba7296ab538eecd4280a67832a (patch) | |
| tree | 218f37dc04fa14323d2ca7704e47a830dcd98b22 /include | |
| parent | f547dae96d770cc7bc27d3790d0d87bb8e37963d (diff) | |
| download | elna-12e304fd56f054ba7296ab538eecd4280a67832a.tar.gz | |
Allow assigning contants to enumeration members
Diffstat (limited to 'include')
| -rw-r--r-- | include/elna/boot/ast.h | 21 | ||||
| -rw-r--r-- | include/elna/boot/evaluator.h | 7 | ||||
| -rw-r--r-- | include/elna/boot/name_analysis.h | 5 | ||||
| -rw-r--r-- | include/elna/boot/symbol.h | 9 | ||||
| -rw-r--r-- | include/elna/gcc/elna-tree.h | 2 |
5 files changed, 26 insertions, 18 deletions
diff --git a/include/elna/boot/ast.h b/include/elna/boot/ast.h index fba8ad4..c3b43bb 100644 --- a/include/elna/boot/ast.h +++ b/include/elna/boot/ast.h @@ -546,23 +546,15 @@ namespace elna::boot struct field_initializer { - field_initializer(identifier name, expression *value); - field_initializer(const field_initializer&) = delete; - field_initializer(field_initializer&& other) noexcept; - - field_initializer& operator=(const field_initializer&) = delete; - field_initializer& operator=(field_initializer&& other) noexcept; - - ~field_initializer(); + field_initializer(identifier&& name, expression *value); const std::string& name() const; const identifier& id() const; expression& value() const; - void value(expression& value); private: identifier m_name; - expression *m_value; + std::unique_ptr<expression> m_value; }; class record_constructor_expression : public expression @@ -606,10 +598,15 @@ namespace elna::boot class enumeration_type_expression : public type_expression { public: - const std::vector<identifier> members; + /** + * Member of an enumeration with an optional explicitly written value. + */ + using member_declaration = std::pair<identifier, std::unique_ptr<expression>>; + + const std::vector<member_declaration> members; enumeration_type_expression(const source_position, - std::vector<identifier>&& members); + std::vector<member_declaration>&& members); void accept(parser_visitor *visitor) override; enumeration_type_expression *is_enumeration() override; diff --git a/include/elna/boot/evaluator.h b/include/elna/boot/evaluator.h index dc6fd71..6dc204f 100644 --- a/include/elna/boot/evaluator.h +++ b/include/elna/boot/evaluator.h @@ -40,7 +40,10 @@ namespace elna::boot { type array_type; }; - using payload_type = std::variant<initializer, case_label, array_dimensions>; + struct enumeration_value + { + }; + using payload_type = std::variant<initializer, case_label, array_dimensions, enumeration_value>; non_constant_expression_error(const source_position position, payload_type payload); @@ -93,7 +96,7 @@ namespace elna::boot static std::optional<constant_value> cast_to_bool(const constant_value& source_expression); static std::optional<constant_value> cast_to_char(const constant_value& source_expression); static std::optional<constant_value> cast_to_enumeration(const constant_value& source_expression, - std::size_t member_count, std::size_t target_size); + const enumeration_type& enumeration, std::size_t target_size); static std::optional<constant_value> cast_to_pointer(const constant_value& source_expression); public: diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h index d3f6f10..5cf5d43 100644 --- a/include/elna/boot/name_analysis.h +++ b/include/elna/boot/name_analysis.h @@ -131,7 +131,8 @@ namespace elna::boot array_position, duplicate, constant_procedure, - module_entry + module_entry, + enumeration_values }; struct not_initialized { @@ -154,7 +155,7 @@ namespace elna::boot class member_error final : public diagnostic { public: - enum class kind { not_found, field_on_type }; + enum class kind { not_found, field_on_type, duplicate_value, value_out_of_range }; struct duplicate { std::optional<source_position> original; std::optional<std::string> base; diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h index 0d07b88..07bcf80 100644 --- a/include/elna/boot/symbol.h +++ b/include/elna/boot/symbol.h @@ -209,8 +209,15 @@ namespace elna::boot struct enumeration_type { std::vector<std::string> members; + /// Value of each member, in the order of \c members. + std::vector<std::ptrdiff_t> values; - explicit enumeration_type(const std::vector<std::string>& members); + enumeration_type(const std::vector<std::string>& members, const std::vector<std::ptrdiff_t>& values); + + /// \return The smallest member value. + std::ptrdiff_t minimum() const; + /// \return The largest member value. + std::ptrdiff_t maximum() const; }; /** diff --git a/include/elna/gcc/elna-tree.h b/include/elna/gcc/elna-tree.h index 6dd3616..c160a9b 100644 --- a/include/elna/gcc/elna-tree.h +++ b/include/elna/gcc/elna-tree.h @@ -49,7 +49,7 @@ namespace elna::gcc tree find_field_by_name(tree type, const std::string& field_name); tree build_static_array_type(tree type, const std::uint64_t size); tree build_slice(tree slice_type, tree ptr, tree length); - tree build_enumeration_type(const std::vector<std::string>& members); + tree build_enumeration_type(const boot::enumeration_type& enumeration); tree extract_constant(tree expression); tree constant_to_tree(const boot::constant_value& value, |
