diff options
| author | Carson Fleming <cflems@cflems.net> | 2026-03-31 16:30:29 -1000 |
|---|---|---|
| committer | Carson Fleming <cflems@cflems.net> | 2026-03-31 16:30:29 -1000 |
| commit | 1dfa2971999b4adf36a33866b0b07af07188da08 (patch) | |
| tree | 7d65b9a5780a95bf519fed6d435bdade264aac62 /parser.c | |
| parent | 7cf2065be92855b5b1db31a4bb7afbb4af29a817 (diff) | |
| download | ccc-1dfa2971999b4adf36a33866b0b07af07188da08.tar.gz | |
math n shi
Diffstat (limited to 'parser.c')
| -rw-r--r-- | parser.c | 87 |
1 files changed, 76 insertions, 11 deletions
@@ -107,21 +107,18 @@ static void parse_var_ref(struct var_ref_node* p_node) { p_node->ident = tok.data.ident; } -static void expr_to_lval(struct lval_node* l_node, struct expr_node* e_node) { - switch (e_node->type) { +static void parse_expr_assign(struct expr_node* p_node) { + switch (p_node->type) { case EXPR_VAR_REF: - *l_node = (struct lval_node) { + p_node->as._assign.lval = (struct lval_node) { .type = LVAL_VAR_REF, - .as._var_ref = e_node->as._var_ref, + .as._var_ref = p_node->as._var_ref, }; return; default: PARSER_PANIC("expression is not assignable"); } -} -static void parse_expr_assign(struct expr_node* p_node) { - expr_to_lval(&p_node->as._assign.lval, p_node); p_node->type = EXPR_ASSIGN; p_node->as._assign.rval = protected_alloc(sizeof(struct expr_node)); @@ -167,6 +164,59 @@ static void parse_expr_call(struct expr_node* p_node) { expect(TK_RPAREN); } +static void parse_unary(struct unary_node* p_node) { + peek_or_panic(); + switch (tok.type) { + case TK_NEG: + expect(TK_NEG); + p_node->op = UNARY_NEG; + break; + default: + PARSER_PANIC("expected unary operator"); + } + + p_node->expr = protected_alloc(sizeof(struct expr_node)); + parse_expr(p_node->expr); +} + +static void parse_expr_binary(struct expr_node* p_node) { + struct expr_node* lhs = protected_alloc(sizeof(struct expr_node)); + struct expr_node* rhs = protected_alloc(sizeof(struct expr_node)); + + *lhs = *p_node; + *p_node = (struct expr_node) { + .type = EXPR_BINARY, + .as._binary = { + .lhs = lhs, + .rhs = rhs, + }, + }; + + peek_or_panic(); + switch (tok.type) { + case TK_PLUS: + expect(TK_PLUS); + p_node->as._binary.op = BINARY_ADD; + break; + case TK_NEG: + expect(TK_NEG); + p_node->as._binary.op = BINARY_SUB; + break; + case TK_STAR: + expect(TK_STAR); + p_node->as._binary.op = BINARY_MUL; + break; + case TK_DIV: + expect(TK_DIV); + p_node->as._binary.op = BINARY_DIV; + break; + default: + PARSER_PANIC("expected binary operator"); + } + + parse_expr(rhs); +} + static void parse_expr(struct expr_node* p_node) { peek_or_panic(); switch (tok.type) { @@ -175,6 +225,10 @@ static void parse_expr(struct expr_node* p_node) { parse_expr(p_node); expect(TK_RPAREN); break; + case TK_NEG: + p_node->type = EXPR_UNARY; + parse_unary(&p_node->as._unary); + break; case TK_INT_LIT: case TK_CHAR_LIT: case TK_FLOAT_LIT: @@ -190,10 +244,21 @@ static void parse_expr(struct expr_node* p_node) { } peek_or_panic(); - if (tok.type == TK_ASSIGN) - parse_expr_assign(p_node); - else if (tok.type == TK_LPAREN) - parse_expr_call(p_node); + switch (tok.type) { + case TK_ASSIGN: + parse_expr_assign(p_node); + break; + case TK_LPAREN: + parse_expr_call(p_node); + break; + case TK_PLUS: + case TK_NEG: + case TK_STAR: + case TK_DIV: + parse_expr_binary(p_node); + break; + default: + } } static void parse_var_decl(struct var_decl_node* p_node) { |
