lang_2023/src/execute_visitor.cpp

754 lines
26 KiB
C++
Raw Normal View History

2023-05-07 20:21:19 +03:00
// for clangd
#include "../include/execute_visitor.hpp"
#include <cwchar>
#include <optional>
#include <variant>
2023-05-07 20:21:19 +03:00
// TODO
namespace interpreter {
// Sources -----------------
void ExecuteVisitor::Visit(SourceFile* node) { // never used ??
2023-05-07 20:21:19 +03:00
for (auto& statement : node->statements) {
Visitor::Visit(statement);
}
}
// Namespaces, partitions -----------------
void ExecuteVisitor::Visit(NamespaceSources* node) { // never used ??
2023-05-07 20:21:19 +03:00
for (auto& statement : node->statements) {
Visitor::Visit(statement);
}
}
void ExecuteVisitor::Visit(Namespace* node) { // never used ??
// Visit(&node->type);
2023-05-07 20:21:19 +03:00
Visit(&node->scope);
}
// Definitions -----------------
void ExecuteVisitor::Visit(ImportStatement* node) {} // no value
void ExecuteVisitor::Visit(AliasDefinitionStatement* node) {} // no value
2023-05-07 20:21:19 +03:00
2023-05-09 15:24:19 +03:00
void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on function call
2023-05-07 20:21:19 +03:00
Visitor::Visit(node->value);
2023-05-09 17:42:35 +03:00
is_const_definition_ = node->modifier;
Visitor::Visit(node->name); // current_type_ passed from value
is_const_definition_ = std::nullopt;
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(FunctionDeclaration* node) {} // no value
2023-05-07 20:21:19 +03:00
2023-05-09 15:24:19 +03:00
void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call
// Visit(node->definition.get());
2023-05-07 20:21:19 +03:00
Visitor::Visit(node->value);
}
void ExecuteVisitor::Visit(TypeDefinitionStatement* node) {} // no value
void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement* node) {} // no value
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(TypeclassDefinitionStatement* node) {} // no value
2023-05-07 20:21:19 +03:00
2023-05-08 20:34:36 +03:00
void ExecuteVisitor::Visit(PartitionStatement* node) {
Visitor::Visit(node->value);
}
2023-05-07 20:21:19 +03:00
// Flow control -----------------
2023-05-09 23:36:47 +03:00
void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) {} // handled in TypeConstructorPattern
2023-05-07 20:21:19 +03:00
2023-05-09 15:24:19 +03:00
// TODO
2023-05-10 23:13:50 +03:00
// TODO: non-variant constructor patterns
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(TypeConstructorPattern* node) {
2023-05-10 23:13:50 +03:00
if (!node->constructor->constructor_id_.has_value()) { // checked in typeckeck visitor ??
error_handling::HandleRuntimeError("Type constructor pattern constructor name not found", node->base);
}
utils::IdType constructor_id = node->constructor->constructor_id_.value();
// TODO: not only variants
info::value::VariantValue* value_info =
ExtractValue<info::value::VariantValue>(current_value_, node->base);
if (constructor_id != value_info->current_constructor) {
case_matched_ = false;
return;
}
// <--
// extract named parameters ??
for (size_t i = 0; i < node->parameters.size(); ++i) { // not visit if case not matched inside ??
current_value_ = value_info->value.fields[i].second;
Visitor::Visit(node->parameters[i].value);
2023-05-07 20:21:19 +03:00
}
}
2023-05-09 23:36:47 +03:00
void ExecuteVisitor::Visit(MatchCase* node) {} // handeled in Match
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(Match* node) {
2023-05-09 23:36:47 +03:00
context_manager_.EnterContext();
2023-05-07 20:21:19 +03:00
Visitor::Visit(node->value);
2023-05-09 23:36:47 +03:00
utils::IdType value = current_value_;
bool case_choosen = false;
bool statement_visited = false;
2023-05-07 20:21:19 +03:00
for (auto& match_case : node->matches) {
2023-05-09 23:36:47 +03:00
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();
}
}
2023-05-07 20:21:19 +03:00
}
2023-05-09 23:36:47 +03:00
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>(
2023-05-10 23:13:50 +03:00
info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()),
2023-05-09 23:36:47 +03:00
utils::ValueType::Tmp);
}
context_manager_.ExitContext();
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(Condition* node) {
2023-05-09 23:36:47 +03:00
context_manager_.EnterContext();
2023-05-07 20:21:19 +03:00
for (size_t i = 0; i < node->conditions.size(); ++i) {
2023-05-09 15:24:19 +03:00
if (HandleCondition(node->conditions[i], node->base)) {
2023-05-07 20:21:19 +03:00
Visitor::Visit(node->statements[i]);
2023-05-09 15:24:19 +03:00
if (node->statements.size() == node->conditions.size()) {
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
2023-05-09 23:36:47 +03:00
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
2023-05-09 15:24:19 +03:00
utils::ValueType::Tmp); // take value type from current_value_ ??
}
return; // current_value_ passed from statement
}
2023-05-07 20:21:19 +03:00
}
if (node->statements.size() > node->conditions.size()) {
Visitor::Visit(node->statements[node->conditions.size()]);
2023-05-09 15:24:19 +03:00
} else {
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
2023-05-10 23:13:50 +03:00
info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()),
2023-05-09 15:24:19 +03:00
utils::ValueType::Tmp);
2023-05-07 20:21:19 +03:00
}
2023-05-09 23:36:47 +03:00
context_manager_.ExitContext();
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(DoWhileLoop* node) {
2023-05-09 23:36:47 +03:00
context_manager_.EnterContext();
std::vector<utils::IdType> result;
do {
Visitor::Visit(node->statement);
if (active_loop_control_expression_.has_value()) {
if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
active_loop_control_expression_ = std::nullopt;
break;
}
active_loop_control_expression_ = std::nullopt;
continue;
}
result.push_back(current_value_);
} while(HandleCondition(node->condition, node->base));
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
2023-05-09 23:36:47 +03:00
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
2023-05-09 23:36:47 +03:00
context_manager_.ExitContext();
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(WhileLoop* node) {
2023-05-09 23:36:47 +03:00
context_manager_.EnterContext();
std::vector<utils::IdType> result;
while(HandleCondition(node->condition, node->base)) {
Visitor::Visit(node->statement);
if (active_loop_control_expression_.has_value()) {
if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
active_loop_control_expression_ = std::nullopt;
break;
}
active_loop_control_expression_ = std::nullopt;
continue;
}
result.push_back(current_value_);
}
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
2023-05-09 23:36:47 +03:00
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
2023-05-09 23:36:47 +03:00
context_manager_.ExitContext();
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(ForLoop* node) {
2023-05-09 23:36:47 +03:00
context_manager_.EnterContext();
std::vector<utils::IdType> result;
2023-05-09 17:42:35 +03:00
// TODO: extend to different interval types (not only array)
2023-05-07 20:21:19 +03:00
Visitor::Visit(node->interval);
info::value::ArrayValue* interval = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
for (auto& value : interval->elements) {
current_value_ = value;
Visitor::Visit(node->variable);
Visitor::Visit(node->statement);
if (active_loop_control_expression_.has_value()) {
if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
active_loop_control_expression_ = std::nullopt;
break;
}
active_loop_control_expression_ = std::nullopt;
continue;
}
result.push_back(current_value_);
}
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
2023-05-09 23:36:47 +03:00
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
2023-05-09 23:36:47 +03:00
context_manager_.ExitContext();
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(LoopLoop* node) {
2023-05-09 23:36:47 +03:00
context_manager_.EnterContext();
std::vector<utils::IdType> result;
while(true) {
Visitor::Visit(node->statement);
if (active_loop_control_expression_.has_value()) {
if (active_loop_control_expression_.value() == LoopControlExpression::Break) {
active_loop_control_expression_ = std::nullopt;
break;
}
active_loop_control_expression_ = std::nullopt;
continue;
}
result.push_back(current_value_);
}
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
2023-05-09 23:36:47 +03:00
info::value::ArrayValue(std::move(result), false, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
2023-05-09 23:36:47 +03:00
context_manager_.ExitContext();
2023-05-07 20:21:19 +03:00
}
// Statements, expressions, blocks, etc. -----------------
void ExecuteVisitor::Visit(Block* node) {
2023-05-09 15:24:19 +03:00
context_manager_.EnterContext();
2023-05-07 20:21:19 +03:00
for (auto& statement : node->statements) {
return_value_ = std::nullopt;
2023-05-07 20:21:19 +03:00
Visitor::Visit(statement);
if (return_value_.has_value()) {
current_value_ = return_value_.value();
return;
}
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
context_manager_.ExitContext();
2023-05-09 15:24:19 +03:00
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(ScopedStatement* node) {
2023-05-09 17:42:35 +03:00
Visitor::Visit(node->statement); // current_value_ passed from statement
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(LoopControlExpression& node) {
active_loop_control_expression_ = node;
current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp); // ??
}
2023-05-07 20:21:19 +03:00
// Operators
void ExecuteVisitor::Visit(BinaryOperatorExpression* node) {
2023-05-09 17:42:35 +03:00
context_manager_.EnterContext();
auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).definition;
if (maybe_function_definition.has_value()) {
Visitor::Visit(node->left_expression);
// TODO: custom argument value types, references, etc.
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
context_manager_.DefineVariable(
node->is_method_ ? utils::ClassInternalVarName : maybe_function_definition.value().argument_names[0],
current_value_);
Visitor::Visit(node->left_expression);
// TODO: custom argument value types, references, etc.
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
context_manager_.DefineVariable(maybe_function_definition.value().argument_names[node->is_method_ ? 0 : 1], current_value_);
Visit(maybe_function_definition.value().node);
} else {
// TODO: builtin operators, etc. (imports?)
error_handling::HandleRuntimeError("Binary operator definition not found", node->base);
}
context_manager_.ExitContext();
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(ReferenceExpression* node) {
2023-05-09 17:42:35 +03:00
// TODO: check, that there is no references to "Tmp"??
2023-05-07 20:21:19 +03:00
Visit(node->expression.get());
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
current_value_ = context_manager_.AddValue(
2023-05-09 23:36:47 +03:00
info::value::ReferenceToValue(node->references, current_value_, context_manager_.GetValueManager()),
value_type);
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(AccessExpression* node) {
// TODO: extend to other types
2023-05-07 20:21:19 +03:00
Visit(node->name.get());
info::value::ArrayValue* array_value = ExtractValue<info::value::ArrayValue>(current_value_, node->base);
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
2023-05-07 20:21:19 +03:00
Visitor::Visit(node->id);
long long index = *ExtractInternalValue<long long>(current_value_, node->base); // TODO: size_t
2023-05-10 23:13:50 +03:00
if (index < 0 || index >= (long long)array_value->elements.size()) {
error_handling::HandleRuntimeError("Access index out of range", node->base);
}
current_value_ = context_manager_.ToModifiedValue(array_value->elements[index], value_type); // needed ??
2023-05-07 20:21:19 +03:00
}
// Other Expressions
void ExecuteVisitor::Visit(FunctionCallExpression* node) {
2023-05-09 17:42:35 +03:00
context_manager_.EnterContext();
2023-05-07 20:21:19 +03:00
if (node->prefix.has_value()) {
if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
2023-05-09 17:42:35 +03:00
// modify value on const methods, etc. ??
context_manager_.DefineVariable(utils::ClassInternalVarName, current_value_);
2023-05-07 20:21:19 +03:00
} else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) {
2023-05-09 17:42:35 +03:00
TypeExpression& prefix = *std::get<std::unique_ptr<TypeExpression>>(node->prefix.value());
// TODO: abstract types, local abstract types, abstract types, ... as path entities
for (auto& path_type : prefix.path) {
CollectTypeContext(path_type);
}
CollectTypeContext(prefix.type);
2023-05-07 20:21:19 +03:00
} else {
// error
}
}
2023-05-09 17:42:35 +03:00
auto function_declaration = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).declaration.value(); // checked in type_check_visitor
2023-05-07 20:21:19 +03:00
2023-05-09 17:42:35 +03:00
for (size_t i = 0; i < node->parameters.size(); ++i) {
// TODO: local bastract types, absract types, etc.
context_manager_.DefineLocalType(function_declaration.parameters[i].type, node->parameters[i]->type_id_.value()); // TODO: check
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).definition;
if (maybe_function_definition.has_value()) {
for (size_t i = 0; i < node->arguments.size(); ++i) {
Visitor::Visit(node->arguments[i]);
// TODO: custom argument value types, references, etc.
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Const);
context_manager_.DefineVariable(maybe_function_definition.value().argument_names[i], current_value_);
}
Visit(maybe_function_definition.value().node);
} else {
// TODO: builtin functions, etc. (imports?)
error_handling::HandleRuntimeError("Function definition not found", node->base);
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
context_manager_.ExitContext();
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(TupleExpression* node) {
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
fields.reserve(node->expressions.size());
2023-05-07 20:21:19 +03:00
for (auto& expression : node->expressions) {
Visitor::Visit(expression);
fields.push_back({std::nullopt, current_value_});
2023-05-07 20:21:19 +03:00
}
2023-05-09 15:24:19 +03:00
current_value_ = context_manager_.AddValue<info::value::TupleValue>(
2023-05-09 23:36:47 +03:00
info::value::TupleValue(std::move(fields), context_manager_.GetValueManager()),
2023-05-09 15:24:19 +03:00
utils::ValueType::Tmp);
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
void ExecuteVisitor::Visit(VariantExpression* node) {
// TODO: decide about return type (variant)
2023-05-09 23:36:47 +03:00
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()) {
2023-05-10 23:13:50 +03:00
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields
{{std::nullopt, expression_value->value.value()}};
info::value::TupleValue variant_tuple =
info::value::TupleValue(std::move(fields), context_manager_.GetValueManager());
2023-05-09 17:42:35 +03:00
current_value_ = context_manager_.AddValue<info::value::VariantValue>(
2023-05-10 23:13:50 +03:00
info::value::VariantValue(std::move(variant_tuple), i),
2023-05-09 17:42:35 +03:00
utils::ValueType::Tmp);
2023-05-09 17:42:35 +03:00
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
2023-05-09 23:36:47 +03:00
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
2023-05-09 17:42:35 +03:00
utils::ValueType::Tmp);
return;
}
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
2023-05-10 23:13:50 +03:00
info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()),
2023-05-09 17:42:35 +03:00
utils::ValueType::Tmp);
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(ReturnExpression* node) {
Visitor::Visit(node->expression);
return_value_ = current_value_;
2023-05-07 20:21:19 +03:00
}
2023-05-09 23:36:47 +03:00
void ExecuteVisitor::Visit(TypeConstructorParameter* node) {} // handled in TypeConstructor
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(TypeConstructor* node) {
2023-05-09 23:36:47 +03:00
// 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());
2023-05-07 20:21:19 +03:00
for (auto& parameter : node->parameters) {
2023-05-09 23:36:47 +03:00
Visitor::Visit(parameter.value);
// TODO: copy/move parameters
fields.push_back(
{ parameter.name.has_value() ? std::optional<std::string>(parameter.name.value()) : std::nullopt,
2023-05-09 23:36:47 +03:00
current_value_ });
2023-05-07 20:21:19 +03:00
}
2023-05-09 23:36:47 +03:00
current_value_ = context_manager_.AddValue<info::value::TupleValue>(
info::value::TupleValue(std::move(fields), context_manager_.GetValueManager()),
utils::ValueType::Tmp);
2023-05-07 20:21:19 +03:00
}
// TODO
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(LambdaFunction* node) {
error_handling::HandleInternalError("Lambda function are not implemented yet",
"ExecuteVisitor.LambdaFunction");
2023-05-07 20:21:19 +03:00
}
void ExecuteVisitor::Visit(ArrayExpression* node) {
2023-05-09 15:24:19 +03:00
std::vector<utils::IdType> elements;
elements.reserve(node->elements.size());
2023-05-07 20:21:19 +03:00
for (auto& element : node->elements) {
Visitor::Visit(element);
2023-05-09 15:24:19 +03:00
elements.push_back(current_value_);
2023-05-07 20:21:19 +03:00
}
2023-05-09 15:24:19 +03:00
current_value_ = context_manager_.AddValue<info::value::ArrayValue>(
2023-05-09 23:36:47 +03:00
info::value::ArrayValue(std::move(elements), true, context_manager_.GetValueManager()), // maybe size not fixed??
2023-05-09 15:24:19 +03:00
utils::ValueType::Tmp);
2023-05-07 20:21:19 +03:00
}
// Name
2023-05-09 17:47:43 +03:00
void ExecuteVisitor::Visit(NameExpression* node) { // TODO: check
2023-05-09 17:42:35 +03:00
if (node->names.empty()) {
error_handling::HandleInternalError("Names array is empty", "ExecuteVisitor.NameExpression");
}
std::optional<utils::IdType> maybe_variable_value =
context_manager_.GetVariableInfo(node->names[0]);
2023-05-09 17:42:35 +03:00
if (!maybe_variable_value.has_value()) {
error_handling::HandleRuntimeError("Variable not found", node->base);
}
current_value_ = maybe_variable_value.value();
if (node->names.size() > 1) {
utils::ValueType variable_value_type = context_manager_.GetValueType(current_value_);
for (size_t i = 1; i < node->names.size(); ++i) {
std::optional<utils::IdType> maybe_field_value = context_manager_.GetAnyValue(current_value_)->GetFieldValue(node->names[i]); // TODO
2023-05-09 17:42:35 +03:00
if (!maybe_field_value.has_value()) {
error_handling::HandleRuntimeError("Variable field not found", node->base);
2023-05-09 17:42:35 +03:00
}
current_value_ = maybe_field_value.value();
}
current_value_ = context_manager_.ToModifiedValue(current_value_, variable_value_type);
2023-05-07 20:21:19 +03:00
}
}
2023-05-09 17:42:35 +03:00
void ExecuteVisitor::Visit(TupleName* node) { // TODO: check
utils::IdType value = current_value_;
std::optional<info::value::TupleValue*> maybe_tuple_value = context_manager_.GetValue<info::value::TupleValue>(value);
if (maybe_tuple_value.has_value()) {
error_handling::HandleRuntimeError("Mismatched value types in tuple variable definition", node->base);
}
if (maybe_tuple_value.value()->fields.size() != node->names.size()) {
error_handling::HandleRuntimeError("Mismatched field count in tuple variable definition", node->base);
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
if (!is_const_definition_.has_value()) {
error_handling::HandleInternalError("No value in is_const_definition_", "TypeCheckVisitor.TupleName");
}
utils::ValueType value_type = context_manager_.GetValueType(value);
if (value_type == utils::ValueType::Const
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
error_handling::HandleRuntimeError("TupleName: value type expression not match variable definition modifier", node->base);
}
for (size_t i = 0; i < node->names.size(); ++i) {
current_value_ = maybe_tuple_value.value()->fields[i].second;
if (value_type == utils::ValueType::Tmp) { // TODO: ??
current_value_ = context_manager_.ToModifiedValue(current_value_, utils::ValueType::Tmp);
}
Visitor::Visit(node->names[i]);
}
current_value_ = value;
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
// TODO
2023-05-09 23:36:47 +03:00
// TODO: make variant of TupleValue
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(VariantName* node) {
2023-05-09 17:42:35 +03:00
utils::IdType value = current_value_;
std::optional<info::value::VariantValue*> maybe_variant_value = context_manager_.GetValue<info::value::VariantValue>(value);
if (!maybe_variant_value.has_value()) {
error_handling::HandleRuntimeError("Mismatched value types in variant variable definition", node->base);
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
2023-05-09 23:36:47 +03:00
for (size_t i = 0; i < node->names.size(); ++i) {
if (i == maybe_variant_value.value()->current_constructor) {
2023-05-10 23:13:50 +03:00
if (maybe_variant_value.value()->value.fields.empty()) {
current_value_ = context_manager_.AddValue(
info::value::InternalValue(info::value::Unit()),
utils::IsConstModifierToValueType(is_const_definition_.value()));
// TODO: check, that same with typecheck
} else {
current_value_ = context_manager_.AddValue(
maybe_variant_value.value()->value,
utils::IsConstModifierToValueType(is_const_definition_.value()));
}
2023-05-09 23:36:47 +03:00
current_value_ = context_manager_.AddValue(
2023-05-10 23:13:50 +03:00
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
utils::IsConstModifierToValueType(is_const_definition_.value()));
2023-05-09 23:36:47 +03:00
} else {
current_value_ = context_manager_.AddValue(
2023-05-10 23:13:50 +03:00
info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()),
2023-05-09 23:36:47 +03:00
utils::IsConstModifierToValueType(is_const_definition_.value()));
}
Visitor::Visit(node->names[i]);
}
2023-05-09 17:42:35 +03:00
// TODO: find out, which constructor used
// set value to that constructor and None (empty OptionalValue) to others
current_value_ = value;
2023-05-07 20:21:19 +03:00
}
2023-05-09 17:42:35 +03:00
void ExecuteVisitor::Visit(AnnotatedName* node) { // TODO: check
utils::IdType value = current_value_;
if (!is_const_definition_.has_value()) {
error_handling::HandleInternalError("No value in is_const_definition_",
"TypeCheckVisitor.AnnotatedName");
}
utils::ValueType value_type = context_manager_.GetValueType(current_value_);
if (value_type == utils::ValueType::Const
&& is_const_definition_.value() == utils::IsConstModifier::Var) {
error_handling::HandleRuntimeError("AnnotatedName: value type expression not match variable definition modifier", node->base);
}
current_value_ = context_manager_.ToModifiedValue(value, utils::IsConstModifierToValueType(is_const_definition_.value()));
if (!context_manager_.DefineVariable(node->name, current_value_)) {
error_handling::HandleRuntimeError("Variable name already present in context", node->base);
2023-05-07 20:21:19 +03:00
}
}
// Type, typeclass, etc. -----------------
// Type
void ExecuteVisitor::Visit(FunctionType* node) {} // no value
void ExecuteVisitor::Visit(TupleType* node) {} // no value
void ExecuteVisitor::Visit(VariantType* node) {} // no value
void ExecuteVisitor::Visit(TypeExpression* node) {} // no value
void ExecuteVisitor::Visit(ExtendedScopedAnyType* node) {} // no value
2023-05-07 20:21:19 +03:00
// Typeclass
void ExecuteVisitor::Visit(ParametrizedTypeclass* node) {} // no value
2023-05-07 20:21:19 +03:00
// Typeclass & Type -----------------
void ExecuteVisitor::Visit(ParametrizedType* node) {} // no value
2023-05-07 20:21:19 +03:00
// Identifiers, constants, etc. -----------------
// void ExecuteVisitor::Visit(ExtendedName* node) {}
2023-05-07 20:21:19 +03:00
// void ExecuteVisitor::Visit(std::string* node) {} // std::string
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(FloatNumberLiteral* node) {
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
info::value::InternalValue(node->value),
utils::ValueType::Tmp);
}
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(NumberLiteral* node) {
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
info::value::InternalValue(node->value),
utils::ValueType::Tmp);
}
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(StringLiteral* node) {
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
info::value::InternalValue(node->value),
utils::ValueType::Tmp);
}
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(CharLiteral* node) {
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
info::value::InternalValue(node->value),
utils::ValueType::Tmp);
}
void ExecuteVisitor::Visit(UnitLiteral* node) {
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
info::value::InternalValue(info::value::Unit()),
utils::ValueType::Tmp);
}
2023-05-07 20:21:19 +03:00
void ExecuteVisitor::Visit(BoolLiteral* node) {
current_value_ = context_manager_.AddValue<info::value::InternalValue>(
info::value::InternalValue(node->value),
utils::ValueType::Tmp);
}
//
2023-05-07 20:21:19 +03:00
bool ExecuteVisitor::HandleCondition(Expression& node, const BaseNode& base_node) {
Visitor::Visit(node);
return *ExtractInternalValue<bool>(current_value_, base_node);
}
2023-05-08 20:34:36 +03:00
2023-05-09 17:42:35 +03:00
// TODO: handle abstract types, handle local abstract types, etc.
void ExecuteVisitor::CollectTypeContext(const ParametrizedType& type) {
if (!type.type_id_.has_value()) {
return;
}
auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(type.type_id_.value());
if (!maybe_type_info.has_value()) {
error_handling::HandleInternalError("CollectTypeContext unimplemented anything except AnyType", "ExecuteVisitor.CollectTYpeContext");
}
info::definition::AnyType& type_info = *maybe_type_info.value(); // check, that has value ??
for (size_t i = 0; i < type.parameters.size(); ++i) {
if (type.parameters[i]->type_id_.has_value()) {
context_manager_.DefineLocalType(type_info.parameters[i].type,
type.parameters[i]->type_id_.value());
2023-05-09 23:36:47 +03:00
}
}
}
// 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<NameIdentifier>>(node),
2023-05-09 23:36:47 +03:00
value)) {
error_handling::HandleRuntimeError("Can't redifine variable", base_node);
}
break;
case 1:
Visitor::Visit(*std::get<std::unique_ptr<Literal>>(node));
2023-05-10 23:13:50 +03:00
error_handling::HandleInternalError("Unimplemented EqualValues", "ExecuteVisitor.CheckPattern");
// if (!context_manager_.EqualValues(current_value_, value)) { // TODO
// case_matched_ = false;
// }
2023-05-09 23:36:47 +03:00
break;
case 2:
Visit(std::get<std::unique_ptr<TypeConstructorPattern>>(node).get());
break;
default:
// error
break;
2023-05-09 17:42:35 +03:00
}
}
2023-05-07 20:21:19 +03:00
} // namespace interpreter