diff --git a/include/abstract_types_context.hpp b/include/abstract_types_context.hpp new file mode 100644 index 0000000..0113185 --- /dev/null +++ b/include/abstract_types_context.hpp @@ -0,0 +1,73 @@ +#pragma once + +#include +#include +#include +#include + +// for clangd +#include "utils.hpp" + +namespace info { + +class AbstractTypesContextManager { +public: + void EnterContext() { + contexts_.emplace_back(); + } + + void ExitContext() { + if (contexts_.empty()) { + // error + } + + contexts_.pop_back(); + } + + void ExitFromAllContexts() { + contexts_.clear(); + } + + bool DefineType(const std::string& type, utils::IdType id) { + return contexts_.back().DefineType(type, id); + } + + std::optional GetTypeId(const std::string& type) { + for (ssize_t i = contexts_.size() - 1; i >= 0; --i) { + auto maybe_type = contexts_[i].GetTypeId(type); + if (maybe_type.has_value()) { + return maybe_type.value(); + } + } + return std::nullopt; + } + +private: + class Context { + public: + bool DefineType(const std::string& type, utils::IdType id) { + if (types_.count(type) > 0) { + return false; + } + types_[type] = id; + return true; + } + + std::optional GetTypeId(const std::string& type) { + auto type_iter = types_.find(type); + + if (type_iter == types_.end()) { + return std::nullopt; + } + + return type_iter->second; + } + + private: + std::unordered_map types_; + }; + + std::vector contexts_; +}; + +} // namespace info diff --git a/include/error_handling.hpp b/include/error_handling.hpp index 3c9d4df..aee85cb 100644 --- a/include/error_handling.hpp +++ b/include/error_handling.hpp @@ -1,29 +1,24 @@ +#pragma once + #include -enum class ErrorVisitor { - BuildVisitor, - PrintVisitor, - FindSymbolsVisitor, - // ... -}; +namespace error_handling { -// TODO -inline void handle_error(std::string message, ErrorVisitor visitor) { // TODO: add place in code - std::string visitor_str; - switch (visitor) { - case ErrorVisitor::BuildVisitor: - visitor_str = "Build Visitor"; - break; - case ErrorVisitor::PrintVisitor: - visitor_str = "Print Visitor"; - break; - case ErrorVisitor::FindSymbolsVisitor: - visitor_str = "Find Symbols Visitor"; - break; - // ... - default: - break; - } - std::cerr << "Error: " << message << " in " << visitor_str; +inline void HandleParsingError(const std::string& message, std::pair place) { + std::cout << "Parsing Error: " << message << " at (" << place.first << ", " << place.second << ").\n"; exit(1); } + +inline void HandleInternalError(const std::string& message, const std::string& place) { + std::cout << "Internal Error: " << message << " at " << place << ".\n"; + exit(1); +} + +inline void HandleTypecheckError(const std::string& message) { // TODO: place in code + std::cout << "Typecheck Error: " << message << ".\n"; + exit(1); +} + +// ... + +} // namespace error_handling diff --git a/include/global_info.hpp b/include/global_info.hpp index 2801d1d..7156427 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -63,6 +63,10 @@ public: TypeGraph* GetAbstractTypeGraph() { return global_info_.GetAbstractTypeGraph(); } + + const std::vector& GetCurrentPath() { + return current_path_; + } private: NamespaceVisitor(GlobalInfo& global_info) : global_info_(global_info), namespace_stack_({&global_info.global_namespace_}) {} @@ -75,6 +79,7 @@ public: const std::vector& path); private: std::vector namespace_stack_; + std::vector current_path_; GlobalInfo& global_info_; }; diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index f89d36b..dd5fcaf 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -297,6 +297,7 @@ struct AliasDefinitionStatement { std::vector parameters; std::unique_ptr value; + std::vector parameter_graph_ids_; utils::IdType type_id_; }; @@ -321,6 +322,7 @@ struct FunctionDefinitionStatement { SuperExpression value; utils::IdType function_id_; + std::vector argument_graph_ids_; }; struct TypeDefinitionStatement { @@ -335,6 +337,7 @@ struct AbstractTypeDefinitionStatement { enum { Basic, Abstract } modifier; std::unique_ptr type; + utils::IdType type_graph_id_; utils::IdType type_id_; }; @@ -362,6 +365,8 @@ struct TypeDefinition { struct AnnotatedAbstractType { AbstractTypeIdentifier type; std::vector typeclasses; + + utils::IdType type_graph_id_; }; // ----------------- Flow control ----------------- @@ -518,6 +523,8 @@ struct TypeExpression { std::vector namespaces; AnyTypeIdentifier type; std::optional array_size; // if array; 0 - dynamic size + + utils::IdType type_id_; }; struct ExtendedScopedAnyType { @@ -535,6 +542,8 @@ struct ParametrizedTypeclass { struct TypeclassExpression { std::vector namespaces; TypeclassIdentifier typeclass; + + utils::IdType type_id_; }; // ----------------- Comments [IGNORE] ----------------- diff --git a/include/link_symbols_visitor.hpp b/include/link_symbols_visitor.hpp index 42801f8..f723e19 100644 --- a/include/link_symbols_visitor.hpp +++ b/include/link_symbols_visitor.hpp @@ -3,15 +3,17 @@ #include // for clangd +#include "abstract_types_context.hpp" #include "visitor.hpp" - +#include "global_info.hpp" namespace interpreter { // TODO, (maybe add VisitSourceFile?) class LinkSymbolsVisitor : public Visitor { public: - explicit LinkSymbolsVisitor() {} + explicit LinkSymbolsVisitor(info::GlobalInfo& global_info) + : namespace_visitor_(global_info.CreateVisitor()) {} private: // Sources ----------------- @@ -102,16 +104,18 @@ private: // 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; + // // 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: + info::GlobalInfo::NamespaceVisitor namespace_visitor_; + info::AbstractTypesContextManager abstract_types_; }; } // namespace interpreter diff --git a/include/type_graph.hpp b/include/type_graph.hpp index 78e8937..19cfe23 100644 --- a/include/type_graph.hpp +++ b/include/type_graph.hpp @@ -15,13 +15,11 @@ namespace info { class TypeGraph { public: - size_t AddVertex(const std::vector& path, - const std::vector& methods = {}, + size_t AddVertex(const std::vector& methods = {}, const std::vector& typeclasses = {}) { is_calculated_ = false; Vertex vertex; - vertex.path = path; for (auto& method : methods) { vertex.new_requirements.methods.insert(storage_.GetId(method)); @@ -35,14 +33,9 @@ public: edges_.emplace_back(); back_edges_.emplace_back(); - verticle_ids_[vertex.path] = verticles_.size() - 1; return verticles_.size() - 1; } - size_t FindVertex(const std::vector& path) { - return verticle_ids_[path]; - } - std::vector VertexMethods(size_t id) { if (!is_calculated_) { // error @@ -162,7 +155,6 @@ private: }; struct Vertex { - std::vector path; RequirementsData new_requirements; std::optional cluster; }; @@ -212,7 +204,6 @@ private: } private: - std::unordered_map, size_t> verticle_ids_; std::vector> edges_; std::vector> back_edges_; std::vector verticles_; diff --git a/src/find_symbols_visitor.cpp b/src/find_symbols_visitor.cpp index 8029194..f15b7ad 100644 --- a/src/find_symbols_visitor.cpp +++ b/src/find_symbols_visitor.cpp @@ -54,6 +54,7 @@ void FindSymbolsVisitor::Visit(Namespace* node) { // Definitions ----------------- +// TODO: add imported symbols to symbol table (global info) void FindSymbolsVisitor::Visit(ImportStatement* node) { is_in_statement = true; @@ -65,8 +66,6 @@ void FindSymbolsVisitor::Visit(ImportStatement* node) { is_in_statement = false; } -// <-- current position - void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) { is_in_statement = true; @@ -86,6 +85,11 @@ void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) { break; } alias_info.parameters = node->parameters; + node->parameter_graph_ids_.resize(node->parameters.size()); + for (size_t i = 0; i < node->parameters.size(); ++i) { + node->parameter_graph_ids_[i] = namespace_visitor_.GetAbstractTypeGraph()->AddVertex(); + } + alias_info.value.node = node->value.get(); info.type = std::move(alias_info); @@ -136,8 +140,10 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) { } info.argument_names.resize(definition->arguments.size()); + node->argument_graph_ids_.resize(definition->arguments.size()); for (size_t i = 0; i < definition->arguments.size(); ++i) { info.argument_names[i] = definition->arguments[i].name; + node->argument_graph_ids_[i] = namespace_visitor_.GetAbstractTypeGraph()->AddVertex(); } info.expression = &node->value; @@ -202,6 +208,7 @@ void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) { info.type = std::move(abstract_type_info); + node->type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex(); // ?? node->type_id_ = namespace_visitor_.AddType(type, std::move(info)); is_in_statement = false; @@ -245,6 +252,8 @@ void FindSymbolsVisitor::Visit(AnyAnnotatedType* node) { info.typeclass_nodes[i] = &node->typeclasses[i]; } + node->type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex(); + current_info_ = std::move(info); } diff --git a/src/global_info.cpp b/src/global_info.cpp index dbf1a42..a2f7e02 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -28,10 +28,12 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, } namespace_info->type_name = name; + current_path_.push_back(name); } void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name) { // TODO: enter sibling namespace, etc. namespace_stack_.push_back(&namespace_stack_.back()->namespaces[name]); + current_path_.push_back(name); } void GlobalInfo::NamespaceVisitor::ExitNamespace() { @@ -41,10 +43,13 @@ void GlobalInfo::NamespaceVisitor::ExitNamespace() { } namespace_stack_.pop_back(); + current_path_.pop_back(); } void GlobalInfo::NamespaceVisitor::ToGlobalNamespace() { namespace_stack_.clear(); + current_path_.clear(); + namespace_stack_.push_back(&global_info_.global_namespace_); } diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index 9c7542f..1934779 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -1,12 +1,12 @@ // for clangd #include "../include/link_symbols_visitor.hpp" +#include "../include/error_handling.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)); @@ -16,523 +16,267 @@ void LinkSymbolsVisitor::Visit(SourceFile* node) { // error } } - out_ << "\n)\n"; } void LinkSymbolsVisitor::Visit(Sources* node) { - out_ << "[Sources](\n"; + abstract_types_.EnterContext(); for (auto& statement : node->statements) { Visitor::Visit(statement); } - out_ << ")\n"; + abstract_types_.ExitContext(); } // 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"; + // TODO 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"; + namespace_visitor_.EnterNamespace(node->type); Visit(node->scope.get()); - out_ << "}\n"; + namespace_visitor_.ExitNamespace(); } // 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(ImportStatement* node) {} 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; + abstract_types_.EnterContext(); + for (size_t i = 0; i parameters.size(); ++i) { + abstract_types_.DefineType(node->parameters[i], node->parameter_graph_ids_[i]); } - out_ << ' '; - Visit(&node->type); - out_ << "] = ("; Visit(node->value.get()); - out_ << ")\n"; + abstract_types_.ExitContext(); } void LinkSymbolsVisitor::Visit(VariableDefinitionStatement* node) { - out_ << "[Variable "; - switch (node->modifier) { - case VariableDefinitionStatement::Const: - out_ << "const"; - break; - case VariableDefinitionStatement::Var: - out_ << "var"; - break; - } - out_ << ' '; + abstract_types_.EnterContext(); Visitor::Visit(node->name); - out_ << "] = ("; Visitor::Visit(node->value); - out_ << ")\n"; + abstract_types_.ExitContext(); } void LinkSymbolsVisitor::Visit(FunctionDeclaration* node) { - out_ << "[FunctionDeclaration "; - Visit(&node->name); - out_ << "] ("; + abstract_types_.EnterContext(); for (auto& parameter : node->parameters) { Visit(parameter.get()); + abstract_types_.DefineType(parameter->type, parameter->type_graph_id_); } - out_ << ") : ("; Visit(node->type.get()); - out_ << ")\n"; + abstract_types_.ExitContext(); } void LinkSymbolsVisitor::Visit(FunctionDefinitionStatement* node) { - out_ << "[Function] ("; + abstract_types_.EnterContext(); Visit(node->definition.get()); - out_ << ") = ("; Visitor::Visit(node->value); - out_ << ")\n"; + abstract_types_.ExitContext(); } void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) { - out_ << "[Type "; - switch (node->modifier) { - case TypeDefinitionStatement::Struct: - out_ << "struct"; - break; - case TypeDefinitionStatement::Class: - out_ << "class"; - break; - } - out_ << "] ("; + abstract_types_.EnterContext(); Visit(node->definition.get()); - out_ << ") = ("; Visitor::Visit(node->value); - out_ << ")\n"; + abstract_types_.ExitContext(); } 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"; + // TODO: can't be used before definition + abstract_types_.DefineType(node->type->type, node->type->type_graph_id_); } void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { - out_ << "[Typeclass] ("; + abstract_types_.EnterContext(); Visit(node->definition.get()); - if (!node->requirements.empty()) { - out_ << ") : (\n"; - } for (auto& requirement : node->requirements) { - out_ << "& "; Visit(requirement.get()); - out_ << "\n"; } - out_ << ")\n"; + abstract_types_.ExitContext(); } // Definition parts void LinkSymbolsVisitor::Visit(FunctionDefinition* node) { - out_ << "[FunctionDefinition "; - switch (node->modifier) { - case FunctionDefinition::Operator: - out_ << "operator"; - break; - case FunctionDefinition::Function: - out_ << "function"; - break; + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + abstract_types_.DefineType(parameter->type, parameter->type_graph_id_); } - 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_ << ')'; + for (auto& parameter : node->parameters) { + Visit(parameter.get()); + abstract_types_.DefineType(parameter->type, parameter->type_graph_id_); } - out_ << ' '; } void LinkSymbolsVisitor::Visit(AnyAnnotatedType* node) { - out_ << "[Annotated (Abstract) Type "; - Visit(&node->type); - out_ << ']'; + // TODO check ?? 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"; + Visitor::Visit(node->statement); } 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; - } -} +void LinkSymbolsVisitor::Visit(LoopControlExpression& node) {} // 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] ("; + abstract_types_.EnterContext(); for (auto& parameter : node->parameters) { Visit(parameter.get()); + abstract_types_.DefineType(parameter->type, parameter->type_graph_id_); } - if (!node->parameters.empty()) { - out_ << ") : ("; - } - for (auto& argument : node->arguments) { - Visit(&argument); - } - out_ << ") -> (\n"; Visitor::Visit(node->expression); - out_ << ")\n"; + abstract_types_.ExitContext(); } 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_ << '.'; - } + for (auto& expression : node->expressions) { + Visitor::Visit(expression); } - 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_ << ')'; } } @@ -541,143 +285,117 @@ void LinkSymbolsVisitor::Visit(AnnotatedName* node) { // 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)); + // do nothing } 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 "; + std::vector path; + path.reserve(node->namespaces.size()); - 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_ << '.'; + if (std::holds_alternative>(type_namespace)) { + path.push_back(*std::get>(type_namespace)); + } else if (std::holds_alternative>(type_namespace)) { + path.push_back(std::get>(type_namespace)->type_expression->type); + } else { + // error + } + } + + std::optional maybe_type = namespace_visitor_.FindType(path, node->type); + std::optional maybe_abstract_type = std::nullopt; + + if (path.size() == 0) { + maybe_abstract_type = abstract_types_.GetTypeId(node->type); + } + + if (maybe_abstract_type.has_value()) { + if (maybe_type.has_value()) { + error_handling::HandleTypecheckError("Ambigious type"); + } else { + node->type_id_ = maybe_abstract_type.value(); + } + } else if (maybe_type.has_value()) { + node->type_id_ = maybe_type.value(); + } else { + error_handling::HandleTypecheckError("Type not found"); } - 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); + for (auto& parameter : node->parameters) { + Visitor::Visit(parameter); } - out_ << ')'; } void LinkSymbolsVisitor::Visit(TypeclassExpression* node) { - out_ << "[TypeclassExpression] ("; + std::vector path; + path.reserve(node->namespaces.size()); + for (auto& typeclass_namespace : node->namespaces) { Visitor::Visit(typeclass_namespace); - out_ << '.'; + if (std::holds_alternative>(typeclass_namespace)) { + path.push_back(*std::get>(typeclass_namespace)); + } else if (std::holds_alternative>(typeclass_namespace)) { + path.push_back(std::get>(typeclass_namespace)->type_expression->type); + } else { + // error + } } - Visit(&node->typeclass); - out_ << ')'; -} -// Identifiers, constants, etc. ----------------- + std::optional maybe_typeclass = namespace_visitor_.FindType(path, node->typeclass); + std::optional maybe_abstract_typeclass = std::nullopt; -void LinkSymbolsVisitor::Visit(ExtendedName* node) { - out_ << "[ExtendedName " << node->name << "] "; -} + if (path.size() == 0) { + maybe_abstract_typeclass = abstract_types_.GetTypeId(node->typeclass); + } -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 << "] "; + if (maybe_abstract_typeclass.has_value()) { + if (maybe_typeclass.has_value()) { + error_handling::HandleTypecheckError("Ambigious type"); + } else { + node->type_id_ = maybe_abstract_typeclass.value(); + } + } else if (maybe_typeclass.has_value()) { + node->type_id_ = maybe_typeclass.value(); + } else { + error_handling::HandleTypecheckError("Type not found"); + } } } // namespace interpreter diff --git a/src/print_visitor.cpp b/src/print_visitor.cpp index f7081d2..9948889 100644 --- a/src/print_visitor.cpp +++ b/src/print_visitor.cpp @@ -317,9 +317,9 @@ void PrintVisitor::Visit(DoWhileLoop* node) { void PrintVisitor::Visit(WhileLoop* node) { out_ << "[While] ("; - Visitor::Visit(node->statement); - out_ << ") [do] (\n"; Visitor::Visit(node->condition); + out_ << ") [do] (\n"; + Visitor::Visit(node->statement); out_ << ")\n"; } void PrintVisitor::Visit(ForLoop* node) { @@ -637,9 +637,9 @@ void PrintVisitor::Visit(ExtendedScopedAnyType* node) { void PrintVisitor::Visit(ParametrizedTypeclass* node) { out_ << "[ParametrizedTypeclass] ("; Visit(node->typeclass_expression.get()); - for (auto& paramater : node->parameters) { + for (auto& parameter : node->parameters) { out_ << ' '; - Visitor::Visit(paramater); + Visitor::Visit(parameter); } out_ << ')'; }