diff options
Diffstat (limited to 'include/elna/boot/symbol.h')
| -rw-r--r-- | include/elna/boot/symbol.h | 55 |
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; |
