From: Brendan Hansen Date: Thu, 14 Jan 2021 22:38:55 +0000 (-0600) Subject: struct literals work with new argument filling system X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=78543c68d86181c6d24985c6b33a225ecd824f56;p=onyx.git struct literals work with new argument filling system --- diff --git a/bin/onyx b/bin/onyx index 0ad6f334..6880818d 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index 92360087..135a491c 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -995,6 +995,8 @@ 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); + 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); diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 6dd7d7f4..e29d952c 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -963,59 +963,23 @@ CheckStatus check_struct_literal(AstStructLiteral* sl) { return Check_Error; } - if (bh_arr_length(sl->values) == 0) { - bh_arr_new(global_heap_allocator, sl->values, type_structlike_mem_count(sl->type)); - bh_arr_set_length(sl->values, type_structlike_mem_count(sl->type)); - bh_arr_zero(sl->values); - - StructMember s; - bh_arr_each(AstNamedValue *, named_value, sl->named_values) { - token_toggle_end((*named_value)->token); - if (!type_lookup_member(sl->type, (*named_value)->token->text, &s)) { - onyx_report_error((*named_value)->token->pos, - "The field '%s' does not exist on type '%s'.", (*named_value)->token->text, type_get_name(sl->type)); - token_toggle_end((*named_value)->token); - return Check_Error; - } - token_toggle_end((*named_value)->token); - - if (s.included_through_use) { - onyx_report_error((*named_value)->token->pos, "Cannot specify value for member '%s', which was included through a 'use' statement.", s.name); - return Check_Error; - } - - if (sl->values[s.idx] != NULL) { - onyx_report_error((*named_value)->token->pos, "Multiple values given for '%b'.", (*named_value)->token->text, (*named_value)->token->length); - return Check_Error; - } - - sl->values[s.idx] = (AstTyped *) (*named_value)->value; - } - - if (sl->type->kind == Type_Kind_Struct) { - bh_arr_each(StructMember*, smem, sl->type->Struct.memarr) { - u32 idx = (*smem)->idx; - - if (sl->values[idx] == NULL) { - if (*(*smem)->initial_value == NULL) { - onyx_report_error(sl->token->pos, "No value was given for the field '%s'.", (*smem)->name); - return Check_Error; - } + i32 mem_count = type_structlike_mem_count(sl->type); - sl->values[idx] = *(*smem)->initial_value; - } + 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)) { + bh_arr_each(AstTyped *, value, sl->values) { + if (*value == NULL) { + i32 member_idx = value - sl->values; // Pointer subtraction hack + + onyx_report_error(sl->token->pos, + "Value not given for %d%s member, '%s'.", + member_idx + 1, bh_num_suffix(member_idx + 1), + sl->type->Struct.memarr[member_idx]->name); } } - } - - i32 mem_count = type_structlike_mem_count(sl->type); - if (mem_count != bh_arr_length(sl->values)) { - onyx_report_error(sl->token->pos, - "'%s' expects %d values, given %d.", - type_get_name(sl->type), - mem_count, - bh_arr_length(sl->values)); return Check_Error; } diff --git a/src/onyxparser.c b/src/onyxparser.c index 911cca10..ad1d6fca 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -27,6 +27,8 @@ 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 AstTyped* parse_factor(OnyxParser* parser); static AstTyped* parse_compound_assignment(OnyxParser* parser, AstTyped* lhs); static AstTyped* parse_compound_expression(OnyxParser* parser, b32 assignment_allowed); @@ -183,37 +185,10 @@ static b32 parse_possible_struct_literal(OnyxParser* parser, AstTyped* left, Ast expect_token(parser, '.'); expect_token(parser, '{'); - b32 is_named = (peek_token(1)->type == '='); - OnyxToken* name = NULL; - while (parser->curr->type != '}') { - if (parser->hit_unexpected_token) break; - - if (is_named) { - name = expect_token(parser, Token_Type_Symbol); - expect_token(parser, '='); - } else { - name = NULL; - } - - AstTyped *expr = parse_expression(parser, 0); - - if (is_named) { - AstNamedValue* nv = make_node(AstStructMember, Ast_Kind_Named_Value); - nv->token = name; - nv->value = (AstNode *) expr; - - bh_arr_push(sl->named_values, nv); - - } else { - bh_arr_push(sl->values, expr); - } - - if (parser->curr->type != '}') - expect_token(parser, ','); - } - - expect_token(parser, '}'); + parse_values_and_named_values(parser, '}', + (bh_arr(AstNode *)*) &sl->values, + (bh_arr(AstNamedValue *)*) &sl->named_values); *ret = (AstTyped *) sl; return 1; @@ -247,6 +222,39 @@ 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; + + while (parser->curr->type != end_token) { + if (parser->hit_unexpected_token) return; + + if (peek_token(0)->type == Token_Type_Symbol && peek_token(1)->type == '=') { + OnyxToken* name = expect_token(parser, Token_Type_Symbol); + expect_token(parser, '='); + + AstNamedValue* named_value = make_node(AstNamedValue, Ast_Kind_Named_Value); + named_value->token = name; + named_value->value = (AstNode *) parse_expression(parser, 0); + + bh_arr_push(named_values, named_value); + + } else { + AstNode* value = (AstNode *) parse_expression(parser, 0); + bh_arr_push(values, value); + } + + if (parser->curr->type != end_token) + expect_token(parser, ','); + } + + expect_token(parser, end_token); + + *pvalues = values; + *pnamed_values = named_values; +} + // ( ) // - // ! diff --git a/src/onyxutils.c b/src/onyxutils.c index 77d2d742..dbb34a08 100644 --- a/src/onyxutils.c +++ b/src/onyxutils.c @@ -900,10 +900,7 @@ b32 fill_in_arguments(bh_arr(AstNode *) values, bh_arr(AstNamedValue *) named_va 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); - + onyx_report_error(provider->token->pos, "'%s' is not a valid named parameter here.", named_value->token->text); token_toggle_end(named_value->token); return 0; } @@ -914,13 +911,11 @@ b32 fill_in_arguments(bh_arr(AstNode *) values, bh_arr(AstNamedValue *) named_va values[idx] = named_value->value; } + 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) return 0; - } + if (values[idx] == NULL) values[idx] = lookup_default_value_by_idx(provider, idx); + if (values[idx] == NULL) success = 0; } - return 1; + return success; } \ No newline at end of file