diff --git a/src/.type_check_visitor.cpp.kate-swp b/src/.type_check_visitor.cpp.kate-swp new file mode 100644 index 0000000..4e62eee Binary files /dev/null and b/src/.type_check_visitor.cpp.kate-swp differ diff --git a/src/find_symbols_visitor.cpp b/src/find_symbols_visitor.cpp index d153976..2b46230 100644 --- a/src/find_symbols_visitor.cpp +++ b/src/find_symbols_visitor.cpp @@ -11,6 +11,13 @@ namespace interpreter { // Namespaces, partitions ----------------- void FindSymbolsVisitor::Visit(Namespace* node) { + if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) { + // other type of error?? + error_handling::HandleParsingError("Can't use const /var namespace inside const / var namespace", + node->base.start_position, + node->base.end_position); + } + namespace_visitor_.AddEnterNamespace(node->type, node->modifier, node, node->base); Visitor::Visit(&node->scope); diff --git a/src/type_check_visitor.cpp b/src/type_check_visitor.cpp index e8451f2..1d4c7ee 100644 --- a/src/type_check_visitor.cpp +++ b/src/type_check_visitor.cpp @@ -138,8 +138,7 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { context_manager_.EnterContext(); for (auto& parameter : node->parameters) { // declaration correctness check // TODO: needed?? - std::vector requirements = - global_info_.GetAnnotatedTypeTypeclassesVector(parameter.get()); + auto requirements = global_info_.GetAnnotatedTypeTypeclassesSet(parameter.get()); current_type_ = context_manager_.AddValue( info::type::AbstractType(utils::AbstractTypeModifier::Abstract, parameter->type, @@ -218,8 +217,7 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { } for (auto& parameter : declaration->parameters) { - std::vector requirements = - global_info_.GetAnnotatedTypeTypeclassesVector(parameter.get()); + auto requirements = global_info_.GetAnnotatedTypeTypeclassesSet(parameter.get()); current_type_ = context_manager_.AddValue(info::type::AbstractType(utils::AbstractTypeModifier::Abstract, parameter->type, requirements), @@ -283,8 +281,7 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) { void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) { is_in_statement_ = true; - std::vector requirements = - global_info_.GetAnnotatedTypeTypeclassesVector(node->type.get()); + auto requirements = global_info_.GetAnnotatedTypeTypeclassesSet(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_)) { @@ -792,7 +789,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) { // Other Expressions -// TODO: builtin functions/methods +// TODO: builtin functions / methods // TODO: abstract types (check typeclass requirements) void TypeCheckVisitor::Visit(FunctionCallExpression* node) { std::optional maybe_function_declaration; @@ -827,9 +824,20 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { 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 }; - maybe_function_id = namespace_visitor_.FindFunctionId(current_type_path, node->name); // TODO: check !!! + std::string namespace_name = + namespace_visitor_.GetCurrentNamespace()->type_name; + utils::ClassInternalsModifier namespace_modifier = + namespace_visitor_.GetCurrentNamespace()->modifier; + namespace_visitor_.ExitNamespace(); + + maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name); + if (!maybe_function_id.has_value()) { + // call functions from static namespace of current type + std::vector current_type_path { namespace_visitor_.GetCurrentNamespace()->type_name }; + maybe_function_id = namespace_visitor_.FindFunctionId(current_type_path, node->name); // TODO: check !!! + } + + namespace_visitor_.EnterNamespace(namespace_name, namespace_modifier); } else { maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name); } @@ -845,11 +853,10 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) { } // 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); } - function_declaration = maybe_function_declaration.value(); + FunctionDeclaration* function_declaration = maybe_function_declaration.value(); // check & collect parmeters if (function_declaration->parameters.size() != node->parameters.size()) { @@ -1474,29 +1481,27 @@ std::optional Visitor::Visit(*expression_node); utils::IdType expression_type = current_type_; - auto maybe_typeclass_function_info = - typeclass_graph_.GetFunctionInfo(node->name, std::nullopt); - - auto maybe_abstract_type_info = - context_manager_.GetValue(expression_type); + auto maybe_typeclass_graph_id = typeclass_graph_.FindFunctionTypeclass(node->name); + auto maybe_abstract_type_info = context_manager_.GetValue(expression_type); if (maybe_abstract_type_info.has_value()) { - if (!maybe_typeclass_function_info.has_value()) { + if (!maybe_typeclass_graph_id.has_value()) { error_handling::HandleTypecheckError("Typeclass function not found", base_node); } info::type::AbstractType* abstract_type_info = maybe_abstract_type_info.value(); - if (!typeclass_graph_.FindFunctionTypeclass(node->name).value()) { - error_handling::HandleInternalError("Typeclass function info found, but typeclas id not found", + auto maybe_typeclass_function_info = typeclass_graph_.GetFunctionInfo(node->name, + maybe_typeclass_graph_id.value()); + if (!maybe_typeclass_function_info.has_value()) { + error_handling::HandleInternalError("Typeclass function info found, but typeclass id not found (abstract type)", "TypeCheckVisitor.FindSubExpressionMethodAndUpdate"); } - - if (abstract_type_info->HasTypeclass(typeclass_graph_.FindFunctionTypeclass(node->name).value())) { + if (abstract_type_info->HasTypeclass(maybe_typeclass_graph_id.value())) { + node->typeclass_graph_id_ = maybe_typeclass_graph_id; 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()) { @@ -1504,21 +1509,20 @@ std::optional } utils::IdType type_id = maybe_defined_type_info.value()->GetTypeId(); - std::optional maybe_type_info = - global_info_.GetTypeInfo(type_id); + auto 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"); } + info::definition::AnyType* type_info = maybe_type_info.value(); - // 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]; + std::optional maybe_const_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(type_info->parent_namespace).const_namespaces.at(type_info->type.type)).functions[node->name]; 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]; + maybe_function_id = global_info_.GetNamespaceInfo(global_info_.GetNamespaceInfo(type_info->parent_namespace).var_namespaces.at(type_info->type.type)).functions[node->name]; } if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage @@ -1534,6 +1538,21 @@ std::optional maybe_function_declaration = global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node; } + + if (!maybe_function_declaration.has_value() && maybe_typeclass_graph_id.has_value()) { + auto typeclasses = global_info_.GetAnnotatedTypeTypeclassesSet(type_info->type.node); + auto function_typeclass_iter = typeclasses.find(maybe_typeclass_graph_id.value()); + + if (function_typeclass_iter != typeclasses.end()) { + auto maybe_typeclass_function_info = typeclass_graph_.GetFunctionInfo(node->name, + maybe_typeclass_graph_id.value()); + if (!maybe_typeclass_function_info.has_value()) { + error_handling::HandleInternalError("Typeclass function info found, but typeclass id not found (definied type)", + "TypeCheckVisitor.FindSubExpressionMethodAndUpdate"); + } + maybe_function_declaration = maybe_typeclass_function_info.value()->declaration; + } + } } return maybe_function_declaration; } @@ -1551,8 +1570,8 @@ std::optional error_handling::HandleTypecheckError("Can't call function from array type namespace", node->base); } - std::optional maybe_local_abstract_type = - context_manager_.GetLocalType(type_node->type.type); + // std::optional maybe_local_abstract_type = + // context_manager_.GetLocalType(type_node->type.type); std::vector path; path.reserve(type_node->path.size() + 1);