aboutsummaryrefslogtreecommitdiff
path: root/include/elna/boot/symbol.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/elna/boot/symbol.h')
-rw-r--r--include/elna/boot/symbol.h55
1 files changed, 43 insertions, 12 deletions
diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h
index 46d9c2c..dd3e8ff 100644
--- a/include/elna/boot/symbol.h
+++ b/include/elna/boot/symbol.h
@@ -41,9 +41,15 @@ namespace elna::boot
struct procedure_type;
struct enumeration_type;
+ /**
+ * Represents a type stored in the symbol table.
+ *
+ * All types are wrapped in \c std::shared_ptr so that copying is cheap.
+ * There is also an empty type representing an error.
+ */
class type
{
- std::variant<
+ using Payload = std::variant<
std::monostate,
std::weak_ptr<alias_type>,
std::shared_ptr<primitive_type>,
@@ -54,21 +60,45 @@ namespace elna::boot
std::shared_ptr<slice_type>,
std::shared_ptr<procedure_type>,
std::shared_ptr<enumeration_type>
- > payload;
+ >;
+ Payload payload;
public:
+ /**
+ * Constructs an empty, invalid type.
+ */
type() = default;
+ /**
+ * Constructs a type alias.
+ *
+ * The specialization is required because the type is internally stored
+ * as \c std::weak_ptr.
+ *
+ * \param alias Stored type.
+ */
explicit type(std::shared_ptr<alias_type> alias);
- explicit type(std::shared_ptr<primitive_type> primitive);
- explicit type(std::shared_ptr<record_type> record);
- explicit type(std::shared_ptr<pointer_type> pointer);
- explicit type(std::shared_ptr<constant_type> constant);
- explicit type(std::shared_ptr<array_type> array);
- explicit type(std::shared_ptr<slice_type> slice);
- explicit type(std::shared_ptr<procedure_type> procedure);
- explicit type(std::shared_ptr<enumeration_type> enumeration);
+ /**
+ * Constructs a non empty type.
+ *
+ * \tparam T Type kind.
+ * \param value Concrete type.
+ */
+ template<typename T>
+ explicit type(std::shared_ptr<T> value)
+ requires is_in_variant_v<std::shared_ptr<T>, Payload>
+ : payload(std::move(value))
+ {
+ }
+
+ /**
+ * Checks whether \p T is currently stored and returns this concrete
+ * type.
+ *
+ * \tparam T Type kind to check.
+ * \return Concrete type or \c nullptr.
+ */
template<typename T>
std::shared_ptr<T> get() const;
@@ -76,6 +106,9 @@ namespace elna::boot
bool operator==(const type& other) const;
explicit operator bool() const;
+ /**
+ * \return Whether type holds no concrete type.
+ */
bool empty() const;
/**
@@ -129,8 +162,6 @@ namespace elna::boot
explicit primitive_type(const std::string& identifier);
};
- using type_field = std::pair<std::string, type>;
-
struct record_type
{
ordered_map<type> fields;