diff --git a/include/global_info.hpp b/include/global_info.hpp index c0f5195..2b64cd9 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -213,6 +213,45 @@ public: return &global_info_.namespaces_[GetCurrentNamespaceId()]; } + std::optional GetCurrentNamespaceTypeId() { + if (!GetCurrentNamespace()->any_node.has_value()) { + return std::nullopt; + } + return GetCurrentNamespace()->any_node.value()->link_type_id_; + } + + std::optional GetCurrentNamespaceAnyType() { + std::optional id = GetCurrentNamespaceTypeId(); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetAnyTypeInfo(id.value()); + } + + template + std::optional GetCurrentNamespaceType() { + std::optional id = GetCurrentNamespaceTypeId(); + if (!id.has_value()) { + return std::nullopt; + } + return global_info_.GetTypeInfo(id.value()); + } + + std::optional GetCurrentNamespaceTypeclassId() { + if (!GetCurrentNamespace()->any_node.has_value()) { + return std::nullopt; + } + return GetCurrentNamespace()->any_node.value()->link_typeclass_id_; + } + + std::optional GetCurrentNamespaceTypeclass() { + std::optional id = GetCurrentNamespaceTypeclassId(); + if (!id.has_value()) { + return std::nullopt; + } + return &global_info_.GetTypeclassInfo(id.value()); + } + bool IsInGlobalNamespace() { return namespace_stack_.size() == 1; } diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index dbdd483..e49fc5c 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -2,6 +2,7 @@ // for clangd #include "interpreter_tree.hpp" +#include "typeclass_graph.hpp" #include "types.hpp" #include "contexts.hpp" #include "utils.hpp" @@ -17,7 +18,10 @@ class TypeCheckVisitor : public Visitor { public: explicit TypeCheckVisitor(info::GlobalInfo& global_info, info::ContextManager& context_manager) - : namespace_visitor_(global_info.CreateVisitor()), context_manager_(context_manager) {} + : namespace_visitor_(global_info.CreateVisitor()), + global_info_(global_info), + typeclass_graph_(*global_info.GetTypeclassGraph()), + context_manager_(context_manager) {} private: // Sources ----------------- @@ -138,6 +142,8 @@ private: private: info::GlobalInfo::NamespaceVisitor namespace_visitor_; + info::GlobalInfo& global_info_; + info::TypeclassGraph& typeclass_graph_; info::ContextManager& context_manager_; std::unordered_set type_namespaces_; diff --git a/src/.type_check_visitor.cpp.kate-swp b/src/.type_check_visitor.cpp.kate-swp new file mode 100644 index 0000000..d33116d Binary files /dev/null and b/src/.type_check_visitor.cpp.kate-swp differ diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 0af9348..ac3ccfe 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -34,7 +34,7 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) { void TypeCheckVisitor::Visit(Namespace* node) { if (node->link_typeclass_id_.has_value()) { - utils::IdType graph_id = namespace_visitor_.GetGlobalInfo()->GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_; + utils::IdType graph_id = global_info_.GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_; std::vector requirements = namespace_visitor_.GetTypeclassGraph()->GetTypeclassDependencies(graph_id); requirements.push_back(graph_id); @@ -51,7 +51,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { context_manager_.DefineLocalType(node->type, abstract_type); } else if (node->link_type_id_.has_value()) { if (node->modifier != utils::ClassInternalsModifier::Static) { - auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(node->link_type_id_.value()); + auto maybe_type_info = global_info_.GetTypeInfo(node->link_type_id_.value()); if (!maybe_type_info.has_value()) { error_handling::HandleTypecheckError("Namespace type is not AnyType", node->base); @@ -127,10 +127,11 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { bool was_in_statement = is_in_statement_; is_in_statement_ = true; + context_manager_.EnterContext(); for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed?? std::vector requirements = - namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(parameter.get()); + global_info_.GetAnnotatedTypeTypeclasses(parameter.get()); current_type_ = context_manager_.AddValue( info::type::AbstractType(utils::AbstractTypeModifier::Abstract, parameter->type, @@ -153,7 +154,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { is_in_statement_ = true; context_manager_.EnterContext(); - info::definition::Function& function_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_); + info::definition::Function& function_info = global_info_.GetFunctionInfo(node->function_id_); if (!function_info.declaration.has_value()) { error_handling::HandleTypecheckError("Function defined, but not declared", node->base); @@ -163,7 +164,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { for (auto parameter : declaration.parameters) { std::vector requirements = - namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(parameter.node); + global_info_.GetAnnotatedTypeTypeclasses(parameter.node); current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract, parameter.type, requirements), @@ -208,7 +209,7 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { is_in_statement_ = true; std::vector requirements = - namespace_visitor_.GetGlobalInfo()->GetAnnotatedTypeTypeclasses(node->type.get()); + global_info_.GetAnnotatedTypeTypeclasses(node->type.get()); 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_)) { @@ -279,7 +280,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name utils::IdType constructor_id = node->constructor->constructor_id_.value(); - info::definition::Constructor constructor_info = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(constructor_id); + info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id); utils::IdType type_id = constructor_info.type_id; @@ -288,7 +289,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name // TODO: handle alias types std::optional maybe_type_info = - namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type_id); + global_info_.GetTypeInfo(type_id); if (!maybe_type_info.has_value()) { // TODO error_handling::HandleInternalError("Implemented only for AnyType", @@ -597,7 +598,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { node->is_method_ = false; if (maybe_operator_id.has_value()) { - operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value()); + operator_info = &global_info_.GetFunctionInfo(maybe_operator_id.value()); node->is_method_ = false; } else { Visitor::Visit(node->left_expression); @@ -609,7 +610,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { error_handling::HandleTypecheckError("Operator not found (type is not DefinedType)", node->base); } - auto maybe_left_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(maybe_left_type.value()->GetTypeId()); + auto maybe_left_type_info = global_info_.GetTypeInfo(maybe_left_type.value()->GetTypeId()); std::string left_type_name = maybe_left_type_info.value()->type.type; @@ -637,7 +638,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) { maybe_operator_id = maybe_const_operator_id; } - operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value()); + operator_info = &global_info_.GetFunctionInfo(maybe_operator_id.value()); node->is_method_ = true; } @@ -743,7 +744,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { utils::IdType type_id = maybe_expression_type.value()->GetTypeId(); - std::optional maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type_id); + std::optional maybe_type_info = global_info_.GetTypeInfo(type_id); if (!maybe_type_info.has_value()) { error_handling::HandleInternalError("Functions/Methods implemented only for AnyType", @@ -751,7 +752,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } // TODO: better decision ?? - std::optional maybe_const_function_id = namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(maybe_type_info.value()->parent_namespace).const_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name]; + std::optional maybe_const_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(maybe_type_info.value()->parent_namespace).const_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name]; utils::ValueType expression_value_type = context_manager_.GetValueType(current_type_); @@ -762,7 +763,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { if (expression_value_type == utils::ValueType::Var || expression_value_type == utils::ValueType::Tmp) { // TODO: choose expression value types - maybe_function_id = namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(maybe_type_info.value()->parent_namespace).var_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name]; + maybe_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(maybe_type_info.value()->parent_namespace).var_namespaces.at(maybe_type_info.value()->type.type)).functions[node->name]; } if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage @@ -802,7 +803,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } std::optional maybe_function_declaration = - namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_function_id.value()).declaration; + global_info_.GetFunctionInfo(maybe_function_id.value()).declaration; if (!maybe_function_declaration.has_value()) { error_handling::HandleTypecheckError("No function declaration found for function in function call expression", node->base); } @@ -904,7 +905,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { utils::IdType constructor_id = node->constructor->constructor_id_.value(); - info::definition::Constructor constructor_info = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(constructor_id); + info::definition::Constructor constructor_info = global_info_.GetConstructorInfo(constructor_id); utils::IdType type_id = constructor_info.type_id; @@ -913,7 +914,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: handle alias types std::optional maybe_type_info = - namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type_id); + global_info_.GetTypeInfo(type_id); if (!maybe_type_info.has_value()) { // TODO error_handling::HandleInternalError("Implemented only for AnyType", "TypeCheckVisitor.TypeConstructor"); @@ -1254,7 +1255,7 @@ void TypeCheckVisitor::Visit(TypeExpression* node) { } else if (node->type.type_id_.has_value()) { // TODO: chack that names are different (always true ??) std::optional maybe_type_info = - namespace_visitor_.GetGlobalInfo()->GetTypeInfo(node->type.type_id_.value()); + global_info_.GetTypeInfo(node->type.type_id_.value()); if (!maybe_type_info.has_value()) { // TODO: add alias, abstract, ... types error_handling::HandleInternalError("No AnyType found", "TypeCheckVisitor.TypeExpression"); @@ -1352,7 +1353,7 @@ void TypeCheckVisitor::CollectTypeContext(const ParametrizedType& type, } std::optional maybe_type_info = - namespace_visitor_.GetGlobalInfo()->GetTypeInfo(type.type_id_.value()); + global_info_.GetTypeInfo(type.type_id_.value()); if (!maybe_type_info.has_value()) { error_handling::HandleInternalError("Wrong type id", "TypeCheckVisitor.CollectTypeContext");