From 3c643d2759eac8f41ac96e6067f0dd125a637410 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Mon, 17 Apr 2023 12:09:02 +0300 Subject: [PATCH] abstract type graph added to symbol table --- CMakeLists.txt | 1 + include/find_symbols_visitor.hpp | 6 +- include/global_info.hpp | 15 + include/interpreter_tree.hpp | 15 + include/link_symbols_visitor.hpp | 117 ++++++ include/type_check_visitor.hpp | 6 +- src/find_symbols_visitor.cpp | 18 +- src/link_symbols_visitor.cpp | 683 +++++++++++++++++++++++++++++++ 8 files changed, 845 insertions(+), 16 deletions(-) create mode 100644 include/link_symbols_visitor.hpp create mode 100644 src/link_symbols_visitor.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 04f47cd..df4e2b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ add_executable(lang_interpreter src/main.cpp src/build_visitor.cpp src/print_visitor.cpp src/find_symbols_visitor.cpp + src/global_info.cpp src/parser.c include/parser.h tree-sitter/lib/src/lib.c) diff --git a/include/find_symbols_visitor.hpp b/include/find_symbols_visitor.hpp index 1e859e8..8f33261 100644 --- a/include/find_symbols_visitor.hpp +++ b/include/find_symbols_visitor.hpp @@ -11,7 +11,8 @@ namespace interpreter { class FindSymbolsVisitor : public Visitor { public: - explicit FindSymbolsVisitor(info::GlobalInfo& global_info) : global_info_(global_info) {} + explicit FindSymbolsVisitor(info::GlobalInfo& global_info) + : namespace_visitor_(global_info.CreateVisitor()) {} private: // Sources ----------------- @@ -112,7 +113,8 @@ private: // // void Visit(CharLiteral* node) override; private: - info::GlobalInfo& global_info_; + info::GlobalInfo::NamespaceVisitor namespace_visitor_; + bool is_in_statement = false; std::any current_info_; }; diff --git a/include/global_info.hpp b/include/global_info.hpp index 92ed2f3..2801d1d 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -6,6 +6,7 @@ // for clangd #include "symbols_info.hpp" +#include "type_graph.hpp" #include "utils.hpp" namespace info { @@ -54,6 +55,14 @@ public: std::optional FindTypeclass(const std::optional>& path, const std::string typeclass); + + NamespaceVisitor CreateVisitor() { + return global_info_.CreateVisitor(); + } + + TypeGraph* GetAbstractTypeGraph() { + return global_info_.GetAbstractTypeGraph(); + } private: NamespaceVisitor(GlobalInfo& global_info) : global_info_(global_info), namespace_stack_({&global_info.global_namespace_}) {} @@ -74,6 +83,10 @@ public: return NamespaceVisitor(*this); } + TypeGraph* GetAbstractTypeGraph() { + return &abstract_type_graph_; + } + // TODO: remember about vector realloc FunctionInfo* GetFunctionInfo(utils::IdType id) { return &functions_[id]; @@ -94,6 +107,8 @@ private: std::vector types_; std::vector typeclasses_; + info::TypeGraph abstract_type_graph_; + NamespaceInfo global_namespace_; std::vector imports_; std::unordered_map usages_; diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index 08269bd..f89d36b 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -6,6 +6,9 @@ #include #include +// for clangd +#include "utils.hpp" + namespace interpreter::tokens { // ----------------- Declarations ----------------- @@ -293,6 +296,8 @@ struct AliasDefinitionStatement { TypeIdentifier type; std::vector parameters; std::unique_ptr value; + + utils::IdType type_id_; }; struct VariableDefinitionStatement { @@ -306,28 +311,38 @@ struct FunctionDeclaration { NameOrOperatorIdentifier name; std::vector> parameters; std::unique_ptr type; + + utils::IdType function_id_; }; struct FunctionDefinitionStatement { bool is_inline; std::unique_ptr definition; SuperExpression value; + + utils::IdType function_id_; }; struct TypeDefinitionStatement { enum { Struct, Class } modifier; std::unique_ptr definition; AnyType value; + + utils::IdType type_id_; }; struct AbstractTypeDefinitionStatement { enum { Basic, Abstract } modifier; std::unique_ptr type; + + utils::IdType type_id_; }; struct TypeclassDefinitionStatement { std::unique_ptr definition; std::vector> requirements; + + utils::IdType typeclass_id_; }; // Definition parts ----------------- diff --git a/include/link_symbols_visitor.hpp b/include/link_symbols_visitor.hpp new file mode 100644 index 0000000..42801f8 --- /dev/null +++ b/include/link_symbols_visitor.hpp @@ -0,0 +1,117 @@ +#pragma once + +#include + +// for clangd +#include "visitor.hpp" + + +namespace interpreter { + +// TODO, (maybe add VisitSourceFile?) +class LinkSymbolsVisitor : public Visitor { +public: + explicit LinkSymbolsVisitor() {} + +private: + // Sources ----------------- + + void Visit(SourceFile* node) override; + void Visit(Sources* node) override; + + // Namespaces, partitions ----------------- + + void Visit(Partition* node) override; + void Visit(Namespace* node) override; + + // Definitions ----------------- + + void Visit(ImportStatement* node) override; + void Visit(AliasDefinitionStatement* node) override; + void Visit(VariableDefinitionStatement* node) override; + void Visit(FunctionDeclaration* node) override; + void Visit(FunctionDefinitionStatement* node) override; + void Visit(TypeDefinitionStatement* node) override; + void Visit(AbstractTypeDefinitionStatement* node) override; + void Visit(TypeclassDefinitionStatement* node) override; + + // Definition parts + + void Visit(FunctionDefinition* node) override; + void Visit(TypeDefinition* node) override; + void Visit(AnyAnnotatedType* node) override; + + // Flow control ----------------- + + void Visit(MatchCase* node) override; + void Visit(Match* node) override; + void Visit(Condition* node) override; + void Visit(DoWhileLoop* node) override; + void Visit(WhileLoop* node) override; + void Visit(ForLoop* node) override; + void Visit(LoopLoop* node) override; + + // Statements, expressions, blocks, etc. ----------------- + + void Visit(Block* node) override; + + void Visit(ScopedStatement* node) override; + + // Operators + + void Visit(BinaryOperatorExpression* node) override; + void Visit(UnaryOperatorExpression* node) override; + void Visit(ReferenceExpression* node) override; + + // Simple Expressions + + void Visit(FunctionCallExpression* node) override; + + void Visit(TupleExpression* node) override; + void Visit(VariantExpression* node) override; + void Visit(ReturnExpression* node) override; + void Visit(TypeConstructor* node) override; + void Visit(LambdaFunction* node) override; + void Visit(ArrayExpression* node) override; + + void Visit(LoopControlExpression& node) override; // enum + + // Name + + void Visit(NameExpression* node) override; + void Visit(TupleName* node) override; + void Visit(VariantName* node) override; + void Visit(AnnotatedName* node) override; + + // Type, typeclass, etc. ----------------- + + // Type + + void Visit(FunctionType* node) override; + void Visit(TupleType* node) override; + void Visit(VariantType* node) override; + void Visit(ParametrizedType* node) override; + void Visit(TypeExpression* node) override; + + void Visit(ExtendedScopedAnyType* node) override; + + // Typeclass + + void Visit(ParametrizedTypeclass* node) override; + void Visit(TypeclassExpression* node) override; + + // Identifiers, constants, etc. ----------------- + + void Visit(ExtendedName* node) override; + + void Visit(std::string* node) override; // std::string + + void Visit(FloatNumberLiteral* node) override; + void Visit(NumberLiteral* node) override; + void Visit(StringLiteral* node) override; + void Visit(CharLiteral* node) override; + +private: +}; + +} // namespace interpreter diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index fbbc83f..e279645 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -5,15 +5,12 @@ #include "symbols_info.hpp" #include "visitor.hpp" #include "global_info.hpp" -#include "type_graph.hpp" namespace interpreter { class TypeCheckVisitor : public Visitor { public: - explicit TypeCheckVisitor(info::GlobalInfo& global_info, - info::TypeGraph& type_graph) - : global_info_(global_info), type_graph_(type_graph) {} + explicit TypeCheckVisitor(info::GlobalInfo& global_info) : global_info_(global_info) {} private: // Sources ----------------- @@ -115,7 +112,6 @@ private: private: info::GlobalInfo& global_info_; - info::TypeGraph type_graph_; info::TypeInfoContextManager context_manager_; info::TypeInfo current_type_; diff --git a/src/find_symbols_visitor.cpp b/src/find_symbols_visitor.cpp index 85038e7..8029194 100644 --- a/src/find_symbols_visitor.cpp +++ b/src/find_symbols_visitor.cpp @@ -47,9 +47,9 @@ void FindSymbolsVisitor::Visit(Namespace* node) { name = node->name.value().name; } - global_info_.AddEnterNamespace(node->type, modifier, name); + namespace_visitor_.AddEnterNamespace(node->type, modifier, name); Visit(node->scope.get()); - global_info_.ExitNamespace(); + namespace_visitor_.ExitNamespace(); } // Definitions ----------------- @@ -60,7 +60,7 @@ void FindSymbolsVisitor::Visit(ImportStatement* node) { info::ImportInfo info; info.module_name = node->module_name; info.symbols = node->symbols; - global_info_.AddImport(std::move(info), node->name); + namespace_visitor_.AddImport(std::move(info), node->name); is_in_statement = false; } @@ -90,7 +90,7 @@ void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) { info.type = std::move(alias_info); - global_info_.AddType(node->type, std::move(info)); + node->type_id_ = namespace_visitor_.AddType(node->type, std::move(info)); is_in_statement = false; } @@ -116,7 +116,7 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) { if (was_in_statement) { current_info_ = std::move(info); } else { - global_info_.AddFunctionDeclaration(node->name, std::move(info)); + node->function_id_ = namespace_visitor_.AddFunctionDeclaration(node->name, std::move(info)); is_in_statement = false; } } @@ -142,7 +142,7 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) { info.expression = &node->value; - global_info_.AddFunctionDefinition(definition->name, std::move(info)); + node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info)); is_in_statement = false; } @@ -173,7 +173,7 @@ void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) { info.type = std::move(any_type_info); - global_info_.AddType(type, std::move(info)); + node->type_id_ = namespace_visitor_.AddType(type, std::move(info)); is_in_statement = false; } @@ -202,7 +202,7 @@ void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) { info.type = std::move(abstract_type_info); - global_info_.AddType(type, std::move(info)); + node->type_id_ = namespace_visitor_.AddType(type, std::move(info)); is_in_statement = false; } @@ -228,7 +228,7 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { current_info_.reset(); } - global_info_.AddTypeclass(definition->type.get()->type, std::move(info)); + node->typeclass_id_ = namespace_visitor_.AddTypeclass(definition->type.get()->type, std::move(info)); is_in_statement = false; } diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp new file mode 100644 index 0000000..9c7542f --- /dev/null +++ b/src/link_symbols_visitor.cpp @@ -0,0 +1,683 @@ +// for clangd +#include "../include/link_symbols_visitor.hpp" + +namespace interpreter { + +// Sources ----------------- + +void LinkSymbolsVisitor::Visit(SourceFile* node) { + out_ << "[SourceFile] (\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)\n"; +} + +void LinkSymbolsVisitor::Visit(Sources* node) { + out_ << "[Sources](\n"; + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } + out_ << ")\n"; +} + +// Namespaces, partitions ----------------- + +void LinkSymbolsVisitor::Visit(Partition* node) { + out_ << "[Partition] "; + switch (node->name) { + 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 LinkSymbolsVisitor::Visit(Namespace* node) { + out_ << "[Namespace] "; + if (node->name.has_value()) { + if (node->modifier.has_value()) { + switch (node->modifier.value()) { + case Namespace::Const: + out_ << "const "; + break; + case Namespace::Var: + out_ << "var "; + break; + } + } else { + // error + } + Visit(&node->name.value()); + } + Visit(&node->type); + out_ << "{\n"; + Visit(node->scope.get()); + out_ << "}\n"; +} + +// Definitions ----------------- + +void LinkSymbolsVisitor::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 LinkSymbolsVisitor::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 LinkSymbolsVisitor::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 LinkSymbolsVisitor::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 LinkSymbolsVisitor::Visit(FunctionDefinitionStatement* node) { + out_ << "[Function] ("; + Visit(node->definition.get()); + out_ << ") = ("; + Visitor::Visit(node->value); + out_ << ")\n"; +} + +void LinkSymbolsVisitor::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 LinkSymbolsVisitor::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 LinkSymbolsVisitor::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 LinkSymbolsVisitor::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->parameters.empty()) { + out_ << " ("; + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + } + out_ << ')'; + } + if (!node->arguments.empty()) { + out_ << " : ("; + for (auto& argument : node->arguments) { + Visit(&argument); + } + out_ << ')'; + } + out_ << ' '; +} + +void LinkSymbolsVisitor::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 LinkSymbolsVisitor::Visit(AnyAnnotatedType* node) { + out_ << "[Annotated (Abstract) Type "; + Visit(&node->type); + out_ << ']'; + if (!node->typeclasses.empty() > 0) { + out_ << " ("; + for (auto& typeclass : node->typeclasses) { + Visitor::Visit(typeclass); + } + out_ << ')'; + } + out_ << ' '; +} + +// Flow control ----------------- + +void LinkSymbolsVisitor::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 LinkSymbolsVisitor::Visit(Match* node) { + out_ << "[Match] ("; + Visitor::Visit(node->value); + out_ << ") [with] (\n"; + for (auto& match_case : node->matches) { + Visit(&match_case); + } + out_ << ")\n"; +} + +void LinkSymbolsVisitor::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 LinkSymbolsVisitor::Visit(DoWhileLoop* node) { + out_ << "[Do] (\n"; + Visitor::Visit(node->statement); + out_ << ") [while] ("; + Visitor::Visit(node->condition); + out_ << ")\n"; +} + +void LinkSymbolsVisitor::Visit(WhileLoop* node) { + out_ << "[While] ("; + Visitor::Visit(node->statement); + out_ << ") [do] (\n"; + Visitor::Visit(node->condition); + out_ << ")\n"; +} +void LinkSymbolsVisitor::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 LinkSymbolsVisitor::Visit(LoopLoop* node) { + out_ << "[Loop] (\n"; + Visitor::Visit(node->statement); + out_ << ")\n"; +} + +// Statements, expressions, blocks, etc. ----------------- + +void LinkSymbolsVisitor::Visit(Block* node) { + out_ << "[Block] {\n"; + for (auto& statement : node->statements) { + Visitor::Visit(statement); + } + out_ << "}\n"; +} + +void LinkSymbolsVisitor::Visit(ScopedStatement* node) { + out_ << "[Scoped] ( "; + Visitor::Visit(node->statement); + out_ << ")\n"; +} + +void LinkSymbolsVisitor::Visit(LoopControlExpression& node) { // enum + switch (node) { + case LoopControlExpression::Break: + out_ << "[Break]\n"; + break; + case LoopControlExpression::Continue: + out_ << "[Continue]\n"; + break; + } +} + +// Operators + +void LinkSymbolsVisitor::Visit(BinaryOperatorExpression* node) { + out_ << "[BinaryOperator] ("; + Visitor::Visit(node->left_expression); + out_ << ") ["; + Visit(&node->operator_name); + out_ << "] ("; + Visitor::Visit(node->right_expression); + out_ << ')'; +} + +void LinkSymbolsVisitor::Visit(UnaryOperatorExpression* node) { + out_ << "[UnaryOperator "; + Visit(&node->operator_name); + out_ << "] ("; + Visitor::Visit(node->expression); + out_ << ')'; +} + +void LinkSymbolsVisitor::Visit(ReferenceExpression* node) { + out_ << "[ReferenceExpression "; + for (auto& reference : node->references) { + switch (reference) { + case ReferenceType::Reference: + out_ << '~'; + break; + case ReferenceType::UniqueReference: + out_ << '@'; + break; + } + } + out_ << "] ("; + Visit(node->expression.get()); + out_ << ')'; +} + +// Other Expressions + +void LinkSymbolsVisitor::Visit(FunctionCallExpression* node) { + out_ << "[FunctionCall "; + Visit(node->name.get()); + out_ << "] ("; + for (auto& argument : node->arguments) { + Visitor::Visit(argument); + out_ << ", "; + } + out_ << ")"; +} + +void LinkSymbolsVisitor::Visit(TupleExpression* node) { + out_ << "[TupleExpression] ("; + for (auto& expression : node->expressions) { + out_ << "&"; + Visitor::Visit(expression); + } + out_ << ")"; +} + +void LinkSymbolsVisitor::Visit(VariantExpression* node) { + out_ << "[VariantExpression] ("; + for (auto& expression : node->expressions) { + out_ << "|"; + Visitor::Visit(expression); + } + out_ << ")"; +} + +void LinkSymbolsVisitor::Visit(ReturnExpression* node) { + out_ << "[Return] ("; + Visitor::Visit(node->expression); + out_ << ")\n"; +} + +void LinkSymbolsVisitor::Visit(TypeConstructor* node) { + out_ << "[TypeConstructor "; + Visit(node->type.get()); + out_ << "]\n("; + + bool is_first = true; + for (auto& parameter : node->parameters) { + if (!is_first) { + out_ << ")\n"; + is_first = false; + } + out_ << '('; + Visit(&std::get<0>(parameter)); + switch (std::get<1>(parameter)) { + case TypeConstructor::Assign: + out_ << " = "; + break; + case TypeConstructor::Move: + out_ << " <- "; + break; + } + Visitor::Visit(std::get<2>(parameter)); + } + out_ << ")\n"; +} + +void LinkSymbolsVisitor::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 LinkSymbolsVisitor::Visit(ArrayExpression* node) { + out_ << "[ArrayExpression] (["; + for (auto& element : node->elements) { + Visitor::Visit(element); + out_ << ';'; + } + out_ << "])"; +} + +// Name + +void LinkSymbolsVisitor::Visit(NameExpression* node) { + out_ << "[NameExpression] ("; + for (auto& variable_namespace : node->namespaces) { + Visitor::Visit(variable_namespace); + out_ << '.'; + } + for (size_t i = 0; i < node->expressions.size(); ++i) { + Visitor::Visit(node->expressions[i]); + if (i + 1 < node->expressions.size()) { + out_ << '.'; + } + } + out_ << ')'; +} + +void LinkSymbolsVisitor::Visit(TupleName* node) { + out_ << "[TupleName] ("; + for (auto& name : node->names) { + out_ << "& "; + Visitor::Visit(name); + } + out_ << ')'; +} + +void LinkSymbolsVisitor::Visit(VariantName* node) { + out_ << "[VariantName] ("; + for (auto& name : node->names) { + out_ << "| "; + Visitor::Visit(name); + } + out_ << ')'; +} + +void LinkSymbolsVisitor::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 LinkSymbolsVisitor::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 LinkSymbolsVisitor::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 LinkSymbolsVisitor::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 LinkSymbolsVisitor::Visit(ParametrizedType* node) { + out_ << "[ParametrizedType] ("; + Visit(node->type_expression.get()); + for (auto& parameter : node->parameters) { + out_ << ' '; + Visitor::Visit(parameter); + } + out_ << ')'; +} + +void LinkSymbolsVisitor::Visit(TypeExpression* node) { + out_ << "[TypeExpression "; + + if (node->array_size.has_value()) { + out_ << "[array size: " << node->array_size.value() << ']'; + } + + out_ << "] ("; + for (auto& type_namespace : node->namespaces) { + Visitor::Visit(type_namespace); + out_ << '.'; + } + Visit(&node->type); + out_ << ')'; +} + +void LinkSymbolsVisitor::Visit(ExtendedScopedAnyType* node) { + out_ << "[ExtendedScopedAnyType "; + for (auto& reference : node->references) { + switch (reference) { + case ReferenceType::Reference: + out_ << '~'; + break; + case ReferenceType::UniqueReference: + out_ << '@'; + break; + } + } + out_ << "] ("; + Visitor::Visit(node->type); + out_ << ')'; +} + +// Typeclass + +void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { + out_ << "[ParametrizedTypeclass] ("; + Visit(node->typeclass_expression.get()); + for (auto& paramater : node->parameters) { + out_ << ' '; + Visitor::Visit(paramater); + } + out_ << ')'; +} + +void LinkSymbolsVisitor::Visit(TypeclassExpression* node) { + out_ << "[TypeclassExpression] ("; + for (auto& typeclass_namespace : node->namespaces) { + Visitor::Visit(typeclass_namespace); + out_ << '.'; + } + Visit(&node->typeclass); + out_ << ')'; +} + +// Identifiers, constants, etc. ----------------- + +void LinkSymbolsVisitor::Visit(ExtendedName* node) { + out_ << "[ExtendedName " << node->name << "] "; +} + +void LinkSymbolsVisitor::Visit(std::string* node) { // std::string + out_ << "[Identifier " << *node << "] "; +} + +void LinkSymbolsVisitor::Visit(FloatNumberLiteral* node) { + out_ << "[FloatNumber " << node->value << "] "; +} + +void LinkSymbolsVisitor::Visit(NumberLiteral* node) { + out_ << "[Number " << node->value << "] "; +} + +void LinkSymbolsVisitor::Visit(StringLiteral* node) { + out_ << "[String " << node->value << "] "; +} + +void LinkSymbolsVisitor::Visit(CharLiteral* node) { + out_ << "[Char " << node->value << "] "; +} + +} // namespace interpreter