diff --git a/include/definitions.hpp b/include/definitions.hpp index bdf1b3b..ed1f01a 100644 --- a/include/definitions.hpp +++ b/include/definitions.hpp @@ -90,6 +90,8 @@ struct Namespace { std::unordered_map namespaces; std::unordered_map variable_namespaces; + Namespace* parent_namespace = nullptr;; + std::optional modifier; // modifier => variable namespace std::string type_name; }; diff --git a/include/global_info.hpp b/include/global_info.hpp index babd93e..f57cd2b 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -21,7 +21,7 @@ public: struct Path { std::vector> path_types; definition::Namespace* result; - } + }; void AddImport(definition::Import&& import_info, const std::optional& name = std::nullopt); diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index eaf587f..249d00c 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -557,6 +557,9 @@ struct TypeExpression { TypeSubExpression type; std::optional array_size; // if array; 0 - dynamic size + + std::optional type_id_; + std::optional constructor_id_; }; struct ExtendedScopedAnyType { diff --git a/src/global_info.cpp b/src/global_info.cpp index 5ae8f99..234735f 100644 --- a/src/global_info.cpp +++ b/src/global_info.cpp @@ -27,6 +27,8 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name, namespace_stack_.push_back(namespace_info); } + namespace_info->parent_namespace = namespace_stack_.back(); + namespace_info->type_name = name; current_path_.push_back(name); } diff --git a/src/link_symbols_visitor.cpp b/src/link_symbols_visitor.cpp index a6dd0de..02492e3 100644 --- a/src/link_symbols_visitor.cpp +++ b/src/link_symbols_visitor.cpp @@ -50,6 +50,7 @@ void LinkSymbolsVisitor::Visit(Namespace* node) { // Type // TODO: link internal stages +// TODO: find constructors ? void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check std::vector path; path.reserve(node->path.size()); @@ -58,12 +59,31 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check path.push_back(NameFromTypeSubExpression(path_type)); } - std::optional maybe_type = namespace_visitor_.FindType(path, NameFromTypeSubExpression(node->type)); + node->type_id_ = namespace_visitor_.FindType(path, NameFromTypeSubExpression(node->type)); + node->type_id_ = 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"); + if (!node->type_id_.has_value() && !node->constructor_id_.has_value()) { + error_handling::HandleTypecheckError("Type or constructor not found"); + } + + 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 maybe_type = parent_namespace->types.find(type_namespace->type_name); // TODO: make method ?? + if (maybe_type.has_value()) { + node->path[i]-> + } + + if (parent_namespace == nullptr) { + error_handling::HandleInternalError("Parent namespace is null in type expression", "LinkSymbolsVisitor"); + } + + type_namespace = parent_namespace; + } } }