lang_2023/src/link_symbols_visitor.cpp

145 lines
4.7 KiB
C++
Raw Normal View History

2023-05-08 20:34:36 +03:00
#include <optional>
// for clangd
#include "../include/link_symbols_visitor.hpp"
#include "../include/error_handling.hpp"
2023-05-08 20:34:36 +03:00
#include "../include/types.hpp"
namespace interpreter {
// Namespaces, partitions -----------------
void LinkSymbolsVisitor::Visit(Namespace* node) {
2023-05-02 15:18:08 +03:00
// Visitor::Visit(&node->type); // not needed
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalTypeId(node->type);
2023-05-02 16:16:55 +03:00
std::optional<utils::IdType> maybe_typeclass;
2023-05-16 12:43:55 +03:00
if (namespace_visitor_.IsInGlobalNamespace()) {
maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type);
2023-05-02 16:16:55 +03:00
}
2023-05-02 15:18:08 +03:00
if (maybe_type.has_value() && maybe_typeclass.has_value()) {
2023-05-16 12:43:55 +03:00
error_handling::HandleNamesError("Ambigious namespace name (typeclass or type)", node->base);
}
2023-05-05 11:59:02 +03:00
2023-05-02 15:18:08 +03:00
if (maybe_type.has_value()) {
node->link_type_id_ = maybe_type.value();
}
2023-05-02 15:18:08 +03:00
if (maybe_typeclass.has_value()) {
node->link_typeclass_id_ = maybe_typeclass.value();
}
namespace_visitor_.EnterNamespace(node->type, node->modifier);
2023-05-02 15:18:08 +03:00
Visitor::Visit(&node->scope);
2023-05-02 15:18:08 +03:00
namespace_visitor_.ExitNamespace();
}
2023-05-14 13:05:46 +03:00
// Definitions -----------------
void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
Visitor::Visit(node->definition.get());
for (auto& function_requirement : node->requirements) {
2023-05-16 12:43:55 +03:00
namespace_visitor_.EnterNamespace(node->definition->type->type, function_requirement.first);
2023-05-14 13:05:46 +03:00
Visitor::Visit(function_requirement.second.get());
2023-05-16 12:43:55 +03:00
namespace_visitor_.ExitNamespace();
2023-05-14 13:05:46 +03:00
}
2023-05-16 12:43:55 +03:00
auto maybe_graph_id = namespace_visitor_.GetGlobalInfo()->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();
2023-05-14 13:05:46 +03:00
}
// Type, typeclass, etc. -----------------
// Type
2023-05-16 12:43:55 +03:00
void LinkSymbolsVisitor::Visit(TypeExpression* node) {
std::vector<std::string> path;
2023-05-02 15:18:08 +03:00
path.reserve(node->path.size());
2023-05-02 15:18:08 +03:00
for (auto& path_type : node->path) {
2023-05-03 15:03:57 +03:00
path.push_back(path_type.type);
}
node->type_id_ = namespace_visitor_.FindTypeId(path, node->type.type);
node->constructor_id_ = namespace_visitor_.FindConstructorId(path, node->type.type);
2023-05-02 15:18:08 +03:00
2023-05-08 20:34:36 +03:00
// internal type
if (info::type::ToInternalType(node->type.type).has_value()) {
if (!node->path.empty()) {
2023-05-16 12:43:55 +03:00
error_handling::HandleNamesError("Internal type is not in namespace", node->base);
2023-05-08 20:34:36 +03:00
}
if (!node->type.parameters.empty()) {
2023-05-16 12:43:55 +03:00
error_handling::HandleNamesError("Can't parametrize internal type", node->base);
2023-05-08 20:34:36 +03:00
}
return;
}
// check made in typecheck visitor ??
//////////////////////////////////////////////////////////
2023-05-08 20:34:36 +03:00
// abstract / basic / TODO: local abstract type
// if (path.size() == 0 && (namespace_visitor_.FindAbstractType(node->type.type).has_value()) {
// return;
// }
//////////////////////////////////////////////////////////
if (!node->type_id_.has_value() && !node->constructor_id_.has_value()) {
// check made in typecheck visitor ??
return;
}
2023-05-02 16:51:47 +03:00
2023-05-04 16:11:25 +03:00
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) {
2023-05-16 12:43:55 +03:00
error_handling::HandleNamesError("Contructor and type with same name have different types", node->base);
2023-05-04 16:11:25 +03:00
}
node->type_id_ = constructor_type_id;
}
2023-05-03 15:03:57 +03:00
if (node->type_id_.has_value()) {
node->type.type_id_ = node->type_id_.value();
}
std::optional<info::definition::Namespace*> maybe_type_namespace = namespace_visitor_.FindNamespace(path);
2023-05-02 16:51:47 +03:00
if (maybe_type_namespace.has_value()) {
info::definition::Namespace* type_namespace = maybe_type_namespace.value();
2023-05-02 16:51:47 +03:00
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);
2023-05-02 16:51:47 +03:00
2023-05-03 15:03:57 +03:00
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;
2023-05-02 16:51:47 +03:00
}
type_namespace = parent_namespace;
}
}
}
// Typeclass
2023-05-16 12:43:55 +03:00
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) {
std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclassId(node->typeclass);
2023-05-02 15:18:08 +03:00
if (maybe_typeclass.has_value()) {
node->typeclass_id_ = maybe_typeclass.value();
} else {
2023-05-16 12:43:55 +03:00
error_handling::HandleNamesError("Typeclass not found", node->base);
}
if (node->parameters.size() > 0) {
error_handling::HandleNamesError("Parametrized typeclasses not implemented yet", node->base);
}
}
} // namespace interpreter