lang_2023/src/link_symbols_visitor.cpp

93 lines
2.8 KiB
C++
Raw Normal View History

// for clangd
#include "../include/link_symbols_visitor.hpp"
#include "../include/error_handling.hpp"
2023-05-02 16:16:55 +03:00
#include <optional>
namespace interpreter {
2023-05-02 15:18:08 +03:00
const std::string& NameFromTypeSubExpression(const TypeSubExpression& type) {
if (std::holds_alternative<std::unique_ptr<std::string>>(type)) {
return *std::get<std::unique_ptr<std::string>>(type);
} else if (std::holds_alternative<std::unique_ptr<ParametrizedType>>(type)) {
return std::get<std::unique_ptr<ParametrizedType>>(type)->type;
}
2023-05-02 15:18:08 +03:00
error_handling::HandleInternalError("Empty variant", "NameFromTypeSubExpression");
exit(1); // TODO: better decision ??
}
// Namespaces, partitions -----------------
void LinkSymbolsVisitor::Visit(Namespace* node) {
2023-05-02 15:18:08 +03:00
// Visitor::Visit(&node->type); // not needed
2023-05-02 16:16:55 +03:00
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalType(node->type);
std::optional<utils::IdType> maybe_typeclass;
if (namespace_visitor_.GetCurrentPath().size() == 0) {
maybe_typeclass = namespace_visitor_.FindTypeclass(node->type);
}
2023-05-02 15:18:08 +03:00
if (maybe_type.has_value() && maybe_typeclass.has_value()) {
error_handling::HandleTypecheckError("Ambigious namespace name (typeclass or type)");
}
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();
}
2023-05-02 15:18:08 +03:00
namespace_visitor_.EnterNamespace(node->type);
2023-05-02 15:18:08 +03:00
Visitor::Visit(&node->scope);
2023-05-02 15:18:08 +03:00
namespace_visitor_.ExitNamespace();
}
// Type, typeclass, etc. -----------------
// Type
2023-05-02 15:18:08 +03:00
// TODO: link internal stages
void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
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) {
path.push_back(NameFromTypeSubExpression(path_type));
}
2023-05-02 15:18:08 +03:00
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindType(path, NameFromTypeSubExpression(node->type));
if (maybe_type.has_value()) {
node->type_id_ = maybe_type.value();
} else {
error_handling::HandleTypecheckError("Type not found");
}
}
// Typeclass
2023-05-02 15:18:08 +03:00
void LinkSymbolsVisitor::Visit(TypeclassExpression* node) { // TODO: check
std::string typeclass;
2023-05-02 15:18:08 +03:00
if (std::holds_alternative<std::unique_ptr<std::string>>(node->typeclass)) {
typeclass = *std::get<std::unique_ptr<std::string>>(node->typeclass);
} else if (std::holds_alternative<std::unique_ptr<ParametrizedTypeclass>>(node->typeclass)) {
typeclass = std::get<std::unique_ptr<ParametrizedTypeclass>>(node->typeclass)->typeclass;
} else {
// error
}
2023-05-02 15:18:08 +03:00
std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclass(typeclass);
if (maybe_typeclass.has_value()) {
node->typeclass_id_ = maybe_typeclass.value();
} else {
error_handling::HandleTypecheckError("Type not found");
}
}
} // namespace interpreter