Resolving operator overloads functions
This commit is contained in:
@@ -269,6 +269,8 @@ struct Ast_Decl: Ast{
|
||||
Intern_String name;
|
||||
Intern_String unique_name; // For code generation, currently only present on lambdas
|
||||
|
||||
U64 operator_overload_arguments_hash;
|
||||
|
||||
Ast_Scope *scope;
|
||||
Ast_Expr *typespec;
|
||||
union{
|
||||
|
||||
@@ -849,7 +849,6 @@ parse_decl(B32 is_global){
|
||||
if(!expr->scope){
|
||||
compiler_error(tname, "Operator overload doesn't have body");
|
||||
}
|
||||
|
||||
if(!is_valid_operator_overload(pctx, tname->intern_val)){
|
||||
compiler_error(tname, "This operator cannot be overloaded");
|
||||
}
|
||||
|
||||
@@ -251,11 +251,17 @@ type_array(Ast_Type *base, S64 size){
|
||||
return result;
|
||||
}
|
||||
|
||||
inline U64
|
||||
calculate_hash_for_arguments(Array<Ast_Type *> args){
|
||||
U64 result = 13;
|
||||
For(args) result = hash_mix(result, hash_ptr(it));
|
||||
return result;
|
||||
}
|
||||
|
||||
function Ast_Type *
|
||||
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
||||
Ast_Type *ret = type_try_tupling(return_vals, ast);
|
||||
U64 hash_without_ret = 13; // @function_overloading scrap this if we changed course
|
||||
For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it));
|
||||
U64 hash_without_ret = calculate_hash_for_arguments(args);
|
||||
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret);
|
||||
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
|
||||
|
||||
@@ -838,6 +844,39 @@ resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag searc
|
||||
return decl;
|
||||
}
|
||||
|
||||
function Ast_Decl *
|
||||
resolve_operator_overload(Ast_Scope *scope, Token *pos, Intern_String name, U64 argument_hash){
|
||||
|
||||
// Search for all possible candidates
|
||||
Scratch scratch;
|
||||
Scope_Search search = make_scope_search(scratch, scope, name);
|
||||
search.exit_on_find = false;
|
||||
scope_search(&search);
|
||||
|
||||
if(search.results.len == 0){
|
||||
compiler_error(pos, "Failed to find matching operator overload for [%s] No operator of this kind is defined", name.str);
|
||||
}
|
||||
|
||||
// Resolve them until we hit a match
|
||||
Array<Ast_Decl *> matching_ops = {scratch};
|
||||
For(search.results){
|
||||
resolve_decl(it);
|
||||
if(it->type->func.hash_without_ret == argument_hash){
|
||||
matching_ops.add(it);
|
||||
}
|
||||
}
|
||||
|
||||
if(matching_ops.len == 0){
|
||||
compiler_error(pos, "Failed to find matching operator overload for [%s]", name.str);
|
||||
}
|
||||
|
||||
if(matching_ops.len > 1){
|
||||
compiler_error(pos, "Found multiple matching operator overloads for [%s]", name.str);
|
||||
}
|
||||
|
||||
return matching_ops.data[0];
|
||||
}
|
||||
|
||||
function void
|
||||
insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
|
||||
// This function is called when resolving statements
|
||||
|
||||
Reference in New Issue
Block a user