use package core;
old_va_test :: proc (prefix: string, va: ..i32) {
+ println(prefix);
for v: va do println(v);
}
new_va_test :: proc (prefix: string, va: ...) {
println(prefix);
- for i: 0 .. 2 {
+ for i: 0 .. va.count {
x : i32;
vararg_get(va, ^x);
println(x);
}
-
- for i: 0 .. 2 {
- x : f32;
- vararg_get(va, ^x);
- println(x);
- }
}
main :: proc (args: [] cstring) {
new_va_test("foo", 1, 2, 3.0f, 5.0f);
+ old_va_test("bar", 1);
}
-
-// Things needed to make the above work"
-/*
- 1. A RawVarArg type in the type system
- 2. Parsing '...' as a rawvararg
- 3. Typechecking is disabled for arguments in a rawvararg
- 4. RawVarArg is treated as a pointer
-*/
ArgState arg_state = AS_Expecting_Exact;
i32 arg_pos = 0;
- while (arg_pos < bh_arr_length(arg_arr)) {
+ while (1) {
switch (arg_state) {
case AS_Expecting_Exact: {
if (arg_pos >= callee->type->Function.param_count) goto type_checking_done;
continue;
}
+ if (arg_pos >= bh_arr_length(arg_arr)) goto type_checking_done;
if (!type_check_or_auto_cast(arg_arr[arg_pos]->value, formal_params[arg_pos])) {
onyx_report_error(arg_arr[arg_pos]->token->pos,
"The function '%b' expects a value of type '%s' for %d%s parameter, got '%s'.",
}
case AS_Expecting_Typed_VA: {
+ call->va_kind = VA_Kind_Typed;
+
+ if (arg_pos >= bh_arr_length(arg_arr)) goto type_checking_done;
if (!type_check_or_auto_cast(arg_arr[arg_pos]->value, variadic_type)) {
onyx_report_error(arg_arr[arg_pos]->token->pos,
"The function '%b' expects a value of type '%s' for the variadic parameter, '%b', got '%s'.",
}
arg_arr[arg_pos]->va_kind = VA_Kind_Typed;
- call->va_kind = VA_Kind_Typed;
break;
}
case AS_Expecting_Untyped_VA: {
- arg_arr[arg_pos]->va_kind = VA_Kind_Untyped;
call->va_kind = VA_Kind_Untyped;
+
+ if (arg_pos >= bh_arr_length(arg_arr)) goto type_checking_done;
+ arg_arr[arg_pos]->va_kind = VA_Kind_Untyped;
break;
}
}
type_checking_done:
- if (arg_pos < callee->type->Function.param_count) {
+ if (arg_pos < callee->type->Function.needed_param_count) {
onyx_report_error(call->token->pos, "Too few arguments to function call.");
return 1;
}
switch (call->va_kind) {
case VA_Kind_Typed: {
- WID(WI_GLOBAL_GET, vararg_offset);
+ WID(WI_GLOBAL_GET, stack_top_idx);
+ WID(WI_I32_CONST, vararg_offset);
+ WI(WI_I32_ADD);
WID(WI_I32_CONST, vararg_count);
break;
}