#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; InternalValue(std::variant&& value) : value(std::move(value)) {} public: std::variant value; }; struct TupleValue { public: TupleValue() = default; TupleValue(std::unordered_map&& fields) : fields(fields) {} public: std::unordered_map fields; }; struct VariantValue { public: VariantValue() = default; VariantValue(size_t constructor, TupleValue value) : constructor(constructor), value(value) {} public: size_t constructor; TupleValue 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; ArrayValue(const std::vector& elements) : elements(elements) {} public: std::vector elements; }; struct OptionalValue { public: OptionalValue() = default; OptionalValue(utils::IdType value) : value(value) {} public: std::optional value; }; struct Value { // DefinedValue ?? std::variant value; }; class ValueManager { public: template utils::IdType AddType(const T& value, utils::ValueType value_type) { values_.push_back(std::pair {value, value_type}); return values_.size() - 1; } utils::IdType AddAnyType(Value&& value, utils::ValueType value_type) { values_.push_back(std::pair {std::move(value), value_type}); return values_.size() - 1; } template std::optional GetType(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* GetAnyType(utils::IdType value_id) { return &values_.at(value_id).first; } utils::ValueType GetValueType(utils::IdType value_id) { return values_.at(value_id).second; } private: std::vector> values_; }; } // namespace info::value