// ---------------------------------
// 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;
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);
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);
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;
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);
}
}
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
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;
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);
} 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);
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) {
--- /dev/null
+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.
--- /dev/null
+#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");
+}
+