small cleanup of the new compile-time parameters
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 18 Jan 2021 01:55:38 +0000 (19:55 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 18 Jan 2021 01:55:38 +0000 (19:55 -0600)
core/array.onyx
core/map.onyx
include/onyxastnodes.h
onyx.exe
src/onyxastnodes.c
src/onyxchecker.c
src/onyxutils.c
tests/baked_parameters [new file with mode: 0644]
tests/baked_parameters.onyx [new file with mode: 0644]

index 0cd4978ce7c2a3d5cf03b171c977dfb76a24a6a7..4bd68f707e3b7a9f1f4cdc29f3aa505dd7de7ce6 100644 (file)
@@ -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;
index 1712c837858bb5d9f333ab8bc227402196126262..8656ca78f44b03d07c8cd2899fd27ebef4a00e6f 100644 (file)
@@ -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);
index bacc11161709202075cf642de945abfe18bf4cc5..9f5ffa06d5d58491f61a578cdb10198198b544bb 100644 (file)
@@ -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);
index 56828a13b16cdfeb13578536daadaa748e06d502..d764d5af338c02426c4ccd6f0e3357a94a0020f4 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index 51a12a114de18aca41f7fa4d2e6fbaf60ad24f57..f560b33952f815ef5996d7438e33a0f8cbe7f973 100644 (file)
@@ -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);
 }
index ea7905bbc2d3e292193310f4482df9d52a0e3f88..4c1d01232aa50c38b7fc6c780777ad14bb1793b3 100644 (file)
@@ -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;
index 63d064d24d3b88d4cc641faa9fa3feee68aaef03..a791013fbe946c26562a8db0e1e3df5749151c43 100644 (file)
@@ -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 (file)
index 0000000..4b3ac72
--- /dev/null
@@ -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 (file)
index 0000000..18e51ab
--- /dev/null
@@ -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");
+}
+