// for clangd #include "../include/print_visitor.hpp" namespace interpreter { // Sources ----------------- void PrintVisitor::Visit(SourceFile* node) { out_ << "[SourceFile] (\n\n"; for (auto& statement : node->statements) { Visitor::Visit(statement); } out_ << "\n)\n"; } // Namespaces, partitions ----------------- void PrintVisitor::Visit(PartitionSources* node) { out_ << "[PartitionSources](\n"; for (auto& statement : node->statements) { Visitor::Visit(statement); } out_ << ")\n"; } void PrintVisitor::Visit(Partition* node) { out_ << "[Partition] "; switch (node->name) { case Partition::Test: out_ << "TEST"; break; case Partition::Interface: out_ << "INTERFACE"; break; case Partition::Code: out_ << "CODE"; break; } out_ << " {\n"; Visit(&node->scope); out_ << "}\n"; } void PrintVisitor::Visit(NamespaceSources* node) { out_ << "[NamespaceSources](\n"; for (auto& statement : node->statements) { Visitor::Visit(statement); } out_ << ")\n"; } void PrintVisitor::Visit(Namespace* node) { out_ << "[Namespace] "; if (node->modifier.has_value()) { switch (node->modifier.value()) { case Namespace::Const: out_ << "const "; break; case Namespace::Var: out_ << "var "; break; } } Visit(&node->type); out_ << "{\n"; Visit(&node->scope); out_ << "}\n"; } // Definitions ----------------- void PrintVisitor::Visit(ImportStatement* node) { if (node->name.has_value()) { out_ << "[Use " << node->name.value() << "] = "; } out_ << "[Import " << node->module_name << "]"; if (!node->symbols.empty()) { out_ << " (\n"; for (auto& symbol : node->symbols) { Visit(&symbol); out_ << '\n'; } out_ << ')'; } out_ << '\n'; } void PrintVisitor::Visit(AliasDefinitionStatement* node) { out_ << "[Alias "; switch (node->modifier) { case AliasDefinitionStatement::Alias: out_ << "alias"; break; case AliasDefinitionStatement::Type: out_ << "type"; break; case AliasDefinitionStatement::Let: out_ << "let"; break; } out_ << ' '; Visit(&node->type); out_ << "] = ("; Visit(node->value.get()); out_ << ")\n"; } void PrintVisitor::Visit(VariableDefinitionStatement* node) { out_ << "[Variable "; switch (node->modifier) { case VariableDefinitionStatement::Const: out_ << "const"; break; case VariableDefinitionStatement::Var: out_ << "var"; break; } out_ << ' '; Visitor::Visit(node->name); out_ << "] = ("; Visitor::Visit(node->value); out_ << ")\n"; } void PrintVisitor::Visit(FunctionDeclaration* node) { out_ << "[FunctionDeclaration "; Visit(&node->name); out_ << "] ("; for (auto& parameter : node->parameters) { Visit(parameter.get()); } out_ << ") : ("; Visit(node->type.get()); out_ << ")\n"; } void PrintVisitor::Visit(FunctionDefinitionStatement* node) { out_ << "[Function] ("; Visit(node->definition.get()); out_ << ") = ("; Visitor::Visit(node->value); out_ << ")\n"; } void PrintVisitor::Visit(TypeDefinitionStatement* node) { out_ << "[Type "; switch (node->modifier) { case TypeDefinitionStatement::Struct: out_ << "struct"; break; case TypeDefinitionStatement::Class: out_ << "class"; break; } out_ << "] ("; Visit(node->definition.get()); out_ << ") = ("; Visitor::Visit(node->value); out_ << ")\n"; } void PrintVisitor::Visit(AbstractTypeDefinitionStatement* node) { out_ << "[AbstractType "; switch (node->modifier) { case AbstractTypeDefinitionStatement::Basic: out_ << "basic"; break; case AbstractTypeDefinitionStatement::Abstract: out_ << "abstract"; break; } out_ << "] ("; Visit(node->type.get()); out_ << ")\n"; } void PrintVisitor::Visit(TypeclassDefinitionStatement* node) { out_ << "[Typeclass] ("; Visit(node->definition.get()); if (!node->requirements.empty()) { out_ << ") : (\n"; } for (auto& requirement : node->requirements) { out_ << "& "; Visit(requirement.get()); out_ << "\n"; } out_ << ")\n"; } // Definition parts void PrintVisitor::Visit(FunctionDefinition* node) { out_ << "[FunctionDefinition "; switch (node->modifier) { case FunctionDefinition::Operator: out_ << "operator"; break; case FunctionDefinition::Function: out_ << "function"; break; } out_ << ' '; Visit(&node->name); out_ << "]"; if (!node->arguments.empty()) { out_ << " : ("; for (auto& argument : node->arguments) { Visit(&argument); } out_ << ')'; } out_ << ' '; } void PrintVisitor::Visit(TypeDefinition* node) { out_ << "[TypeDefinition] ("; Visit(node->type.get()); out_ << ')'; if (!node->parameters.empty()) { out_ << '('; for (auto& parameter : node->parameters) { Visit(parameter.get()); } out_ << ')'; } out_ << ' '; } void PrintVisitor::Visit(AnyAnnotatedType* node) { out_ << "[Annotated (Abstract) Type "; Visit(&node->type); out_ << ']'; if (!node->typeclasses.empty()) { out_ << " ("; for (auto& typeclass : node->typeclasses) { Visit(typeclass.get()); } out_ << ')'; } out_ << ' '; } // Flow control ----------------- void PrintVisitor::Visit(TypeConstructorPatternParameter* node) { out_ << "[TypeConstructorPatternParameter "; if (node->name.has_value()) { Visit(&node->name.value()); out_ << " = "; } Visitor::Visit(node->value); out_ << "]"; } void PrintVisitor::Visit(TypeConstructorPattern* node) { out_ << "[TypeConstructorPattern "; Visit(node->constructor.get()); out_ << "]\n("; bool is_first = true; for (auto& parameter : node->parameters) { if (!is_first) { out_ << ")\n"; } is_first = false; out_ << '('; Visit(¶meter); } out_ << ")\n"; } void PrintVisitor::Visit(MatchCase* node) { out_ << "[MatchCase | "; Visitor::Visit(node->value); if (node->condition.has_value()) { out_ << " ? "; Visitor::Visit(node->condition.value()); } if (node->statement.has_value()) { out_ << " -> "; Visitor::Visit(node->statement.value()); } out_ << "]\n"; } void PrintVisitor::Visit(Match* node) { out_ << "[Match] ("; Visitor::Visit(node->value); out_ << ") [with] (\n"; for (auto& match_case : node->matches) { Visit(&match_case); } out_ << ")\n"; } void PrintVisitor::Visit(Condition* node) { out_ << "[If] ("; Visitor::Visit(node->conditions[0]); out_ << ") [then] (\n"; Visitor::Visit(node->statements[0]); out_ << ')'; for (size_t i = 1; i < node->conditions.size(); ++i) { out_ << " [elif] ("; Visitor::Visit(node->conditions[i]); out_ << ") [then] (\n"; Visitor::Visit(node->statements[i]); out_ << ')'; } if (node->statements.size() > node->conditions.size()) { out_ << " [else] (\n"; Visitor::Visit(node->statements[node->conditions.size()]); out_ << ')'; } out_ << '\n'; } void PrintVisitor::Visit(DoWhileLoop* node) { out_ << "[Do] (\n"; Visitor::Visit(node->statement); out_ << ") [while] ("; Visitor::Visit(node->condition); out_ << ")\n"; } void PrintVisitor::Visit(WhileLoop* node) { out_ << "[While] ("; Visitor::Visit(node->condition); out_ << ") [do] (\n"; Visitor::Visit(node->statement); out_ << ")\n"; } void PrintVisitor::Visit(ForLoop* node) { out_ << "[For] ("; Visitor::Visit(node->variable); out_ << ") [in] ("; Visitor::Visit(node->interval); out_ << ") [do] (\n"; Visitor::Visit(node->statement); out_ << ")\n"; } void PrintVisitor::Visit(LoopLoop* node) { out_ << "[Loop] (\n"; Visitor::Visit(node->statement); out_ << ")\n"; } // Statements, expressions, blocks, etc. ----------------- void PrintVisitor::Visit(Block* node) { out_ << "[Block] {\n"; for (auto& statement : node->statements) { Visitor::Visit(statement); } out_ << "}\n"; } void PrintVisitor::Visit(ScopedStatement* node) { out_ << "[Scoped] ( "; Visitor::Visit(node->statement); out_ << ")\n"; } void PrintVisitor::Visit(LoopControlExpression& node) { // enum switch (node) { case LoopControlExpression::Break: out_ << "[Break]\n"; break; case LoopControlExpression::Continue: out_ << "[Continue]\n"; break; } } // Operators void PrintVisitor::Visit(BinaryOperatorExpression* node) { out_ << "[BinaryOperator] ("; Visitor::Visit(node->left_expression); out_ << ") ["; Visit(&node->operator_name); out_ << "] ("; Visitor::Visit(node->right_expression); out_ << ')'; } void PrintVisitor::Visit(UnaryOperatorExpression* node) { out_ << "[UnaryOperator "; Visit(&node->operator_name); out_ << "] ("; Visitor::Visit(node->expression); out_ << ')'; } void PrintVisitor::Visit(ReferenceExpression* node) { out_ << "[ReferenceExpression "; for (auto& reference : node->references) { switch (reference) { case utils::ReferenceType::Reference: out_ << '~'; break; case utils::ReferenceType::UniqueReference: out_ << '@'; break; } } out_ << "] ("; Visit(node->expression.get()); out_ << ')'; } void PrintVisitor::Visit(AccessExpression* node) { out_ << "[AccessExpression] ("; Visit(node->name.get()); out_ << ") : ("; Visitor::Visit(node->id); out_ << ')'; } // Other Expressions void PrintVisitor::Visit(FunctionCallExpression* node) { out_ << "[FunctionCall "; if (node->prefix.has_value()) { out_ << '('; 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 } out_ << ")."; } Visit(&node->name); out_ << "] ("; for (auto& argument : node->arguments) { Visitor::Visit(argument); out_ << ", "; } out_ << ")"; } void PrintVisitor::Visit(TupleExpression* node) { out_ << "[TupleExpression] ("; for (auto& expression : node->expressions) { out_ << "&"; Visitor::Visit(expression); } out_ << ")"; } void PrintVisitor::Visit(VariantExpression* node) { out_ << "[VariantExpression] ("; for (auto& expression : node->expressions) { out_ << "|"; Visitor::Visit(expression); } out_ << ")"; } void PrintVisitor::Visit(ReturnExpression* node) { out_ << "[Return] ("; Visitor::Visit(node->expression); out_ << ")\n"; } void PrintVisitor::Visit(TypeConstructorParameter* node) { out_ << "[TypeConstructorParameter "; if (node->name.has_value()) { Visit(&node->name.value()); switch (node->asignment_modifier.value()) { case TypeConstructorParameter::Assign: out_ << " = "; break; case TypeConstructorParameter::Move: out_ << " <- "; break; } } Visitor::Visit(node->value); out_ << "]"; } void PrintVisitor::Visit(TypeConstructor* node) { out_ << "[TypeConstructor "; Visit(node->constructor.get()); out_ << "]\n("; bool is_first = true; for (auto& parameter : node->parameters) { if (!is_first) { out_ << ")\n"; } is_first = false; out_ << '('; Visit(¶meter); } out_ << ")\n"; } void PrintVisitor::Visit(LambdaFunction* node) { out_ << "[LambdaFunction] ("; for (auto& parameter : node->parameters) { Visit(parameter.get()); } if (!node->parameters.empty()) { out_ << ") : ("; } for (auto& argument : node->arguments) { Visit(&argument); } out_ << ") -> (\n"; Visitor::Visit(node->expression); out_ << ")\n"; } void PrintVisitor::Visit(ArrayExpression* node) { out_ << "[ArrayExpression] ( ,"; for (auto& element : node->elements) { Visitor::Visit(element); out_ << " ,"; } out_ << ")"; } // Name void PrintVisitor::Visit(NameExpression* node) { out_ << "[NameExpression] ("; for (size_t i = 0; i < node->names.size(); ++i) { Visit(&node->names[i]); if (i + 1 < node->names.size()) { out_ << "::"; } } out_ << ')'; } void PrintVisitor::Visit(TupleName* node) { out_ << "[TupleName] ("; for (auto& name : node->names) { out_ << "& "; Visitor::Visit(name); } out_ << ')'; } void PrintVisitor::Visit(VariantName* node) { out_ << "[VariantName] ("; for (auto& name : node->names) { out_ << "| "; Visitor::Visit(name); } out_ << ')'; } void PrintVisitor::Visit(AnnotatedName* node) { out_ << "[AnnotatedName "; Visit(&node->name); out_ << ']'; if (node->type.has_value()) { out_ << " : ("; Visitor::Visit(node->type.value()); out_ << ')'; } } // Type, typeclass, etc. ----------------- // Type void PrintVisitor::Visit(FunctionType* node) { out_ << "[FunctionType] ("; bool is_first = true; for (auto& type : node->types) { if (!is_first) { out_ << " -> "; } is_first = false; Visitor::Visit(type); } out_ << ')'; } void PrintVisitor::Visit(TupleType* node) { out_ << "[TupleType "; if (node->type.has_value()) { Visit(&node->type.value()); } out_ << "] ("; for (auto& entity : node->entities) { out_ << "& "; if (entity.first.has_value()) { Visit(&entity.first.value()); out_ << " : "; } Visit(entity.second.get()); } out_ << ')'; } void PrintVisitor::Visit(VariantType* node) { out_ << "[VariantType "; if (node->type.has_value()) { Visit(&node->type.value()); } out_ << "] ("; for (auto& constructor : node->constructors) { out_ << "| "; if (std::holds_alternative(constructor)) { Visit(&std::get(constructor)); } else if (std::holds_alternative>(constructor)) { Visit(std::get>(constructor).get()); } else { // error } } out_ << ')'; } void PrintVisitor::Visit(TypeExpression* node) { out_ << "[TypeExpression "; if (node->array_size.has_value()) { out_ << "[array size: " << node->array_size.value() << ']'; } out_ << "] ("; for (auto& type : node->path) { Visitor::Visit(type); out_ << "::"; } Visitor::Visit(node->type); out_ << ')'; } void PrintVisitor::Visit(ExtendedScopedAnyType* node) { out_ << "[ExtendedScopedAnyType "; for (auto& reference : node->references) { switch (reference) { case utils::ReferenceType::Reference: out_ << '~'; break; case utils::ReferenceType::UniqueReference: out_ << '@'; break; } } out_ << "] ("; Visitor::Visit(node->type); out_ << ')'; } // Typeclass void PrintVisitor::Visit(TypeclassExpression* node) { out_ << "[TypeclassExpression] ("; Visitor::Visit(node->typeclass); out_ << ')'; } void PrintVisitor::Visit(ParametrizedTypeclass* node) { out_ << "[ParametrizedTypeclass] ("; Visit(&node->typeclass); for (auto& parameter : node->parameters) { out_ << ' '; Visit(parameter.get()); } out_ << ')'; } // Typeclass & Type ----------------- void PrintVisitor::Visit(ParametrizedType* node) { out_ << "[ParametrizedType] ("; Visit(&node->type); for (auto& parameter : node->parameters) { out_ << ' '; Visit(parameter.get()); } out_ << ')'; } // Identifiers, constants, etc. ----------------- void PrintVisitor::Visit(ExtendedName* node) { out_ << "[ExtendedName " << node->name << "] "; } void PrintVisitor::Visit(std::string* node) { // std::string out_ << "[Identifier " << *node << "] "; } void PrintVisitor::Visit(FloatNumberLiteral* node) { out_ << "[FloatNumber " << node->value << "] "; } void PrintVisitor::Visit(NumberLiteral* node) { out_ << "[Number " << node->value << "] "; } void PrintVisitor::Visit(StringLiteral* node) { out_ << "[String " << node->value << "] "; } void PrintVisitor::Visit(CharLiteral* node) { out_ << "[Char " << node->value << "] "; } void PrintVisitor::Visit(UnitLiteral* node) { out_ << "[Unit ()] "; } } // namespace interpreter