Changing rules of operator overload lookup

This commit is contained in:
Krzosa Karol
2022-09-29 20:15:44 +02:00
parent 37489b2730
commit ab19ebc992
3 changed files with 22 additions and 15 deletions

View File

@@ -792,19 +792,20 @@ function void
scope_search(Scope_Search *search){ scope_search(Scope_Search *search){
// Climb the scope tree and search each scope in module and also // Climb the scope tree and search each scope in module and also
// search in implicitly imported scopes // search in implicitly imported scopes
Ast_Scope *scope = search->scope; For_Named(search->scopes, scope){
for(Ast_Scope *it = scope; it; it=it->parent_scope){ for(Ast_Scope *it = scope; it; it=it->parent_scope){
inside_scope_search(search, it, 0); inside_scope_search(search, it, 0);
if(search->exit_on_find && search->results.len){ if(search->exit_on_find && search->results.len){
return; return;
} }
if(search->search_only_current_scope){ if(search->search_only_current_scope){
return; return;
}
} }
inside_scope_search(search, scope->module, 0);
} }
inside_scope_search(search, scope->module, 0);
} }
function Scope_Search function Scope_Search
@@ -813,7 +814,8 @@ make_scope_search(Arena *arena, Ast_Scope *scope, Intern_String name){
result.results.allocator = arena; result.results.allocator = arena;
result.name = name; result.name = name;
result.scope_visit_id = ++pctx->scope_visit_id; result.scope_visit_id = ++pctx->scope_visit_id;
result.scope = scope; result.scopes = {arena};
result.scopes.add(scope);
result.exit_on_find = true; result.exit_on_find = true;
return result; return result;
} }
@@ -909,13 +911,16 @@ map_operator_intern_to_identifier_name(Intern_String op){
} }
function Ast_Decl * function Ast_Decl *
resolve_operator_overload(Ast_Scope *scope, Token *pos, Token_Kind op, U64 argument_hash){ resolve_operator_overload(Ast_Scope *scope, Ast_Type *left, Ast_Type *right, Token *pos, Token_Kind op, U64 argument_hash){
Intern_String name = map_operator_to_intern(op); Intern_String name = map_operator_to_intern(op);
if(name.str == 0) return 0; if(name.str == 0) return 0;
// Search for all possible candidates // Search for all possible candidates in three scopes
// The current module, left type definition module, right type definition module
Scratch scratch; Scratch scratch;
Scope_Search search = make_scope_search(scratch, scope, name); Scope_Search search = make_scope_search(scratch, scope, name);
if( left->ast && left->ast->parent_scope) search.scopes.add(left->ast->parent_scope);
if(right && right->ast && right->ast->parent_scope) search.scopes.add(right->ast->parent_scope);
search.exit_on_find = false; search.exit_on_find = false;
scope_search(&search); scope_search(&search);
@@ -1639,7 +1644,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
// Try finding a operator overload // Try finding a operator overload
if(!is_const){ if(!is_const){
U64 hash = calculate_hash_for_arguments(left.type, right.type); U64 hash = calculate_hash_for_arguments(left.type, right.type);
Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, node->pos, node->op, hash); Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, left.type, right.type, node->pos, node->op, hash);
if(operator_overload){ if(operator_overload){
proceed_to_default_operator_handler = false; proceed_to_default_operator_handler = false;
if(operator_overload->lambda->ret.len != 1){ if(operator_overload->lambda->ret.len != 1){
@@ -1706,7 +1711,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
B32 proceed_to_default_operator_handler = true; B32 proceed_to_default_operator_handler = true;
if(!value.is_const){ if(!value.is_const){
U64 hash = calculate_hash_for_arguments(value.type); U64 hash = calculate_hash_for_arguments(value.type);
Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, node->pos, node->op, hash); Ast_Decl *operator_overload = resolve_operator_overload(node->parent_scope, value.type, 0, node->pos, node->op, hash);
if(operator_overload){ if(operator_overload){
proceed_to_default_operator_handler = false; proceed_to_default_operator_handler = false;
if(operator_overload->lambda->ret.len != 1){ if(operator_overload->lambda->ret.len != 1){

View File

@@ -10,7 +10,7 @@ struct Operand{
struct Scope_Search { struct Scope_Search {
Array<Ast_Decl *> results; Array<Ast_Decl *> results;
Intern_String name; Intern_String name;
Ast_Scope *scope; Array<Ast_Scope *> scopes;
bool exit_on_find; bool exit_on_find;
bool search_only_current_scope; bool search_only_current_scope;

View File

@@ -10,6 +10,8 @@ Vec3 :: struct;; x: F32; y: F32; z: F32
main :: (): int main :: (): int
a := Vec3{1,1,1} a := Vec3{1,1,1}
b := Vec3{2,3,4} b := Vec3{2,3,4}
// The expressions are replaced with the defined lambdas
c := a + b c := a + b
Assert(c.x == 3 && c.y == 4 && c.z == 5) Assert(c.x == 3 && c.y == 4 && c.z == 5)
d := -c d := -c