From 29510d33cab6e86b28b12c6246bca58acdab26e2 Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Wed, 29 Jul 2026 23:35:15 -0400 Subject: support for comma-separated expression lists where valid --- parser.c | 104 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 38 deletions(-) (limited to 'parser.c') diff --git a/parser.c b/parser.c index c2eadbe..40d5bbd 100644 --- a/parser.c +++ b/parser.c @@ -178,7 +178,7 @@ static void parse_expr_call(struct expr_node* p_node) { if (var_def->loc.type != STO_FN) PARSER_PANIC("called object is not a function"); - p_node->inner.call.called_fn_ref = var_def->loc.decl; + p_node->inner.call.fn_ref = var_def->loc.decl; break; default: PARSER_PANIC("expression is not callable"); @@ -250,13 +250,19 @@ static void parse_expr_binary(struct expr_node* p_node) { parse_expr(rhs); } +static void parse_paren(struct paren_node* p_node) { + expect(TK_LPAREN); + p_node->expr_list = ccc_alloc(sizeof(struct expr_list_node)); + parse_expr_list(p_node->expr_list); + expect(TK_RPAREN); +} + static void parse_expr(struct expr_node* p_node) { peek_or_panic(); switch (tok.type) { case TK_LPAREN: - expect(TK_LPAREN); - parse_expr(p_node); - expect(TK_RPAREN); + p_node->type = EXPR_PAREN; + parse_paren(&p_node->inner.paren); break; case TK_NEG: p_node->type = EXPR_UNARY; @@ -294,23 +300,38 @@ static void parse_expr(struct expr_node* p_node) { } } -static void parse_var_decl(struct var_decl_node* p_node) { - parse_type_ref(&p_node->type); +static void parse_decl(const struct type* type, struct decl_node* p_node) { expect(TK_IDENT); - p_node->def_ref = scope_define_var(scope, (struct var_def) { - .type = &p_node->type, + .type = type, .name = tok.data.ident, .loc.type = STO_UNRESOLVED, }); if (p_node->def_ref == NULL) - PARSER_PANIC("redefinition of '%s'", tok.data.ident); + PARSER_PANIC("redefinition of '%s' in same scope", tok.data.ident); peek_or_panic(); if (tok.type == TK_ASSIGN) { expect(TK_ASSIGN); p_node->initial_value = ccc_alloc(sizeof(struct expr_node)); parse_expr(p_node->initial_value); + peek_or_panic(); + } + + if (tok.type == TK_COMMA) { + expect(TK_COMMA); + p_node->next = ccc_alloc(sizeof(struct decl_node)); + parse_decl(type, p_node->next); + } +} + +static void parse_decl_list(struct decl_list_node* p_node) { + parse_type_ref(&p_node->type); + + peek_or_panic(); + if (tok.type == TK_IDENT) { + p_node->head = ccc_alloc(sizeof(struct decl_node)); + parse_decl(&p_node->type, p_node->head); } } @@ -325,8 +346,8 @@ static void parse_return(struct return_node* p_node) { return; } - p_node->ret_val = ccc_alloc(sizeof(struct expr_node)); - parse_expr(p_node->ret_val); + p_node->ret_val = ccc_alloc(sizeof(struct expr_list_node)); + parse_expr_list(p_node->ret_val); } static void parse_group(struct group_node* p_node) { @@ -357,8 +378,8 @@ static void parse_if(struct if_node* p_node) { p_node->scope = scope; expect(TK_LPAREN); - p_node->cond = ccc_alloc(sizeof(struct expr_node)); - parse_expr(p_node->cond); + p_node->cond = ccc_alloc(sizeof(struct expr_list_node)); + parse_expr_list(p_node->cond); expect(TK_RPAREN); p_node->true_branch = ccc_alloc(sizeof(struct stmt_node)); @@ -382,8 +403,8 @@ static void parse_while(struct loop_node* p_node) { p_node->scope = scope; expect(TK_LPAREN); - p_node->cond = ccc_alloc(sizeof(struct expr_node)); - parse_expr(p_node->cond); + p_node->cond = ccc_alloc(sizeof(struct expr_list_node)); + parse_expr_list(p_node->cond); expect(TK_RPAREN); p_node->body = ccc_alloc(sizeof(struct stmt_node)); @@ -406,14 +427,14 @@ static bool is_type_token() { static void parse_loop_init(struct loop_init_node* p_node) { peek_or_panic(); - if (!is_type_token()) { + if (is_type_token()) { + p_node->type = INIT_DECL_LIST; + p_node->decl_list = ccc_alloc(sizeof(struct decl_list_node)); + parse_decl_list(p_node->decl_list); + } else { p_node->type = INIT_EXPR_LIST; p_node->expr_list = ccc_alloc(sizeof(struct expr_list_node)); parse_expr_list(p_node->expr_list); - } else { - p_node->type = INIT_DECL; - p_node->decl = ccc_alloc(sizeof(struct var_decl_node)); - parse_var_decl(p_node->decl); } } @@ -432,14 +453,14 @@ static void parse_for(struct loop_node* p_node) { expect(TK_SEMI); peek_or_panic(); if (tok.type != TK_SEMI) { - p_node->cond = ccc_alloc(sizeof(struct expr_node)); - parse_expr(p_node->cond); + p_node->cond = ccc_alloc(sizeof(struct expr_list_node)); + parse_expr_list(p_node->cond); } expect(TK_SEMI); peek_or_panic(); if (tok.type != TK_RPAREN) { - p_node->incr = ccc_alloc(sizeof(struct expr_node)); - parse_expr(p_node->incr); + p_node->incr = ccc_alloc(sizeof(struct expr_list_node)); + parse_expr_list(p_node->incr); } expect(TK_RPAREN); @@ -477,29 +498,36 @@ static void parse_stmt(struct stmt_node* p_node) { parse_return(&p_node->inner.return_); break; } else if (is_type_token()) { - p_node->type = STMT_VAR_DECL; - parse_var_decl(&p_node->inner.var_decl); + p_node->type = STMT_DECL_LIST; + parse_decl_list(&p_node->inner.decl_list); break; } default: - p_node->type = STMT_EXPR; - parse_expr(&p_node->inner.expr); + p_node->type = STMT_EXPR_LIST; + parse_expr_list(&p_node->inner.expr_list); } expect(TK_SEMI); } -static void parse_decl_list(struct decl_list_node* p_node) { - for (;;) { - p_node->decl = ccc_alloc(sizeof(struct var_decl_node)); - parse_var_decl(p_node->decl); +static void parse_fn_arg(struct arg_decl_node* p_node) { + parse_type_ref(&p_node->type); - peek_or_panic(); - if (tok.type != TK_COMMA) break; + expect(TK_IDENT); + p_node->def_ref = scope_define_var(scope, (struct var_def) { + .type = &p_node->type, + .name = tok.data.ident, + .loc.type = STO_UNRESOLVED, + }); + if (p_node->def_ref == NULL) + PARSER_PANIC("redefinition of parameter '%s'", tok.data.ident); + + peek_or_panic(); + if (tok.type == TK_COMMA) { expect(TK_COMMA); - p_node->next = ccc_alloc(sizeof(struct decl_list_node)); - p_node = p_node->next; + p_node->next = ccc_alloc(sizeof(struct arg_decl_node)); + parse_fn_arg(p_node->next); } } @@ -529,8 +557,8 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { peek_or_panic(); if (tok.type != TK_RPAREN) { - p_node->args = ccc_alloc(sizeof(struct decl_list_node)); - parse_decl_list(p_node->args); + p_node->args = ccc_alloc(sizeof(struct arg_decl_node)); + parse_fn_arg(p_node->args); } expect(TK_RPAREN); -- cgit v1.2.3