From 0cabbd2a0853c332c82af621b8716643741d758a Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Tue, 21 Jul 2026 14:36:02 -0700 Subject: more faithful grammar --- parser.c | 110 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 57 insertions(+), 53 deletions(-) (limited to 'parser.c') diff --git a/parser.c b/parser.c index 28e36e3..7bad30f 100644 --- a/parser.c +++ b/parser.c @@ -124,34 +124,29 @@ static void parse_var_ref(struct var_ref_node* p_node) { } static void parse_expr_assign(struct expr_node* p_node) { - switch (p_node->type) { - case EXPR_VAR_REF: - p_node->inner.assign.lval = (struct lval_node) { - .type = LVAL_VAR_REF, - .inner.var_ref = p_node->inner.var_ref, - }; - break; - default: - PARSER_PANIC("expression is not assignable"); - } + struct expr_node* lval = protected_alloc(sizeof(struct expr_node)); + *lval = *p_node; p_node->type = EXPR_ASSIGN; - p_node->inner.assign.rval = protected_alloc(sizeof(struct expr_node)); + struct assign_node* a_node = &p_node->inner.assign; + a_node->lval = lval; expect(TK_ASSIGN); - parse_expr(p_node->inner.assign.rval); + a_node->rval = protected_alloc(sizeof(struct expr_node)); + parse_expr(a_node->rval); } -static void parse_args_eval(struct args_eval_node** pp_arg) { +static void parse_expr_list(struct expr_list_node* p_node) { for (;;) { - *pp_arg = protected_alloc(sizeof(struct args_eval_node)); - (*pp_arg)->expr = protected_alloc(sizeof(struct expr_node)); - parse_expr((*pp_arg)->expr); - pp_arg = &((*pp_arg)->next); + p_node->expr = protected_alloc(sizeof(struct expr_node)); + parse_expr(p_node->expr); peek_or_panic(); - if (tok.type == TK_RPAREN) break; + if (tok.type != TK_COMMA) break; expect(TK_COMMA); + + p_node->next = protected_alloc(sizeof(struct expr_list_node)); + p_node = p_node->next; } } @@ -174,7 +169,11 @@ static void parse_expr_call(struct expr_node* p_node) { expect(TK_LPAREN); peek_or_panic(); - if (tok.type != TK_RPAREN) parse_args_eval(&p_node->inner.call.args); + if (tok.type != TK_RPAREN) { + p_node->inner.call.args = + protected_alloc(sizeof(struct expr_list_node)); + parse_expr_list(p_node->inner.call.args); + } expect(TK_RPAREN); } @@ -286,6 +285,13 @@ static void parse_var_decl(struct var_decl_node* p_node) { }); if (p_node->def_ref == NULL) PARSER_PANIC("redefinition of '%s'", tok.data.ident); + + peek_or_panic(); + if (tok.type == TK_ASSIGN) { + expect(TK_ASSIGN); + p_node->initial_value = protected_alloc(sizeof(struct expr_node)); + parse_expr(p_node->initial_value); + } } static void parse_stmt(struct stmt_node* p_node); @@ -366,6 +372,25 @@ static void parse_while(struct loop_node* p_node) { scope_pop(&scope); } +static void parse_loop_init(struct loop_init_node* p_node) { + peek_or_panic(); + if (tok.type != TK_IDENT + || !scope_get_type(scope, NULL, &(struct type_key) { + .name = tok.data.ident, + .how_long = 0, + .marked_signed = false, + .marked_unsigned = false, + })) { + p_node->type = INIT_EXPR_LIST; + p_node->expr_list = protected_alloc(sizeof(struct expr_list_node)); + parse_expr_list(p_node->expr_list); + } else { + p_node->type = INIT_DECL; + p_node->decl = protected_alloc(sizeof(struct var_decl_node)); + parse_var_decl(p_node->decl); + } +} + static void parse_for(struct loop_node* p_node) { expect_kw("for"); @@ -375,8 +400,8 @@ static void parse_for(struct loop_node* p_node) { expect(TK_LPAREN); peek_or_panic(); if (tok.type != TK_SEMI) { - p_node->init = protected_alloc(sizeof(struct expr_node)); - parse_expr(p_node->init); + p_node->init = protected_alloc(sizeof(struct loop_init_node)); + parse_loop_init(p_node->init); } expect(TK_SEMI); peek_or_panic(); @@ -398,30 +423,6 @@ static void parse_for(struct loop_node* p_node) { scope_pop(&scope); } -static void parse_stmt_assign(struct stmt_node* p_node) { - peek_or_panic(); - if (tok.type != TK_ASSIGN) return; - - switch (p_node->type) { - case STMT_VAR_DECL: - p_node->inner.expr.inner.assign.lval = (struct lval_node) { - .type = LVAL_VAR_DECL, - .inner.var_decl = p_node->inner.var_decl, - }; - break; - default: - return; - } - - p_node->type = STMT_EXPR; - p_node->inner.expr.type = EXPR_ASSIGN; - p_node->inner.expr.inner.assign.rval = - protected_alloc(sizeof(struct expr_node)); - - expect(TK_ASSIGN); - parse_expr(p_node->inner.expr.inner.assign.rval); -} - static void parse_stmt(struct stmt_node* p_node) { peek_or_panic(); switch (tok.type) { @@ -467,20 +468,20 @@ static void parse_stmt(struct stmt_node* p_node) { parse_expr(&p_node->inner.expr); } - parse_stmt_assign(p_node); expect(TK_SEMI); } -static void parse_args_decl(struct args_decl_node** pp_decl) { +static void parse_decl_list(struct decl_list_node* p_node) { for (;;) { - *pp_decl = protected_alloc(sizeof(struct args_decl_node)); - (*pp_decl)->decl = protected_alloc(sizeof(struct var_decl_node)); - parse_var_decl((*pp_decl)->decl); - pp_decl = &((*pp_decl)->next); + p_node->decl = protected_alloc(sizeof(struct var_decl_node)); + parse_var_decl(p_node->decl); peek_or_panic(); - if (tok.type == TK_RPAREN) break; + if (tok.type != TK_COMMA) break; expect(TK_COMMA); + + p_node->next = protected_alloc(sizeof(struct decl_list_node)); + p_node = p_node->next; } } @@ -509,7 +510,10 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { p_node->scope = scope; peek_or_panic(); - if (tok.type != TK_RPAREN) parse_args_decl(&p_node->args); + if (tok.type != TK_RPAREN) { + p_node->args = protected_alloc(sizeof(struct decl_list_node)); + parse_decl_list(p_node->args); + } expect(TK_RPAREN); -- cgit v1.2.3