bugfixes with varargs
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 26 Sep 2020 19:54:34 +0000 (14:54 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sat, 26 Sep 2020 19:54:34 +0000 (14:54 -0500)
onyx
progs/vararg_test.onyx
src/onyxchecker.c
src/onyxwasm.c

diff --git a/onyx b/onyx
index 0c8c465e7c6380edb449ada383101e4bf0aecedf..6c79fdedb1c7f90d473dee5061b21196c5ee8391 100755 (executable)
Binary files a/onyx and b/onyx differ
index aac4c49797bcfd2916231a4ed1e0857412537cf7..c66dc106798900714e5faf2b62942700a638a6d8 100644 (file)
@@ -5,6 +5,7 @@ package main
 use package core;
 
 old_va_test :: proc (prefix: string, va: ..i32) {
+    println(prefix);
     for v: va do println(v);
 }
 
@@ -20,27 +21,14 @@ vararg_get :: proc (va: vararg, ret: ^$T) -> bool {
 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
-*/
index 9e298475558bd55a805199ed985e99890bce2377..ebe8cadd5fe117258ec87ed83bab1e14c28bcf08 100644 (file)
@@ -430,7 +430,7 @@ b32 check_call(AstCall* call) {
 
     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;
@@ -448,6 +448,7 @@ b32 check_call(AstCall* call) {
                     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'.",
@@ -464,6 +465,9 @@ b32 check_call(AstCall* call) {
             }
 
             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'.",
@@ -476,13 +480,14 @@ b32 check_call(AstCall* call) {
                 }
 
                 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;
             }
         }
@@ -492,7 +497,7 @@ b32 check_call(AstCall* call) {
 
 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;
     }
index 60d9e95cec626e34714c3892bf2cf13fc3c2ccd7..3d055bc6cf06eb410638daf6f1a082dda1e798fe 100644 (file)
@@ -1360,7 +1360,9 @@ EMIT_FUNC(call, AstCall* call) {
 
     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;
         }