aboutsummaryrefslogtreecommitdiffstats
path: root/src/parser.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-26 08:14:02 +0200
committerBad Diode <bd@badd10de.dev>2024-06-26 08:14:02 +0200
commit5453e1545b4b3663408456ac8c8aedf2da856ac0 (patch)
tree1ec8119f53233f99c27a125afc15f6d896bf9ff4 /src/parser.c
parent131bb573e16ecc760b682b3c43149d59a94b9bd7 (diff)
downloadbdl-5453e1545b4b3663408456ac8c8aedf2da856ac0.tar.gz
bdl-5453e1545b4b3663408456ac8c8aedf2da856ac0.zip
Add better ergonomics for nested struct literals
Diffstat (limited to 'src/parser.c')
-rw-r--r--src/parser.c38
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
523void 523void
524parse_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
553void
524parse_keyword(Parser *parser) { 554parse_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)) {