From: Brendan Hansen Date: Fri, 6 Aug 2021 20:46:10 +0000 (-0500) Subject: polymorphic overloads can signal yield for header X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=3a6186c3434474d6a4ccf663a63130a4b1211e34;p=onyx.git polymorphic overloads can signal yield for header --- diff --git a/bin/onyx b/bin/onyx index f63a1aec..9181d948 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/container/iter.onyx b/core/container/iter.onyx index 880c8245..c9c6c4e9 100644 --- a/core/container/iter.onyx +++ b/core/container/iter.onyx @@ -248,41 +248,43 @@ enumerate :: (it: Iterator($T), start_index: i32 = 0) -> Iterator(Enumeration_Va }; } -from_array :: (arr: [..] $T) -> Iterator(^T) { - return from_slice((#type [] T).{ arr.data, arr.count }); -} +from_array :: #match { + (arr: [..] $T) -> Iterator(^T) { + return from_slice((#type [] T).{ arr.data, arr.count }); + }, + + (arr: [] $T) -> Iterator(^T) { + Context :: struct (T: type_expr) { + data: ^T; + count: u32; + current: u32; + } -from_slice :: (arr: [] $T) -> Iterator(^T) { - Context :: struct (T: type_expr) { - data: ^T; - count: u32; - current: u32; - } + c := make(#type Context(T)); + c.data = arr.data; + c.count = arr.count; + c.current = 0; - c := make(#type Context(T)); - c.data = arr.data; - c.count = arr.count; - c.current = 0; + next :: ($T: type_expr, use _: ^Context(T)) -> (^T, bool) { + if current < count { + defer current += 1; + return ^data[current], true; - next :: ($T: type_expr, use _: ^Context(T)) -> (^T, bool) { - if current < count { - defer current += 1; - return ^data[current], true; + } else { + return null, false; + } + } - } else { - return null, false; + close :: (data: rawptr) { + cfree(data); } - } - close :: (data: rawptr) { - cfree(data); + return .{ + data = c, + next = #solidify next { T = T }, + close = close, + }; } - - return .{ - data = c, - next = #solidify next { T = T }, - close = close, - }; } fold :: (it: Iterator($T), initial_value: R, combine: (T, $R) -> R) -> R { diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index f9b8ee26..4d7c137d 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -939,6 +939,9 @@ struct AstPolySolution { }; struct AstSolidifiedFunction { + b32 header_complete: 1; + b32 body_complete: 1; + AstFunction* func; Scope* poly_scope; }; @@ -1326,7 +1329,7 @@ AstNode* polymorphic_proc_try_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual); void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload); -AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* args); +AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* args, b32* should_yield); AstTyped* find_matching_overload_by_type(bh_arr(OverloadOption) overloads, Type* type); void report_unable_to_match_overload(AstCall* call); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 3bf1c746..ca848767 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -435,9 +435,10 @@ CheckStatus check_call(AstCall* call) { while (call->callee->kind == Ast_Kind_Alias) call->callee = ((AstAlias *) call->callee)->alias; if (call->callee->kind == Ast_Kind_Overloaded_Function) { - AstTyped* new_callee = find_matching_overload_by_arguments(((AstOverloadedFunction *) call->callee)->overloads, &call->args); + b32 should_yield = 0; + AstTyped* new_callee = find_matching_overload_by_arguments(((AstOverloadedFunction *) call->callee)->overloads, &call->args, &should_yield); if (new_callee == NULL) { - if (call->callee->entity->state > Entity_State_Check_Types) { + if (call->callee->entity->state > Entity_State_Check_Types && !should_yield) { report_unable_to_match_overload(call); return Check_Error; @@ -906,7 +907,8 @@ static AstCall* binaryop_try_operator_overload(AstBinaryOp* binop) { bh_arr_push(args.values, binop->left); bh_arr_push(args.values, binop->right); - AstTyped* overload = find_matching_overload_by_arguments(operator_overloads[binop->operation], &args); + b32 should_yield = 0; + AstTyped* overload = find_matching_overload_by_arguments(operator_overloads[binop->operation], &args, &should_yield); if (overload == NULL) { bh_arr_free(args.values); return NULL; diff --git a/src/onyxutils.c b/src/onyxutils.c index 77b92643..35948245 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -372,6 +372,8 @@ static AstSolidifiedFunction generate_solidified_function( b32 header_only) { AstSolidifiedFunction solidified_func; + solidified_func.header_complete = 0; + solidified_func.body_complete = 0; // NOTE: Use the position of token if one was provided, otherwise just use NULL. OnyxFilePos poly_scope_pos = { 0 }; @@ -943,16 +945,20 @@ AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupM ensure_polyproc_cache_is_created(pp); + AstSolidifiedFunction solidified_func; + char* unique_key = build_poly_slns_unique_key(slns); if (bh_table_has(AstSolidifiedFunction, pp->concrete_funcs, unique_key)) { - AstSolidifiedFunction solidified_func = bh_table_get(AstSolidifiedFunction, pp->concrete_funcs, unique_key); - return solidified_func.func; + solidified_func = bh_table_get(AstSolidifiedFunction, pp->concrete_funcs, unique_key); + + } else { + // NOTE: This function is only going to have the header of it correctly created. + // Nothing should happen to this function's body or else the original will be corrupted. + // - brendanfh 2021/01/10 + solidified_func = generate_solidified_function(pp, slns, NULL, 1); } - // NOTE: This function is only going to have the header of it correctly created. - // Nothing should happen to this function's body or else the original will be corrupted. - // - brendanfh 2021/01/10 - AstSolidifiedFunction solidified_func = generate_solidified_function(pp, slns, NULL, 1); + if (solidified_func.header_complete) return solidified_func.func; Entity func_header_entity = { .state = Entity_State_Resolve_Symbols, @@ -968,6 +974,8 @@ AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupM return NULL; } + solidified_func.header_complete = successful; + // NOTE: Cache the function for later use, only if it didn't have errors in its header. bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func); @@ -1058,7 +1066,7 @@ void build_all_overload_options(bh_arr(OverloadOption) overloads, bh_imap* all_o } } -AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* param_args) { +AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* param_args, b32* should_yield) { Arguments args; arguments_clone(&args, param_args); arguments_ensure_length(&args, bh_arr_length(args.values) + bh_arr_length(args.named_values)); @@ -1084,7 +1092,15 @@ AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, // NOTE: Overload is not something that is known to be overloadable. if (overload == NULL) continue; if (overload->kind != Ast_Kind_Function) continue; - if (overload->type == NULL) continue; + if (overload->type == NULL) { + // If it was not possible to create the type for this procedure, tell the + // caller that this should yield and try again later. + if (should_yield) *should_yield = 1; + + // return and not continue because if the overload that didn't have a type will + // work in the future, then it has to take precedence over the other options available. + return NULL; + } assert(overload->type->kind == Type_Kind_Function); // NOTE: If the arguments cannot be placed successfully in the parameters list