lang_2023/include/values.hpp

198 lines
4.9 KiB
C++
Raw Normal View History

#pragma once
#include <string>
#include <variant>
#include <optional>
#include <unordered_map>
// for clangd
#include "interpreter_tree.hpp"
#include "utils.hpp"
namespace info::value {
2023-05-09 23:36:47 +03:00
struct ValueManager;
struct Unit {};
struct InternalValue {
public:
InternalValue() = default;
2023-05-09 15:51:13 +03:00
template<typename T>
explicit InternalValue(const T& value) : value(value) {} // move ??
template<typename T>
std::optional<T*> GetValue() {
if (!std::holds_alternative<T>(value)) {
return std::nullopt;
}
2023-05-09 15:51:13 +03:00
return &std::get<T>(value);
}
2023-05-09 23:36:47 +03:00
std::optional<utils::IdType> GetFieldValue(const std::string& name);
public:
std::variant<double,
long long,
std::string,
char,
bool,
Unit> value;
};
struct TupleValue {
public:
2023-05-10 23:13:50 +03:00
TupleValue() = default;
2023-05-10 23:13:50 +03:00
TupleValue(std::vector<std::pair<std::optional<std::string>, utils::IdType>>&& fields,
ValueManager* value_manager)
2023-05-09 23:36:47 +03:00
: fields(std::move(fields)), value_manager_(value_manager) {}
std::optional<utils::IdType> GetFieldValue(const std::string& name);
public:
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
2023-05-09 23:36:47 +03:00
private:
2023-05-10 23:13:50 +03:00
ValueManager* value_manager_ = nullptr;
};
struct VariantValue {
public:
2023-05-10 23:13:50 +03:00
explicit VariantValue() = default;
2023-05-09 23:36:47 +03:00
2023-05-10 23:13:50 +03:00
VariantValue(TupleValue&& value, size_t current_constructor)
: value(std::move(value)), current_constructor(current_constructor) {}
public:
2023-05-10 23:13:50 +03:00
TupleValue value;
2023-05-09 23:36:47 +03:00
size_t current_constructor;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
};
struct ReferenceToValue {
public:
2023-05-10 23:13:50 +03:00
ReferenceToValue() = default;
2023-05-09 23:36:47 +03:00
ReferenceToValue(const std::vector<utils::ReferenceModifier>& references,
2023-05-09 23:36:47 +03:00
utils::IdType value,
ValueManager* value_manager)
: references(references), value(value), value_manager_(value_manager) {}
public:
std::vector<utils::ReferenceModifier> references;
utils::IdType value;
2023-05-09 23:36:47 +03:00
std::optional<utils::IdType> GetFieldValue(const std::string& name);
private:
2023-05-10 23:13:50 +03:00
ValueManager* value_manager_ = nullptr;
};
struct FunctionValue {
public:
2023-05-10 23:13:50 +03:00
FunctionValue() = default;
2023-05-09 23:36:47 +03:00
template<typename T>
FunctionValue(const T& function, ValueManager* value_manager)
: function(function), value_manager_(value_manager) {}
public:
std::variant<interpreter::tokens::FunctionDeclaration*,
interpreter::tokens::LambdaFunction*> function;
2023-05-09 23:36:47 +03:00
std::optional<utils::IdType> GetFieldValue(const std::string& name);
private:
2023-05-10 23:13:50 +03:00
ValueManager* value_manager_ = nullptr;
};
struct ArrayValue {
public:
2023-05-10 23:13:50 +03:00
ArrayValue() = default;
2023-05-09 23:36:47 +03:00
2023-05-10 23:13:50 +03:00
ArrayValue(std::vector<utils::IdType>&& elements,
bool is_constant_size,
ValueManager* value_manager)
2023-05-09 23:36:47 +03:00
: elements(std::move(elements)), is_constant_size(is_constant_size), value_manager_(value_manager) {}
public:
std::vector<utils::IdType> elements;
bool is_constant_size = false;
2023-05-09 23:36:47 +03:00
std::optional<utils::IdType> GetFieldValue(const std::string& name);
private:
2023-05-10 23:13:50 +03:00
ValueManager* value_manager_ = nullptr;
};
struct OptionalValue {
public:
2023-05-10 23:13:50 +03:00
OptionalValue() = default;
2023-05-09 23:36:47 +03:00
2023-05-10 23:13:50 +03:00
OptionalValue(std::optional<utils::IdType> value, ValueManager* value_manager)
2023-05-09 23:36:47 +03:00
: value(value), value_manager_(value_manager) {}
2023-05-09 23:36:47 +03:00
std::optional<utils::IdType> GetFieldValue(const std::string& name);
public:
std::optional<utils::IdType> value;
2023-05-09 23:36:47 +03:00
private:
2023-05-10 23:13:50 +03:00
ValueManager* value_manager_ = nullptr;
};
struct Value { // DefinedValue ??
2023-05-09 15:51:13 +03:00
public:
Value() = default;
template<typename T>
explicit Value(const T& value) : value(value) {} // move ??
2023-05-09 23:36:47 +03:00
std::optional<utils::IdType> GetFieldValue(const std::string& name);
2023-05-09 15:51:13 +03:00
public:
std::variant<InternalValue,
TupleValue,
VariantValue,
ReferenceToValue,
FunctionValue, // ??
ArrayValue,
OptionalValue> value;
};
class ValueManager {
public:
template<typename T>
2023-05-07 20:21:19 +03:00
utils::IdType AddValue(const T& value, utils::ValueType value_type) {
2023-05-09 15:51:13 +03:00
values_.push_back(std::pair<Value, utils::ValueType> {Value(value), value_type});
return values_.size() - 1;
}
2023-05-07 20:21:19 +03:00
utils::IdType AddAnyValue(Value&& value, utils::ValueType value_type) {
values_.push_back(std::pair<Value, utils::ValueType> {std::move(value), value_type});
return values_.size() - 1;
}
template<typename T>
2023-05-07 20:21:19 +03:00
std::optional<T*> GetValue(utils::IdType value_id) {
if (!std::holds_alternative<T>(values_.at(value_id).first.value)) {
return std::nullopt;
}
return &std::get<T>(values_.at(value_id).first.value);
}
2023-05-07 20:21:19 +03:00
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;
}
2023-05-09 15:51:13 +03:00
2023-05-10 23:13:50 +03:00
bool EqualValues(utils::IdType first_value, utils::IdType second_value) = delete; // TODO
2023-05-09 15:51:13 +03:00
2023-05-10 23:13:50 +03:00
bool AddValueRequirement(utils::IdType value, utils::IdType requrement) = delete;
2023-05-09 15:51:13 +03:00
private:
std::vector<std::pair<Value, utils::ValueType>> values_;
};
} // namespace info::value