From a90bcb5d92fbde7278bb3cb6c8e880ce0d3aa37b Mon Sep 17 00:00:00 2001 From: ProgramSnail Date: Wed, 17 May 2023 10:44:20 +0300 Subject: [PATCH] type_check_visitor function_call_expression structure change --- include/type_check_visitor.hpp | 17 +-- src/type_check_visitor.cpp | 188 ++++++++++++++------------------- 2 files changed, 91 insertions(+), 114 deletions(-) diff --git a/include/type_check_visitor.hpp b/include/type_check_visitor.hpp index 77f6daa..a641186 100644 --- a/include/type_check_visitor.hpp +++ b/include/type_check_visitor.hpp @@ -141,14 +141,17 @@ private: void CheckPattern(Pattern& node, const BaseNode& base_node); - std::optional - FindSubExpressionMethod(utils::IdType expression_type, - const std::string& name, - const BaseNode& base_node); + std::optional + FindSubExpressionMethodAndUpdate(FunctionCallExpression* node, + SubExpressionToken* expression_node, + const std::string& name, + const BaseNode& base_node); - std::optional FindTypeFunction(TypeExpression* node, - const std::string& name, - std::unordered_map& context); + std::optional + FindTypeFunctionAndUpdate(FunctionCallExpression* node, + TypeExpression* type_node, + const std::string& name, + std::unordered_map& context); private: info::GlobalInfo::NamespaceVisitor namespace_visitor_; diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index 4926275..9f8964a 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -795,10 +795,9 @@ void TypeCheckVisitor::Visit(AccessExpression* node) { // TODO: builtin functions/methods // TODO: abstract types (check typeclass requirements) void TypeCheckVisitor::Visit(FunctionCallExpression* node) { - std::optional maybe_function_id; - std::unordered_map context; + std::optional maybe_function_declaration; - std::optional expression_type; + std::unordered_map context; // guaranteed, that name.size() > 0 if (node->name[0] == '_') { @@ -806,17 +805,17 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { "TypeCheckVisitor.FunctionCallExpresssion"); } - // try to find function id + // try to find function declaration if (node->prefix.has_value()) { if (std::holds_alternative>(node->prefix.value())) { - Visitor::Visit(*std::get>(node->prefix.value())); - expression_type = current_type_; - maybe_function_id = FindSubExpressionMethod( - expression_type.value(), + 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_id = FindTypeFunction( + maybe_function_declaration = FindTypeFunctionAndUpdate( + node, std::get>(node->prefix.value()).get(), node->name, context); @@ -825,6 +824,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { "TypeCheckVisitor.FunctionCallExpression"); } } else { + std::optional maybe_function_id; + if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) { // call functions from static namespace of current type std::vector current_type_path { namespace_visitor_.GetCurrentNamespace()->type_name }; @@ -832,100 +833,56 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } else { maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name); } - } - if (maybe_function_id.has_value()) { - // found function id => function defined or declared in type // ?? + if (maybe_function_id.has_value() && global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.has_value()) { + node->function_id_ = maybe_function_id.value(); - // find function declaration - std::optional& maybe_function_declaration = - global_info_.GetFunctionInfo(maybe_function_id.value()).declaration; - FunctionDeclaration* function_declaration = nullptr; - if (maybe_function_declaration.has_value()) { - function_declaration = maybe_function_declaration.value().node; + maybe_function_declaration = + global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node; } else { - auto maybe_function_info = - typeclass_graph_.GetFunctionInfo(node->name, std::nullopt); - - if (!maybe_function_info.has_value()) { - error_handling::HandleTypecheckError("No function declaration found for function in function call expression", node->base); - } - - function_declaration = maybe_function_info.value()->declaration; - } - - // check & collect parmeters - if (function_declaration->parameters.size() != node->parameters.size()) { - error_handling::HandleTypecheckError("Mismatched parameter count in function call expression", node->base); - } - for (size_t i = 0; i < node->parameters.size(); ++i) { - Visit(node->parameters[i].get()); - - std::string parameter_name = function_declaration->parameters[i]->type; - - if (context.count(parameter_name) != 0) { - error_handling::HandleInternalError("Local abstract types with same name in one context", - "TypeCheckVisitor.FunctionCallExpresssion"); - } - context[parameter_name] = current_type_; - } - - // check arguments - if (function_declaration->type->types.size() != node->arguments.size() + 1) { - error_handling::HandleTypecheckError("Mismatched argument count in function call expression", node->base); - } - for (size_t i = 0; i < node->arguments.size(); ++i) { - Visitor::Visit(function_declaration->type->types[i]); - utils::IdType argument_type = TypeInContext(current_type_, context); - - Visitor::Visit(node->arguments[i]); - context_manager_.AddValueRequirement(current_type_, argument_type); - } - - node->function_id_ = maybe_function_id.value(); // IMPORTANT - - Visitor::Visit(function_declaration->type->types.back()); - current_type_ = TypeInContext(current_type_, context); - } else { - // TODO: handle typeclass functions - auto maybe_function_info = typeclass_graph_.GetFunctionInfo(node->name, std::nullopt); - - if (!maybe_function_info.has_value()) { - error_handling::HandleTypecheckError("Can't find function", node->base); - } - - if (node->prefix.has_value()) { - if (std::holds_alternative>(node->prefix.value())) { - // std::get>(node->prefix.value()).get() - // TODO - } else if (std::holds_alternative>(node->prefix.value())) { - // std::get>(node->prefix.value()).get() - // context_manager_.GetLocalType() - // TODO - } else { - error_handling::HandleInternalError("Unexpected prefix type (when checking typeclass function)", - "TypeCheckVisitor.FunctionCallExpression"); - } - } else { - // TODO + maybe_function_declaration = std::nullopt; } } - /* - - if (node->path.empty() && maybe_local_abstract_type.has_value()) { - // TODO: find function in one of typeclasses + // function declaration check + FunctionDeclaration* function_declaration = nullptr; + if (!maybe_function_declaration.has_value()) { + error_handling::HandleTypecheckError("No function declaration found for function in function call expression", node->base); } - if (!maybe_function_id.has_value()) { - auto maybe_any_type_info = global_info_.GetTypeInfo(node->type_id_.value()); + function_declaration = maybe_function_declaration.value(); - if (maybe_function_info.has_value() && node->type_id_.has_value() && global_info_.GetAnnotatedTypeFunctionsMap(.value()->type.node).count(name) != 0) { + // check & collect parmeters + if (function_declaration->parameters.size() != node->parameters.size()) { + error_handling::HandleTypecheckError("Mismatched parameter count in function call expression", node->base); + } + for (size_t i = 0; i < node->parameters.size(); ++i) { + Visit(node->parameters[i].get()); + std::string parameter_name = function_declaration->parameters[i]->type; + + if (context.count(parameter_name) != 0) { + error_handling::HandleInternalError("Local abstract types with same name in one context", + "TypeCheckVisitor.FunctionCallExpresssion"); } - // TODO: try to find in one of typeclasses + context[parameter_name] = current_type_; } - */ + // check arguments + if (function_declaration->type->types.size() != node->arguments.size() + 1) { + error_handling::HandleTypecheckError("Mismatched argument count in function call expression", node->base); + } + for (size_t i = 0; i < node->arguments.size(); ++i) { + Visitor::Visit(function_declaration->type->types[i]); + utils::IdType argument_type = TypeInContext(current_type_, context); + + Visitor::Visit(node->arguments[i]); + context_manager_.AddValueRequirement(current_type_, argument_type); + } + + // node->function_id_ = maybe_function_id.value(); // IMPORTANT // TODO: do in functions + + Visitor::Visit(function_declaration->type->types.back()); + current_type_ = TypeInContext(current_type_, context); } void TypeCheckVisitor::Visit(TupleExpression* node) { @@ -1507,11 +1464,16 @@ void TypeCheckVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) { // TODO: internal types ?? // TODO: abstract types, typeclasses -std::optional - TypeCheckVisitor::FindSubExpressionMethod(utils::IdType expression_type, - const std::string& name, - 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; + + Visitor::Visit(*expression_node); + utils::IdType expression_type = current_type_; std::optional maybe_expression_type_info = context_manager_.GetValue(expression_type); @@ -1550,37 +1512,49 @@ std::optional maybe_function_id = maybe_const_function_id; } - return maybe_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; } // TODO: internal types ?? // TODO: abstract types, typeclasses -std::optional - TypeCheckVisitor::FindTypeFunction(TypeExpression* node, - const std::string& name, - std::unordered_map& context) { +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; - if (node->array_size.has_value()) { + if (type_node->array_size.has_value()) { error_handling::HandleTypecheckError("Can't call function from array type namespace", node->base); } std::optional maybe_local_abstract_type = - context_manager_.GetLocalType(node->type.type); + context_manager_.GetLocalType(type_node->type.type); std::vector path; - path.reserve(node->path.size() + 1); + path.reserve(type_node->path.size() + 1); - for (auto& path_type : node->path) { + for (auto& path_type : type_node->path) { path.push_back(path_type.type); } - path.push_back(node->type.type); + path.push_back(type_node->type.type); maybe_function_id = namespace_visitor_.FindFunctionId(path, name); - CollectTypeExpressionContext(*node, context); + CollectTypeExpressionContext(*type_node, context); - return maybe_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; } } // namespace interpreter