diff options
| author | Carson Fleming <cflems@cflems.net> | 2026-03-28 09:42:44 -1000 |
|---|---|---|
| committer | Carson Fleming <cflems@cflems.net> | 2026-03-28 09:42:44 -1000 |
| commit | 33d10c0a684eaacb59102e2e2c2494ef54113aa1 (patch) | |
| tree | 230b1f1cfc4a6cde3285e2fac35c7f9a7a414e17 /parser.c | |
| parent | 55929c155f929a886a0fe72c1c16a7913830350a (diff) | |
| download | ccc-33d10c0a684eaacb59102e2e2c2494ef54113aa1.tar.gz | |
we got assignments bois
Diffstat (limited to 'parser.c')
| -rw-r--r-- | parser.c | 82 |
1 files changed, 77 insertions, 5 deletions
@@ -78,6 +78,8 @@ static void parse_type(struct type_node* p_node) { } } +static void parse_expr(struct expr_node* p_node); + static void parse_int_lit(struct int_lit_node* p_node) { expect(TK_INT_LIT); p_node->val = tok.data.int_lit; @@ -88,23 +90,64 @@ static void parse_var_ref(struct var_ref_node* p_node) { p_node->ident = tok.data.ident; } +static void parse_expr_assign(struct expr_node* p_node) { + peek_or_panic(); + if (tok.type != TK_ASSIGN) return; + + switch (p_node->type) { + case EXPR_VAR_REF: + p_node->as._assign.lval = (struct lval_node) { + .type = LVAL_VAR_REF, + .as._var_ref = p_node->as._var_ref, + }; + break; + default: + PARSER_PANIC("expression is not assignable"); + } + + p_node->type = EXPR_ASSIGN; + p_node->as._assign.rval = protected_alloc(sizeof(struct expr_node)); + + expect(TK_ASSIGN); + parse_expr(p_node->as._assign.rval); +} + static void parse_expr(struct expr_node* p_node) { peek_or_panic(); switch (tok.type) { - case TK_SEMI: - p_node->type = EXPR_EMPTY; - return; + case TK_LPAREN: + expect(TK_LPAREN); + parse_expr(p_node); + expect(TK_RPAREN); + break; case TK_INT_LIT: p_node->type = EXPR_INT_LIT; parse_int_lit(&p_node->as._int_lit); - return; + break; case TK_IDENT: p_node->type = EXPR_VAR_REF; parse_var_ref(&p_node->as._var_ref); - return; + + peek_or_panic(); + if (tok.type == TK_ASSIGN) { + p_node->type = EXPR_ASSIGN; + p_node->as._assign = (struct assign_node) { + .lval = { + .type = LVAL_VAR_REF, + .as._var_ref = p_node->as._var_ref, + }, + .rval = protected_alloc(sizeof(struct expr_node)), + }; + + expect(TK_ASSIGN); + parse_expr(p_node->as._assign.rval); + } + break; default: PARSER_PANIC("expected expression"); } + + parse_expr_assign(p_node); } static void parse_var_decl(struct var_decl_node* p_node) { @@ -144,9 +187,36 @@ static void parse_group(struct group_node* p_node) { expect(TK_RCURLY); } +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->as._expr.as._assign.lval = (struct lval_node) { + .type = LVAL_VAR_DECL, + .as._var_decl = p_node->as._var_decl, + }; + break; + default: + return; + } + + p_node->type = STMT_EXPR; + p_node->as._expr.type = EXPR_ASSIGN; + p_node->as._expr.as._assign.rval = + protected_alloc(sizeof(struct expr_node)); + + expect(TK_ASSIGN); + parse_expr(p_node->as._expr.as._assign.rval); +} + static void parse_stmt(struct stmt_node* p_node) { peek_or_panic(); switch (tok.type) { + case TK_SEMI: + p_node->type = STMT_EMPTY; + break; case TK_LCURLY: p_node->type = STMT_GROUP; parse_group(&p_node->as._group); @@ -165,6 +235,8 @@ static void parse_stmt(struct stmt_node* p_node) { p_node->type = STMT_EXPR; parse_expr(&p_node->as._expr); } + + parse_stmt_assign(p_node); expect(TK_SEMI); } |
