// for clangd #include "../include/link_symbols_visitor.hpp" #include "../include/error_handling.hpp" #include namespace interpreter { // Namespaces, partitions ----------------- void LinkSymbolsVisitor::Visit(Namespace* node) { // Visitor::Visit(&node->type); // not needed std::optional maybe_type = namespace_visitor_.FindLocalType(node->type); std::optional maybe_typeclass; if (namespace_visitor_.GetCurrentPath().size() == 0) { maybe_typeclass = namespace_visitor_.FindTypeclass(node->type); } if (maybe_type.has_value() && maybe_typeclass.has_value()) { error_handling::HandleTypecheckError("Ambigious namespace name (typeclass or type)", node->base); } if (maybe_type.has_value()) { node->link_type_id_ = maybe_type.value(); } if (maybe_typeclass.has_value()) { node->link_typeclass_id_ = maybe_typeclass.value(); } namespace_visitor_.EnterNamespace(node->type); Visitor::Visit(&node->scope); namespace_visitor_.ExitNamespace(); } // Type, typeclass, etc. ----------------- // Type void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check std::vector path; path.reserve(node->path.size()); for (auto& path_type : node->path) { path.push_back(path_type.type); } node->type_id_ = namespace_visitor_.FindType(path, node->type.type); node->constructor_id_ = namespace_visitor_.FindConstructor(path, node->type.type); if (!node->type_id_.has_value() && !node->constructor_id_.has_value()) { error_handling::HandleTypecheckError("Type or constructor not found", node->base); } if (node->constructor_id_.has_value()) { utils::IdType constructor_type_id = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(node->constructor_id_.value()).type_id; if (node->type_id_.has_value() && node->type_id_.value() != constructor_type_id) { error_handling::HandleTypecheckError("Contructor and type with same name have different types", node->base); } node->type_id_ = constructor_type_id; } if (node->type_id_.has_value()) { node->type.type_id_ = node->type_id_.value(); } std::optional maybe_type_namespace = namespace_visitor_.FindNamespace(path); if (maybe_type_namespace.has_value()) { 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 = type_namespace->parent_namespace; auto type_iter = parent_namespace->types.find(type_namespace->type_name); if (type_iter != parent_namespace->types.end()) { node->path[i].type_id_ = type_iter->second; } if (parent_namespace == nullptr) { error_handling::HandleInternalError("Parent namespace is null in type expression", "LinkSymbolsVisitor"); } type_namespace = parent_namespace; } } } // Typeclass void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check std::optional maybe_typeclass = namespace_visitor_.FindTypeclass(node->typeclass); if (maybe_typeclass.has_value()) { node->typeclass_id_ = maybe_typeclass.value(); } else { error_handling::HandleTypecheckError("Type not found", node->base); } } } // namespace interpreter