// for clangd #include "../include/print_visitor.hpp" namespace interpreter { void PrintVisitor::Visit(Node* node) { out_ << "[Node]\n"; } // Sources ----------------- void PrintVisitor::Visit(SourceFile* node) { out_ << "\n\n"; for (auto& statement : node->statements) { if (std::holds_alternative(statement)) { Visit(&std::get(statement)); } else if (std::holds_alternative(statement)) { Visitor::Visit(std::get(statement)); } else { // error } } out_ << "\n"; } void PrintVisitor::Visit(Sources* node) { out_ << "\n\n"; for (auto& statement : node->statements) { Visitor::Visit(statement); } out_ << "\n"; } // Namespaces, partittions ----------------- void PrintVisitor::Visit(Partition* node) { out_ << " "; switch (node->type) { case Partition::Test: out_ << "TEST"; break; case Partition::Interface: out_ << "INTERFACE"; break; case Partition::Core: out_ << "CORE"; break; case Partition::Lib: out_ << "LIB"; break; case Partition::Module: out_ << "MODULE"; break; case Partition::Exe: out_ << "EXE"; break; } out_ << " {\n"; Visit(node->scope.get()); out_ << "} \n"; } void PrintVisitor::Visit(Namespace* node) { out_ << " "; if (std::holds_alternative>(node->name)) { if (node->is_const) { out_ << "const "; } else { out_ << "var "; } Visit(std::get>(node->name).get()); } else if (std::holds_alternative>(node->name)) { Visit(std::get>(node->name).get()); } else { // error } out_ << "{\n"; Visit(node->scope.get()); out_ << "} \n"; } // Definitions ----------------- void PrintVisitor::Visit(ImportStatement* node) { out_ << " \"" << node->module_name << "\" "; if (node->symbols.size() > 0) { out_ << '\n'; } for (auto& symbol : node->symbols) { Visitor::Visit(symbol); out_ << '\n'; } out_ << "\n"; } void PrintVisitor::Visit(UsageDefinition* node) { out_ << " "; Visit(&node->name); out_ << " = "; Visit(node->import_statement.get()); out_ << "\n"; } void PrintVisitor::Visit(AliasDefinition* node) { out_ << " "; Visit(node->type.get()); out_ << " = "; Visit(node->value.get()); out_ << "\n"; } void PrintVisitor::Visit(VariableDefinition* node) { out_ << " " << (node->is_const ? "const" : "var") << ' '; Visit(&node->name); out_ << " = "; Visitor::Visit(node->value); out_ << "\n"; } void PrintVisitor::Visit(FunctionDeclaration* node) { out_ << " "; Visit(&node->name); out_ << "\n"; for (auto& parameter : node->parameters) { Visit(parameter.get()); } out_ << " : \n"; for (auto& argument_type : node->argument_types) { Visitor::Visit(argument_type); } out_ << "\n"; } void PrintVisitor::Visit(FunctionDefinition* node) { out_ << " "; Visit(node->name.get()); out_ << " = "; Visitor::Visit(node->value); out_ << "\n"; } void PrintVisitor::Visit(AliasTypeDefinition* node) { out_ << " "; Visit(node->name.get()); out_ << " = "; Visit(node->value.get()); out_ << "\n"; } void PrintVisitor::Visit(TypeDefinition* node) { out_ << " "; Visit(node->name.get()); out_ << " = "; Visitor::Visit(node->value); out_ << "\n"; } void PrintVisitor::Visit(TypeclassDefinition* node) { out_ << " "; Visit(node->name.get()); if (node->requirements.size() > 0) { out_ << " : \n"; } for (auto& requirement : node->requirements) { out_ << "& "; Visit(requirement.get()); } out_ << "\n"; } // Definition parts void PrintVisitor::Visit(DefinedName* node) { out_ << " "; Visit(&node->name); if (node->parameters.size() > 0) { out_ << "\n"; } for (auto& parameter : node->parameters) { Visit(parameter.get()); } if (node->arguments.size() > 0) { out_ << " : \n"; } for (auto& argument : node->arguments) { Visit(argument.get()); } out_ << "\n"; } void PrintVisitor::Visit(DefinedAnnotatedName* node) { out_ << " "; Visit(&node->name); out_ << " : "; if (std::holds_alternative>(node->type)) { Visit(std::get>(node->type).get()); } else if (std::holds_alternative>(node->type)) { Visit(std::get>(node->type).get()); } else { // no annotation } out_ << " "; } void PrintVisitor::Visit(DefinedType* node) { out_ << " "; Visit(node->type.get()); if (node->parameters.size() > 0) { out_ << "\n"; } for (auto& parameter : node->parameters) { Visit(parameter.get()); } if (node->arguments.size() > 0) { out_ << " : \n"; } for (auto& argument : node->arguments) { Visit(argument.get()); } out_ << "\n"; } void PrintVisitor::Visit(DefinedTypeclass* node) { out_ << " "; Visit(node->typeclass.get()); if (node->parameters.size() > 0) { out_ << "\n"; } for (auto& parameter : node->parameters) { Visit(parameter.get()); } if (node->arguments.size() > 0) { out_ << " : \n"; } for (auto& argument : node->arguments) { Visit(argument.get()); } out_ << "\n"; } void PrintVisitor::Visit(DefinitionParameter* node) { out_ << " " << (node->typeclasses.size() > 0 ? "(" : ""); Visit(&node->type); out_ << ' '; for (auto& typeclass : node->typeclasses) { Visit(typeclass.get()); } out_ << "\n"; } void PrintVisitor::Visit(DefinitionArgument* node) { out_ << " " << (node->types.size() > 0 ? "(" : ""); Visit(&node->name); out_ << ' '; for (auto& type : node->types) { Visit(type.get()); } out_ << "\n"; } // Flow control ----------------- void PrintVisitor::Visit(Match* node) { out_ << " "; Visitor::Visit(node->value); out_ << " with\n"; for (auto& match_case : node->matches) { out_ << "| "; Visitor::Visit(match_case.value); if (match_case.condition.has_value()) { out_ << " ? "; Visitor::Visit(match_case.condition.value()); } if (match_case.statement.has_value()) { out_ << " -> "; Visitor::Visit(match_case.statement.value()); } out_ << '\n'; } out_ << "\n"; } void PrintVisitor::Visit(Condition* node) { out_ << " "; Visitor::Visit(node->conditions[0]); out_ << " then\n"; Visitor::Visit(node->statements[0]); out_ << '\n'; 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_ << '\n'; } if (node->statements.size() > node->conditions.size()) { out_ << "else "; Visitor::Visit(node->statements[node->conditions.size()]); out_ << '\n'; } out_ << "\n"; } void PrintVisitor::Visit(DoWhileLoop* node) { out_ << "\n"; Visitor::Visit(node->statement); out_ << "\nwhile\n"; Visitor::Visit(node->condition); out_ << "\n\n"; } void PrintVisitor::Visit(WhileLoop* node) { out_ << "\n"; Visitor::Visit(node->statement); out_ << "\ndo\n"; Visitor::Visit(node->condition); out_ << "\n\n"; } void PrintVisitor::Visit(ForLoop* node) { out_ << "\n"; Visitor::Visit(node->variable); out_ << "\nin\n"; Visitor::Visit(node->interval); out_ << "\ndo\n"; Visitor::Visit(node->statement); out_ << "\n"; } void PrintVisitor::Visit(LoopLoop* node) { out_ << "\n"; Visitor::Visit(node->statement); out_ << "<\n/Loop>\n"; } // Statements, expressions, blocks, etc. ----------------- void PrintVisitor::Visit(Block* node) { out_ << " {\n"; for (auto& statement : node->statements) { Visitor::Visit(statement); } out_ << "} \n"; } void PrintVisitor::Visit(ScopedStatement* node) { out_ << " ( "; Visitor::Visit(node->statement); out_ << " ) "; } void PrintVisitor::Visit(LoopControlExpression& node) { // enum switch (node) { case LoopControlExpression::Break: out_ << "\n"; break; case LoopControlExpression::Continue: out_ << "\n"; break; } } // Operators void PrintVisitor::Visit(BinaryOperatorExpression* node) { out_ << " "; Visitor::Visit(node->left_expression); out_ << ' '; Visit(&node->operator_name); out_ << ' '; Visitor::Visit(node->right_expression); out_ << " "; } void PrintVisitor::Visit(UnaryOperatorExpression* node) { out_ << " "; Visit(&node->operator_name); out_ << ' '; Visitor::Visit(node->expression); out_ << " "; } // Simple Expressions void PrintVisitor::Visit(FunctionCallExpression* node) { out_ << " "; Visit(node->name.get()); out_ << ' '; for (auto& argument : node->arguments) { Visitor::Visit(argument); out_ << ' '; } out_ << ""; } void PrintVisitor::Visit(TupleExpression* node) { out_ << " "; out_ << ' '; for (auto& expression : node->expressions) { out_ << "& "; Visitor::Visit(expression); } out_ << " "; } void PrintVisitor::Visit(VariantExpression* node) { out_ << " "; out_ << ' '; for (auto& expression : node->expressions) { out_ << "& "; Visitor::Visit(expression); } out_ << " "; } void PrintVisitor::Visit(ReturnExpression* node) { out_ << " "; Visitor::Visit(node->expression); out_ << " "; } // Lambda void PrintVisitor::Visit(LambdaFunction* node) { out_ << " \\ "; for (auto& parameter : node->parameters) { Visit(parameter.get()); } if (node->parameters.size() > 0) { out_ << " : "; } for (auto& argument : node->arguments) { Visit(argument.get()); } out_ << " -> "; Visitor::Visit(node->expression); out_ << " "; } // Name void PrintVisitor::Visit(NameSuperExpression* node) { out_ << " "; for (auto& variable_namespace : node->namespaces) { Visitor::Visit(variable_namespace); out_ << '.'; } for (int i = 0; i < node->expressions.size(); ++i) { Visitor::Visit(node->expressions[i]); if (i + 1 < node->expressions.size()) { out_ << '.'; } } out_ << "\n"; } void PrintVisitor::Visit(NameExpression* node) { out_ << " "; for (auto& variable_namespace : node->namespaces) { Visitor::Visit(variable_namespace); out_ << '.'; } for (int i = 0; i < node->names.size(); ++i) { Visit(&node->names[i]); if (i + 1 < node->names.size()) { out_ << '.'; } } out_ << "\n"; } void PrintVisitor::Visit(TupleName* node) { out_ << " "; for (auto& name : node->names) { out_ << '&'; Visit(name.get()); } out_ << "\n"; } void PrintVisitor::Visit(VariantName* node) { out_ << " "; for (auto& name : node->names) { out_ << '|'; Visit(name.get()); } out_ << "\n"; } void PrintVisitor::Visit(AnnotatedName* node) { out_ << " "; Visit(&node->name); out_ << ' '; Visit(node->type.get()); out_ << " "; } // Type void PrintVisitor::Visit(TypeConstructor* node) { out_ << " "; Visit(node->type.get()); out_ << '\n'; for (auto& parameter : node->parameters) { Visit(¶meter.first); out_ << " = "; Visitor::Visit(parameter.second); out_ << '\n'; } out_ << "\n"; } void PrintVisitor::Visit(TupleType* node) { out_ << " "; Visit(&node->type); // optional out_ << ' '; for (auto& entity : node->entities) { out_ << "& "; if (entity.first != "") { Visit(&entity.first); out_ << " : "; } Visitor::Visit(entity.second); } out_ << ""; } void PrintVisitor::Visit(VariantType* node) { out_ << " "; Visit(&node->type); // optional out_ << ' '; for (auto& constructor : node->constructors) { out_ << "| "; Visit(&constructor.first); Visit(constructor.second.get()); } out_ << ""; } void PrintVisitor::Visit(AnnotatedType* node) { out_ << " "; Visit(node->type_expression.get()); if (node->annotations.size() > 0) { out_ << " :"; } for (auto& annotation : node->annotations) { out_ << " "; Visit(annotation.get()); } out_ << ""; } void PrintVisitor::Visit(ParametrizedType* node) { out_ << " "; Visit(node->type_expression.get()); for (auto& paramater : node->parameters) { out_ << ' '; Visitor::Visit(paramater); } out_ << " "; } void PrintVisitor::Visit(TypeExpression* node) { out_ << " "; for (auto& type_namespace : node->namespaces) { Visitor::Visit(type_namespace); out_ << '.'; } Visit(&node->type); out_ << " "; } // Typeclass void PrintVisitor::Visit(AnnotatedTypeclass* node) { out_ << " "; Visit(node->typeclass_expression.get()); if (node->annotations.size() > 0) { out_ << " :"; } for (auto& annotation : node->annotations) { out_ << " "; Visit(annotation.get()); } out_ << ""; } void PrintVisitor::Visit(ParametrizedTypeclass* node) { out_ << " "; Visit(node->typeclass_expression.get()); for (auto& paramater : node->parameters) { out_ << ' '; Visitor::Visit(paramater); } out_ << " "; } void PrintVisitor::Visit(TypeclassExpression* node) { out_ << " "; for (auto& typeclass_namespace : node->namespaces) { Visitor::Visit(typeclass_namespace); out_ << '.'; } Visit(&node->typeclass); out_ << " "; } // Identifiers, constants, etc. ----------------- void PrintVisitor::Visit(AnyIdentifier* node) { // std::string out_ << ""; } void PrintVisitor::Visit(FloatNumberLiteral* node) { out_ << "value << " />"; } void PrintVisitor::Visit(NumberLiteral* node) { out_ << "value << " />"; } void PrintVisitor::Visit(StringLiteral* node) { out_ << "value << " />"; } void PrintVisitor::Visit(CharLiteral* node) { out_ << "value << " />"; } } // namespace interpreter