From: Brendan Hansen Date: Mon, 18 Jan 2021 01:55:38 +0000 (-0600) Subject: small cleanup of the new compile-time parameters X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=7dcd526975c72847b966f9e18d900adaef7c7f87;p=onyx.git small cleanup of the new compile-time parameters --- diff --git a/core/array.onyx b/core/array.onyx index 0cd4978c..4bd68f70 100644 --- a/core/array.onyx +++ b/core/array.onyx @@ -3,6 +3,12 @@ package core.array // --------------------------------- // Dynamic Arrays // --------------------------------- +make :: proc ($T: type_expr, initial_cap := 4) -> [..] T { + arr : [..] T; + init(^arr, initial_cap); + return arr; +} + init :: proc (arr: ^[..] $T, initial_cap := 4) { arr.count = 0; arr.capacity = initial_cap; diff --git a/core/map.onyx b/core/map.onyx index 1712c837..8656ca78 100644 --- a/core/map.onyx +++ b/core/map.onyx @@ -18,6 +18,12 @@ MapEntry :: struct (K: type_expr, V: type_expr) { value : V; } +make :: proc ($Key: type_expr, $Value: type_expr, default: Value = 0, hash_count: i32 = 16) -> Map(Key, Value) { + map : Map(Key, Value); + init(^map, default = default, hash_count = hash_count); + return map; +} + init :: proc (use map: ^Map($K, $V), default: V = ~~0, hash_count: i32 = 16) { array.init(^hashes, hash_count); array.init(^entries, 4); diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index bacc1116..9f5ffa06 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -1029,15 +1029,14 @@ b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg); void arguments_ensure_length(Arguments* args, u32 count); void arguments_clone(Arguments* dest, Arguments* src); void arguments_deep_clone(bh_allocator a, Arguments* dest, Arguments* src); -void arguments_removed_baked(Arguments* args); +void arguments_remove_baked(Arguments* args); // GROSS: Using void* to avoid having to cast everything. const char* node_get_type_name(void* node); typedef enum PolyProcLookupMethod { - PPLM_By_Call, - PPLM_By_Function_Type, PPLM_By_Arguments, + PPLM_By_Function_Type, } PolyProcLookupMethod; AstFunction* polymorphic_proc_lookup(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxToken* tkn); AstFunction* polymorphic_proc_solidify(AstPolyProc* pp, bh_arr(AstPolySolution) slns, OnyxToken* tkn); diff --git a/onyx.exe b/onyx.exe index 56828a13..d764d5af 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index 51a12a11..f560b339 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -714,7 +714,7 @@ void arguments_deep_clone(bh_allocator a, Arguments* dest, Arguments* src) { bh_arr_push(dest->values, (AstTyped *) ast_clone(a, (AstNode *) *val)); } -void arguments_removed_baked(Arguments* args) { +void arguments_remove_baked(Arguments* args) { fori (i, 0, bh_arr_length(args->values)) { if (args->values[i]->kind != Ast_Kind_Argument) continue; if (!((AstArgument *) args->values[i])->is_baked) continue; @@ -740,5 +740,9 @@ const char* node_get_type_name(void* node) { return node_get_type_name(((AstArgument *) node)->value); } + if (((AstNode *) node)->kind == Ast_Kind_Polymorphic_Proc) { + return "polymorphic procedure"; + } + return type_get_name(((AstTyped *) node)->type); } diff --git a/src/onyxchecker.c b/src/onyxchecker.c index ea7905bb..4c1d0123 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -466,12 +466,12 @@ CheckStatus check_call(AstCall* call) { } if (callee->kind == Ast_Kind_Polymorphic_Proc) { - call->callee = (AstTyped *) polymorphic_proc_lookup((AstPolyProc *) call->callee, PPLM_By_Call, call, call->token); + call->callee = (AstTyped *) polymorphic_proc_lookup((AstPolyProc *) call->callee, PPLM_By_Arguments, &call->args, call->token); if (call->callee == NULL) return Check_Error; callee = (AstFunction *) call->callee; - arguments_removed_baked(&call->args); + arguments_remove_baked(&call->args); } // NOTE: Build callee's type @@ -496,12 +496,10 @@ CheckStatus check_call(AstCall* call) { non_vararg_param_count--; i32 arg_count = bh_max(non_vararg_param_count, non_baked_argument_count(&call->args)); - arguments_ensure_length(&call->args, arg_count); char* err_msg = NULL; fill_in_arguments(&call->args, (AstNode *) callee, &err_msg); - if (err_msg != NULL) { onyx_report_error(call->token->pos, err_msg); return Check_Error; diff --git a/src/onyxutils.c b/src/onyxutils.c index 63d064d2..a791013f 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -399,17 +399,7 @@ static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLo if (param->kind == PPK_Poly_Type) { Type* actual_type = NULL; - if (pp_lookup == PPLM_By_Call) { - AstCall* call = (AstCall *) actual; - - AstTyped* typed_param = lookup_param_in_arguments(pp, param, &call->args, err_msg); - if (typed_param == NULL) goto sln_not_found; - - actual_type = resolve_expression_type(typed_param); - if (actual_type == NULL) goto sln_not_found; - } - - else if (pp_lookup == PPLM_By_Arguments) { + if (pp_lookup == PPLM_By_Arguments) { Arguments* args = (Arguments *) actual; AstTyped* typed_param = lookup_param_in_arguments(pp, param, args, err_msg); @@ -439,14 +429,7 @@ static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLo } else if (param->kind == PPK_Baked_Value) { AstTyped* value = NULL; - if (pp_lookup == PPLM_By_Call) { - AstCall* call = (AstCall *) actual; - - value = lookup_param_in_arguments(pp, param, &call->args, err_msg); - if (value == NULL) goto sln_not_found; - } - - else if (pp_lookup == PPLM_By_Arguments) { + if (pp_lookup == PPLM_By_Arguments) { Arguments* args = (Arguments *) actual; value = lookup_param_in_arguments(pp, param, args, err_msg); @@ -490,14 +473,17 @@ static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLo param->type = type_build_from_ast(semstate.node_allocator, param->type_expr); if (!type_check_or_auto_cast(&value, param->type)) { - *err_msg = "Expected parameter of a different type. This error message should be wayyy better."; + *err_msg = bh_aprintf(global_scratch_allocator, + "The procedure '%s' expects a value of type '%s' for %d%s parameter, got '%s'.", + get_function_name(pp->base_func), + type_get_name(param->type), + param->idx + 1, + bh_num_suffix(param->idx + 1), + node_get_type_name(value)); goto sln_not_found; } - resolved = ((PolySolveResult) { - .kind = PSK_Value, - .value = value, - }); + resolved = ((PolySolveResult) { PSK_Value, value }); } if (orig_value->kind == Ast_Kind_Argument) { diff --git a/tests/baked_parameters b/tests/baked_parameters new file mode 100644 index 00000000..4b3ac720 --- /dev/null +++ b/tests/baked_parameters @@ -0,0 +1,18 @@ +0 1 2 3 4 +0 1 2 3 4 5 6 7 8 9 +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 +0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 +1234 +1234 +1234 +1234 +1234 +1234 +1234 +1234 +1234 +1234 +Dwight's age is 32. +Jim's age is 25. +Pam's age is 24. +Michael's age is 0. diff --git a/tests/baked_parameters.onyx b/tests/baked_parameters.onyx new file mode 100644 index 00000000..18e51ab1 --- /dev/null +++ b/tests/baked_parameters.onyx @@ -0,0 +1,50 @@ +#load "core/std/js" + +use package core + +count_to :: proc ($N: i32) { + for i: 0 .. N do printf("%i ", i); + print("\n"); +} + +alloc_slice :: proc ($T: type_expr, N: i32) -> [] T { + data := cast(^T) calloc(sizeof T * N); + return <[] T>.{ data, N }; +} + +count_to_30 :: #solidify count_to { N = #value 30 }; + +main :: proc (args: [] cstr) { + count_to(5); + count_to(10); + count_to_30(); + + // This counts as a compile-time known value. + UP_TO :: 100; + count_to(UP_TO); + + sl := alloc_slice(i32, 10); + for ^elem: sl do *elem = 1234; + + for elem: sl do println(elem); + + + // This is so much cleaner than the alternative. + ages := map.make(str, u32, default=0); + defer map.free(^ages); + + map.put(^ages, "Dwight", 32); + map.put(^ages, "Jim", 25); + map.put(^ages, "Pam", 24); + + print_age :: proc (ages: ^map.Map(str, u32), name: str) { + age := map.get(ages, name); + printf("%s's age is %i.\n", name, age); + } + + print_age(^ages, "Dwight"); + print_age(^ages, "Jim"); + print_age(^ages, "Pam"); + print_age(^ages, "Michael"); +} +