diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-26 08:14:02 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-26 08:14:02 +0200 |
commit | 5453e1545b4b3663408456ac8c8aedf2da856ac0 (patch) | |
tree | 1ec8119f53233f99c27a125afc15f6d896bf9ff4 /src/parser.c | |
parent | 131bb573e16ecc760b682b3c43149d59a94b9bd7 (diff) | |
download | bdl-5453e1545b4b3663408456ac8c8aedf2da856ac0.tar.gz bdl-5453e1545b4b3663408456ac8c8aedf2da856ac0.zip |
Add better ergonomics for nested struct literals
Diffstat (limited to 'src/parser.c')
-rw-r--r-- | src/parser.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/src/parser.c b/src/parser.c index e38f2ca..67c7e8c 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -521,6 +521,36 @@ parse_struct_field(Parser *parser) { | |||
521 | } | 521 | } |
522 | 522 | ||
523 | void | 523 | void |
524 | parse_struct_lit_field(Parser *parser) { | ||
525 | if (parser->panic) return; | ||
526 | #if DEBUG == 1 | ||
527 | print("parsing struct field "); | ||
528 | print_token(parser->previous); | ||
529 | #endif | ||
530 | Node *field = node_alloc(parser, NODE_FIELD, parser->current); | ||
531 | if (!field) return; | ||
532 | parse_consume(parser, TOK_SYMBOL, | ||
533 | cstr("expected symbol name on struct field")); | ||
534 | field->value.sym = parser->previous.val; | ||
535 | parse_consume(parser, TOK_ASSIGN, | ||
536 | cstr("expected field value on struct literal")); | ||
537 | if (parse_match(parser, TOK_LCURLY)) { | ||
538 | Node *type = node_alloc(parser, NODE_COMPOUND_TYPE, parser->current); | ||
539 | if (!type) return; | ||
540 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | ||
541 | parse_struct_lit_field(parser); | ||
542 | Node *subfield = array_pop(parser->nodes); | ||
543 | array_push(type->elements, subfield, parser->storage); | ||
544 | } | ||
545 | field->field_type = type; | ||
546 | } else { | ||
547 | parse_expr(parser, PREC_LOW); | ||
548 | field->field_val = array_pop(parser->nodes); | ||
549 | } | ||
550 | array_push(parser->nodes, field, parser->storage); | ||
551 | } | ||
552 | |||
553 | void | ||
524 | parse_keyword(Parser *parser) { | 554 | parse_keyword(Parser *parser) { |
525 | if (parser->panic) return; | 555 | if (parser->panic) return; |
526 | Token prev = parser->previous; | 556 | Token prev = parser->previous; |
@@ -940,12 +970,8 @@ parse_symbol(Parser *parser) { | |||
940 | // Struct literal. | 970 | // Struct literal. |
941 | node->kind = NODE_STRUCT_LIT; | 971 | node->kind = NODE_STRUCT_LIT; |
942 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { | 972 | while (!parse_match(parser, TOK_RCURLY) && !parser->panic) { |
943 | Node *field = node_alloc(parser, NODE_FIELD, parser->current); | 973 | parse_struct_lit_field(parser); |
944 | parse_consume(parser, TOK_SYMBOL, cstr("expected symbol name")); | 974 | Node *field = array_pop(parser->nodes); |
945 | field->value.sym = parser->previous.val; | ||
946 | parse_consume(parser, TOK_ASSIGN, cstr("expected assignment")); | ||
947 | parse_expr(parser, PREC_LOW); | ||
948 | field->field_val = array_pop(parser->nodes); | ||
949 | array_push(node->elements, field, parser->storage); | 975 | array_push(node->elements, field, parser->storage); |
950 | } | 976 | } |
951 | } else if (parse_match(parser, TOK_LSQUARE)) { | 977 | } else if (parse_match(parser, TOK_LSQUARE)) { |