aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-10-07 17:33:40 +0200
committerEugen Wissner <belka@caraus.de>2026-10-07 17:45:20 +0200
commit12e304fd56f054ba7296ab538eecd4280a67832a (patch)
tree218f37dc04fa14323d2ca7704e47a830dcd98b22 /include
parentf547dae96d770cc7bc27d3790d0d87bb8e37963d (diff)
downloadelna-12e304fd56f054ba7296ab538eecd4280a67832a.tar.gz
Allow assigning contants to enumeration members
Diffstat (limited to 'include')
-rw-r--r--include/elna/boot/ast.h21
-rw-r--r--include/elna/boot/evaluator.h7
-rw-r--r--include/elna/boot/name_analysis.h5
-rw-r--r--include/elna/boot/symbol.h9
-rw-r--r--include/elna/gcc/elna-tree.h2
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,