From 155d1971b7cd56d3206808c36c6b40357bc31cbb Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Fri, 17 Jul 2026 03:20:34 -0700 Subject: almost fibonacci but it needs the type checker --- parser.c | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'parser.c') diff --git a/parser.c b/parser.c index e078ae9..9a3e7f3 100644 --- a/parser.c +++ b/parser.c @@ -30,10 +30,9 @@ static void* protected_alloc(size_t sz) { static void unexpected_token(enum token_type expected) { /* TODO: print what token was expected */ - PARSER_PANIC("unexpected token"); + PARSER_PANIC("unexpected token; expected %d", expected); } -/* TODO: reorganize the lexer to make peek cheaper */ static void peek_or_panic() { if (!lexer_peek(&tok)) PARSER_PANIC("unexpected EOF"); @@ -311,6 +310,25 @@ static void parse_group(struct group_node* p_node) { expect(TK_RCURLY); } +static void parse_if(struct if_node* p_node) { + expect_kw("if"); + + expect(TK_LPAREN); + p_node->cond = protected_alloc(sizeof(struct expr_node)); + parse_expr(p_node->cond); + expect(TK_RPAREN); + + p_node->true_branch = protected_alloc(sizeof(struct stmt_node)); + parse_stmt(p_node->true_branch); + + peek_or_panic(); + if (tok.type != TK_IDENT || strcmp(tok.data.ident, "else") != 0) return; + expect_kw("else"); + + p_node->false_branch = protected_alloc(sizeof(struct stmt_node)); + parse_stmt(p_node->false_branch); +} + static void parse_stmt_assign(struct stmt_node* p_node) { peek_or_panic(); if (tok.type != TK_ASSIGN) return; @@ -346,7 +364,11 @@ static void parse_stmt(struct stmt_node* p_node) { parse_group(&p_node->inner.group); return; case TK_IDENT: - if (strcmp(tok.data.ident, "return") == 0) { + if (strcmp(tok.data.ident, "if") == 0) { + p_node->type = STMT_IF; + parse_if(&p_node->inner.if_); + return; + } else if (strcmp(tok.data.ident, "return") == 0) { p_node->type = STMT_RETURN; parse_return(&p_node->inner.return_); break; @@ -383,6 +405,14 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { expect(TK_IDENT); p_node->name = tok.data.ident; + scope_define_var(scope, (struct var_def) { + .name = p_node->name, + .loc = { + .type = STO_FN, + .decl = p_node, + }, + }); + expect(TK_LPAREN); scope_push(&scope); @@ -393,15 +423,6 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { expect(TK_RPAREN); - /* defining here makes recursion possible */ - scope_define_var(scope, (struct var_def) { - .name = p_node->name, - .loc = { - .type = STO_FN, - .decl = p_node, - }, - }); - parse_group(&p_node->body); scope_pop(&scope); -- cgit v1.2.3