mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +00:00
fixes, part of execute_visitor
This commit is contained in:
parent
7d96fe5a86
commit
802b736e15
7 changed files with 345 additions and 92 deletions
|
|
@ -18,6 +18,7 @@ include_directories(include
|
||||||
|
|
||||||
add_executable(lang_interpreter src/main.cpp
|
add_executable(lang_interpreter src/main.cpp
|
||||||
src/types.cpp
|
src/types.cpp
|
||||||
|
src/values.cpp
|
||||||
src/global_info.cpp
|
src/global_info.cpp
|
||||||
include/definitions.hpp
|
include/definitions.hpp
|
||||||
src/visitor.cpp
|
src/visitor.cpp
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ private:
|
||||||
|
|
||||||
bool HandleCondition(Expression& condition, const BaseNode& base_node);
|
bool HandleCondition(Expression& condition, const BaseNode& base_node);
|
||||||
void CollectTypeContext(const ParametrizedType& type);
|
void CollectTypeContext(const ParametrizedType& type);
|
||||||
|
void CheckPattern(Pattern& node, const BaseNode& base_node);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
T* ExtractValue(utils::IdType value, const BaseNode& base_node) {
|
T* ExtractValue(utils::IdType value, const BaseNode& base_node) {
|
||||||
|
|
@ -169,6 +170,7 @@ private:
|
||||||
std::optional<LoopControlExpression> active_loop_control_expression_;
|
std::optional<LoopControlExpression> active_loop_control_expression_;
|
||||||
std::optional<utils::IdType> return_value_; // TODO: work outside block ??
|
std::optional<utils::IdType> return_value_; // TODO: work outside block ??
|
||||||
std::optional<utils::IsConstModifier> is_const_definition_;
|
std::optional<utils::IsConstModifier> is_const_definition_;
|
||||||
|
bool case_matched_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace interpreter
|
} // namespace interpreter
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace info::value {
|
namespace info::value {
|
||||||
|
|
||||||
|
struct ValueManager;
|
||||||
|
|
||||||
struct Unit {};
|
struct Unit {};
|
||||||
|
|
||||||
struct InternalValue {
|
struct InternalValue {
|
||||||
|
|
@ -27,6 +29,8 @@ public:
|
||||||
}
|
}
|
||||||
return &std::get<T>(value);
|
return &std::get<T>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name);
|
||||||
public:
|
public:
|
||||||
std::variant<double,
|
std::variant<double,
|
||||||
long long,
|
long long,
|
||||||
|
|
@ -38,67 +42,104 @@ public:
|
||||||
|
|
||||||
struct TupleValue {
|
struct TupleValue {
|
||||||
public:
|
public:
|
||||||
TupleValue() = default;
|
explicit TupleValue(ValueManager* value_manager) : value_manager_(value_manager) {}
|
||||||
explicit TupleValue(std::vector<std::pair<std::optional<std::string>, utils::IdType>>&& fields) : fields(std::move(fields)) {}
|
|
||||||
|
|
||||||
|
explicit TupleValue(std::vector<std::pair<std::optional<std::string>, utils::IdType>>&& fields,
|
||||||
|
ValueManager* value_manager)
|
||||||
|
: fields(std::move(fields)), value_manager_(value_manager) {}
|
||||||
|
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name);
|
||||||
public:
|
public:
|
||||||
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
|
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ValueManager* value_manager_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariantValue {
|
struct VariantValue {
|
||||||
public:
|
public:
|
||||||
VariantValue() = default;
|
explicit VariantValue(ValueManager* value_manager) : value_manager_(value_manager) {}
|
||||||
VariantValue(utils::IdType value) // TupleValue ?? // TODO: add type & constructor??
|
|
||||||
: value(value) {}
|
// TupleValue ?? // TODO: add type??
|
||||||
|
VariantValue(utils::IdType value, size_t current_constructor, ValueManager* value_manager)
|
||||||
|
: value(value), current_constructor(current_constructor), value_manager_(value_manager) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
utils::IdType value;
|
utils::IdType value;
|
||||||
|
size_t current_constructor;
|
||||||
|
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name);
|
||||||
|
private:
|
||||||
|
ValueManager* value_manager_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReferenceToValue {
|
struct ReferenceToValue {
|
||||||
public:
|
public:
|
||||||
ReferenceToValue() = default;
|
explicit ReferenceToValue(ValueManager* value_manager) : value_manager_(value_manager) {}
|
||||||
|
|
||||||
ReferenceToValue(const std::vector<utils::ReferenceModifier>& references,
|
ReferenceToValue(const std::vector<utils::ReferenceModifier>& references,
|
||||||
utils::IdType value)
|
utils::IdType value,
|
||||||
: references(references), value(value) {}
|
ValueManager* value_manager)
|
||||||
|
: references(references), value(value), value_manager_(value_manager) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<utils::ReferenceModifier> references;
|
std::vector<utils::ReferenceModifier> references;
|
||||||
utils::IdType value;
|
utils::IdType value;
|
||||||
|
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name);
|
||||||
|
private:
|
||||||
|
ValueManager* value_manager_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionValue {
|
struct FunctionValue {
|
||||||
public:
|
public:
|
||||||
FunctionValue() = default;
|
explicit FunctionValue(ValueManager* value_manager) : value_manager_(value_manager) {}
|
||||||
FunctionValue(std::variant<interpreter::tokens::FunctionDeclaration*,
|
|
||||||
interpreter::tokens::LambdaFunction*> function)
|
template<typename T>
|
||||||
: function(function) {}
|
FunctionValue(const T& function, ValueManager* value_manager)
|
||||||
|
: function(function), value_manager_(value_manager) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::variant<interpreter::tokens::FunctionDeclaration*,
|
std::variant<interpreter::tokens::FunctionDeclaration*,
|
||||||
interpreter::tokens::LambdaFunction*> function;
|
interpreter::tokens::LambdaFunction*> function;
|
||||||
|
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name);
|
||||||
|
private:
|
||||||
|
ValueManager* value_manager_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct ArrayValue {
|
struct ArrayValue {
|
||||||
public:
|
public:
|
||||||
ArrayValue() = default;
|
explicit ArrayValue(ValueManager* value_manager) : value_manager_(value_manager) {}
|
||||||
|
|
||||||
explicit ArrayValue(std::vector<utils::IdType>&& elements,
|
explicit ArrayValue(std::vector<utils::IdType>&& elements,
|
||||||
bool is_constant_size)
|
bool is_constant_size,
|
||||||
: elements(std::move(elements)), is_constant_size(is_constant_size) {}
|
ValueManager* value_manager)
|
||||||
|
: elements(std::move(elements)), is_constant_size(is_constant_size), value_manager_(value_manager) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<utils::IdType> elements;
|
std::vector<utils::IdType> elements;
|
||||||
bool is_constant_size = false;
|
bool is_constant_size = false;
|
||||||
|
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name);
|
||||||
|
private:
|
||||||
|
ValueManager* value_manager_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OptionalValue {
|
struct OptionalValue {
|
||||||
public:
|
public:
|
||||||
OptionalValue() = default;
|
explicit OptionalValue(ValueManager* value_manager) : value_manager_(value_manager) {}
|
||||||
explicit OptionalValue(utils::IdType value) : value(value) {}
|
|
||||||
|
|
||||||
|
explicit OptionalValue(utils::IdType value, ValueManager* value_manager)
|
||||||
|
: value(value), value_manager_(value_manager) {}
|
||||||
|
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name);
|
||||||
public:
|
public:
|
||||||
std::optional<utils::IdType> value;
|
std::optional<utils::IdType> value;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ValueManager* value_manager_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Value { // DefinedValue ??
|
struct Value { // DefinedValue ??
|
||||||
|
|
@ -108,6 +149,7 @@ public:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
explicit Value(const T& value) : value(value) {} // move ??
|
explicit Value(const T& value) : value(value) {} // move ??
|
||||||
|
|
||||||
|
std::optional<utils::IdType> GetFieldValue(const std::string& name);
|
||||||
public:
|
public:
|
||||||
std::variant<InternalValue,
|
std::variant<InternalValue,
|
||||||
TupleValue,
|
TupleValue,
|
||||||
|
|
|
||||||
|
|
@ -60,50 +60,82 @@ void ExecuteVisitor::Visit(PartitionStatement* node) {
|
||||||
|
|
||||||
// Flow control -----------------
|
// Flow control -----------------
|
||||||
|
|
||||||
// TODO
|
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {} // handled in TypeConstructorPattern
|
||||||
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {
|
|
||||||
if (node->name.has_value()) {
|
|
||||||
// Visit(&node->name.value());
|
|
||||||
}
|
|
||||||
Visitor::Visit(node->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
|
void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
|
||||||
// TODO: not only tuples
|
// TODO: not only tuples
|
||||||
Visit(node->constructor.get());
|
Visit(node->constructor.get()); // TODO: ?? check is same constructor_id ??
|
||||||
for (auto& parameter : node->parameters) {
|
for (auto& parameter : node->parameters) { // TODO: pass parameters separately
|
||||||
Visit(¶meter);
|
Visitor::Visit(parameter.value); // handle TypeConstructorPatternParameter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
void ExecuteVisitor::Visit(MatchCase* node) {} // handeled in Match
|
||||||
void ExecuteVisitor::Visit(MatchCase* node) {
|
|
||||||
Visitor::Visit(node->value);
|
|
||||||
if (node->condition.has_value()) {
|
|
||||||
Visitor::Visit(node->condition.value());
|
|
||||||
}
|
|
||||||
if (node->statement.has_value()) {
|
|
||||||
Visitor::Visit(node->statement.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
void ExecuteVisitor::Visit(Match* node) {
|
void ExecuteVisitor::Visit(Match* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
|
|
||||||
|
utils::IdType value = current_value_;
|
||||||
|
|
||||||
|
bool case_choosen = false;
|
||||||
|
bool statement_visited = false;
|
||||||
for (auto& match_case : node->matches) {
|
for (auto& match_case : node->matches) {
|
||||||
Visit(&match_case);
|
if (case_choosen) {
|
||||||
|
if (match_case.statement.has_value()) {
|
||||||
|
Visitor::Visit(match_case.statement.value());
|
||||||
|
statement_visited = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
current_value_ = value;
|
||||||
|
case_matched_ = true;
|
||||||
|
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
Visitor::Visit(node->value);
|
||||||
|
|
||||||
|
if (case_matched_ && (match_case.condition.has_value() ? HandleCondition(match_case.condition.value(), match_case.base) : true)) {
|
||||||
|
case_choosen = true;
|
||||||
|
if (match_case.statement.has_value()) {
|
||||||
|
Visitor::Visit(match_case.statement.value());
|
||||||
|
statement_visited = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (case_choosen) {
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statement_visited) {
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||||
|
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
} else {
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||||
|
info::value::OptionalValue(context_manager_.GetValueManager()),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(Condition* node) {
|
void ExecuteVisitor::Visit(Condition* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
for (size_t i = 0; i < node->conditions.size(); ++i) {
|
for (size_t i = 0; i < node->conditions.size(); ++i) {
|
||||||
if (HandleCondition(node->conditions[i], node->base)) {
|
if (HandleCondition(node->conditions[i], node->base)) {
|
||||||
Visitor::Visit(node->statements[i]);
|
Visitor::Visit(node->statements[i]);
|
||||||
|
|
||||||
if (node->statements.size() == node->conditions.size()) {
|
if (node->statements.size() == node->conditions.size()) {
|
||||||
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||||
info::value::OptionalValue(current_value_),
|
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp); // take value type from current_value_ ??
|
utils::ValueType::Tmp); // take value type from current_value_ ??
|
||||||
}
|
}
|
||||||
return; // current_value_ passed from statement
|
return; // current_value_ passed from statement
|
||||||
|
|
@ -113,12 +145,16 @@ void ExecuteVisitor::Visit(Condition* node) {
|
||||||
Visitor::Visit(node->statements[node->conditions.size()]);
|
Visitor::Visit(node->statements[node->conditions.size()]);
|
||||||
} else {
|
} else {
|
||||||
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||||
info::value::OptionalValue(),
|
info::value::OptionalValue(context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(DoWhileLoop* node) {
|
void ExecuteVisitor::Visit(DoWhileLoop* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
std::vector<utils::IdType> result;
|
std::vector<utils::IdType> result;
|
||||||
do {
|
do {
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
|
|
@ -135,11 +171,15 @@ void ExecuteVisitor::Visit(DoWhileLoop* node) {
|
||||||
} while(HandleCondition(node->condition, node->base));
|
} while(HandleCondition(node->condition, node->base));
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
info::value::ArrayValue(std::move(result), false),
|
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(WhileLoop* node) {
|
void ExecuteVisitor::Visit(WhileLoop* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
std::vector<utils::IdType> result;
|
std::vector<utils::IdType> result;
|
||||||
while(HandleCondition(node->condition, node->base)) {
|
while(HandleCondition(node->condition, node->base)) {
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
|
|
@ -156,10 +196,14 @@ void ExecuteVisitor::Visit(WhileLoop* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
info::value::ArrayValue(std::move(result), false),
|
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
}
|
}
|
||||||
void ExecuteVisitor::Visit(ForLoop* node) {
|
void ExecuteVisitor::Visit(ForLoop* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
std::vector<utils::IdType> result;
|
std::vector<utils::IdType> result;
|
||||||
|
|
||||||
// TODO: extend to different interval types (not only array)
|
// TODO: extend to different interval types (not only array)
|
||||||
|
|
@ -184,11 +228,15 @@ void ExecuteVisitor::Visit(ForLoop* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
info::value::ArrayValue(std::move(result), false),
|
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(LoopLoop* node) {
|
void ExecuteVisitor::Visit(LoopLoop* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
std::vector<utils::IdType> result;
|
std::vector<utils::IdType> result;
|
||||||
while(true) {
|
while(true) {
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
|
|
@ -205,8 +253,10 @@ void ExecuteVisitor::Visit(LoopLoop* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
info::value::ArrayValue(std::move(result), false),
|
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statements, expressions, blocks, etc. -----------------
|
// Statements, expressions, blocks, etc. -----------------
|
||||||
|
|
@ -297,7 +347,7 @@ void ExecuteVisitor::Visit(ReferenceExpression* node) {
|
||||||
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue(
|
current_value_ = context_manager_.AddValue(
|
||||||
info::value::ReferenceToValue(node->references, current_value_),
|
info::value::ReferenceToValue(node->references, current_value_, context_manager_.GetValueManager()),
|
||||||
value_type);
|
value_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,29 +426,29 @@ void ExecuteVisitor::Visit(TupleExpression* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue<info::value::TupleValue>(
|
current_value_ = context_manager_.AddValue<info::value::TupleValue>(
|
||||||
info::value::TupleValue(std::move(fields)),
|
info::value::TupleValue(std::move(fields), context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(VariantExpression* node) {
|
void ExecuteVisitor::Visit(VariantExpression* node) {
|
||||||
// TODO: decide about return type (variant)
|
// TODO: decide about return type (variant)
|
||||||
for (auto& expression : node->expressions) {
|
for (size_t i = 0; i < node->expressions.size(); ++i) {
|
||||||
Visitor::Visit(expression);
|
Visitor::Visit(node->expressions[i]);
|
||||||
info::value::OptionalValue* expression_value = ExtractValue<info::value::OptionalValue>(current_value_, node->base);
|
info::value::OptionalValue* expression_value = ExtractValue<info::value::OptionalValue>(current_value_, node->base);
|
||||||
if (expression_value->value.has_value()) {
|
if (expression_value->value.has_value()) {
|
||||||
current_value_ = context_manager_.AddValue<info::value::VariantValue>(
|
current_value_ = context_manager_.AddValue<info::value::VariantValue>(
|
||||||
info::value::VariantValue(expression_value->value.value()),
|
info::value::VariantValue(expression_value->value.value(), i, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||||
info::value::OptionalValue(current_value_),
|
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||||
info::value::OptionalValue(),
|
info::value::OptionalValue(context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,21 +457,27 @@ void ExecuteVisitor::Visit(ReturnExpression* node) {
|
||||||
return_value_ = current_value_;
|
return_value_ = current_value_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
void ExecuteVisitor::Visit(TypeConstructorParameter* node) {
|
|
||||||
if (node->name.has_value()) {
|
|
||||||
// Visit(&node->name.value());
|
|
||||||
}
|
|
||||||
Visitor::Visit(node->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO
|
void ExecuteVisitor::Visit(TypeConstructorParameter* node) {} // handled in TypeConstructor
|
||||||
|
|
||||||
|
|
||||||
void ExecuteVisitor::Visit(TypeConstructor* node) {
|
void ExecuteVisitor::Visit(TypeConstructor* node) {
|
||||||
// TODO: not only tuples
|
// TODO: support for non-tuples
|
||||||
Visit(node->constructor.get());
|
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
|
||||||
|
|
||||||
|
// Visit(node->constructor.get()); // use parameters from type expression ??
|
||||||
|
fields.reserve(node->parameters.size());
|
||||||
for (auto& parameter : node->parameters) {
|
for (auto& parameter : node->parameters) {
|
||||||
Visit(¶meter);
|
Visitor::Visit(parameter.value);
|
||||||
|
// TODO: copy/move parameters
|
||||||
|
fields.push_back(
|
||||||
|
{ parameter.name.has_value() ? std::optional<std::string>(parameter.name.value().name) : std::nullopt,
|
||||||
|
current_value_ });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_value_ = context_manager_.AddValue<info::value::TupleValue>(
|
||||||
|
info::value::TupleValue(std::move(fields), context_manager_.GetValueManager()),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
@ -440,7 +496,7 @@ void ExecuteVisitor::Visit(ArrayExpression* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
|
||||||
info::value::ArrayValue(std::move(elements), true), // maybe size not fixed??
|
info::value::ArrayValue(std::move(elements), true, context_manager_.GetValueManager()), // maybe size not fixed??
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -513,6 +569,7 @@ void ExecuteVisitor::Visit(TupleName* node) { // TODO: check
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
// TODO: make variant of TupleValue
|
||||||
void ExecuteVisitor::Visit(VariantName* node) {
|
void ExecuteVisitor::Visit(VariantName* node) {
|
||||||
utils::IdType value = current_value_;
|
utils::IdType value = current_value_;
|
||||||
|
|
||||||
|
|
@ -522,6 +579,20 @@ void ExecuteVisitor::Visit(VariantName* node) {
|
||||||
error_handling::HandleRuntimeError("Mismatched value types in variant variable definition", node->base);
|
error_handling::HandleRuntimeError("Mismatched value types in variant variable definition", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||||
|
if (i == maybe_variant_value.value()->current_constructor) {
|
||||||
|
// TODO if (fields_count.empty()) ... else ...
|
||||||
|
current_value_ = context_manager_.AddValue(
|
||||||
|
info::value::OptionalValue(maybe_variant_value.value()->value, context_manager_.GetValueManager()),
|
||||||
|
utils::IsConstModifierToValueType(is_const_definition_.value())); // TODO ??
|
||||||
|
} else {
|
||||||
|
current_value_ = context_manager_.AddValue(
|
||||||
|
info::value::OptionalValue(context_manager_.GetValueManager()),
|
||||||
|
utils::IsConstModifierToValueType(is_const_definition_.value()));
|
||||||
|
}
|
||||||
|
|
||||||
|
Visitor::Visit(node->names[i]);
|
||||||
|
}
|
||||||
// TODO: find out, which constructor used
|
// TODO: find out, which constructor used
|
||||||
// set value to that constructor and None (empty OptionalValue) to others
|
// set value to that constructor and None (empty OptionalValue) to others
|
||||||
|
|
||||||
|
|
@ -633,6 +704,34 @@ void ExecuteVisitor::CollectTypeContext(const ParametrizedType& type) {
|
||||||
if (type.parameters[i]->type_id_.has_value()) {
|
if (type.parameters[i]->type_id_.has_value()) {
|
||||||
context_manager_.DefineLocalType(type_info.parameters[i].type,
|
context_manager_.DefineLocalType(type_info.parameters[i].type,
|
||||||
type.parameters[i]->type_id_.value());
|
type.parameters[i]->type_id_.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
void ExecuteVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
|
||||||
|
utils::IdType value = current_value_;
|
||||||
|
|
||||||
|
switch (node.index()) {
|
||||||
|
case 0:
|
||||||
|
value = context_manager_.ToModifiedValue(value, utils::ValueType::Const); // ??
|
||||||
|
if (!context_manager_.DefineVariable(std::get<std::unique_ptr<ExtendedName>>(node)->name,
|
||||||
|
value)) {
|
||||||
|
error_handling::HandleRuntimeError("Can't redifine variable", base_node);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
Visitor::Visit(*std::get<std::unique_ptr<Literal>>(node));
|
||||||
|
if (!context_manager_.EqualValues(current_value_, value)) { // TODO
|
||||||
|
case_matched_ = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Visit(std::get<std::unique_ptr<TypeConstructorPattern>>(node).get());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// error
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -364,16 +364,15 @@ void TypeCheckVisitor::Visit(MatchCase* node) {
|
||||||
error_handling::HandleTypecheckError("Match case condition is not bool expression", node->base);
|
error_handling::HandleTypecheckError("Match case condition is not bool expression", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->statement.has_value()) {
|
// IMPORTANT: statement visited in Match
|
||||||
Visitor::Visit(node->statement.value());
|
|
||||||
}
|
|
||||||
// current_type_ from statement is current_type_ for MatchCase
|
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
|
void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
|
||||||
// TODO: types can be different in block statement
|
// TODO: types can be different in block statement
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
utils::IdType type;
|
utils::IdType type;
|
||||||
|
|
||||||
bool is_type_found = false;
|
bool is_type_found = false;
|
||||||
|
|
@ -381,17 +380,26 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
utils::IdType value_type = current_type_;
|
utils::IdType value_type = current_type_;
|
||||||
|
|
||||||
for (size_t i = 0; i < node->matches.size(); ++i) {
|
// TODO: several matches with one statement typecheck <- check proposed solution
|
||||||
|
std::optional<Expression*> nearest_statement;
|
||||||
|
for (ssize_t i = (ssize_t)node->matches.size() - 1; i >= 0; --i) { // TODO: internal contexts ??
|
||||||
current_type_ = value_type;
|
current_type_ = value_type;
|
||||||
|
|
||||||
context_manager_.EnterContext();
|
context_manager_.EnterContext();
|
||||||
Visit(&node->matches[i]);
|
Visit(&node->matches[i]);
|
||||||
context_manager_.ExitContext();
|
|
||||||
|
|
||||||
if (!node->matches[i].statement.has_value()) {
|
if (node->matches[i].statement.has_value()) {
|
||||||
|
nearest_statement = &node->matches[i].statement.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nearest_statement.has_value()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Visitor::Visit(*nearest_statement.value());
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
|
||||||
if (!is_type_found) {
|
if (!is_type_found) {
|
||||||
type = current_type_;
|
type = current_type_;
|
||||||
is_type_found = true;
|
is_type_found = true;
|
||||||
|
|
@ -408,10 +416,18 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
|
||||||
|
|
||||||
current_type_ = type;
|
current_type_ = type;
|
||||||
|
|
||||||
|
current_type_ = context_manager_.AddValue(
|
||||||
|
info::type::OptionalType(current_type_, context_manager_.GetValueManager()),
|
||||||
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(Condition* node) {
|
void TypeCheckVisitor::Visit(Condition* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
// TODO: types can be different in statement
|
// TODO: types can be different in statement
|
||||||
utils::IdType type;
|
utils::IdType type;
|
||||||
|
|
||||||
|
|
@ -421,9 +437,8 @@ void TypeCheckVisitor::Visit(Condition* node) {
|
||||||
error_handling::HandleTypecheckError("Condition statement condition is not bool expression", node->base);
|
error_handling::HandleTypecheckError("Condition statement condition is not bool expression", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
context_manager_.EnterContext();
|
|
||||||
Visitor::Visit(node->statements[i]);
|
Visitor::Visit(node->statements[i]);
|
||||||
context_manager_.ExitContext();
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
type = current_type_;
|
type = current_type_;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -434,9 +449,8 @@ void TypeCheckVisitor::Visit(Condition* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->statements.size() > node->conditions.size()) {
|
if (node->statements.size() > node->conditions.size()) {
|
||||||
context_manager_.EnterContext();
|
|
||||||
Visitor::Visit(node->statements[node->conditions.size()]);
|
Visitor::Visit(node->statements[node->conditions.size()]);
|
||||||
context_manager_.ExitContext();
|
|
||||||
if (!context_manager_.EqualValues(type, current_type_)) {
|
if (!context_manager_.EqualValues(type, current_type_)) {
|
||||||
error_handling::HandleTypecheckError("Condition statement else have different type from other cases", node->base);
|
error_handling::HandleTypecheckError("Condition statement else have different type from other cases", node->base);
|
||||||
}
|
}
|
||||||
|
|
@ -447,42 +461,52 @@ void TypeCheckVisitor::Visit(Condition* node) {
|
||||||
utils::ValueType::Tmp); // ??
|
utils::ValueType::Tmp); // ??
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(DoWhileLoop* node) {
|
void TypeCheckVisitor::Visit(DoWhileLoop* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
Visitor::Visit(node->condition);
|
Visitor::Visit(node->condition);
|
||||||
if (!context_manager_.EqualValues(context_manager_.AddValue(info::type::InternalType::Bool, utils::ValueType::Tmp), current_type_)) {
|
if (!context_manager_.EqualValues(context_manager_.AddValue(info::type::InternalType::Bool, utils::ValueType::Tmp), current_type_)) {
|
||||||
error_handling::HandleTypecheckError("Do while loop statement condition is not bool expression", node->base);
|
error_handling::HandleTypecheckError("Do while loop statement condition is not bool expression", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
context_manager_.EnterContext();
|
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
context_manager_.ExitContext();
|
|
||||||
|
|
||||||
current_type_ = context_manager_.AddValue(
|
current_type_ = context_manager_.AddValue(
|
||||||
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
|
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
|
||||||
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(WhileLoop* node) {
|
void TypeCheckVisitor::Visit(WhileLoop* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
Visitor::Visit(node->condition);
|
Visitor::Visit(node->condition);
|
||||||
if (!context_manager_.EqualValues(context_manager_.AddValue(info::type::InternalType::Bool, utils::ValueType::Tmp), current_type_)) {
|
if (!context_manager_.EqualValues(context_manager_.AddValue(info::type::InternalType::Bool, utils::ValueType::Tmp), current_type_)) {
|
||||||
error_handling::HandleTypecheckError("While loop statement condition is not bool expression", node->base);
|
error_handling::HandleTypecheckError("While loop statement condition is not bool expression", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
context_manager_.EnterContext();
|
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
context_manager_.ExitContext();
|
|
||||||
|
|
||||||
current_type_ = context_manager_.AddValue(
|
current_type_ = context_manager_.AddValue(
|
||||||
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
|
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(ForLoop* node) {
|
void TypeCheckVisitor::Visit(ForLoop* node) {
|
||||||
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
Visitor::Visit(node->interval);
|
Visitor::Visit(node->interval);
|
||||||
std::optional<info::type::ArrayType*> maybe_interval_type = context_manager_.GetValue<info::type::ArrayType>(current_type_);
|
std::optional<info::type::ArrayType*> maybe_interval_type = context_manager_.GetValue<info::type::ArrayType>(current_type_);
|
||||||
|
|
||||||
|
|
@ -490,8 +514,6 @@ void TypeCheckVisitor::Visit(ForLoop* node) {
|
||||||
error_handling::HandleTypecheckError("For loop interval type mismatch", node->base);
|
error_handling::HandleTypecheckError("For loop interval type mismatch", node->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
context_manager_.EnterContext();
|
|
||||||
|
|
||||||
current_type_ = context_manager_.ToModifiedValue(maybe_interval_type.value()->GetElementsType(),
|
current_type_ = context_manager_.ToModifiedValue(maybe_interval_type.value()->GetElementsType(),
|
||||||
utils::IsConstModifierToValueType(node->variable_modifier));
|
utils::IsConstModifierToValueType(node->variable_modifier));
|
||||||
|
|
||||||
|
|
@ -501,22 +523,26 @@ void TypeCheckVisitor::Visit(ForLoop* node) {
|
||||||
|
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
|
|
||||||
context_manager_.ExitContext();
|
|
||||||
|
|
||||||
current_type_ = context_manager_.AddValue(
|
current_type_ = context_manager_.AddValue(
|
||||||
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
|
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
|
||||||
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(LoopLoop* node) {
|
void TypeCheckVisitor::Visit(LoopLoop* node) {
|
||||||
context_manager_.EnterContext();
|
context_manager_.EnterContext();
|
||||||
|
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
context_manager_.ExitContext();
|
|
||||||
|
|
||||||
current_type_ = context_manager_.AddValue(
|
current_type_ = context_manager_.AddValue(
|
||||||
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
|
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
|
context_manager_.ExitContext();
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -897,9 +923,9 @@ void TypeCheckVisitor::Visit(VariantExpression* node) {
|
||||||
std::nullopt),
|
std::nullopt),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
current_type_ = context_manager_.AddValue(info::type::OptionalType(current_type_,
|
current_type_ = context_manager_.AddValue(
|
||||||
context_manager_.GetValueManager()),
|
info::type::OptionalType(current_type_, context_manager_.GetValueManager()),
|
||||||
utils::ValueType::Tmp);
|
utils::ValueType::Tmp);
|
||||||
|
|
||||||
node->base.type_ = current_type_;
|
node->base.type_ = current_type_;
|
||||||
}
|
}
|
||||||
|
|
@ -1134,7 +1160,9 @@ void TypeCheckVisitor::Visit(VariantName* node) {
|
||||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||||
if (maybe_type_value.value()->GetConstructors()[i].GetFields().empty()) {
|
if (maybe_type_value.value()->GetConstructors()[i].GetFields().empty()) {
|
||||||
current_type_ = context_manager_.AddValue(
|
current_type_ = context_manager_.AddValue(
|
||||||
info::type::OptionalType(context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp), context_manager_.GetValueManager()),
|
info::type::OptionalType(
|
||||||
|
context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp),
|
||||||
|
context_manager_.GetValueManager()),
|
||||||
utils::IsConstModifierToValueType(is_const_definition_.value())); // TODO ??
|
utils::IsConstModifierToValueType(is_const_definition_.value())); // TODO ??
|
||||||
} else {
|
} else {
|
||||||
info::type::TupleType constructor_type_value = maybe_type_value.value()->GetConstructors()[i];
|
info::type::TupleType constructor_type_value = maybe_type_value.value()->GetConstructors()[i];
|
||||||
|
|
@ -1408,12 +1436,15 @@ void TypeCheckVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
|
||||||
|
|
||||||
switch (node.index()) {
|
switch (node.index()) {
|
||||||
case 0:
|
case 0:
|
||||||
context_manager_.DefineVariable(std::get<std::unique_ptr<ExtendedName>>(node)->name,
|
value_type = context_manager_.ToModifiedValue(value_type, utils::ValueType::Const); // ??
|
||||||
value_type);
|
if (!context_manager_.DefineVariable(std::get<std::unique_ptr<ExtendedName>>(node)->name,
|
||||||
|
value_type)) {
|
||||||
|
error_handling::HandleTypecheckError("Can't redifine variable", base_node);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
Visitor::Visit(*std::get<std::unique_ptr<Literal>>(node));
|
Visitor::Visit(*std::get<std::unique_ptr<Literal>>(node));
|
||||||
if (context_manager_.EqualValues(current_type_, value_type)) { // TODO: better solution ??
|
if (!context_manager_.EqualValues(current_type_, value_type)) { // TODO: better solution ??
|
||||||
error_handling::HandleTypecheckError("Literal and value have different types", base_node);
|
error_handling::HandleTypecheckError("Literal and value have different types", base_node);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
// for clangd
|
// for clangd
|
||||||
#include "../include/types.hpp"
|
#include "../include/types.hpp"
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
namespace info::type {
|
namespace info::type {
|
||||||
|
|
||||||
|
|
|
||||||
79
src/values.cpp
Normal file
79
src/values.cpp
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
// for clangd
|
||||||
|
#include "../include/values.hpp"
|
||||||
|
|
||||||
|
namespace info::value {
|
||||||
|
|
||||||
|
std::optional<utils::IdType> InternalValue::GetFieldValue(const std::string& name) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
std::optional<utils::IdType> TupleValue::GetFieldValue(const std::string& name) {
|
||||||
|
for (size_t i = 0; i < fields.size(); ++i) { // TODO: optimize??
|
||||||
|
if (fields[i].first.has_value() && fields[i].first.value() == name) {
|
||||||
|
return fields[i].second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
std::optional<utils::IdType> VariantValue::GetFieldValue(const std::string& name) {
|
||||||
|
return value_manager_->GetAnyValue(value)->GetFieldValue(name); // TODO: TupleType ??
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
std::optional<utils::IdType> ReferenceToValue::GetFieldValue(const std::string& name) {
|
||||||
|
return value_manager_->GetAnyValue(value)->GetFieldValue(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
std::optional<utils::IdType> FunctionValue::GetFieldValue(const std::string& name) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
std::optional<utils::IdType> ArrayValue::GetFieldValue(const std::string& name) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
std::optional<utils::IdType> OptionalValue::GetFieldValue(const std::string& name) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
std::optional<utils::IdType> Value::GetFieldValue(const std::string& name) {
|
||||||
|
size_t index = value.index();
|
||||||
|
|
||||||
|
switch (index) {
|
||||||
|
case 0:
|
||||||
|
return std::get<InternalValue>(value).GetFieldValue(name);
|
||||||
|
case 1:
|
||||||
|
return std::get<TupleValue>(value).GetFieldValue(name);
|
||||||
|
case 2:
|
||||||
|
return std::get<VariantValue>(value).GetFieldValue(name);
|
||||||
|
case 3:
|
||||||
|
return std::get<ReferenceToValue>(value).GetFieldValue(name);
|
||||||
|
case 4:
|
||||||
|
return std::get<FunctionValue>(value).GetFieldValue(name);
|
||||||
|
case 5:
|
||||||
|
return std::get<ArrayValue>(value).GetFieldValue(name);
|
||||||
|
case 6:
|
||||||
|
return std::get<OptionalValue>(value).GetFieldValue(name);
|
||||||
|
default:
|
||||||
|
// error
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace info::value
|
||||||
Loading…
Add table
Add a link
Reference in a new issue