summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-03-28 09:42:44 -1000
committerCarson Fleming <cflems@cflems.net>2026-03-28 09:42:44 -1000
commit33d10c0a684eaacb59102e2e2c2494ef54113aa1 (patch)
tree230b1f1cfc4a6cde3285e2fac35c7f9a7a414e17 /parser.c
parent55929c155f929a886a0fe72c1c16a7913830350a (diff)
downloadccc-33d10c0a684eaacb59102e2e2c2494ef54113aa1.tar.gz
we got assignments bois
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c82
1 files changed, 77 insertions, 5 deletions
diff --git a/parser.c b/parser.c
index d4af5a0..8166ea5 100644
--- a/parser.c
+++ b/parser.c
@@ -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);
}