From: Brendan Hansen Date: Fri, 15 Jan 2021 15:45:25 +0000 (-0600) Subject: refactored a lot of the argument code for calls and struct literals X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=f9374e199d6f664b04e6c5b401d05eac9bbae7dc;p=onyx.git refactored a lot of the argument code for calls and struct literals --- diff --git a/bin/onyx b/bin/onyx index 3458061f..509b8300 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 3db35154..7fe4c937 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -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, diff --git a/include/onyxlex.h b/include/onyxlex.h index 645a5c93..4d7bb280 100644 --- a/include/onyxlex.h +++ b/include/onyxlex.h @@ -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 diff --git a/onyx.exe b/onyx.exe index e6452587..19e6f3f2 100644 Binary files a/onyx.exe and b/onyx.exe differ diff --git a/src/onyx.c b/src/onyx.c index 67164bac..64e9a623 100644 --- a/src/onyx.c +++ b/src/onyx.c @@ -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); diff --git a/src/onyxastnodes.c b/src/onyxastnodes.c index bb41ae4b..ba52da93 100644 --- a/src/onyxastnodes.c +++ b/src/onyxastnodes.c @@ -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 diff --git a/src/onyxchecker.c b/src/onyxchecker.c index f648dc9b..7d933731 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -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); diff --git a/src/onyxclone.c b/src/onyxclone.c index 14444d12..07d8d678 100644 --- a/src/onyxclone.c +++ b/src/onyxclone.c @@ -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; diff --git a/src/onyxlex.c b/src/onyxlex.c index c88a31a4..0f60262b 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -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; +} diff --git a/src/onyxparser.c b/src/onyxparser.c index c415e82f..57745c81 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -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; } // ( ) @@ -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; diff --git a/src/onyxsymres.c b/src/onyxsymres.c index acb7c988..fd30f2a4 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -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; diff --git a/src/onyxutils.c b/src/onyxutils.c index a0a274f1..21306d1c 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -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; diff --git a/src/onyxwasm.c b/src/onyxwasm.c index bd504314..794a3224 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -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++; }