mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +00:00
fixes, function definition search in typecheck
This commit is contained in:
parent
0b53b2f218
commit
afecbd64f5
6 changed files with 123 additions and 129 deletions
|
|
@ -205,15 +205,21 @@ public:
|
|||
return current_path_;
|
||||
}
|
||||
|
||||
const std::vector<utils::IdType>& GetCurrentPathNamespaces() {
|
||||
return namespace_stack_;
|
||||
}
|
||||
|
||||
// use only after LinkSymbolsVisitor
|
||||
std::vector<utils::IdType> GetCurrentPathTypes() {
|
||||
std::vector<utils::IdType> types;
|
||||
std::vector<std::optional<utils::IdType>> GetCurrentPathTypes() {
|
||||
std::vector<std::optional<utils::IdType>> types;
|
||||
|
||||
types.reserve(namespace_stack_.size());
|
||||
for (auto& namespace_id : namespace_stack_) {
|
||||
definition::Namespace& namespace_info = global_info_.GetNamespaceInfo(namespace_id);
|
||||
if (namespace_info.any_node.has_value() && namespace_info.any_node.value()->link_type_id_.has_value()) {
|
||||
types.push_back(namespace_info.any_node.value()->link_type_id_.value());
|
||||
} else {
|
||||
types.push_back(std::nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -522,7 +522,7 @@ struct FunctionCallExpression {
|
|||
|
||||
// only one from two is present
|
||||
std::optional<utils::IdType> function_id_;
|
||||
std::optional<utils::IdType> typeclass_graph_id_;
|
||||
std::optional<utils::IdType> graph_id_; // for type or typeclass
|
||||
bool is_method_of_first_argument_ = false;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,8 @@ private:
|
|||
|
||||
void AddTypeFunctionsToTypeclassGraph(utils::IdType type_id,
|
||||
utils::IdType graph_id,
|
||||
utils::ClassInternalsModifier namespace_modifier);
|
||||
utils::ClassInternalsModifier namespace_modifier,
|
||||
const BaseNode& base_node);
|
||||
|
||||
private:
|
||||
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ private:
|
|||
bool is_method);
|
||||
|
||||
std::optional<FunctionDeclaration*>
|
||||
FindDefinedTypeTypeclassFunctionAndUpdate(
|
||||
FindDefinedTypeFunctionAndUpdate(
|
||||
FunctionCallExpression* node,
|
||||
info::definition::AnyType* defined_type,
|
||||
bool is_method);
|
||||
|
|
|
|||
|
|
@ -55,15 +55,18 @@ void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
|||
|
||||
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
||||
graph_id,
|
||||
utils::ClassInternalsModifier::Static);
|
||||
utils::ClassInternalsModifier::Static,
|
||||
node->base);
|
||||
|
||||
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
||||
graph_id,
|
||||
utils::ClassInternalsModifier::Const);
|
||||
utils::ClassInternalsModifier::Const,
|
||||
node->base);
|
||||
|
||||
AddTypeFunctionsToTypeclassGraph(node->type_id_,
|
||||
graph_id,
|
||||
utils::ClassInternalsModifier::Var);
|
||||
utils::ClassInternalsModifier::Var,
|
||||
node->base);
|
||||
}
|
||||
|
||||
void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
|
|
@ -164,7 +167,8 @@ void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) {
|
|||
|
||||
void LinkSymbolsVisitor::AddTypeFunctionsToTypeclassGraph(utils::IdType type_id,
|
||||
utils::IdType graph_id,
|
||||
utils::ClassInternalsModifier namespace_modifier) {
|
||||
utils::ClassInternalsModifier namespace_modifier,
|
||||
const BaseNode& base_node) {
|
||||
auto maybe_type_graph_info = typeclass_graph_.GetTypeVertex(graph_id);
|
||||
if (!maybe_type_graph_info.has_value()) {
|
||||
error_handling::HandleInternalError("Type in typeclass graph is not marked as type",
|
||||
|
|
@ -198,10 +202,12 @@ void LinkSymbolsVisitor::AddTypeFunctionsToTypeclassGraph(utils::IdType type_id,
|
|||
|
||||
type_graph_info->functions[function.first] = function_graph_info;
|
||||
} else {
|
||||
if (function_info.definition.has_value()) {
|
||||
function_graph_iter->second.is_defined_in_owner = true;
|
||||
function_graph_iter->second.definition = function_info.definition.value().node;
|
||||
if (namespace_modifier != function_graph_iter->second.modifier) {
|
||||
error_handling::HandleTypecheckError("Type function \"" + function.first + "\" has definitions / declarations with different modifiers (static / const /var)", base_node);
|
||||
}
|
||||
|
||||
error_handling::HandleInternalError("This code should be unreachable",
|
||||
"LinkSymbolsVisitor.AddTypeFunctionsToTypeclassGraph");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -713,6 +713,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
|
|||
// Other Expressions
|
||||
|
||||
// TODO: builtin functions / methods
|
||||
// TODO: find & check definitions
|
||||
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||
|
||||
|
|
@ -776,7 +777,27 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
context_manager_.AddValueRequirement(current_type_, argument_type);
|
||||
}
|
||||
|
||||
// node->function_id_ = maybe_function_id.value(); // IMPORTANT // TODO: do in functions
|
||||
if (node->function_id_.has_value()) {
|
||||
if (!global_info_.GetFunctionInfo(node->function_id_.value()).definition.has_value()) {
|
||||
error_handling::HandleTypecheckError("No function definition found (non-type function)", node->base);
|
||||
}
|
||||
} else if (node->graph_id_.has_value()) {
|
||||
if (typeclass_graph_.GetVertex(node->graph_id_.value()).modifier != info::TypeclassGraph::Modifier::Typeclass) {
|
||||
auto maybe_graph_function_info = typeclass_graph_.GetFunctionInfo(node->name, node->graph_id_.value());
|
||||
|
||||
if (!maybe_graph_function_info.has_value()) {
|
||||
error_handling::HandleInternalError("FunctionInfo by graph_id_ not found",
|
||||
"TypeCheckVisitor.FunctionCallExpression");
|
||||
}
|
||||
|
||||
if (!maybe_graph_function_info.value()->definition.has_value()) {
|
||||
error_handling::HandleTypecheckError("No function definition found (type function)", node->base);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error_handling::HandleInternalError("No function_id_ and graph_id_ found",
|
||||
"TypeCheckVisitor.FunctionCallExpression");
|
||||
}
|
||||
|
||||
Visitor::Visit(function_declaration->type->types.back());
|
||||
current_type_ = TypeInContext(current_type_, context);
|
||||
|
|
@ -1372,7 +1393,6 @@ void TypeCheckVisitor::CheckPattern(Pattern& node, const BaseNode& base_node) {
|
|||
}
|
||||
|
||||
// TODO: internal types ??
|
||||
// TODO: find & check definitions
|
||||
std::optional<FunctionDeclaration*>
|
||||
TypeCheckVisitor::FindExpressionMethodAndUpdate(FunctionCallExpression* node,
|
||||
utils::IdType expression_type) {
|
||||
|
|
@ -1399,35 +1419,9 @@ std::optional<FunctionDeclaration*>
|
|||
}
|
||||
info::definition::AnyType* type_info = maybe_type_info.value();
|
||||
|
||||
std::optional<utils::IdType> 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);
|
||||
|
||||
std::optional<utils::IdType> maybe_function_id;
|
||||
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(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
|
||||
error_handling::HandleTypecheckError("Redefinition of method: const & var", node->base);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!maybe_function_declaration.has_value()) {
|
||||
maybe_function_declaration = FindDefinedTypeTypeclassFunctionAndUpdate(node,
|
||||
type_info,
|
||||
true);
|
||||
}
|
||||
maybe_function_declaration = FindDefinedTypeFunctionAndUpdate(node,
|
||||
type_info,
|
||||
true);
|
||||
}
|
||||
return maybe_function_declaration;
|
||||
}
|
||||
|
|
@ -1467,26 +1461,26 @@ std::optional<FunctionDeclaration*>
|
|||
}
|
||||
path.push_back(type_node->type.type);
|
||||
|
||||
std::optional<utils::IdType> maybe_function_id = namespace_visitor_.FindFunctionId(path, node->name);
|
||||
|
||||
CollectTypeExpressionContext(*type_node, context);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!maybe_function_declaration.has_value() && type_node->type_id_.has_value()) {
|
||||
if (type_node->type_id_.has_value()) {
|
||||
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(type_node->type_id_.value());
|
||||
if (!maybe_type_info.has_value()) {
|
||||
error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType",
|
||||
"TypeCheckVisitor.FindTypeFunctionAndUpdate");
|
||||
}
|
||||
|
||||
maybe_function_declaration = FindDefinedTypeTypeclassFunctionAndUpdate(node,
|
||||
maybe_type_info.value(),
|
||||
false);
|
||||
maybe_function_declaration = FindDefinedTypeFunctionAndUpdate(node,
|
||||
maybe_type_info.value(),
|
||||
false);
|
||||
} else {
|
||||
std::optional<utils::IdType> maybe_function_id = namespace_visitor_.FindFunctionId(path, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return maybe_function_declaration;
|
||||
|
|
@ -1494,36 +1488,63 @@ std::optional<FunctionDeclaration*>
|
|||
|
||||
std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(FunctionCallExpression* node) {
|
||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||
std::optional<utils::IdType> maybe_function_id;
|
||||
|
||||
if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) {
|
||||
std::string namespace_name =
|
||||
namespace_visitor_.GetCurrentNamespace()->type_name;
|
||||
utils::ClassInternalsModifier namespace_modifier =
|
||||
namespace_visitor_.GetCurrentNamespace()->modifier;
|
||||
namespace_visitor_.ExitNamespace();
|
||||
const std::vector<utils::IdType>& path_namespaces = namespace_visitor_.GetCurrentPathNamespaces();
|
||||
auto path_types = namespace_visitor_.GetCurrentPathTypes();
|
||||
for (ssize_t i = (ssize_t)path_types.size() - 1; i >= 0; --i) { // optimize ??
|
||||
if (path_types[i].has_value()) {
|
||||
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(path_types[i].value());
|
||||
if (!maybe_type_info.has_value()) {
|
||||
error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType",
|
||||
"TypeCheckVisitor.FindTypeFunctionAndUpdate");
|
||||
}
|
||||
|
||||
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<std::string> current_type_path { namespace_visitor_.GetCurrentNamespace()->type_name };
|
||||
maybe_function_id = namespace_visitor_.FindFunctionId(current_type_path, node->name); // TODO: check !!!
|
||||
maybe_function_declaration =
|
||||
FindDefinedTypeFunctionAndUpdate(node,
|
||||
maybe_type_info.value(),
|
||||
false);
|
||||
} else {
|
||||
auto function_iter = global_info_.GetNamespaceInfo(path_namespaces[i]).functions.find(node->name);
|
||||
if (function_iter != global_info_.GetNamespaceInfo(path_namespaces[i]).functions.end()) {
|
||||
auto& maybe_declaration_info = global_info_.GetFunctionInfo(function_iter->second).declaration;
|
||||
|
||||
if (maybe_declaration_info.has_value()) {
|
||||
maybe_function_declaration = maybe_declaration_info.value().node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace_visitor_.EnterNamespace(namespace_name, namespace_modifier);
|
||||
} else {
|
||||
maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
|
||||
if (maybe_function_declaration.has_value()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (maybe_function_id.has_value() && global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.has_value()) {
|
||||
node->function_id_ = maybe_function_id.value();
|
||||
maybe_function_declaration =
|
||||
global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node;
|
||||
} else {
|
||||
maybe_function_declaration = std::nullopt;
|
||||
}
|
||||
// ------------------ replaced ------------------
|
||||
// if (namespace_visitor_.GetCurrentNamespace()->modifier != utils::ClassInternalsModifier::Static) {
|
||||
// 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<std::string> current_type_path { namespace_visitor_.GetCurrentNamespace()->type_name };
|
||||
// maybe_function_id = namespace_visitor_.FindFunctionId(current_type_path, node->name);
|
||||
// }
|
||||
//
|
||||
// namespace_visitor_.EnterNamespace(namespace_name, namespace_modifier);
|
||||
// } else {
|
||||
// maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
|
||||
// }
|
||||
//
|
||||
// if (maybe_function_id.has_value() && global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.has_value()) {
|
||||
// node->function_id_ = maybe_function_id.value();
|
||||
// maybe_function_declaration =
|
||||
// global_info_.GetFunctionInfo(maybe_function_id.value()).declaration.value().node;
|
||||
// }
|
||||
|
||||
// call as method of first argument // TODO: earlier??
|
||||
if (!maybe_function_declaration.has_value() && node->is_binary_operator_expression && node->arguments.size() > 0) {
|
||||
Visitor::Visit(node->arguments[0]);
|
||||
maybe_function_declaration = FindExpressionMethodAndUpdate(node, current_type_);
|
||||
|
|
@ -1532,30 +1553,6 @@ std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(Func
|
|||
}
|
||||
}
|
||||
|
||||
// try to find typeclass function in for parent namespaces (check definition ??)
|
||||
if (!maybe_function_declaration.has_value()) {
|
||||
// TODO: check
|
||||
auto path_types = namespace_visitor_.GetCurrentPathTypes();
|
||||
if (!path_types.empty()) {
|
||||
for (ssize_t i = (ssize_t)path_types.size() - 1; i >= 0; --i) { // optimize
|
||||
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(path_types[i]);
|
||||
if (!maybe_type_info.has_value()) {
|
||||
error_handling::HandleInternalError("typeclass functions / methods implemented only for AnyType",
|
||||
"TypeCheckVisitor.FindTypeFunctionAndUpdate");
|
||||
}
|
||||
|
||||
maybe_function_declaration =
|
||||
FindDefinedTypeTypeclassFunctionAndUpdate(node,
|
||||
maybe_type_info.value(),
|
||||
false);
|
||||
|
||||
if (maybe_function_declaration.has_value()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return maybe_function_declaration;
|
||||
}
|
||||
|
||||
|
|
@ -1589,44 +1586,28 @@ std::optional<FunctionDeclaration*>
|
|||
error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base);
|
||||
}
|
||||
|
||||
node->typeclass_graph_id_ = maybe_typeclass_graph_id;
|
||||
node->graph_id_ = maybe_typeclass_graph_id;
|
||||
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
|
||||
|
||||
return maybe_function_declaration;
|
||||
}
|
||||
|
||||
std::optional<FunctionDeclaration*>
|
||||
TypeCheckVisitor::FindDefinedTypeTypeclassFunctionAndUpdate(
|
||||
FunctionCallExpression* node,
|
||||
info::definition::AnyType* defined_type,
|
||||
bool is_method) {
|
||||
TypeCheckVisitor::FindDefinedTypeFunctionAndUpdate(
|
||||
FunctionCallExpression* node,
|
||||
info::definition::AnyType* defined_type,
|
||||
bool is_method) {
|
||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||
|
||||
auto maybe_typeclass_graph_id = typeclass_graph_.FindFunctionTypeclass(node->name);
|
||||
if (!maybe_typeclass_graph_id.has_value()) {
|
||||
auto maybe_type_function_info = typeclass_graph_.GetFunctionInfo(node->name, defined_type->type.node->graph_id_);
|
||||
|
||||
if (!maybe_type_function_info.has_value()) {
|
||||
return std::nullopt;
|
||||
// error_handling::HandleTypecheckError("Function is not declared in type", node->base);
|
||||
}
|
||||
|
||||
auto typeclasses = typeclass_graph_.GetDependenciesSet(defined_type->type.node->graph_id_);
|
||||
auto function_typeclass_iter = typeclasses.find(maybe_typeclass_graph_id.value());
|
||||
|
||||
if (function_typeclass_iter == typeclasses.end()) {
|
||||
error_handling::HandleTypecheckError("Function typeclass not pesent in type typeclasses list (defined type)", node->base);
|
||||
}
|
||||
|
||||
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.FindDefinedTypeTypeclassFunctionAndUpdate");
|
||||
}
|
||||
|
||||
if ((maybe_typeclass_function_info.value()->modifier == utils::ClassInternalsModifier::Static) != is_method) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
node->typeclass_graph_id_ = maybe_typeclass_graph_id;
|
||||
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
|
||||
node->graph_id_ = defined_type->type.node->graph_id_;
|
||||
maybe_function_declaration = maybe_type_function_info.value()->declaration;
|
||||
|
||||
return maybe_function_declaration;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue