#pragma once #include #include #include #include // for clangd #include "interpreter_tree.hpp" #include "utils.hpp" namespace info::value { struct Unit {}; struct InternalValue { public: InternalValue() = default; template explicit InternalValue(const T& value) : value(value) {} // move ?? template std::optional GetValue() { if (!std::holds_alternative(value)) { return std::nullopt; } return &std::get(value); } public: std::variant value; }; struct TupleValue { public: TupleValue() = default; explicit TupleValue(std::vector, utils::IdType>>&& fields) : fields(std::move(fields)) {} public: std::vector, utils::IdType>> fields; }; struct VariantValue { public: VariantValue() = default; VariantValue(utils::IdType value) // TupleValue ?? // TODO: add type & constructor?? : value(value) {} public: utils::IdType value; }; struct ReferenceToValue { public: ReferenceToValue() = default; ReferenceToValue(const std::vector& references, utils::IdType value) : references(references), value(value) {} public: std::vector references; utils::IdType value; }; struct FunctionValue { public: FunctionValue() = default; FunctionValue(std::variant function) : function(function) {} public: std::variant function; }; struct ArrayValue { public: ArrayValue() = default; explicit ArrayValue(std::vector&& elements, bool is_constant_size) : elements(std::move(elements)), is_constant_size(is_constant_size) {} public: std::vector elements; bool is_constant_size = false; }; struct OptionalValue { public: OptionalValue() = default; explicit OptionalValue(utils::IdType value) : value(value) {} public: std::optional value; }; struct Value { // DefinedValue ?? public: Value() = default; template explicit Value(const T& value) : value(value) {} // move ?? public: std::variant value; }; class ValueManager { public: template utils::IdType AddValue(const T& value, utils::ValueType value_type) { values_.push_back(std::pair {Value(value), value_type}); return values_.size() - 1; } utils::IdType AddAnyValue(Value&& value, utils::ValueType value_type) { values_.push_back(std::pair {std::move(value), value_type}); return values_.size() - 1; } template std::optional GetValue(utils::IdType value_id) { if (!std::holds_alternative(values_.at(value_id).first.value)) { return std::nullopt; } return &std::get(values_.at(value_id).first.value); } Value* GetAnyValue(utils::IdType value_id) { return &values_.at(value_id).first; } utils::ValueType GetValueType(utils::IdType value_id) { return values_.at(value_id).second; } bool EqualTypes(utils::IdType first_type, utils::IdType second_type) = delete; // TODO bool AddTypeRequirement(utils::IdType type, utils::IdType requrement) = delete; private: std::vector> values_; }; } // namespace info::value