From: Brendan Hansen Date: Fri, 15 Jan 2021 00:05:36 +0000 (-0600) Subject: BROKEN BUILD; want to debug on windows X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=688a63234fa304f7bec50b1e6aa67f3c3db3e619;p=onyx.git BROKEN BUILD; want to debug on windows --- diff --git a/bin/onyx b/bin/onyx index 2137d52e..bb4dec3c 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 5679e6d1..825d2d96 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -993,7 +993,7 @@ 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); +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); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index dbbe4380..f9640cad 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -296,7 +296,7 @@ CheckStatus check_switch(AstSwitch* switchnode) { return 0; } -static AstTyped* match_overloaded_function(bh_arr(AstTyped *) arg_arr, bh_arr(AstTyped *) overloads) { +static AstTyped* match_overloaded_function(bh_arr(AstTyped *) arg_arr, bh_arr(AstNamedValue *) named_values, bh_arr(AstTyped *) overloads) { bh_arr_each(AstTyped *, node, overloads) { AstFunction* overload = NULL; if ((*node)->kind == Ast_Kind_Function) { @@ -308,14 +308,29 @@ static AstTyped* match_overloaded_function(bh_arr(AstTyped *) arg_arr, bh_arr(As if (overload == NULL) continue; - fill_in_type((AstTyped *) overload); + 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]; + + b32 values_place_correctly = fill_in_arguments( + (bh_arr(AstNode *)) new_arg_arr, + named_values, + (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(arg_arr) < (i32) ol_type->needed_param_count) continue; + if (bh_arr_length(new_arg_arr) < (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, arg_arr) { + bh_arr_each(AstTyped*, arg, new_arg_arr) { if (param_left == 0) goto no_match; param_left--; @@ -337,11 +352,28 @@ static AstTyped* match_overloaded_function(bh_arr(AstTyped *) arg_arr, bh_arr(As return (AstTyped *) *node; no_match: + if (named_values != NULL) + bh_arr_free(new_arg_arr); + continue; } return NULL; } +CheckStatus check_argument(AstArgument** parg) { + CHECK(expression, (AstTyped **) parg); + (*parg)->type = (*parg)->value->type; + + if ((*parg)->value->kind == Ast_Kind_Overloaded_Function) { + onyx_report_error((*parg)->token->pos, + "Cannot pass overloaded function '%b' as argument.", + (*parg)->value->token->text, (*parg)->value->token->length); + return Check_Error; + } + + return Check_Success; +} + typedef enum ArgState { AS_Expecting_Exact, AS_Expecting_Typed_VA, @@ -365,24 +397,17 @@ CheckStatus check_call(AstCall* call) { CHECK(expression, &call->callee); AstFunction* callee = (AstFunction *) call->callee; - bh_arr(AstArgument *) arg_arr = call->arg_arr; - // NOTE: Check arguments - bh_arr_each (AstArgument *, actual, arg_arr) { - CHECK(expression, (AstTyped **) actual); - (*actual)->type = (*actual)->value->type; - - if ((*actual)->value->kind == Ast_Kind_Overloaded_Function) { - onyx_report_error((*actual)->token->pos, - "Cannot pass overloaded function '%b' as argument.", - (*actual)->value->token->text, (*actual)->value->token->length); - return Check_Error; - } - } + 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); if (callee->kind == Ast_Kind_Overloaded_Function) { call->callee = match_overloaded_function( (bh_arr(AstTyped *)) call->arg_arr, + call->named_args, ((AstOverloadedFunction *) callee)->overloads); if (call->callee == NULL) { @@ -396,6 +421,20 @@ CheckStatus check_call(AstCall* call) { strncat(arg_str, ", ", 1023); } + if (bh_arr_length(call->named_args) > 0) { + bh_arr_each(AstNamedValue *, named_value, call->named_args) { + 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'. + + if (named_value != &bh_arr_last(call->named_args)) + strncat(arg_str, ", ", 1023); + } + } + onyx_report_error(call->token->pos, "unable to match overloaded function with provided argument types: (%s)", arg_str); bh_free(global_scratch_allocator, arg_str); @@ -431,18 +470,26 @@ CheckStatus check_call(AstCall* call) { return Check_Error; } - if (callee->kind == Ast_Kind_Function) { - if (bh_arr_length(arg_arr) < bh_arr_length(callee->params)) { - while (bh_arr_length(arg_arr) < bh_arr_length(callee->params) - && callee->params[bh_arr_length(arg_arr)].default_value != NULL) { - AstTyped* dv = callee->params[bh_arr_length(arg_arr)].default_value; + i32 arg_count = bh_max( + bh_arr_length(call->arg_arr) + bh_arr_length(call->named_args), + (i32) callee->type->Function.param_count); - AstArgument* new_arg = make_argument(semstate.node_allocator, dv); - bh_arr_push(arg_arr, new_arg); - } + 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); + + { + char* err_msg = NULL; + fill_in_arguments((AstNode **) call->arg_arr, call->named_args, (AstNode *) callee, &err_msg); + + if (err_msg != NULL) { + onyx_report_error(call->token->pos, err_msg); + return Check_Error; } } + bh_arr(AstArgument *) arg_arr = call->arg_arr; + // NOTE: If we are calling an intrinsic function, translate the // call into an intrinsic call node. if (callee->flags & Ast_Flag_Intrinsic) { @@ -723,7 +770,7 @@ static AstCall* binaryop_try_operator_overload(AstBinaryOp* binop) { bh_arr_push(args, binop->left); bh_arr_push(args, binop->right); - AstTyped* overload = match_overloaded_function(args, operator_overloads[binop->operation]); + AstTyped* overload = match_overloaded_function(args, NULL, operator_overloads[binop->operation]); if (overload == NULL) { bh_arr_free(args); return NULL; @@ -968,7 +1015,11 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) { 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); - if (!fill_in_arguments((bh_arr(AstNode *)) sl->values, sl->named_values, (AstNode *) sl)) { + + char* err_msg = NULL; + if (!fill_in_arguments((bh_arr(AstNode *)) sl->values, sl->named_values, (AstNode *) sl, &err_msg)) { + onyx_report_error(sl->token->pos, err_msg); + bh_arr_each(AstTyped *, value, sl->values) { if (*value == NULL) { i32 member_idx = value - sl->values; // Pointer subtraction hack diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 71b90e08..acb7c988 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -242,6 +242,9 @@ static void symres_call(AstCall* call) { 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); } static void symres_size_of(AstSizeOf* so) { diff --git a/src/onyxutils.c b/src/onyxutils.c index 4be805a6..9c5ab5ab 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -372,18 +372,33 @@ static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLo Type* actual_type; if (pp_lookup == PPLM_By_Call) { - if (param->idx >= (u64) bh_arr_length(((AstCall *) actual)->arg_arr)) { - if (err_msg) *err_msg = "Not enough arguments to polymorphic procedure."; + bh_arr(AstArgument *) arg_arr = ((AstCall *) actual)->arg_arr; + bh_arr(AstNamedValue *) named_values = ((AstCall *) actual)->named_args; + + if (param->idx >= (u64) bh_arr_length(arg_arr)) { + // CLEANUP: This is a really long access chain. + OnyxToken* param_name = pp->base_func->params[param->idx].local->token; + + bh_arr_each(AstNamedValue *, named_value, named_values) { + if (token_equals(param_name, (*named_value)->token)) { + actual_type = resolve_expression_type((AstTyped *) (*named_value)->value); + break; + } + } + + // nocheckin + if (err_msg) *err_msg = "Not enough arguments to polymorphic procedure. This error message may not be entirely right."; goto sln_not_found; - } - bh_arr(AstArgument *) arg_arr = ((AstCall *) actual)->arg_arr; - actual_type = resolve_expression_type(arg_arr[param->idx]->value); + } else { + actual_type = resolve_expression_type(arg_arr[param->idx]->value); + } } else if (pp_lookup == PPLM_By_Value_Array) { bh_arr(AstTyped *) arg_arr = (bh_arr(AstTyped *)) actual; + // nocheckin if ((i32) param->idx >= bh_arr_length(arg_arr)) { if (err_msg) *err_msg = "Not enough arguments to polymorphic procedure."; goto sln_not_found; @@ -884,7 +899,8 @@ static AstNode* lookup_default_value_by_idx(AstNode* provider, i32 idx) { case Ast_Kind_Function: { AstFunction* func = (AstFunction *) provider; - return (AstNode *) func->params[idx].default_value; + AstArgument* arg = make_argument(semstate.node_allocator, func->params[idx].default_value); + return (AstNode *) arg; } default: return NULL; @@ -893,22 +909,28 @@ 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) { +b32 fill_in_arguments(bh_arr(AstNode *) values, bh_arr(AstNamedValue *) named_values, AstNode* provider, char** err_msg) { bh_arr_each(AstNamedValue *, p_named_value, named_values) { AstNamedValue* named_value = *p_named_value; token_toggle_end(named_value->token); i32 idx = lookup_idx_by_name(provider, named_value->token->text); if (idx == -1) { - onyx_report_error(provider->token->pos, "'%s' is not a valid named parameter here.", named_value->token->text); + if (err_msg) *err_msg = bh_aprintf(global_heap_allocator, "'%s' is not a valid named parameter here.", named_value->token->text); token_toggle_end(named_value->token); return 0; } - token_toggle_end(named_value->token); - assert(idx < bh_arr_length(values)); + + if (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; + token_toggle_end(named_value->token); } b32 success = 1;