operator typecheck refactoring

This commit is contained in:
ProgramSnail 2023-05-09 15:01:11 +03:00
parent 78de51f6f2
commit 5167986ddf

View file

@ -574,42 +574,12 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name); auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name);
const info::definition::Function* operator_info = nullptr; const info::definition::Function* operator_info = nullptr;
bool is_method = false;
if (maybe_operator_id.has_value()) { if (maybe_operator_id.has_value()) {
operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value()); operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
is_method = false;
if (!operator_info->declaration.has_value()) {
error_handling::HandleTypecheckError("Operator declaration not found", node->base);
}
if (!operator_info->definition.has_value()) { // TODO: builtin, etc.
error_handling::HandleTypecheckError("Operator definition not found", node->base);
}
if (operator_info->argument_count != 3) { // 2 + return type
error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
}
if (operator_info->declaration->parameters.size() > 0) {
error_handling::HandleTypecheckError("Operator with parameters", node->base);
}
Visitor::Visit(*operator_info->declaration.value().argument_types[0]);
utils::IdType left_expression_type = current_type_; // TODO: type in context of deduced types
Visitor::Visit(node->left_expression);
if (!context_manager_.AddTypeRequirement(current_type_, left_expression_type)) {
error_handling::HandleTypecheckError("Operator left expression has wrong type", node->base);
}
Visitor::Visit(*operator_info->declaration.value().argument_types[1]);
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
Visitor::Visit(node->right_expression);
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
}
} else { } else {
Visitor::Visit(node->left_expression); Visitor::Visit(node->left_expression);
auto maybe_left_type = context_manager_.GetType<info::type::DefinedType>(current_type_); auto maybe_left_type = context_manager_.GetType<info::type::DefinedType>(current_type_);
@ -648,6 +618,8 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
} }
operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value()); operator_info = &namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
is_method = true;
}
if (!operator_info->declaration.has_value()) { if (!operator_info->declaration.has_value()) {
error_handling::HandleTypecheckError("Operator declaration not found", node->base); error_handling::HandleTypecheckError("Operator declaration not found", node->base);
@ -657,7 +629,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
error_handling::HandleTypecheckError("Operator definition not found", node->base); error_handling::HandleTypecheckError("Operator definition not found", node->base);
} }
if (operator_info->argument_count != 2) { // argument + return type if (operator_info->argument_count != (is_method ? 2 : 3)) { // 2 + return type
error_handling::HandleTypecheckError("Operator wrong argument count", node->base); error_handling::HandleTypecheckError("Operator wrong argument count", node->base);
} }
@ -665,14 +637,25 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
error_handling::HandleTypecheckError("Operator with parameters", node->base); error_handling::HandleTypecheckError("Operator with parameters", node->base);
} }
Visitor::Visit(*operator_info->declaration.value().argument_types[9]); if (!is_method) {
Visitor::Visit(*operator_info->declaration.value().argument_types[0]);
utils::IdType left_expression_type = current_type_; // TODO: type in context of deduced types
Visitor::Visit(node->left_expression);
if (!context_manager_.AddTypeRequirement(current_type_, left_expression_type)) {
error_handling::HandleTypecheckError("Operator left expression has wrong type", node->base);
}
}
Visitor::Visit(*operator_info->declaration.value().argument_types[is_method ? 0 : 1]);
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
Visitor::Visit(node->right_expression); Visitor::Visit(node->right_expression);
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) { if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base); error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
} }
}
node->function_id_ = maybe_operator_id.value(); // IMPORTANT node->function_id_ = maybe_operator_id.value(); // IMPORTANT