mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 06:58:45 +00:00
212 lines
5.4 KiB
C++
212 lines
5.4 KiB
C++
#pragma once
|
|
|
|
#include <string>
|
|
#include <variant>
|
|
#include <optional>
|
|
#include <unordered_map>
|
|
|
|
// for clangd
|
|
#include "interpreter_tree.hpp"
|
|
#include "utils.hpp"
|
|
|
|
namespace info::value {
|
|
|
|
struct ValueManager;
|
|
|
|
struct Unit {};
|
|
|
|
struct InternalValue {
|
|
public:
|
|
InternalValue() = default;
|
|
|
|
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;
|
|
}
|
|
return &std::get<T>(value);
|
|
}
|
|
|
|
bool Same(const InternalValue& value) const;
|
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
public:
|
|
std::variant<double,
|
|
long long,
|
|
std::string,
|
|
char,
|
|
bool,
|
|
Unit> value;
|
|
};
|
|
|
|
struct TupleValue {
|
|
public:
|
|
TupleValue() = default;
|
|
|
|
TupleValue(std::vector<std::pair<std::optional<std::string>, utils::IdType>>&& fields,
|
|
ValueManager* value_manager)
|
|
: fields(std::move(fields)), value_manager_(value_manager) {}
|
|
|
|
bool Same(const TupleValue& other_value) const;
|
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
public:
|
|
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
|
|
|
|
private:
|
|
ValueManager* value_manager_ = nullptr;
|
|
};
|
|
|
|
struct VariantValue {
|
|
public:
|
|
explicit VariantValue() = default;
|
|
|
|
VariantValue(TupleValue&& value, size_t current_constructor)
|
|
: value(std::move(value)), current_constructor(current_constructor) {}
|
|
|
|
public:
|
|
TupleValue value;
|
|
size_t current_constructor;
|
|
|
|
bool Same(const VariantValue& other_value) const;
|
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
};
|
|
|
|
struct ReferenceToValue {
|
|
public:
|
|
ReferenceToValue() = default;
|
|
|
|
ReferenceToValue(const std::vector<utils::ReferenceModifier>& references,
|
|
utils::IdType value,
|
|
ValueManager* value_manager)
|
|
: references(references), value(value), value_manager_(value_manager) {}
|
|
|
|
public:
|
|
std::vector<utils::ReferenceModifier> references;
|
|
utils::IdType value;
|
|
|
|
bool Same(const ReferenceToValue& other_value) const;
|
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
|
|
private:
|
|
ValueManager* value_manager_ = nullptr;
|
|
};
|
|
|
|
struct FunctionValue {
|
|
public:
|
|
FunctionValue() = default;
|
|
|
|
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;
|
|
|
|
bool Same(const FunctionValue& other_value) const;
|
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
|
|
private:
|
|
ValueManager* value_manager_ = nullptr;
|
|
};
|
|
|
|
|
|
struct ArrayValue {
|
|
public:
|
|
ArrayValue() = default;
|
|
|
|
ArrayValue(std::vector<utils::IdType>&& elements,
|
|
bool is_constant_size,
|
|
ValueManager* value_manager)
|
|
: 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;
|
|
|
|
bool Same(const ArrayValue& other_value) const;
|
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
|
|
private:
|
|
ValueManager* value_manager_ = nullptr;
|
|
};
|
|
|
|
struct OptionalValue {
|
|
public:
|
|
OptionalValue() = default;
|
|
|
|
OptionalValue(std::optional<utils::IdType> value, ValueManager* value_manager)
|
|
: value(value), value_manager_(value_manager) {}
|
|
|
|
bool Same(const OptionalValue& other_value) const;
|
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
|
|
public:
|
|
std::optional<utils::IdType> value;
|
|
|
|
private:
|
|
ValueManager* value_manager_ = nullptr;
|
|
};
|
|
|
|
struct Value { // DefinedValue ??
|
|
public:
|
|
Value() = default;
|
|
|
|
template<typename T>
|
|
explicit Value(const T& value) : value(value) {} // move ??
|
|
|
|
bool Same(const Value& other_value) const;
|
|
std::optional<utils::IdType> GetFieldValue(const std::string& name) const;
|
|
|
|
public:
|
|
std::variant<InternalValue,
|
|
TupleValue,
|
|
VariantValue,
|
|
ReferenceToValue,
|
|
FunctionValue, // ??
|
|
ArrayValue,
|
|
OptionalValue> value;
|
|
};
|
|
|
|
class ValueManager {
|
|
public:
|
|
template<typename T>
|
|
utils::IdType AddValue(const T& value, utils::ValueType value_type) {
|
|
values_.push_back(std::pair<Value, utils::ValueType> {Value(value), value_type});
|
|
return values_.size() - 1;
|
|
}
|
|
|
|
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>
|
|
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);
|
|
}
|
|
|
|
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 EqualValues(utils::IdType first_value, utils::IdType second_value) {
|
|
return GetAnyValue(first_value)->Same(*GetAnyValue(second_value));
|
|
}
|
|
|
|
bool AddValueRequirement(utils::IdType value, utils::IdType requrement) = delete;
|
|
|
|
private:
|
|
std::vector<std::pair<Value, utils::ValueType>> values_;
|
|
};
|
|
|
|
} // namespace info::value
|