diff --git a/include/global_info.hpp b/include/global_info.hpp index 660400e..2d1e40b 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -350,19 +350,8 @@ public: return &typeclass_graph_; } - // std::unordered_set - // GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node); - // - // std::vector - // GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node); - // - // std::unordered_map - // GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node, - // const interpreter::tokens::BaseNode& base_node); - // - // std::vector> - // GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node, - // const interpreter::tokens::BaseNode& base_node); + std::optional GetTypeNamespace(utils::IdType id, + utils::ClassInternalsModifier modifier); std::unordered_map* ChooseNamespaces( utils::ClassInternalsModifier modifier, diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index 4532436..8427259 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -294,7 +294,7 @@ struct AliasDefinitionStatement { std::vector parameters; std::unique_ptr value; - utils::IdType type_id_; + utils::IdType type_id_ = 0; }; struct VariableDefinitionStatement { @@ -314,7 +314,7 @@ struct FunctionDeclaration { std::vector> parameters; std::unique_ptr type; - utils::IdType function_id_; + utils::IdType function_id_ = 0; }; struct FunctionDefinitionStatement { @@ -323,7 +323,7 @@ struct FunctionDefinitionStatement { std::unique_ptr definition; SuperExpression value; - utils::IdType function_id_; + utils::IdType function_id_ = 0; }; struct TypeDefinitionStatement { @@ -334,7 +334,7 @@ struct TypeDefinitionStatement { std::unique_ptr definition; AnyType value; - utils::IdType type_id_; + utils::IdType type_id_ = 0; }; struct AbstractTypeDefinitionStatement { @@ -343,8 +343,7 @@ struct AbstractTypeDefinitionStatement { utils::AbstractTypeModifier modifier; std::unique_ptr type; - utils::IdType type_graph_id_; - utils::IdType type_id_; + utils::IdType type_id_ = 0; }; struct TypeclassDefinitionStatement { @@ -354,7 +353,7 @@ struct TypeclassDefinitionStatement { std::vector>> requirements; - utils::IdType typeclass_id_; + utils::IdType typeclass_id_ = 0; }; struct PartitionStatement { @@ -364,7 +363,7 @@ struct PartitionStatement { PartitionName name; SuperExpression value; - utils::IdType executable_id_; + utils::IdType executable_id_ = 0; }; // Definition parts ----------------- @@ -388,6 +387,8 @@ struct AnyAnnotatedType { AnyTypeIdentifier type; std::vector> typeclasses; + + utils::IdType graph_id_ = 0; // for types }; // ----------------- Flow control ----------------- @@ -566,7 +567,7 @@ struct LambdaFunction { Expression expression; std::vector argument_graph_ids_; - utils::IdType return_type_graph_id_; + utils::IdType return_type_graph_id_ = 0; }; struct ArrayExpression { @@ -662,7 +663,7 @@ struct ParametrizedTypeclass { TypeclassIdentifier typeclass; std::vector> parameters; - utils::IdType typeclass_id_; + utils::IdType typeclass_id_ = 0; }; // ----------------- Comments [IGNORE] ----------------- diff --git a/include/link_symbols_visitor.hpp b/include/link_symbols_visitor.hpp index 5307396..ec3326d 100644 --- a/include/link_symbols_visitor.hpp +++ b/include/link_symbols_visitor.hpp @@ -3,7 +3,10 @@ #include // for clangd +#include "definitions.hpp" #include "error_handling.hpp" +#include "typeclass_graph.hpp" +#include "utils.hpp" #include "visitor.hpp" #include "global_info.hpp" @@ -13,7 +16,9 @@ namespace interpreter { class LinkSymbolsVisitor : public Visitor { public: explicit LinkSymbolsVisitor(info::GlobalInfo& global_info) - : namespace_visitor_(global_info.CreateVisitor()) {} + : namespace_visitor_(global_info.CreateVisitor()), + global_info_(global_info), + typeclass_graph_(*global_info.GetTypeclassGraph()) {} void VisitSourceFile(SourceFile* source_file) override { Visitor::Visit(source_file); @@ -121,8 +126,16 @@ private: // // void Visit(CharLiteral* node) override; // // void Visit(BoolLiteral* node) override; + // + + void AddTypeFunctionsToTypeclassGraph(utils::IdType type_id, + utils::IdType graph_id, + utils::ClassInternalsModifier namespace_modifier); + private: info::GlobalInfo::NamespaceVisitor namespace_visitor_; + info::GlobalInfo& global_info_; + info::TypeclassGraph& typeclass_graph_; }; } // namespace interpreter diff --git a/include/types.hpp b/include/types.hpp index 1b6cb04..14d63ee 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -8,7 +8,6 @@ #include // for clangd -#include "error_handling.hpp" #include "utils.hpp" namespace info::type { @@ -17,7 +16,7 @@ namespace info::type { class TypeManager; -class AbstractType { // later will be found in context +class AbstractType { // latter will be found in context public: AbstractType() = default; AbstractType(utils::AbstractTypeModifier modifier, diff --git a/src/find_symbols_visitor.cpp b/src/find_symbols_visitor.cpp index 10191a4..654590d 100644 --- a/src/find_symbols_visitor.cpp +++ b/src/find_symbols_visitor.cpp @@ -191,13 +191,15 @@ void FindSymbolsVisitor::Visit(AnyAnnotatedType* node) { info.node = node; - auto maybe_graph_id = namespace_visitor_.GetGlobalInfo()->AddAnnotatedTypeToGraph(node); // definitions and declarations should be added latter + auto maybe_typeclass_graph_id = namespace_visitor_.GetGlobalInfo()->AddAnnotatedTypeToGraph(node); // definitions and declarations should be added latter - if (!maybe_graph_id.has_value()) { + if (!maybe_typeclass_graph_id.has_value()) { error_handling::HandleInternalError("Can't add annotated type to typeclass graph", "FindSymbolsVisitor.AnyAnnotatedType"); } + node->graph_id_ = maybe_typeclass_graph_id.value(); + current_info_ = std::move(info); } diff --git a/src/global_info.cpp b/src/global_info.cpp index e120cf4..bd35db5 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -460,83 +460,27 @@ std::optional GlobalInfo::NamespaceVisitor::FindNamespaceIn( // -// // cache ?? -// std::unordered_set -// GlobalInfo::GetAnnotatedTypeTypeclassesSet(interpreter::tokens::AnnotatedType* node) { -// -// std::unordered_set typeclasses; -// -// for (auto& typeclass : node->typeclasses) { -// utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_; -// -// std::vector dependencies = typeclass_graph_.GetTypeclassDependencies(graph_id); -// for (auto& dependency : dependencies) { -// typeclasses.insert(dependency); -// } -// -// typeclasses.insert(graph_id); -// } -// return typeclasses; -// } -// -// std::vector -// GlobalInfo::GetAnnotatedTypeTypeclassesVector(interpreter::tokens::AnnotatedType* node) { -// -// std::unordered_set typeclasses_set = GetAnnotatedTypeTypeclassesSet(node); -// -// std::vector typeclasses_vector; -// typeclasses_vector.reserve(typeclasses_vector.size()); -// for (auto& typeclass : typeclasses_set) { -// typeclasses_vector.push_back(typeclass); -// } -// return typeclasses_vector; -// } -// -// std::unordered_map // TODO: optimize, cache -// GlobalInfo::GetAnnotatedTypeFunctionsMap(interpreter::tokens::AnnotatedType* node, -// const interpreter::tokens::BaseNode& base_node) { -// -// std::unordered_map functions; -// -// for (auto& typeclass : node->typeclasses) { -// utils::IdType graph_id = typeclasses_[typeclass->typeclass_id_].graph_id_; -// -// auto requirements = typeclass_graph_.GetTypeclassFunctions(graph_id); -// for (auto& requirement : requirements) { -// auto requirement_iter = functions.find(requirement.first); -// if (requirement_iter == functions.end()) { -// functions[requirement.first] = *requirement.second; -// } else { -// if (requirement_iter->second.definition.has_value()) { -// if (requirement.second->definition.has_value()) { -// error_handling::HandleTypecheckError("Function defined more then in one type requirement", base_node); -// } -// } else { -// requirement_iter->second.definition = requirement.second->definition; -// } -// } -// } -// } -// return functions; -// } -// -// std::vector> // TODO: optimize, cache -// GlobalInfo::GetAnnotatedTypeFunctionsVector(interpreter::tokens::AnnotatedType* node, -// const interpreter::tokens::BaseNode& base_node) { -// -// auto functions_set = GetAnnotatedTypeFunctionsMap(node, base_node); -// -// std::vector> functions_vector; -// functions_vector.reserve(functions_vector.size()); -// for (auto& typeclass : functions_set) { -// functions_vector.push_back(typeclass); -// } -// return functions_vector; -// } +std::optional GlobalInfo::GetTypeNamespace(utils::IdType id, + utils::ClassInternalsModifier modifier) { + auto maybe_type_info = GetTypeInfo(id); + + if (!maybe_type_info.has_value()) { + error_handling::HandleInternalError("Only AnyType is supported now", + "GlobalInfo.GetTypeNamespace"); + } + + std::string& name = maybe_type_info.value()->type.type; + + auto namespaces = ChooseNamespaces(modifier, &GetNamespaceInfo(maybe_type_info.value()->parent_namespace)); + + auto namespace_iter = namespaces->find(name); + + return namespace_iter == namespaces->end() ? std::optional(std::nullopt) : &GetNamespaceInfo(namespace_iter->second); +} std::unordered_map* GlobalInfo::ChooseNamespaces(utils::ClassInternalsModifier modifier, - definition::Namespace* current_namespace) { + definition::Namespace* current_namespace) { std::unordered_map* current_namespaces = nullptr; switch (modifier) { case utils::ClassInternalsModifier::Const: diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index 5eff807..7a3e5fb 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -51,7 +51,19 @@ void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) { Visitor::Visit(node->definition.get()); Visitor::Visit(node->value); - // TODO: add type declarations / definitions + utils::IdType graph_id = node->definition->type->graph_id_; + + AddTypeFunctionsToTypeclassGraph(node->type_id_, + graph_id, + utils::ClassInternalsModifier::Static); + + AddTypeFunctionsToTypeclassGraph(node->type_id_, + graph_id, + utils::ClassInternalsModifier::Const); + + AddTypeFunctionsToTypeclassGraph(node->type_id_, + graph_id, + utils::ClassInternalsModifier::Var); } void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { @@ -62,11 +74,11 @@ void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) { namespace_visitor_.ExitNamespace(); } - auto maybe_graph_id = namespace_visitor_.GetGlobalInfo()->AddTypeclassToGraph(node->typeclass_id_); + auto maybe_graph_id = global_info_.AddTypeclassToGraph(node->typeclass_id_); if (!maybe_graph_id.has_value()) { error_handling::HandleNamesError("Can't add typeclass to graph", node->base); } - namespace_visitor_.GetGlobalInfo()->GetTypeclassInfo(node->typeclass_id_).graph_id_ = maybe_graph_id.value(); + global_info_.GetTypeclassInfo(node->typeclass_id_).graph_id_ = maybe_graph_id.value(); } // Type, typeclass, etc. ----------------- @@ -102,7 +114,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { } if (node->constructor_id_.has_value()) { - utils::IdType constructor_type_id = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(node->constructor_id_.value()).type_id; + utils::IdType constructor_type_id = global_info_.GetConstructorInfo(node->constructor_id_.value()).type_id; if (node->type_id_.has_value() && node->type_id_.value() != constructor_type_id) { error_handling::HandleNamesError("Contructor and type with same name have different types", node->base); @@ -120,7 +132,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { info::definition::Namespace* type_namespace = maybe_type_namespace.value(); for (ssize_t i = (ssize_t)node->path.size(); i >= 0; --i) { - info::definition::Namespace* parent_namespace = &namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(type_namespace->parent_namespace); + info::definition::Namespace* parent_namespace = &global_info_.GetNamespaceInfo(type_namespace->parent_namespace); auto type_iter = parent_namespace->types.find(type_namespace->type_name); if (type_iter != parent_namespace->types.end()) { @@ -148,4 +160,51 @@ void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { } } +// + +void LinkSymbolsVisitor::AddTypeFunctionsToTypeclassGraph(utils::IdType type_id, + utils::IdType graph_id, + utils::ClassInternalsModifier namespace_modifier) { + auto maybe_type_graph_info = typeclass_graph_.GetTypeVertex(graph_id); + if (!maybe_type_graph_info.has_value()) { + error_handling::HandleInternalError("Type in typeclass graph is not marked as type", + "LinkSymbolsVisitor.AddTypeFunctionsToTypeclassGraph"); + } + auto type_graph_info = maybe_type_graph_info.value(); + + auto maybe_namespace = + global_info_.GetTypeNamespace(type_id, namespace_modifier); + + if (maybe_namespace.has_value()) { + for (auto& function : maybe_namespace.value()->functions) { + auto function_info = global_info_.GetFunctionInfo(function.second); + + auto function_graph_iter = type_graph_info->functions.find(function.first); + if (function_graph_iter == type_graph_info->functions.end()) { + info::TypeclassGraph::FunctionInfo function_graph_info; + + // can be found after graph calculation + if (function_info.declaration.has_value()) { + function_graph_info.declaration = function_info.declaration.value().node; + } + + // can be found after graph calculation + if (function_info.definition.has_value()) { + function_graph_info.definition = function_info.definition.value().node; + function_graph_info.is_defined_in_owner = true; + } + + function_graph_info.modifier = namespace_modifier; + + type_graph_info->functions[function.first] = function_graph_info; + } else { + if (function_info.definition.has_value()) { + function_graph_iter->second.is_defined_in_owner = true; + function_graph_iter->second.definition = function_info.definition.value().node; + } + } + } + } +} + } // namespace interpreter diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 9d557f4..6506d34 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -36,8 +36,8 @@ void TypeCheckVisitor::Visit(Namespace* node) { if (node->link_typeclass_id_.has_value()) { utils::IdType graph_id = global_info_.GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_; - std::vector requirement_graph_ids = typeclass_graph_.GetTypeclassDependencies(graph_id); - requirement_graph_ids.push_back(graph_id); + std::unordered_set requirement_graph_ids = typeclass_graph_.GetDependenciesSet(graph_id); + requirement_graph_ids.insert(graph_id); utils::IdType abstract_type = context_manager_.AddValue( info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, @@ -54,7 +54,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // including namespace typeclass // define typeclasses local types as namespace typeclass for (auto& requirement_graph_id : requirement_graph_ids) { - context_manager_.DefineLocalType(typeclass_graph_.GetTypeclass(requirement_graph_id).name, abstract_type); + context_manager_.DefineLocalType(typeclass_graph_.GetVertex(requirement_graph_id).name, abstract_type); } } else if (node->link_type_id_.has_value()) { auto maybe_type_info = global_info_.GetTypeInfo(node->link_type_id_.value()); @@ -81,9 +81,9 @@ void TypeCheckVisitor::Visit(Namespace* node) { // better decision ?? // define typeclasses local types as namespace type - auto typeclass_graph_ids = global_info_.GetAnnotatedTypeTypeclassesVector(type_info->type.node); + auto typeclass_graph_ids = typeclass_graph_.GetDependenciesVector(type_info->type.node->graph_id_); for (auto& typeclass_graph_id : typeclass_graph_ids) { - context_manager_.DefineLocalType(typeclass_graph_.GetTypeclass(typeclass_graph_id).name, type); + context_manager_.DefineLocalType(typeclass_graph_.GetVertex(typeclass_graph_id).name, type); } if (type_namespaces_.count(node->link_type_id_.value()) != 0) { @@ -153,7 +153,7 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { context_manager_.EnterContext(); for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed?? - auto requirements = global_info_.GetAnnotatedTypeTypeclassesSet(parameter.get()); + auto requirements = typeclass_graph_.GetDependenciesSet(parameter->graph_id_); current_type_ = context_manager_.AddValue( info::type::AbstractType(utils::AbstractTypeModifier::Abstract, parameter->type, @@ -203,13 +203,13 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { bool method_found_in_typeclass = false; if (maybe_curent_type.has_value()) { // optiomize?? - auto typeclasses = global_info_.GetAnnotatedTypeTypeclassesSet(maybe_curent_type.value()->type.node); + auto typeclasses = typeclass_graph_.GetDependenciesSet(maybe_curent_type.value()->type.node->graph_id_); method_found_in_typeclass = (typeclasses.count(maybe_typeclass_graph_id.value()) != 0); } else if (maybe_current_typeclass.has_value()) { method_found_in_typeclass = - typeclass_graph_.IsFunctionInTypeclass(function_name, maybe_current_typeclass.value()->graph_id_); + typeclass_graph_.IsFunctionInVertex(function_name, maybe_current_typeclass.value()->graph_id_); } if (!method_found_in_typeclass) { @@ -232,7 +232,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { } for (auto& parameter : declaration->parameters) { - auto requirements = global_info_.GetAnnotatedTypeTypeclassesSet(parameter.get()); + auto requirements = typeclass_graph_.GetDependenciesSet(parameter->graph_id_); current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract, parameter->type, requirements), @@ -269,12 +269,12 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { is_in_statement_ = true; - std::unordered_map required_functions = - global_info_.GetAnnotatedTypeFunctionsMap(node->definition->type.get(), node->base); + const std::unordered_map& required_functions = + typeclass_graph_.GetVertexFunctions(node->definition->type->graph_id_); std::string& type_name = node->definition->type->type; - for (auto& function : required_functions) { // TODO: optimize + for (auto& function : required_functions) { if (function.second.definition.has_value()) { // TODO: check continue; } @@ -300,7 +300,7 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { is_in_statement_ = true; - auto requirements = global_info_.GetAnnotatedTypeTypeclassesSet(node->type.get()); + auto requirements = typeclass_graph_.GetDependenciesSet(node->type->graph_id_); current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements), utils::ValueType::Tmp); if (!context_manager_.DefineLocalType(node->type->type, current_type_)) { @@ -379,11 +379,10 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name std::unordered_map context; CollectTypeExpressionContext(*node->constructor, context); - // TODO: handle alias types std::optional maybe_type_info = global_info_.GetTypeInfo(type_id); - if (!maybe_type_info.has_value()) { // TODO + if (!maybe_type_info.has_value()) { error_handling::HandleInternalError("Implemented only for AnyType", "TypeCheckVisitor.TypeConstructorPattern"); } @@ -1373,6 +1372,7 @@ void TypeCheckVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) { } // TODO: internal types ?? +// TODO: find & check definitions std::optional TypeCheckVisitor::FindExpressionMethodAndUpdate(FunctionCallExpression* node, utils::IdType expression_type) { @@ -1607,7 +1607,7 @@ std::optional return std::nullopt; } - auto typeclasses = global_info_.GetAnnotatedTypeTypeclassesSet(defined_type->type.node); + auto typeclasses = typeclass_graph_.GetDependenciesSet(defined_type->type.node->graph_id_); auto function_typeclass_iter = typeclasses.find(maybe_typeclass_graph_id.value()); if (function_typeclass_iter == typeclasses.end()) { @@ -1615,7 +1615,7 @@ std::optional } auto maybe_typeclass_function_info = typeclass_graph_.GetFunctionInfo(node->name, - maybe_typeclass_graph_id.value()); + maybe_typeclass_graph_id.value()); if (!maybe_typeclass_function_info.has_value()) { error_handling::HandleInternalError("Typeclass function info found, but typeclass id not found (definied type)", "TypeCheckVisitor.FindDefinedTypeTypeclassFunctionAndUpdate");