refactored a lot of the argument code for calls and struct literals
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 15 Jan 2021 15:45:25 +0000 (09:45 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 15 Jan 2021 15:45:25 +0000 (09:45 -0600)
13 files changed:
bin/onyx
include/onyxastnodes.h
include/onyxlex.h
onyx.exe
src/onyx.c
src/onyxastnodes.c
src/onyxchecker.c
src/onyxclone.c
src/onyxlex.c
src/onyxparser.c
src/onyxsymres.c
src/onyxutils.c
src/onyxwasm.c

index 3458061f662a6d989b108a51b770380675c72e7d..509b8300b1e71d880af1a20612117159e269e37f 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
index 3db3515480a788c4890dbb7f6d1be3649fd56b14..7fe4c937df26c04e122449dd0544beac6cbd1951 100644 (file)
@@ -14,7 +14,6 @@ typedef struct AstNumLit AstNumLit;
 typedef struct AstStrLit AstStrLit;
 typedef struct AstLocal AstLocal;
 typedef struct AstCall AstCall;
-typedef struct AstIntrinsicCall AstIntrinsicCall;
 typedef struct AstArgument AstArgument;
 typedef struct AstAddressOf AstAddressOf;
 typedef struct AstDereference AstDereference;
@@ -436,6 +435,13 @@ typedef enum VarArgKind {
     VA_Kind_Untyped,
 } VarArgKind;
 
+typedef struct Arguments Arguments;
+struct Arguments {
+    bh_arr(AstTyped *) values;
+    bh_arr(AstNamedValue *) named_values;
+};
+
+
 // Base Nodes
 #define AstNode_base \
     AstKind kind;             \
@@ -462,7 +468,7 @@ struct AstNode { AstNode_base; };
 struct AstTyped { AstTyped_base; };
 
 // Expression Nodes
-struct AstNamedValue    { AstTyped_base; AstNode* value; };
+struct AstNamedValue    { AstTyped_base; AstTyped* value; };
 struct AstBinaryOp      { AstTyped_base; BinaryOp operation; AstTyped *left, *right; };
 struct AstUnaryOp       { AstTyped_base; UnaryOp operation; AstTyped *expr; };
 struct AstNumLit        { AstTyped_base; union { i32 i; i64 l; f32 f; f64 d; } value; };
@@ -481,8 +487,7 @@ struct AstStructLiteral {
 
     AstTyped *stnode;
 
-    bh_arr(AstNamedValue *) named_values;
-    bh_arr(AstTyped *) values;
+    Arguments args;
 };
 struct AstArrayLiteral {
     AstTyped_base;
@@ -510,20 +515,12 @@ struct AstRangeLiteral {
 struct AstCall {
     AstTyped_base;
 
-    bh_arr(AstArgument *) arg_arr;
-    bh_arr(AstNamedValue *) named_args; // '.value' is a pointer to AstArgument.
-
-    AstTyped *callee;
+    Arguments args;
 
-    VarArgKind va_kind;
-};
-struct AstIntrinsicCall {
-    AstTyped_base;
-
-    bh_arr(AstArgument *) arg_arr;
-    bh_arr(AstNamedValue *) named_args;
-
-    OnyxIntrinsic intrinsic;
+    union {
+        AstTyped *callee;
+        OnyxIntrinsic intrinsic;
+    };
 
     VarArgKind va_kind;
 };
@@ -823,12 +820,6 @@ struct AstPackage {
     Package* package;
 };
 
-typedef struct Arguments Arguments;
-struct Arguments {
-    bh_arr(AstNode *) values;
-    bh_arr(AstNamedValue *) named_values;
-};
-
 extern AstNode empty_node;
 
 typedef enum EntityState {
@@ -999,8 +990,6 @@ Type* resolve_expression_type(AstTyped* node);
 b32 cast_is_legal(Type* from_, Type* to_, char** err_msg);
 char* get_function_name(AstFunction* func);
 
-b32 fill_in_arguments(bh_arr(AstNode *) values, bh_arr(AstNamedValue *) named_values, AstNode* provider, char** err_msg);
-
 AstNumLit* make_int_literal(bh_allocator a, i64 value);
 AstNumLit* make_float_literal(bh_allocator a, f64 value);
 AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right);
@@ -1009,6 +998,12 @@ AstFieldAccess* make_field_access(bh_allocator a, AstTyped* node, char* field);
 AstLocal* make_local(bh_allocator a, OnyxToken* token, AstType* type_node);
 AstNode* make_symbol(bh_allocator a, OnyxToken* sym);
 
+void arguments_initialize(Arguments* args);
+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);
+
 typedef enum PolyProcLookupMethod {
     PPLM_By_Call,
     PPLM_By_Function_Type,
index 645a5c93df2c5d787a0c03e95796ee6f357b831e..4d7bb2806a026750c3b5c2c97eeb1adf80cf678f 100644 (file)
@@ -112,5 +112,6 @@ void onyx_tokenizer_free(OnyxTokenizer* tokenizer);
 void onyx_lex_tokens(OnyxTokenizer* tokenizer);
 
 b32 token_equals(OnyxToken* tkn1, OnyxToken* tkn2);
+b32 token_text_equals(OnyxToken* tkn, char* text);
 
 #endif
index e64525879973b013847facbac4caf914ebb744f3..19e6f3f2db048aea85b5afcd3c792c9feaa6f442 100644 (file)
Binary files a/onyx.exe and b/onyx.exe differ
index 67164bac677558fce37865d5f6da7855c629bf21..64e9a6231b56cbc9712c88b5e9003f4a342a0def 100644 (file)
@@ -438,8 +438,9 @@ static CompilerProgress process_source_file(CompilerState* compiler_state, char*
     bh_table_put(bh_file_contents, compiler_state->loaded_files, (char *) filename, fc);
     fc = bh_table_get(bh_file_contents, compiler_state->loaded_files, (char *) filename);
 
-    if (compiler_state->options->verbose_output == 2)
-        bh_printf("Processing source file:    %s\n", file.filename);
+    if (compiler_state->options->verbose_output == 2) {
+        bh_printf("Processing source file:    %s (%d bytes)\n", file.filename, fc.length);
+    }
 
     ParseResults results = parse_source_file(compiler_state, &fc);
     merge_parse_results(compiler_state, &results);
index bb41ae4b6e6b481801a49b125db743e0334d87ff..ba52da93413f82fe56e5726e0a34f60eebb91d78 100644 (file)
@@ -665,3 +665,45 @@ AstNode* make_symbol(bh_allocator a, OnyxToken* sym) {
     symbol->token = sym;
     return symbol;
 }
+
+void arguments_initialize(Arguments* args) {
+    if (args->values == NULL)       bh_arr_new(global_heap_allocator, args->values, 2);
+    if (args->named_values == NULL) bh_arr_new(global_heap_allocator, args->named_values, 2);
+
+    // CLEANUP: I'm not sure if I need to initialize these to NULL values, but it doesn't hurt.
+    fori (i, 0, 2) {
+        args->values[i] = NULL;
+        args->named_values[i] = NULL;
+    }
+}
+
+void arguments_ensure_length(Arguments* args, u32 count) {
+    // Make the array big enough
+    bh_arr_grow(args->values, count);
+
+    // NULL initialize the new elements
+    fori (i, bh_arr_length(args->values), count) args->values[i] = NULL;
+
+    // Set the actual length to the count, but never let it decrease in size
+    bh_arr_set_length(args->values, bh_max(count, (u32) bh_arr_length(args->values)));
+}
+
+// In clone, the named_values are not copied. This is used in match_overloaded_function since it doesn't need them to be copied.
+void arguments_clone(Arguments* dest, Arguments* src) {
+    dest->named_values = src->named_values;
+    dest->values = bh_arr_copy(global_heap_allocator, src->values);
+}
+
+void arguments_deep_clone(bh_allocator a, Arguments* dest, Arguments* src) {
+    dest->values = NULL;
+    dest->named_values = NULL;
+
+    bh_arr_new(global_heap_allocator, dest->named_values, bh_arr_length(src->named_values));
+    bh_arr_new(global_heap_allocator, dest->values, bh_arr_length(src->values));
+
+    bh_arr_each(AstNamedValue *, nv, src->named_values)
+        bh_arr_push(dest->named_values, (AstNamedValue *) ast_clone(a, *nv));
+
+    bh_arr_each(AstTyped *, val, src->values)
+        bh_arr_push(dest->values, (AstTyped *) ast_clone(a, (AstNode *) *val));
+}
\ No newline at end of file
index f648dc9b1f8db2d7769fd2a4c78b8d89e14176ff..7d93373146c9f75b7bbed6ad13c590cfe82d284f 100644 (file)
@@ -296,46 +296,38 @@ CheckStatus check_switch(AstSwitch* switchnode) {
     return 0;
 }
 
-static AstTyped* match_overloaded_function(bh_arr(AstTyped *) arg_arr, bh_arr(AstNamedValue *) named_values, bh_arr(AstTyped *) overloads) {
+static AstTyped* match_overloaded_function(Arguments* args, bh_arr(AstTyped *) overloads) {
     bh_arr_each(AstTyped *, node, overloads) {
         AstFunction* overload = NULL;
         if ((*node)->kind == Ast_Kind_Function) {
             overload = (AstFunction *) *node;
         }
         else if ((*node)->kind == Ast_Kind_Polymorphic_Proc) {
-            Arguments args;
-            args.values       = (bh_arr(AstNode*)) arg_arr;
-            args.named_values = named_values;
-
-            overload = polymorphic_proc_build_only_header((AstPolyProc *) *node, PPLM_By_Arguments, &args);
+            overload = polymorphic_proc_build_only_header((AstPolyProc *) *node, PPLM_By_Arguments, args);
         }
 
         if (overload == NULL) continue;
 
-        bh_arr(AstTyped *) new_arg_arr = arg_arr;
-        if (named_values != NULL && bh_arr_length(named_values) > 0) {
-            new_arg_arr = NULL;
-            bh_arr_new(global_heap_allocator, new_arg_arr, bh_arr_length(arg_arr) + bh_arr_length(named_values));
-            fori (i, 0, bh_arr_length(arg_arr)) new_arg_arr[i] = arg_arr[i];
-            fori (i, 0, bh_arr_length(named_values)) new_arg_arr[i + bh_arr_length(arg_arr)] = NULL;
-            bh_arr_set_length(new_arg_arr, bh_arr_length(arg_arr) + bh_arr_length(named_values));
+        Arguments* args_to_use = args;
+        if (args->named_values != NULL && bh_arr_length(args->named_values) > 0) {
+            args_to_use = bh_alloc_item(global_scratch_allocator, Arguments);
+
+            arguments_clone(args_to_use, args);
+            arguments_ensure_length(args_to_use, bh_arr_length(args->values) + bh_arr_length(args->named_values));
 
-            b32 values_place_correctly = fill_in_arguments(
-                (bh_arr(AstNode *)) new_arg_arr,
-                named_values,
-                (AstNode *) overload,
-                NULL);
+            b32 values_place_correctly = fill_in_arguments(args_to_use, (AstNode *) overload, NULL);
 
             if (!values_place_correctly) goto no_match;
         }
 
         fill_in_type((AstTyped *) overload);
+
         TypeFunction* ol_type = &overload->type->Function;
-        if (bh_arr_length(new_arg_arr) < (i32) ol_type->needed_param_count) continue;
+        if (bh_arr_length(args_to_use->values) < (i32) ol_type->needed_param_count) continue;
 
         i32 param_left = ol_type->param_count;
         Type** param_type = ol_type->params;
-        bh_arr_each(AstTyped*, arg, new_arg_arr) {
+        bh_arr_each(AstTyped*, arg, args_to_use->values) {
             if (param_left == 0) goto no_match;
             param_left--;
 
@@ -357,11 +349,13 @@ static AstTyped* match_overloaded_function(bh_arr(AstTyped *) arg_arr, bh_arr(As
         return (AstTyped *) *node;
 
 no_match:
-        if (named_values != NULL && bh_arr_length(named_values) > 0)
-            bh_arr_free(new_arg_arr);
+        if (args->named_values != NULL && bh_arr_length(args->named_values) > 0) {
+            bh_arr_free(args_to_use->values);
+        }
 
         continue;
     }
+
     return NULL;
 }
 
@@ -369,23 +363,23 @@ static void report_unable_to_match_overload(AstCall* call) {
     char* arg_str = bh_alloc(global_scratch_allocator, 1024);
     arg_str[0] = '\0';
 
-    bh_arr_each(AstArgument *, arg, call->arg_arr) {
-        strncat(arg_str, type_get_name((*arg)->value->type), 1023);
+    bh_arr_each(AstTyped *, arg, call->args.values) {
+        strncat(arg_str, type_get_name((*arg)->type), 1023);
 
-        if (arg != &bh_arr_last(call->arg_arr))
+        if (arg != &bh_arr_last(call->args.values))
             strncat(arg_str, ", ", 1023);
     }
 
-    if (bh_arr_length(call->named_args) > 0) {
-        bh_arr_each(AstNamedValue *, named_value, call->named_args) { 
+    if (bh_arr_length(call->args.named_values) > 0) {
+        bh_arr_each(AstNamedValue *, named_value, call->args.named_values) { 
             token_toggle_end((*named_value)->token);
             strncat(arg_str, (*named_value)->token->text, 1023);
             token_toggle_end((*named_value)->token);
 
             strncat(arg_str, "=", 1023);
-            strncat(arg_str, type_get_name(((AstTyped *) (*named_value)->value)->type), 1023); // CHECK: this might say 'unknown'.
+            strncat(arg_str, type_get_name((*named_value)->value->type), 1023); // CHECK: this might say 'unknown'.
 
-            if (named_value != &bh_arr_last(call->named_args))
+            if (named_value != &bh_arr_last(call->args.named_values))
                 strncat(arg_str, ", ", 1023);
         }
     }
@@ -395,9 +389,18 @@ static void report_unable_to_match_overload(AstCall* call) {
     bh_free(global_scratch_allocator, arg_str);
 }
 
+CheckStatus check_arguments(Arguments* args) {
+    bh_arr_each(AstTyped *, actual, args->values)
+        CHECK(expression, actual);
+
+    bh_arr_each(AstNamedValue *, named_value, args->named_values)
+        CHECK(expression, &(*named_value)->value);
+
+    return Check_Success;
+}
 
 CheckStatus check_argument(AstArgument** parg) {
-    CHECK(expression, (AstTyped **) parg);
+    CHECK(expression, &(*parg)->value);
     (*parg)->type = (*parg)->value->type;
 
     if ((*parg)->value->kind == Ast_Kind_Overloaded_Function) {
@@ -433,18 +436,10 @@ CheckStatus check_call(AstCall* call) {
     CHECK(expression, &call->callee);
     AstFunction* callee = (AstFunction *) call->callee;
 
-    // NOTE: Check arguments
-    bh_arr_each(AstArgument *, actual, call->arg_arr)
-        CHECK(argument, actual);
-
-    bh_arr_each(AstNamedValue *, named_value, call->named_args)
-        CHECK(argument, (AstArgument **) &(*named_value)->value);
+    check_arguments(&call->args);
 
     if (callee->kind == Ast_Kind_Overloaded_Function) {
-        call->callee = match_overloaded_function(
-            (bh_arr(AstTyped *)) call->arg_arr,
-            call->named_args,
-            ((AstOverloadedFunction *) callee)->overloads);
+        call->callee = match_overloaded_function(&call->args, ((AstOverloadedFunction *) callee)->overloads);
 
         if (call->callee == NULL) {
             report_unable_to_match_overload(call);
@@ -488,15 +483,13 @@ CheckStatus check_call(AstCall* call) {
             non_vararg_param_count--;
 
         i32 arg_count = bh_max(
-            bh_arr_length(call->arg_arr) + bh_arr_length(call->named_args),
+            bh_arr_length(call->args.values) + bh_arr_length(call->args.named_values),
             non_vararg_param_count);
 
-        bh_arr_grow(call->arg_arr, arg_count);
-        fori (i, bh_arr_length(call->arg_arr), arg_count) call->arg_arr[i] = NULL;
-        bh_arr_set_length(call->arg_arr, arg_count);
+        arguments_ensure_length(&call->args, arg_count);
 
         char* err_msg = NULL;
-        fill_in_arguments((AstNode **) call->arg_arr, call->named_args, (AstNode *) callee, &err_msg);
+        fill_in_arguments(&call->args, (AstNode *) callee, &err_msg);
 
         if (err_msg != NULL) {
             onyx_report_error(call->token->pos, err_msg);
@@ -504,7 +497,7 @@ CheckStatus check_call(AstCall* call) {
         }
     }
 
-    bh_arr(AstArgument *) arg_arr = call->arg_arr;
+    bh_arr(AstArgument *) arg_arr = (bh_arr(AstArgument *)) call->args.values;
     bh_arr_each(AstArgument *, arg, arg_arr) {
         if (*arg != NULL) continue;
 
@@ -522,7 +515,7 @@ CheckStatus check_call(AstCall* call) {
         char* intr_name = callee->intrinsic_name->text;
 
         if (bh_table_has(OnyxIntrinsic, intrinsic_table, intr_name)) {
-            ((AstIntrinsicCall *)call)->intrinsic = bh_table_get(OnyxIntrinsic, intrinsic_table, intr_name);
+            call->intrinsic = bh_table_get(OnyxIntrinsic, intrinsic_table, intr_name);
 
         } else {
             onyx_report_error(callee->token->pos, "Intrinsic not supported, '%s'.", intr_name);
@@ -623,7 +616,6 @@ type_checking_done:
     }
 
     callee->flags |= Ast_Flag_Function_Used;
-    call->arg_arr = arg_arr;
 
     return Check_Success;
 }
@@ -787,14 +779,14 @@ CheckStatus check_binaryop_bool(AstBinaryOp** pbinop) {
 static AstCall* binaryop_try_operator_overload(AstBinaryOp* binop) {
     if (bh_arr_length(operator_overloads[binop->operation]) == 0) return NULL;
 
-    bh_arr(AstTyped *) args = NULL;
-    bh_arr_new(global_heap_allocator, args, 2);
-    bh_arr_push(args, binop->left);
-    bh_arr_push(args, binop->right);
+    Arguments args = ((Arguments) { NULL, NULL });
+    bh_arr_new(global_heap_allocator, args.values, 2);
+    bh_arr_push(args.values, binop->left);
+    bh_arr_push(args.values, binop->right);
 
-    AstTyped* overload = match_overloaded_function(args, NULL, operator_overloads[binop->operation]);
+    AstTyped* overload = match_overloaded_function(&args, operator_overloads[binop->operation]);
     if (overload == NULL) {
-        bh_arr_free(args);
+        bh_arr_free(args.values);
         return NULL;
     }
 
@@ -803,11 +795,10 @@ static AstCall* binaryop_try_operator_overload(AstBinaryOp* binop) {
     implicit_call->callee = overload;
     implicit_call->va_kind = VA_Kind_Not_VA;
 
-    bh_arr_each(AstTyped *, arg, args)
+    bh_arr_each(AstTyped *, arg, args.values)
         *arg = (AstTyped *) make_argument(semstate.node_allocator, *arg);
 
-    implicit_call->arg_arr = (AstArgument **) args;
-    implicit_call->named_args = NULL;
+    implicit_call->args = args;
     return implicit_call;
 }
 
@@ -1035,17 +1026,15 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) {
 
     i32 mem_count = type_structlike_mem_count(sl->type);
 
-    bh_arr_grow(sl->values, mem_count);
-    fori (i, bh_arr_length(sl->values), mem_count) sl->values[i] = NULL;
-    bh_arr_set_length(sl->values, mem_count);
+    arguments_ensure_length(&sl->args, mem_count);
 
     char* err_msg = NULL;
-    if (!fill_in_arguments((bh_arr(AstNode *)) sl->values, sl->named_values, (AstNode *) sl, &err_msg)) {
+    if (!fill_in_arguments(&sl->args, (AstNode *) sl, &err_msg)) {
         onyx_report_error(sl->token->pos, err_msg);
         
-        bh_arr_each(AstTyped *, value, sl->values) {
+        bh_arr_each(AstTyped *, value, sl->args.values) {
             if (*value == NULL) {
-                i32 member_idx = value - sl->values; // Pointer subtraction hack
+                i32 member_idx = value - sl->args.values; // Pointer subtraction hack
 
                 onyx_report_error(sl->token->pos,
                     "Value not given for %d%s member, '%s'.",
@@ -1057,7 +1046,7 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) {
         return Check_Error;
     }
 
-    AstTyped** actual = sl->values;
+    AstTyped** actual = sl->args.values;
     StructMember smem;
 
     b32 all_comptime = 1;
@@ -1381,8 +1370,9 @@ CheckStatus check_expression(AstTyped** pexpr) {
         case Ast_Kind_Binary_Op: retval = check_binaryop((AstBinaryOp **) pexpr, 0); break;
         case Ast_Kind_Unary_Op:  retval = check_unaryop((AstUnaryOp **) pexpr); break;
 
-        case Ast_Kind_Call:  retval = check_call((AstCall *) expr); break;
-        case Ast_Kind_Block: retval = check_block((AstBlock *) expr); break;
+        case Ast_Kind_Call:     retval = check_call((AstCall *) expr); break;
+        case Ast_Kind_Argument: retval = check_argument((AstArgument **) pexpr); break;
+        case Ast_Kind_Block:    retval = check_block((AstBlock *) expr); break;
 
         case Ast_Kind_Symbol:
             onyx_report_error(expr->token->pos,
@@ -1416,10 +1406,6 @@ CheckStatus check_expression(AstTyped** pexpr) {
             }
             break;
 
-        case Ast_Kind_Argument:
-            retval = check_expression(&((AstArgument *) expr)->value);
-            break;
-
         case Ast_Kind_NumLit:
             // NOTE: Literal types should have been decided in the parser (for now).
             assert(expr->type != NULL);
index 14444d12a3c6c57295237fbcd9955f0dc1139242..07d8d678f63afe4c0fb967200bd8ccfc7ae5ca8e 100644 (file)
@@ -67,7 +67,7 @@ static inline i32 ast_kind_to_size(AstNode* node) {
         case Ast_Kind_Param: return sizeof(AstLocal);
         case Ast_Kind_Argument: return sizeof(AstArgument);
         case Ast_Kind_Call: return sizeof(AstCall);
-        case Ast_Kind_Intrinsic_Call: return sizeof(AstIntrinsicCall);
+        case Ast_Kind_Intrinsic_Call: return sizeof(AstCall);
         case Ast_Kind_Return: return sizeof(AstReturn);
         case Ast_Kind_Address_Of: return sizeof(AstAddressOf);
         case Ast_Kind_Dereference: return sizeof(AstDereference);
@@ -91,6 +91,7 @@ static inline i32 ast_kind_to_size(AstNode* node) {
         case Ast_Kind_Switch_Case: return sizeof(AstSwitchCase);
         case Ast_Kind_Directive_Solidify: return sizeof(AstDirectiveSolidify);
         case Ast_Kind_Compound: return sizeof(AstCompound);
+        case Ast_Kind_Named_Value: return sizeof(AstNamedValue);
         case Ast_Kind_Count: return 0;
        }
 
@@ -145,11 +146,7 @@ AstNode* ast_clone(bh_allocator a, void* n) {
                        break;
 
                case Ast_Kind_Call:
-            ((AstCall *) nn)->arg_arr = NULL;
-            bh_arr_new(global_heap_allocator, ((AstCall *) nn)->arg_arr, bh_arr_length(((AstCall *) node)->arg_arr));
-            bh_arr_each(AstArgument *, arg, ((AstCall *) node)->arg_arr) {
-                bh_arr_push(((AstCall *) nn)->arg_arr, (AstArgument *) ast_clone(a, *arg));
-            }
+            arguments_deep_clone(a, &((AstCall *) nn)->args, &((AstCall *) node)->args);
                        break;
 
                case Ast_Kind_Argument:
@@ -188,17 +185,7 @@ AstNode* ast_clone(bh_allocator a, void* n) {
 
                        dt->stnode = (AstTyped *) ast_clone(a, st->stnode);
 
-                       dt->named_values = NULL;
-                       dt->values = NULL;
-                       bh_arr_new(global_heap_allocator, dt->named_values, bh_arr_length(st->named_values));
-                       bh_arr_new(global_heap_allocator, dt->values, bh_arr_length(st->values));
-
-                       bh_arr_each(AstNamedValue *, nv, st->named_values)
-                               bh_arr_push(dt->named_values, (AstNamedValue *) ast_clone(a, *nv));
-
-                       bh_arr_each(AstTyped *, val, st->values)
-                               bh_arr_push(dt->values, (AstTyped *) ast_clone(a, *val));
-
+            arguments_deep_clone(a, &dt->args, &st->args);
                        break;
                }
 
@@ -435,6 +422,11 @@ AstNode* ast_clone(bh_allocator a, void* n) {
             }
             break;
         }
+
+        case Ast_Kind_Named_Value: {
+            ((AstNamedValue *) nn)->value = (AstTyped *) ast_clone(a, ((AstNamedValue *) node)->value);
+            break;
+        }
        }
 
        return nn;
index c88a31a47cab5e0cec8f87e3a53853931860a902..0f60262b64141811ceeb6b06ac9858c326c7820b 100644 (file)
@@ -445,3 +445,13 @@ b32 token_equals(OnyxToken* tkn1, OnyxToken* tkn2) {
         if (tkn1->text[i] != tkn2->text[i]) return 0;
     return 1;
 }
+
+b32 token_text_equals(OnyxToken* tkn, char* text) {
+    i32 text_len = strlen(text);
+    if (tkn->length != text_len) return 0;
+
+    fori (i, 0, tkn->length)
+        if (tkn->text[i] != text[i]) return 0;
+        
+    return 1;
+}
index c415e82f4625d405dafbb984531ef17ad60dff2f..57745c815582017f78be16be4318cedea20414f8 100644 (file)
@@ -27,8 +27,7 @@ static AstNumLit*     parse_int_literal(OnyxParser* parser);
 static AstNumLit*     parse_float_literal(OnyxParser* parser);
 static b32            parse_possible_struct_literal(OnyxParser* parser, AstTyped* left, AstTyped** ret);
 static b32            parse_possible_array_literal(OnyxParser* parser, AstTyped* left, AstTyped** ret);
-static void           parse_values_and_named_values(OnyxParser* parser, TokenType end_token,
-                                                    bh_arr(AstNode *)* values, bh_arr(AstNamedValue *)* named_values);
+static void           parse_arguments(OnyxParser* parser, TokenType end_token, Arguments* args);
 static AstTyped*      parse_factor(OnyxParser* parser);
 static AstTyped*      parse_compound_assignment(OnyxParser* parser, AstTyped* lhs);
 static AstTyped*      parse_compound_expression(OnyxParser* parser, b32 assignment_allowed);
@@ -176,19 +175,12 @@ static b32 parse_possible_struct_literal(OnyxParser* parser, AstTyped* left, Ast
     sl->token = parser->curr;
     sl->stnode = left;
 
-    bh_arr_new(global_heap_allocator, sl->values, 4);
-    bh_arr_new(global_heap_allocator, sl->named_values, 4);
-    fori (i, 0, 4) {
-        sl->values[i] = NULL;
-        sl->named_values[i] = NULL;
-    }
+    arguments_initialize(&sl->args);
 
     expect_token(parser, '.');
     expect_token(parser, '{');
 
-    parse_values_and_named_values(parser, '}',
-        (bh_arr(AstNode *)*) &sl->values,
-        (bh_arr(AstNamedValue *)*) &sl->named_values);
+    parse_arguments(parser, '}', &sl->args);
 
     *ret = (AstTyped *) sl;
     return 1;
@@ -222,11 +214,7 @@ static b32 parse_possible_array_literal(OnyxParser* parser, AstTyped* left, AstT
     return 1;
 }
 
-static void parse_values_and_named_values(OnyxParser* parser, TokenType end_token,
-                                          bh_arr(AstNode *)* pvalues, bh_arr(AstNamedValue *)* pnamed_values) {
-    bh_arr(AstNode *)       values       = *pvalues;
-    bh_arr(AstNamedValue *) named_values = *pnamed_values;
-
+static void parse_arguments(OnyxParser* parser, TokenType end_token, Arguments* args) {
     while (parser->curr->type != end_token) {
         if (parser->hit_unexpected_token) return;
 
@@ -236,13 +224,13 @@ static void parse_values_and_named_values(OnyxParser* parser, TokenType end_toke
 
             AstNamedValue* named_value = make_node(AstNamedValue, Ast_Kind_Named_Value);
             named_value->token = name;
-            named_value->value = (AstNode *) parse_expression(parser, 0);
+            named_value->value = parse_expression(parser, 0);
 
-            bh_arr_push(named_values, named_value);
+            bh_arr_push(args->named_values, named_value);
 
         } else {
-            AstNode* value = (AstNode *) parse_expression(parser, 0);
-            bh_arr_push(values, value);
+            AstTyped* value = parse_expression(parser, 0);
+            bh_arr_push(args->values, value);
         }
 
         if (parser->curr->type != end_token)
@@ -250,9 +238,6 @@ static void parse_values_and_named_values(OnyxParser* parser, TokenType end_toke
     }
 
     expect_token(parser, end_token);
-
-    *pvalues = values;
-    *pnamed_values = named_values; 
 }
 
 // ( <expr> )
@@ -613,19 +598,16 @@ static AstTyped* parse_factor(OnyxParser* parser) {
                 call_node->token = expect_token(parser, '(');
                 call_node->callee = retval;
 
-                bh_arr_new(global_heap_allocator, call_node->arg_arr, 2);
-                bh_arr_new(global_heap_allocator, call_node->named_args, 2);
+                arguments_initialize(&call_node->args);
 
-                parse_values_and_named_values(parser, ')',
-                    (bh_arr(AstNode *) *) &call_node->arg_arr,
-                    &call_node->named_args);
+                parse_arguments(parser, ')', &call_node->args);
 
                 // Wrap expressions in AstArgument
-                bh_arr_each(AstArgument *, arg, call_node->arg_arr)
-                    *arg = make_argument(parser->allocator, (AstTyped *) *arg);
+                bh_arr_each(AstTyped *, arg, call_node->args.values)
+                    *arg = (AstTyped *) make_argument(parser->allocator, *arg);
 
-                bh_arr_each(AstNamedValue *, named_value, call_node->named_args)
-                    (*named_value)->value = (AstNode *) make_argument(parser->allocator, (AstTyped *) (*named_value)->value);
+                bh_arr_each(AstNamedValue *, named_value, call_node->args.named_values)
+                    (*named_value)->value = (AstTyped *) make_argument(parser->allocator, (AstTyped *) (*named_value)->value);
 
                 retval = (AstTyped *) call_node;
                 break;
index acb7c988358e2b96d891b9e138bfed713cce927a..fd30f2a49fe0bba43688c92c3acbd9de27f5c8f6 100644 (file)
@@ -236,15 +236,19 @@ static void symres_local(AstLocal** local, b32 add_to_block_locals) {
         symbol_introduce(semstate.curr_scope, (*local)->token, (AstNode *) *local);
 }
 
+static void symres_arguments(Arguments* args) {
+    bh_arr_each(AstTyped *, arg, args->values)
+        symres_expression(arg);
+
+    bh_arr_each(AstNamedValue *, named_arg, args->named_values)
+        symres_expression(&(*named_arg)->value);
+}
+
 static void symres_call(AstCall* call) {
     symres_expression((AstTyped **) &call->callee);
     if (call->callee == NULL) return;
 
-    bh_arr_each(AstArgument *, arg, call->arg_arr)
-        symres_statement((AstNode **) arg);
-
-    bh_arr_each(AstNamedValue *, named_arg, call->named_args)
-        symres_statement(&(*named_arg)->value);
+    symres_arguments(&call->args);
 }
 
 static void symres_size_of(AstSizeOf* so) {
@@ -301,8 +305,8 @@ static void symres_pipe(AstBinaryOp** pipe) {
 
     if ((*pipe)->left == NULL) return;
 
-    bh_arr_insertn(call_node->arg_arr, 0, 1);
-    call_node->arg_arr[0] = make_argument(semstate.node_allocator, (*pipe)->left);
+    bh_arr_insertn(call_node->args.values, 0, 1);
+    call_node->args.values[0] = (AstTyped *) make_argument(semstate.node_allocator, (*pipe)->left);
     call_node->next = (*pipe)->next;
 
     // NOTE: Not a BinaryOp node
@@ -326,19 +330,7 @@ static void symres_struct_literal(AstStructLiteral* sl) {
     while (sl->type_node->kind == Ast_Kind_Type_Alias)
         sl->type_node = ((AstTypeAlias *) sl->type_node)->to;
 
-    if (sl->values != NULL) {
-        bh_arr_each(AstTyped *, expr, sl->values) {
-            if (*expr == NULL) onyx_report_error(sl->token->pos, "Some kind of error occured with this struct literal.");
-            else               symres_expression(expr);
-        }
-    }
-
-    if (sl->named_values != NULL) {
-        bh_arr_each(AstNamedValue *, smem, sl->named_values) {
-            if ((*smem)->value == NULL) onyx_report_error(sl->token->pos, "Some kind of error occured with this struct literal.");
-            else                        symres_expression((AstTyped **) &(*smem)->value);
-        }
-    }
+    symres_arguments(&sl->args);
 }
 
 static void symres_array_literal(AstArrayLiteral* al) {
@@ -376,6 +368,7 @@ static void symres_expression(AstTyped** expr) {
 
         case Ast_Kind_Unary_Op:     symres_unaryop((AstUnaryOp **) expr); break;
         case Ast_Kind_Call:         symres_call((AstCall *) *expr); break;
+        case Ast_Kind_Argument:     symres_expression(&((AstArgument *) *expr)->value); break;
         case Ast_Kind_Block:        symres_block((AstBlock *) *expr); break;
         case Ast_Kind_Address_Of:   symres_expression(&((AstAddressOf *)(*expr))->expr); break;
         case Ast_Kind_Dereference:  symres_expression(&((AstDereference *)(*expr))->expr); break;
index a0a274f147b810901d2fdd417c08d4012c98631d..21306d1c48ee265f6a356cb16c8c0b6db6eefcd4 100644 (file)
@@ -354,7 +354,7 @@ static PolySolveResult solve_poly_type(AstNode* target, AstType* type_expr, Type
 }
 
 static Type* lookup_actual_type_in_arguments(AstPolyProc* pp, AstPolyParam* param, Arguments* args, char** err_msg) {
-    bh_arr(AstNode *) arg_arr = args->values;
+    bh_arr(AstTyped *) arg_arr = args->values;
     bh_arr(AstNamedValue *) named_values = args->named_values;
 
     if (param->idx >= (u64) bh_arr_length(arg_arr)) {
@@ -366,7 +366,7 @@ static Type* lookup_actual_type_in_arguments(AstPolyProc* pp, AstPolyParam* para
             }
         }
 
-        // nocheckin
+        // CLEANUP
         if (err_msg) *err_msg = "Not enough arguments to polymorphic procedure. This error message may not be entirely right.";
 
     } else {
@@ -395,11 +395,9 @@ static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLo
         Type* actual_type = NULL;
 
         if (pp_lookup == PPLM_By_Call) {
-            Arguments args;
-            args.values = (bh_arr(AstNode *)) ((AstCall *) actual)->arg_arr;
-            args.named_values = ((AstCall *) actual)->named_args;
+            AstCall* call = (AstCall *) actual;
 
-            actual_type = lookup_actual_type_in_arguments(pp, param, &args, err_msg);
+            actual_type = lookup_actual_type_in_arguments(pp, param, &call->args, err_msg);
             if (actual_type == NULL) goto sln_not_found;
         }
 
@@ -858,21 +856,14 @@ static i32 lookup_idx_by_name(AstNode* provider, char* name) {
         case Ast_Kind_Function: {
             AstFunction* func = (AstFunction *) provider;
 
-            // CLEANUP nocheckin
             i32 param_idx = -1;
             i32 idx = 0;
             bh_arr_each(AstParam, param, func->params) {
-                token_toggle_end(param->local->token);
-
-                if (strncmp(param->local->token->text, name, param->local->token->length) == 0) {
+                if (token_text_equals(param->local->token, name)) {
                     param_idx = idx;
-
-                    token_toggle_end(param->local->token);
                     break;
                 }
 
-                token_toggle_end(param->local->token);
-
                 idx++;
             }
 
@@ -915,9 +906,9 @@ static AstNode* lookup_default_value_by_idx(AstNode* provider, i32 idx) {
 
 // NOTE: The values array can be partially filled out, and is the resulting array.
 // Returns if all the values were filled in.
-b32 fill_in_arguments(bh_arr(AstNode *) values, bh_arr(AstNamedValue *) named_values, AstNode* provider, char** err_msg) {
-    if (named_values != NULL) {
-        bh_arr_each(AstNamedValue *, p_named_value, named_values) {
+b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg) {
+    if (args->named_values != NULL) {
+        bh_arr_each(AstNamedValue *, p_named_value, args->named_values) {
             AstNamedValue* named_value = *p_named_value;
 
             token_toggle_end(named_value->token);
@@ -928,23 +919,23 @@ b32 fill_in_arguments(bh_arr(AstNode *) values, bh_arr(AstNamedValue *) named_va
                 return 0;
             }
 
-            assert(idx < bh_arr_length(values));
+            assert(idx < bh_arr_length(args->values));
 
-            if (values[idx] != NULL) {
+            if (args->values[idx] != NULL) {
                 if (err_msg) *err_msg = bh_aprintf(global_heap_allocator, "Multiple values given for parameter named '%s'.", named_value->token->text);
                 token_toggle_end(named_value->token);
                 return 0;
             }
 
-            values[idx] = named_value->value;
+            args->values[idx] = named_value->value;
             token_toggle_end(named_value->token);
         }
     }
 
     b32 success = 1;
-    fori (idx, 0, bh_arr_length(values)) {
-        if (values[idx] == NULL) values[idx] = lookup_default_value_by_idx(provider, idx);
-        if (values[idx] == NULL) success = 0;
+    fori (idx, 0, bh_arr_length(args->values)) {
+        if (args->values[idx] == NULL) args->values[idx] = (AstTyped *) lookup_default_value_by_idx(provider, idx);
+        if (args->values[idx] == NULL) success = 0;
     }
 
     return success;
index bd504314835df2bf5207aa4065609d2ae7c6bead..794a3224fe8c27f3c43f6d86801d8dc234c94e21 100644 (file)
@@ -212,7 +212,7 @@ EMIT_FUNC(deferred_stmts,                AstNode* node);
 EMIT_FUNC(binop,                         AstBinaryOp* binop);
 EMIT_FUNC(unaryop,                       AstUnaryOp* unop);
 EMIT_FUNC(call,                          AstCall* call);
-EMIT_FUNC(intrinsic_call,                AstIntrinsicCall* call);
+EMIT_FUNC(intrinsic_call,                AstCall* call);
 EMIT_FUNC(array_access_location,         AstArrayAccess* aa, u64* offset_return);
 EMIT_FUNC(field_access_location,         AstFieldAccess* field, u64* offset_return);
 EMIT_FUNC(local_location,                AstLocal* local, u64* offset_return);
@@ -1329,8 +1329,8 @@ EMIT_FUNC(call, AstCall* call) {
     u32 vararg_offset = 0xffffffff;
     u64 stack_top_store_local;
 
-    bh_arr_each(AstArgument *, parg, call->arg_arr) {
-        AstArgument* arg = *parg;
+    bh_arr_each(AstTyped *, parg, call->args.values) {
+        AstArgument* arg = (AstArgument *) *parg;
 
         b32 place_on_stack  = 0;
         b32 arg_is_compound = type_is_compound(arg->value->type);
@@ -1463,7 +1463,7 @@ EMIT_FUNC(call, AstCall* call) {
 // little endian integers.
 #define SIMD_INT_CONST_INTRINSIC(type, count) { \
         type* byte_buffer = bh_alloc(mod->extended_instr_alloc, 16); \
-        bh_arr(AstArgument *) arg_arr = call->arg_arr; \
+        bh_arr(AstArgument *) arg_arr = (bh_arr(AstArgument *)) call->args.values; \
         fori (i, 0, count) { \
             if (arg_arr[i]->value->kind != Ast_Kind_NumLit) { \
                 onyx_report_error(arg_arr[i]->token->pos, \
@@ -1499,7 +1499,7 @@ EMIT_FUNC(call, AstCall* call) {
     }
 
 
-EMIT_FUNC(intrinsic_call, AstIntrinsicCall* call) {
+EMIT_FUNC(intrinsic_call, AstCall* call) {
     bh_arr(WasmInstruction) code = *pcode;
 
     b32 place_arguments_normally = 1;
@@ -1523,8 +1523,8 @@ EMIT_FUNC(intrinsic_call, AstIntrinsicCall* call) {
     }
 
     if (place_arguments_normally) {
-        bh_arr_each(AstArgument *, arg, call->arg_arr) {
-            emit_expression(mod, &code, (*arg)->value);
+        bh_arr_each(AstTyped *, arg, call->args.values) {
+            emit_expression(mod, &code, *arg);
         }
     }
 
@@ -1583,7 +1583,7 @@ EMIT_FUNC(intrinsic_call, AstIntrinsicCall* call) {
         case ONYX_INTRINSIC_I64X2_CONST:  SIMD_INT_CONST_INTRINSIC(u64, 2);   break;
         case ONYX_INTRINSIC_F32X4_CONST: {
             f32* byte_buffer = bh_alloc(mod->extended_instr_alloc, 16);
-            bh_arr(AstArgument *) arg_arr = call->arg_arr;
+            bh_arr(AstArgument *) arg_arr = (bh_arr(AstArgument *)) call->args.values;
             fori (i, 0, 4) {
                 if (arg_arr[i]->value->kind != Ast_Kind_NumLit) {
                     onyx_report_error(arg_arr[i]->token->pos,
@@ -1600,7 +1600,7 @@ EMIT_FUNC(intrinsic_call, AstIntrinsicCall* call) {
 
         case ONYX_INTRINSIC_F64X2_CONST: {
             f64* byte_buffer = bh_alloc(mod->extended_instr_alloc, 16);
-            bh_arr(AstArgument *) arg_arr = call->arg_arr;
+            bh_arr(AstArgument *) arg_arr = (bh_arr(AstArgument *)) call->args.values;
             fori (i, 0, 2) {
                 if (arg_arr[i]->value->kind != Ast_Kind_NumLit) {
                     onyx_report_error(arg_arr[i]->token->pos,
@@ -1617,7 +1617,7 @@ EMIT_FUNC(intrinsic_call, AstIntrinsicCall* call) {
 
         case ONYX_INTRINSIC_I8X16_SHUFFLE: {
             u8* byte_buffer = bh_alloc(mod->extended_instr_alloc, 16);
-            bh_arr(AstArgument *) arg_arr = call->arg_arr;
+            bh_arr(AstArgument *) arg_arr = (bh_arr(AstArgument *)) call->args.values;
 
             // NOTE: There are two parameters that have to be outputted before
             // the immediate bytes
@@ -1638,20 +1638,21 @@ EMIT_FUNC(intrinsic_call, AstIntrinsicCall* call) {
             break;
         }
 
-        case ONYX_INTRINSIC_I8X16_EXTRACT_LANE_S: SIMD_EXTRACT_LANE_INSTR(WI_I8X16_EXTRACT_LANE_S, call->arg_arr); break;
-        case ONYX_INTRINSIC_I8X16_EXTRACT_LANE_U: SIMD_EXTRACT_LANE_INSTR(WI_I8X16_EXTRACT_LANE_U, call->arg_arr); break;
-        case ONYX_INTRINSIC_I8X16_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_I8X16_REPLACE_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_I16X8_EXTRACT_LANE_S: SIMD_EXTRACT_LANE_INSTR(WI_I16X8_EXTRACT_LANE_S, call->arg_arr); break;
-        case ONYX_INTRINSIC_I16X8_EXTRACT_LANE_U: SIMD_EXTRACT_LANE_INSTR(WI_I16X8_EXTRACT_LANE_U, call->arg_arr); break;
-        case ONYX_INTRINSIC_I16X8_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_I16X8_REPLACE_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_I32X4_EXTRACT_LANE:   SIMD_EXTRACT_LANE_INSTR(WI_I32X4_EXTRACT_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_I32X4_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_I32X4_REPLACE_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_I64X2_EXTRACT_LANE:   SIMD_EXTRACT_LANE_INSTR(WI_I64X2_EXTRACT_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_I64X2_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_I64X2_REPLACE_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_F32X4_EXTRACT_LANE:   SIMD_EXTRACT_LANE_INSTR(WI_F32X4_EXTRACT_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_F32X4_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_F32X4_REPLACE_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_F64X2_EXTRACT_LANE:   SIMD_EXTRACT_LANE_INSTR(WI_F64X2_EXTRACT_LANE, call->arg_arr); break;
-        case ONYX_INTRINSIC_F64X2_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_F64X2_REPLACE_LANE, call->arg_arr); break;
+        // CLEANUP ALL OF THIS
+        case ONYX_INTRINSIC_I8X16_EXTRACT_LANE_S: SIMD_EXTRACT_LANE_INSTR(WI_I8X16_EXTRACT_LANE_S, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I8X16_EXTRACT_LANE_U: SIMD_EXTRACT_LANE_INSTR(WI_I8X16_EXTRACT_LANE_U, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I8X16_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_I8X16_REPLACE_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I16X8_EXTRACT_LANE_S: SIMD_EXTRACT_LANE_INSTR(WI_I16X8_EXTRACT_LANE_S, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I16X8_EXTRACT_LANE_U: SIMD_EXTRACT_LANE_INSTR(WI_I16X8_EXTRACT_LANE_U, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I16X8_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_I16X8_REPLACE_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I32X4_EXTRACT_LANE:   SIMD_EXTRACT_LANE_INSTR(WI_I32X4_EXTRACT_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I32X4_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_I32X4_REPLACE_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I64X2_EXTRACT_LANE:   SIMD_EXTRACT_LANE_INSTR(WI_I64X2_EXTRACT_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_I64X2_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_I64X2_REPLACE_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_F32X4_EXTRACT_LANE:   SIMD_EXTRACT_LANE_INSTR(WI_F32X4_EXTRACT_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_F32X4_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_F32X4_REPLACE_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_F64X2_EXTRACT_LANE:   SIMD_EXTRACT_LANE_INSTR(WI_F64X2_EXTRACT_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
+        case ONYX_INTRINSIC_F64X2_REPLACE_LANE:   SIMD_REPLACE_LANE_INSTR(WI_F64X2_REPLACE_LANE, ((bh_arr(AstArgument *)) call->args.values)); break;
 
         case ONYX_INTRINSIC_I8X16_SWIZZLE: WI(WI_I8X16_SWIZZLE); break;
         case ONYX_INTRINSIC_I8X16_SPLAT:   WI(WI_I8X16_SPLAT); break;
@@ -2031,7 +2032,7 @@ EMIT_FUNC(struct_store, Type* type, u64 offset) {
 EMIT_FUNC(struct_literal, AstStructLiteral* sl) {
     bh_arr(WasmInstruction) code = *pcode;
 
-    bh_arr_each(AstTyped *, val, sl->values) {
+    bh_arr_each(AstTyped *, val, sl->args.values) {
         emit_expression(mod, &code, *val);
     }
 
@@ -2299,7 +2300,8 @@ EMIT_FUNC(expression, AstTyped* expr) {
 
         case Ast_Kind_Block:          emit_block(mod, &code, (AstBlock *) expr, 1); break;
         case Ast_Kind_Call:           emit_call(mod, &code, (AstCall *) expr); break;
-        case Ast_Kind_Intrinsic_Call: emit_intrinsic_call(mod, &code, (AstIntrinsicCall *) expr); break;
+        case Ast_Kind_Argument:       emit_expression(mod, &code, ((AstArgument *) expr)->value); break;
+        case Ast_Kind_Intrinsic_Call: emit_intrinsic_call(mod, &code, (AstCall *) expr); break;
         case Ast_Kind_Binary_Op:      emit_binop(mod, &code, (AstBinaryOp *) expr); break;
         case Ast_Kind_Unary_Op:       emit_unaryop(mod, &code, (AstUnaryOp *) expr); break;
 
@@ -2980,7 +2982,7 @@ static void emit_raw_data(OnyxWasmModule* mod, ptr data, AstTyped* node) {
         assert(sl_type->kind == Type_Kind_Struct);
 
         i32 i = 0;
-        bh_arr_each(AstTyped *, expr, sl->values) {
+        bh_arr_each(AstTyped *, expr, sl->args.values) {
             emit_raw_data(mod, bh_pointer_add(data, sl_type->Struct.memarr[i]->offset), *expr);
             i++;
         }