// for clangd #include "../include/execute_visitor.hpp" #include #include #include // TODO namespace interpreter { // Sources ----------------- void ExecuteVisitor::Visit(SourceFile* node) { // never used ?? for (auto& statement : node->statements) { Visitor::Visit(statement); } } // Namespaces, partitions ----------------- void ExecuteVisitor::Visit(NamespaceSources* node) { // never used ?? for (auto& statement : node->statements) { Visitor::Visit(statement); } } void ExecuteVisitor::Visit(Namespace* node) { // never used ?? // Visit(&node->type); Visit(&node->scope); } // Definitions ----------------- void ExecuteVisitor::Visit(ImportStatement* node) {} // no value void ExecuteVisitor::Visit(AliasDefinitionStatement* node) {} // no value void ExecuteVisitor::Visit(VariableDefinitionStatement* node) { // visited on function call Visitor::Visit(node->name); Visitor::Visit(node->value); } void ExecuteVisitor::Visit(FunctionDeclaration* node) {} // no value void ExecuteVisitor::Visit(FunctionDefinitionStatement* node) { // visited on function call // Visit(node->definition.get()); Visitor::Visit(node->value); } void ExecuteVisitor::Visit(TypeDefinitionStatement* node) {} // no value void ExecuteVisitor::Visit(AbstractTypeDefinitionStatement* node) {} // no value void ExecuteVisitor::Visit(TypeclassDefinitionStatement* node) {} // no value void ExecuteVisitor::Visit(PartitionStatement* node) { Visitor::Visit(node->value); } // Flow control ----------------- void ExecuteVisitor::Visit(TypeConstructorPatternParameter* node) { if (node->name.has_value()) { // Visit(&node->name.value()); } Visitor::Visit(node->value); } // TODO void ExecuteVisitor::Visit(TypeConstructorPattern* node) { // TODO: not only tuples Visit(node->constructor.get()); for (auto& parameter : node->parameters) { Visit(¶meter); } } 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(Match* node) { Visitor::Visit(node->value); for (auto& match_case : node->matches) { Visit(&match_case); } } void ExecuteVisitor::Visit(Condition* node) { 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(current_value_), utils::ValueType::Tmp); // take value type from current_value_ ?? } return; // current_value_ passed from statement } } if (node->statements.size() > node->conditions.size()) { Visitor::Visit(node->statements[node->conditions.size()]); } else { current_value_ = context_manager_.AddValue( info::value::OptionalValue(), utils::ValueType::Tmp); } } void ExecuteVisitor::Visit(DoWhileLoop* node) { std::vector 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(std::move(result), false), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(WhileLoop* node) { std::vector 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(std::move(result), false), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(ForLoop* node) { std::vector result; // TODO: extend on different interval types (not only array) Visitor::Visit(node->interval); info::value::ArrayValue* interval = ExtractValue(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(std::move(result), false), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(LoopLoop* node) { std::vector 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(std::move(result), false), utils::ValueType::Tmp); } // Statements, expressions, blocks, etc. ----------------- void ExecuteVisitor::Visit(Block* node) { // type_info_context_manager_.EnterContext(); // not needed ?? context_manager_.EnterContext(); for (auto& statement : node->statements) { return_value_ = std::nullopt; Visitor::Visit(statement); if (return_value_.has_value()) { current_value_ = return_value_.value(); return; } } // context_manager_.ExitContext(); // type_info_context_manager_.ExitContext(); // not needed ?? current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(ScopedStatement* node) { Visitor::Visit(node->statement); } void ExecuteVisitor::Visit(LoopControlExpression& node) { active_loop_control_expression_ = node; current_value_ = context_manager_.AddValue(info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); // ?? } // Operators void ExecuteVisitor::Visit(BinaryOperatorExpression* node) { Visitor::Visit(node->left_expression); Visitor::Visit(&node->operator_name); Visitor::Visit(node->right_expression); } void ExecuteVisitor::Visit(UnaryOperatorExpression* node) { // Visit(&node->operator_name); Visitor::Visit(node->expression); } void ExecuteVisitor::Visit(ReferenceExpression* node) { // TODO: check, that therie is no references to "Tmp" Visit(node->expression.get()); utils::ValueType value_type = context_manager_.GetValueType(current_value_); current_value_ = context_manager_.AddValue( info::value::ReferenceToValue(node->references, current_value_), value_type); } void ExecuteVisitor::Visit(AccessExpression* node) { // TODO: extend to other types Visit(node->name.get()); info::value::ArrayValue* array_value = ExtractValue(current_value_, node->base); utils::ValueType value_type = context_manager_.GetValueType(current_value_); Visitor::Visit(node->id); long long index = *ExtractInternalValue(current_value_, node->base); // TODO: size_t if (index < 0 || index >= 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 ?? } // Other Expressions void ExecuteVisitor::Visit(FunctionCallExpression* node) { if (node->prefix.has_value()) { if (std::holds_alternative>(node->prefix.value())) { Visitor::Visit(*std::get>(node->prefix.value())); } else if (std::holds_alternative>(node->prefix.value())) { Visit(std::get>(node->prefix.value()).get()); } else { // error } } // Visit(&node->name); for (auto& parameter : node->parameters) { Visit(parameter.get()); } for (auto& argument : node->arguments) { Visitor::Visit(argument); } } void ExecuteVisitor::Visit(TupleExpression* node) { std::vector, utils::IdType>> fields; fields.reserve(node->expressions.size()); for (auto& expression : node->expressions) { Visitor::Visit(expression); fields.push_back({std::nullopt, current_value_}); } current_value_ = context_manager_.AddValue( info::value::TupleValue(std::move(fields)), utils::ValueType::Tmp); } // TODO void ExecuteVisitor::Visit(VariantExpression* node) { // ?? for (auto& expression : node->expressions) { Visitor::Visit(expression); info::value::OptionalValue* expression_value = ExtractValue(current_value_, node->base); if (expression_value->value.has_value()) { break; } } } void ExecuteVisitor::Visit(ReturnExpression* node) { Visitor::Visit(node->expression); return_value_ = current_value_; } void ExecuteVisitor::Visit(TypeConstructorParameter* node) { if (node->name.has_value()) { // Visit(&node->name.value()); } Visitor::Visit(node->value); } // TODO void ExecuteVisitor::Visit(TypeConstructor* node) { // TODO: not only tuples Visit(node->constructor.get()); for (auto& parameter : node->parameters) { Visit(¶meter); } } // TODO void ExecuteVisitor::Visit(LambdaFunction* node) { error_handling::HandleInternalError("Lambda function are not implemented yet", "ExecuteVisitor.LambdaFunction"); } void ExecuteVisitor::Visit(ArrayExpression* node) { std::vector elements; elements.reserve(node->elements.size()); for (auto& element : node->elements) { Visitor::Visit(element); elements.push_back(current_value_); } current_value_ = context_manager_.AddValue( info::value::ArrayValue(std::move(elements), true), // maybe size not fixed?? utils::ValueType::Tmp); } // Name void ExecuteVisitor::Visit(NameExpression* node) { for (auto& name : node->names) { // Visit(&name); } } void ExecuteVisitor::Visit(TupleName* node) { for (auto& name : node->names) { Visitor::Visit(name); } } void ExecuteVisitor::Visit(VariantName* node) { for (auto& name : node->names) { Visitor::Visit(name); } } void ExecuteVisitor::Visit(AnnotatedName* node) { // Visit(&node->name); if (node->type.has_value()) { Visitor::Visit(node->type.value()); } } // 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 // Typeclass void ExecuteVisitor::Visit(ParametrizedTypeclass* node) {} // no value // Typeclass & Type ----------------- void ExecuteVisitor::Visit(ParametrizedType* node) {} // no value // Identifiers, constants, etc. ----------------- // void ExecuteVisitor::Visit(ExtendedName* node) {} // void ExecuteVisitor::Visit(std::string* node) {} // std::string void ExecuteVisitor::Visit(FloatNumberLiteral* node) { current_value_ = context_manager_.AddValue( info::value::InternalValue(node->value), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(NumberLiteral* node) { current_value_ = context_manager_.AddValue( info::value::InternalValue(node->value), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(StringLiteral* node) { current_value_ = context_manager_.AddValue( info::value::InternalValue(node->value), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(CharLiteral* node) { current_value_ = context_manager_.AddValue( info::value::InternalValue(node->value), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(UnitLiteral* node) { current_value_ = context_manager_.AddValue( info::value::InternalValue(info::value::Unit()), utils::ValueType::Tmp); } void ExecuteVisitor::Visit(BoolLiteral* node) { current_value_ = context_manager_.AddValue( info::value::InternalValue(node->value), utils::ValueType::Tmp); } // bool ExecuteVisitor::HandleCondition(Expression& node, const BaseNode& base_node) { Visitor::Visit(node); return *ExtractInternalValue(current_value_, base_node); } } // namespace interpreter