fixes, part of execute_visitor

This commit is contained in:
ProgramSnail 2023-05-09 23:36:47 +03:00
parent 7d96fe5a86
commit 802b736e15
7 changed files with 345 additions and 92 deletions

View file

@ -18,6 +18,7 @@ include_directories(include
add_executable(lang_interpreter src/main.cpp
src/types.cpp
src/values.cpp
src/global_info.cpp
include/definitions.hpp
src/visitor.cpp

View file

@ -141,6 +141,7 @@ private:
bool HandleCondition(Expression& condition, const BaseNode& base_node);
void CollectTypeContext(const ParametrizedType& type);
void CheckPattern(Pattern& node, const BaseNode& base_node);
template<typename T>
T* ExtractValue(utils::IdType value, const BaseNode& base_node) {
@ -169,6 +170,7 @@ private:
std::optional<LoopControlExpression> active_loop_control_expression_;
std::optional<utils::IdType> return_value_; // TODO: work outside block ??
std::optional<utils::IsConstModifier> is_const_definition_;
bool case_matched_;
};
} // namespace interpreter

View file

@ -11,6 +11,8 @@
namespace info::value {
struct ValueManager;
struct Unit {};
struct InternalValue {
@ -27,6 +29,8 @@ public:
}
return &std::get<T>(value);
}
std::optional<utils::IdType> GetFieldValue(const std::string& name);
public:
std::variant<double,
long long,
@ -38,67 +42,104 @@ public:
struct TupleValue {
public:
TupleValue() = default;
explicit TupleValue(std::vector<std::pair<std::optional<std::string>, utils::IdType>>&& fields) : fields(std::move(fields)) {}
explicit TupleValue(ValueManager* value_manager) : value_manager_(value_manager) {}
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:
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
private:
ValueManager* value_manager_;
};
struct VariantValue {
public:
VariantValue() = default;
VariantValue(utils::IdType value) // TupleValue ?? // TODO: add type & constructor??
: value(value) {}
explicit VariantValue(ValueManager* value_manager) : value_manager_(value_manager) {}
// 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:
utils::IdType value;
size_t current_constructor;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
private:
ValueManager* value_manager_;
};
struct ReferenceToValue {
public:
ReferenceToValue() = default;
explicit ReferenceToValue(ValueManager* value_manager) : value_manager_(value_manager) {}
ReferenceToValue(const std::vector<utils::ReferenceModifier>& references,
utils::IdType value)
: references(references), value(value) {}
utils::IdType value,
ValueManager* value_manager)
: references(references), value(value), value_manager_(value_manager) {}
public:
std::vector<utils::ReferenceModifier> references;
utils::IdType value;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
private:
ValueManager* value_manager_;
};
struct FunctionValue {
public:
FunctionValue() = default;
FunctionValue(std::variant<interpreter::tokens::FunctionDeclaration*,
interpreter::tokens::LambdaFunction*> function)
: function(function) {}
explicit FunctionValue(ValueManager* value_manager) : value_manager_(value_manager) {}
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;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
private:
ValueManager* value_manager_;
};
struct ArrayValue {
public:
ArrayValue() = default;
explicit ArrayValue(ValueManager* value_manager) : value_manager_(value_manager) {}
explicit ArrayValue(std::vector<utils::IdType>&& elements,
bool is_constant_size)
: elements(std::move(elements)), is_constant_size(is_constant_size) {}
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;
std::optional<utils::IdType> GetFieldValue(const std::string& name);
private:
ValueManager* value_manager_;
};
struct OptionalValue {
public:
OptionalValue() = default;
explicit OptionalValue(utils::IdType value) : value(value) {}
explicit OptionalValue(ValueManager* value_manager) : value_manager_(value_manager) {}
explicit OptionalValue(utils::IdType value, ValueManager* value_manager)
: value(value), value_manager_(value_manager) {}
std::optional<utils::IdType> GetFieldValue(const std::string& name);
public:
std::optional<utils::IdType> value;
private:
ValueManager* value_manager_;
};
struct Value { // DefinedValue ??
@ -108,6 +149,7 @@ public:
template<typename T>
explicit Value(const T& value) : value(value) {} // move ??
std::optional<utils::IdType> GetFieldValue(const std::string& name);
public:
std::variant<InternalValue,
TupleValue,

View file

@ -60,50 +60,82 @@ void ExecuteVisitor::Visit(PartitionStatement* node) {
// Flow control -----------------
// TODO
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {
if (node->name.has_value()) {
// Visit(&node->name.value());
}
Visitor::Visit(node->value);
}
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {} // handled in TypeConstructorPattern
// TODO
void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
// TODO: not only tuples
Visit(node->constructor.get());
for (auto& parameter : node->parameters) {
Visit(&parameter);
Visit(node->constructor.get()); // TODO: ?? check is same constructor_id ??
for (auto& parameter : node->parameters) { // TODO: pass parameters separately
Visitor::Visit(parameter.value); // handle TypeConstructorPatternParameter
}
}
// TODO
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());
}
}
void ExecuteVisitor::Visit(MatchCase* node) {} // handeled in Match
// TODO
void ExecuteVisitor::Visit(Match* node) {
context_manager_.EnterContext();
Visitor::Visit(node->value);
utils::IdType value = current_value_;
bool case_choosen = false;
bool statement_visited = false;
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) {
context_manager_.EnterContext();
for (size_t i = 0; i < node->conditions.size(); ++i) {
if (HandleCondition(node->conditions[i], node->base)) {
Visitor::Visit(node->statements[i]);
if (node->statements.size() == node->conditions.size()) {
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_ ??
}
return; // current_value_ passed from statement
@ -113,12 +145,16 @@ void ExecuteVisitor::Visit(Condition* node) {
Visitor::Visit(node->statements[node->conditions.size()]);
} else {
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(),
info::value::OptionalValue(context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
context_manager_.ExitContext();
}
void ExecuteVisitor::Visit(DoWhileLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result;
do {
Visitor::Visit(node->statement);
@ -135,11 +171,15 @@ void ExecuteVisitor::Visit(DoWhileLoop* node) {
} while(HandleCondition(node->condition, node->base));
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);
context_manager_.ExitContext();
}
void ExecuteVisitor::Visit(WhileLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result;
while(HandleCondition(node->condition, node->base)) {
Visitor::Visit(node->statement);
@ -156,10 +196,14 @@ void ExecuteVisitor::Visit(WhileLoop* node) {
}
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);
context_manager_.ExitContext();
}
void ExecuteVisitor::Visit(ForLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result;
// 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>(
info::value::ArrayValue(std::move(result), false),
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
}
void ExecuteVisitor::Visit(LoopLoop* node) {
context_manager_.EnterContext();
std::vector<utils::IdType> result;
while(true) {
Visitor::Visit(node->statement);
@ -205,8 +253,10 @@ void ExecuteVisitor::Visit(LoopLoop* node) {
}
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);
context_manager_.ExitContext();
}
// Statements, expressions, blocks, etc. -----------------
@ -297,7 +347,7 @@ void ExecuteVisitor::Visit(ReferenceExpression* node) {
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
current_value_ = context_manager_.AddValue(
info::value::ReferenceToValue(node->references, current_value_),
info::value::ReferenceToValue(node->references, current_value_, context_manager_.GetValueManager()),
value_type);
}
@ -376,29 +426,29 @@ void ExecuteVisitor::Visit(TupleExpression* node) {
}
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);
}
void ExecuteVisitor::Visit(VariantExpression* node) {
// TODO: decide about return type (variant)
for (auto& expression : node->expressions) {
Visitor::Visit(expression);
for (size_t i = 0; i < node->expressions.size(); ++i) {
Visitor::Visit(node->expressions[i]);
info::value::OptionalValue* expression_value = ExtractValue<info::value::OptionalValue>(current_value_, node->base);
if (expression_value->value.has_value()) {
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);
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(current_value_),
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
return;
}
}
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
info::value::OptionalValue(),
info::value::OptionalValue(context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
@ -407,21 +457,27 @@ void ExecuteVisitor::Visit(ReturnExpression* node) {
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) {
// TODO: not only tuples
Visit(node->constructor.get());
// TODO: support for non-tuples
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) {
Visit(&parameter);
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
@ -440,7 +496,7 @@ void ExecuteVisitor::Visit(ArrayExpression* node) {
}
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);
}
@ -513,6 +569,7 @@ void ExecuteVisitor::Visit(TupleName* node) { // TODO: check
}
// TODO
// TODO: make variant of TupleValue
void ExecuteVisitor::Visit(VariantName* node) {
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);
}
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
// set value to that constructor and None (empty OptionalValue) to others
@ -634,6 +705,34 @@ void ExecuteVisitor::CollectTypeContext(const ParametrizedType& type) {
context_manager_.DefineLocalType(type_info.parameters[i].type,
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;
}
}
} // namespace interpreter

View file

@ -364,16 +364,15 @@ void TypeCheckVisitor::Visit(MatchCase* node) {
error_handling::HandleTypecheckError("Match case condition is not bool expression", node->base);
}
if (node->statement.has_value()) {
Visitor::Visit(node->statement.value());
}
// current_type_ from statement is current_type_ for MatchCase
// IMPORTANT: statement visited in Match
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
// TODO: types can be different in block statement
context_manager_.EnterContext();
utils::IdType type;
bool is_type_found = false;
@ -381,17 +380,26 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
Visitor::Visit(node->value);
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;
context_manager_.EnterContext();
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;
}
Visitor::Visit(*nearest_statement.value());
context_manager_.ExitContext();
if (!is_type_found) {
type = current_type_;
is_type_found = true;
@ -408,10 +416,18 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
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_;
}
void TypeCheckVisitor::Visit(Condition* node) {
context_manager_.EnterContext();
// TODO: types can be different in statement
utils::IdType type;
@ -421,9 +437,8 @@ void TypeCheckVisitor::Visit(Condition* node) {
error_handling::HandleTypecheckError("Condition statement condition is not bool expression", node->base);
}
context_manager_.EnterContext();
Visitor::Visit(node->statements[i]);
context_manager_.ExitContext();
if (i == 0) {
type = current_type_;
} else {
@ -434,9 +449,8 @@ void TypeCheckVisitor::Visit(Condition* node) {
}
if (node->statements.size() > node->conditions.size()) {
context_manager_.EnterContext();
Visitor::Visit(node->statements[node->conditions.size()]);
context_manager_.ExitContext();
if (!context_manager_.EqualValues(type, current_type_)) {
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); // ??
}
context_manager_.ExitContext();
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(DoWhileLoop* node) {
context_manager_.EnterContext();
Visitor::Visit(node->condition);
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);
}
context_manager_.EnterContext();
Visitor::Visit(node->statement);
context_manager_.ExitContext();
current_type_ = context_manager_.AddValue(
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(WhileLoop* node) {
context_manager_.EnterContext();
Visitor::Visit(node->condition);
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);
}
context_manager_.EnterContext();
Visitor::Visit(node->statement);
context_manager_.ExitContext();
current_type_ = context_manager_.AddValue(
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(ForLoop* node) {
context_manager_.EnterContext();
Visitor::Visit(node->interval);
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);
}
context_manager_.EnterContext();
current_type_ = context_manager_.ToModifiedValue(maybe_interval_type.value()->GetElementsType(),
utils::IsConstModifierToValueType(node->variable_modifier));
@ -501,22 +523,26 @@ void TypeCheckVisitor::Visit(ForLoop* node) {
Visitor::Visit(node->statement);
context_manager_.ExitContext();
current_type_ = context_manager_.AddValue(
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(LoopLoop* node) {
context_manager_.EnterContext();
Visitor::Visit(node->statement);
context_manager_.ExitContext();
current_type_ = context_manager_.AddValue(
info::type::ArrayType(0, current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_;
}
@ -897,8 +923,8 @@ void TypeCheckVisitor::Visit(VariantExpression* node) {
std::nullopt),
utils::ValueType::Tmp);
current_type_ = context_manager_.AddValue(info::type::OptionalType(current_type_,
context_manager_.GetValueManager()),
current_type_ = context_manager_.AddValue(
info::type::OptionalType(current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
node->base.type_ = current_type_;
@ -1134,7 +1160,9 @@ void TypeCheckVisitor::Visit(VariantName* node) {
for (size_t i = 0; i < node->names.size(); ++i) {
if (maybe_type_value.value()->GetConstructors()[i].GetFields().empty()) {
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 ??
} else {
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()) {
case 0:
context_manager_.DefineVariable(std::get<std::unique_ptr<ExtendedName>>(node)->name,
value_type);
value_type = context_manager_.ToModifiedValue(value_type, utils::ValueType::Const); // ??
if (!context_manager_.DefineVariable(std::get<std::unique_ptr<ExtendedName>>(node)->name,
value_type)) {
error_handling::HandleTypecheckError("Can't redifine variable", base_node);
}
break;
case 1:
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);
}
break;

View file

@ -1,6 +1,5 @@
// for clangd
#include "../include/types.hpp"
#include <cstddef>
namespace info::type {

79
src/values.cpp Normal file
View 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