Resolving operator overloads functions
This commit is contained in:
@@ -269,6 +269,8 @@ struct Ast_Decl: Ast{
|
|||||||
Intern_String name;
|
Intern_String name;
|
||||||
Intern_String unique_name; // For code generation, currently only present on lambdas
|
Intern_String unique_name; // For code generation, currently only present on lambdas
|
||||||
|
|
||||||
|
U64 operator_overload_arguments_hash;
|
||||||
|
|
||||||
Ast_Scope *scope;
|
Ast_Scope *scope;
|
||||||
Ast_Expr *typespec;
|
Ast_Expr *typespec;
|
||||||
union{
|
union{
|
||||||
|
|||||||
@@ -849,7 +849,6 @@ parse_decl(B32 is_global){
|
|||||||
if(!expr->scope){
|
if(!expr->scope){
|
||||||
compiler_error(tname, "Operator overload doesn't have body");
|
compiler_error(tname, "Operator overload doesn't have body");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_valid_operator_overload(pctx, tname->intern_val)){
|
if(!is_valid_operator_overload(pctx, tname->intern_val)){
|
||||||
compiler_error(tname, "This operator cannot be overloaded");
|
compiler_error(tname, "This operator cannot be overloaded");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -251,11 +251,17 @@ type_array(Ast_Type *base, S64 size){
|
|||||||
return result;
|
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 *
|
function Ast_Type *
|
||||||
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
type_lambda(Ast *ast, Array<Ast_Type *> return_vals, Array<Ast_Type *> args){
|
||||||
Ast_Type *ret = type_try_tupling(return_vals, ast);
|
Ast_Type *ret = type_try_tupling(return_vals, ast);
|
||||||
U64 hash_without_ret = 13; // @function_overloading scrap this if we changed course
|
U64 hash_without_ret = calculate_hash_for_arguments(args);
|
||||||
For(args) hash_without_ret = hash_mix(hash_without_ret, hash_ptr(it));
|
|
||||||
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret);
|
U64 hash = hash_mix(hash_ptr(ret), hash_without_ret);
|
||||||
Ast_Type *result = (Ast_Type *)map_get(&pctx->type_map, hash);
|
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;
|
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
|
function void
|
||||||
insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
|
insert_into_scope(Ast_Scope *scope, Ast_Decl *decl){
|
||||||
// This function is called when resolving statements
|
// This function is called when resolving statements
|
||||||
|
|||||||
Reference in New Issue
Block a user