struct literals work with new argument filling system
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 14 Jan 2021 22:38:55 +0000 (16:38 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Thu, 14 Jan 2021 22:38:55 +0000 (16:38 -0600)
bin/onyx
build.sh [changed mode: 0644->0755]
include/onyxastnodes.h
src/onyxchecker.c
src/onyxparser.c
src/onyxutils.c

index 0ad6f33435017d8731130191be56555fa9b5415b..6880818d80831be3d41ec8da9351fd6ee1149266 100755 (executable)
Binary files a/bin/onyx and b/bin/onyx differ
old mode 100644 (file)
new mode 100755 (executable)
index 923600871ad39ebb665ecce3400b6673b3926c49..135a491c13090979ebb9aca2292d33df6a8d5b0b 100644 (file)
@@ -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);
index 6dd7d7f4d5fae0c9c496d4b38cc1a0a734b5e1d2..e29d952cfb592471a4c91077f124f7873297b499 100644 (file)
@@ -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;
     }
 
index 911cca108add6764703dd03c0eb48a6e6d45013a..ad1d6fcabfd9b54352b8ca4f9fcf991a8a70f855 100644 (file)
@@ -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; 
+}
+
 // ( <expr> )
 // - <factor>
 // ! <factor>
index 77d2d742547f2d76155811fb5953cd2d5ce416f1..dbb34a0853173c337f91073c4c449e1faaad09fe 100644 (file)
@@ -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