From 868d514bccc0cc144efbad63bdc2ca56687dccd3 Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Wed, 17 May 2023 11:51:14 +0300 Subject: [PATCH] type_check_visitor FindSubExpressionMethodAndUpdate fixes, fixes --- include/type_check_visitor.hpp | 2 - include/types.hpp | 21 ++++-- src/.type_check_visitor.cpp.kate-swp | Bin 0 -> 123 bytes src/execute_visitor.cpp | 8 ++- src/type_check_visitor.cpp | 93 ++++++++++++++++----------- src/types.cpp | 4 +- 6 files changed, 79 insertions(+), 49 deletions(-) create mode 100644 src/.type_check_visitor.cpp.kate-swp diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index a641186..b2f4b04 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -144,13 +144,11 @@ private: std::optional FindSubExpressionMethodAndUpdate(FunctionCallExpression* node, SubExpressionToken* expression_node, - const std::string& name, const BaseNode& base_node); std::optional FindTypeFunctionAndUpdate(FunctionCallExpression* node, TypeExpression* type_node, - const std::string& name, std::unordered_map& context); private: diff --git a/include/types.hpp b/include/types.hpp index 657dc88..ac3429d 100644 --- a/include/types.hpp +++ b/include/types.hpp @@ -21,12 +21,21 @@ public: AbstractType() = default; AbstractType(utils::AbstractTypeModifier modifier, const std::string& name, - const std::vector& requirements) : modifier_(modifier), name_(name) { - for (auto& typeclass : requirements) { - requirements_.insert(typeclass); + const std::vector& requirement_graph_ids) + : modifier_(modifier), + name_(name) { + for (auto& typeclass : requirement_graph_ids) { + requirement_graph_ids_.insert(typeclass); } } + AbstractType(utils::AbstractTypeModifier modifier, + const std::string& name, + const std::unordered_set& requirement_graph_ids) + : modifier_(modifier), + name_(name), + requirement_graph_ids_(requirement_graph_ids) {} + std::optional InContext(const std::unordered_map& context); bool Same(const AbstractType& type) const; bool operator<(const AbstractType& type) const; @@ -35,10 +44,14 @@ public: std::optional GetFieldType(const std::string& name, const std::unordered_set& type_namespaces) const; + bool HasTypeclass(utils::IdType graph_id) { + return requirement_graph_ids_.count(graph_id) != 0; + } + private: utils::AbstractTypeModifier modifier_; std::string name_; - std::unordered_set requirements_; // TODO: all typeclasses from tree + std::unordered_set requirement_graph_ids_; // TODO: all typeclasses from tree }; class DefinedType { diff --git a/src/.type_check_visitor.cpp.kate-swp b/src/.type_check_visitor.cpp.kate-swp new file mode 100644 index 0000000000000000000000000000000000000000..144402ca939849b679b0b7adb97966dfc2d54012 GIT binary patch literal 123 zcmZQzU=Z?7EJ;-eE>A2_aLdd|RWQ;sU|?Vnxh~;Sy!M&H7h&=BFV|P42Jji(QVI@Y oU|_ull$8f!1y?v%4kU!&$^yA^uECyA#UL(YB7zT6%~GetFunctionInfo(node->function_id_).declaration.value(); // checked in type_check_visitor + // TODO: typeclass functions + auto function_declaration = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_.value()).declaration.value(); // checked in type_check_visitor for (size_t i = 0; i < node->parameters.size(); ++i) { - // TODO: local bastract types, absract types, etc. + // TODO: local abstract types, absract types, etc. context_manager_.DefineLocalType(function_declaration.parameters[i].type, node->parameters[i]->type_id_.value()); // TODO: check } - auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_).definition; + // TODO: typeclass functions + auto maybe_function_definition = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(node->function_id_.value()).definition; if (maybe_function_definition.has_value()) { for (size_t i = 0; i < node->arguments.size(); ++i) { diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 9f8964a..d718447 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -811,19 +811,19 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { maybe_function_declaration = FindSubExpressionMethodAndUpdate( node, std::get>(node->prefix.value()).get(), - node->name, node->base); } else if (std::holds_alternative>(node->prefix.value())) { maybe_function_declaration = FindTypeFunctionAndUpdate( node, std::get>(node->prefix.value()).get(), - node->name, context); } else { error_handling::HandleInternalError("Unexpected prefix type", "TypeCheckVisitor.FunctionCallExpression"); } } else { + // TODO: static functions from parent namespaces' typeclasses + std::optional maybe_function_id; if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) { @@ -1467,7 +1467,6 @@ void TypeCheckVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) { std::optional TypeCheckVisitor::FindSubExpressionMethodAndUpdate(FunctionCallExpression* node, SubExpressionToken* expression_node, - const std::string& name, const BaseNode& base_node) { std::optional maybe_function_id; std::optional maybe_function_declaration; @@ -1475,47 +1474,66 @@ std::optional Visitor::Visit(*expression_node); utils::IdType expression_type = current_type_; - std::optional maybe_expression_type_info = - context_manager_.GetValue(expression_type); - if (!maybe_expression_type_info.has_value()) { - error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type", base_node); - } + auto maybe_typeclass_function_info = + typeclass_graph_.GetFunctionInfo(node->name, std::nullopt); - utils::IdType type_id = maybe_expression_type_info.value()->GetTypeId(); - 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", - "TypeCheckVisitor.FunctionCallExpresssion"); - } + auto maybe_abstract_type_info = + context_manager_.GetValue(expression_type); - // TODO: better decision ?? - 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[name]; + if (maybe_abstract_type_info.has_value()) { + if (!maybe_typeclass_function_info.has_value()) { + error_handling::HandleTypecheckError("Typeclass function not found", base_node); + } - utils::ValueType expression_value_type = context_manager_.GetValueType(expression_type); + info::type::AbstractType* abstract_type_info = maybe_abstract_type_info.value(); - if (expression_value_type == utils::ValueType::Tmp) { - error_handling::HandleInternalError("Expression value type is ValueType::Type", - "TypeCheckVisitor.FunctionCallExpression"); - } + if (!typeclass_graph_.FindFunctionTypeclass(node->name).value()) { + error_handling::HandleInternalError("Typeclass function info found, but typeclas id not found", + "TypeCheckVisitor.FindSubExpressionMethodAndUpdate"); + } - if (expression_value_type == utils::ValueType::Var || expression_value_type == utils::ValueType::Tmp) { - // TODO: choose expression value types - 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[name]; - } + if (abstract_type_info->HaveTypeclass(typeclass_graph_.FindFunctionTypeclass(node->name).value())) { + maybe_function_declaration = maybe_typeclass_function_info.value()->declaration; + } + } else { + // TODO: check typeclass methods for defined type + auto maybe_defined_type_info = + context_manager_.GetValue(expression_type); + if (!maybe_defined_type_info.has_value()) { + error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type", base_node); + } - if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage - error_handling::HandleTypecheckError("Redefinition of method: const & var", base_node); - } + utils::IdType type_id = maybe_defined_type_info.value()->GetTypeId(); + 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", + "TypeCheckVisitor.FunctionCallExpresssion"); + } - if (!maybe_function_id.has_value()) { - maybe_function_id = maybe_const_function_id; - } + // TODO: better decision ?? + 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]; - if (maybe_function_id.has_value()) { - node->function_id_ = maybe_function_id.value(); - maybe_function_declaration = - global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node; + utils::ValueType expression_value_type = context_manager_.GetValueType(expression_type); + + if (expression_value_type == utils::ValueType::Var || expression_value_type == utils::ValueType::Tmp) { + // TODO: choose expression value types + 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 + error_handling::HandleTypecheckError("Redefinition of method: const & var", base_node); + } + + if (!maybe_function_id.has_value()) { + maybe_function_id = maybe_const_function_id; + } + + if (maybe_function_id.has_value()) { + node->function_id_ = maybe_function_id.value(); + maybe_function_declaration = + global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node; + } } return maybe_function_declaration; } @@ -1525,7 +1543,6 @@ std::optional std::optional TypeCheckVisitor::FindTypeFunctionAndUpdate(FunctionCallExpression* node, TypeExpression* type_node, - const std::string& name, std::unordered_map& context) { std::optional maybe_function_id; std::optional maybe_function_declaration; @@ -1545,7 +1562,7 @@ std::optional } path.push_back(type_node->type.type); - maybe_function_id = namespace_visitor_.FindFunctionId(path, name); + maybe_function_id = namespace_visitor_.FindFunctionId(path, node->name); CollectTypeExpressionContext(*type_node, context); diff --git a/src/types.cpp b/src/types.cpp index b0319f4..6ffcc6c 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -17,8 +17,8 @@ bool AbstractType::Same(const AbstractType& type) const { } bool AbstractType::operator<(const AbstractType& type) const { - for (auto& typeclass : requirements_) { - if (type.requirements_.count(typeclass) == 0) { + for (auto& graph_id : requirement_graph_ids_) { + if (type.requirement_graph_ids_.count(graph_id) == 0) { return false; } }