From: Brendan Hansen Date: Mon, 12 Apr 2021 20:52:37 +0000 (-0500) Subject: overloads can be used by value X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=acb027678841aa609f6af59aaa73b4a032d16a45;p=onyx.git overloads can be used by value --- diff --git a/bin/onyx b/bin/onyx index 478d0549..303d9fdd 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 7a5039b8..e256743f 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -1184,6 +1184,7 @@ AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual); AstTyped* find_matching_overload_by_arguments(bh_arr(AstTyped *) overloads, Arguments* args); +AstTyped* find_matching_overload_by_type(bh_arr(AstTyped *) overloads, Type* type); void report_unable_to_match_overload(AstCall* call); AstStructType* polymorphic_struct_lookup(AstPolyStructType* ps_type, bh_arr(AstPolySolution) slns, OnyxFilePos pos); diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index fb654767..95a71aca 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -444,6 +444,18 @@ b32 type_check_or_auto_cast(AstTyped** pnode, Type* type) { return 1; } + if (node->kind == Ast_Kind_Overloaded_Function) { + AstTyped* func = find_matching_overload_by_type(((AstOverloadedFunction *) node)->overloads, type); + if (func == NULL) return 0; + + // HACK: It feels like there should be a better place to flag that a procedure was definitely used. + if (func->kind == Ast_Kind_Function) + func->flags |= Ast_Flag_Function_Used; + + *pnode = func; + node = *pnode; + } + if (node->kind == Ast_Kind_Polymorphic_Proc) { AstFunction* func = polymorphic_proc_lookup((AstPolyProc *) node, PPLM_By_Function_Type, type, node->token); if (func == NULL) return 0; @@ -646,6 +658,8 @@ b32 cast_is_legal(Type* from_, Type* to_, char** err_msg) { } char* get_function_name(AstFunction* func) { + if (func->kind != Ast_Kind_Function) return ""; + if (func->name != NULL) { return bh_aprintf(global_scratch_allocator, "%b", func->name->text, func->name->length); } diff --git a/src/onyxchecker.c b/src/onyxchecker.c index ef55f05d..7e2eae1a 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -321,13 +321,6 @@ CheckStatus check_argument(AstArgument** parg) { CHECK(expression, &(*parg)->value); (*parg)->type = (*parg)->value->type; - if ((*parg)->value->kind == Ast_Kind_Overloaded_Function) { - onyx_report_error((*parg)->token->pos, - "Cannot pass overloaded function '%b' as argument.", - (*parg)->value->token->text, (*parg)->value->token->length); - return Check_Error; - } - return Check_Success; } diff --git a/src/onyxparser.c b/src/onyxparser.c index ae264191..25c9314b 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -1876,6 +1876,7 @@ static AstFunction* parse_function_definition(OnyxParser* parser, OnyxToken* tok if (consume_token_if_next(parser, '{')) { AstOverloadedFunction* ofunc = make_node(AstOverloadedFunction, Ast_Kind_Overloaded_Function); ofunc->token = token; + ofunc->flags |= Ast_Flag_Comptime; bh_arr_new(global_heap_allocator, ofunc->overloads, 4); diff --git a/src/onyxutils.c b/src/onyxutils.c index ded50804..6d7e3aee 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -1019,6 +1019,29 @@ AstTyped* find_matching_overload_by_arguments(bh_arr(AstTyped *) overloads, Argu return matched_overload; } +AstTyped* find_matching_overload_by_type(bh_arr(AstTyped *) overloads, Type* type) { + if (type->kind != Type_Kind_Function) return NULL; + + bh_imap all_overloads; + bh_imap_init(&all_overloads, global_heap_allocator, bh_arr_length(overloads) * 2); + build_all_overload_options(overloads, &all_overloads); + + AstTyped *matched_overload = NULL; + + bh_arr_each(bh__imap_entry, entry, all_overloads.entries) { + AstTyped* node = (AstTyped *) entry->key; + if (node->kind == Ast_Kind_Overloaded_Function) continue; + + if (type_check_or_auto_cast(&node, type)) { + matched_overload = node; + break; + } + } + + bh_imap_free(&all_overloads); + return matched_overload; +} + void report_unable_to_match_overload(AstCall* call) { char* arg_str = bh_alloc(global_scratch_allocator, 1024); arg_str[0] = '\0';