diff options
| author | Carson Fleming <cflems@cflems.net> | 2026-03-27 11:27:08 -1000 |
|---|---|---|
| committer | Carson Fleming <cflems@cflems.net> | 2026-03-27 11:27:08 -1000 |
| commit | 414a608c36b2d8f208ad0223219736d7582948ae (patch) | |
| tree | eeeb284023236a4ee53bb4a78608c3cd1e3992bb /parser.c | |
| parent | fca3bf239cfdf03c4479f5d0c14a21c1fd96ea3e (diff) | |
| download | ccc-414a608c36b2d8f208ad0223219736d7582948ae.tar.gz | |
fix some stuff
Diffstat (limited to 'parser.c')
| -rw-r--r-- | parser.c | 101 |
1 files changed, 53 insertions, 48 deletions
@@ -33,6 +33,12 @@ static void unexpected_token(enum token_type expected) { PARSER_PANIC("unexpected token"); } +/* TODO: reorganize the lexer to make peek cheaper */ +static void peek_or_panic() { + if (!lexer_peek(&tok)) + PARSER_PANIC("unexpected EOF"); +} + static void expect(enum token_type expected) { if (!lexer_pop(&tok)) PARSER_PANIC("unexpected EOF"); @@ -40,46 +46,38 @@ static void expect(enum token_type expected) { if (tok.type != expected) unexpected_token(expected); } -static void peek_or_panic() { - if (!lexer_peek(&tok)) - PARSER_PANIC("unexpected EOF"); -} +static void expect_kw(const char* kw) { + if (!lexer_pop(&tok)) + PARSER_PANIC("unexpected EOF, expected %s", kw); -/* "handle" indicates that we've peeked already */ -static void handle_expr(struct expr_node* p_node); -static void handle_stmt(struct stmt_node* p_node); + if (tok.type != TK_IDENT) + PARSER_PANIC("unexpected token, expected %s", kw); + + if (strcmp(kw, tok.data.ident) != 0) + PARSER_PANIC( + "unexpected identifier %s, expected %s", tok.data.ident, kw); + + /* string won't go in the AST, discard it */ + free(tok.data.ident); + tok.data.ident = NULL; +} -static void handle_type(struct type_node* p_node) { +static void parse_type(struct type_node* p_node) { /* TODO: need some concept of known types in scope */ /* TODO: modifiers, void rules, arrays, etc. */ /* TODO: struct, union, enum */ + expect(TK_IDENT); p_node->name = tok.data.ident; peek_or_panic(); p_node->ptr_level = 0; while (tok.type == TK_STAR) { - p_node->ptr_level++; expect(TK_STAR); + p_node->ptr_level++; + peek_or_panic(); } } -static void parse_return(struct return_node* p_node) { - expect(TK_IDENT); - if (strcmp(tok.data.ident, "return") != 0) - PARSER_PANIC("unexpected token %s; expected: return", tok.data.ident); - - if (!lexer_peek(&tok)) - PARSER_PANIC("unexpected EOF in return statement"); - - if (tok.type == TK_SEMI) { - p_node->ret_val = NULL; - return; - } - - p_node->ret_val = protected_alloc(sizeof(struct expr_node)); - handle_expr(p_node->ret_val); -} - static void parse_int_lit(struct int_lit_node* p_node) { expect(TK_INT_LIT); p_node->val = tok.data.int_lit; @@ -90,7 +88,8 @@ static void parse_var_ref(struct var_ref_node* p_node) { p_node->ident = tok.data.ident; } -static void handle_expr(struct expr_node* p_node) { +static void parse_expr(struct expr_node* p_node) { + peek_or_panic(); switch (tok.type) { case TK_SEMI: p_node->type = EXPR_EMPTY; @@ -108,31 +107,45 @@ static void handle_expr(struct expr_node* p_node) { } } -static void handle_var_decl(struct var_decl_node* p_node) { - handle_type(&p_node->type); +static void parse_var_decl(struct var_decl_node* p_node) { + parse_type(&p_node->type); expect(TK_IDENT); p_node->ident = tok.data.ident; } +static void parse_stmt(struct stmt_node* p_node); + +static void parse_return(struct return_node* p_node) { + expect_kw("return"); + + peek_or_panic(); + if (tok.type == TK_SEMI) { + p_node->ret_val = NULL; + return; + } + + p_node->ret_val = protected_alloc(sizeof(struct expr_node)); + parse_expr(p_node->ret_val); +} + static void parse_group(struct group_node* p_node) { expect(TK_LCURLY); struct stmt_node** pp_node = &p_node->body_head; for (;;) { - if (!lexer_peek(&tok)) - PARSER_PANIC("unexpected EOF in statement group"); - + peek_or_panic(); if (tok.type == TK_RCURLY) break; *pp_node = protected_alloc(sizeof(struct stmt_node)); - handle_stmt(*pp_node); + parse_stmt(*pp_node); pp_node = &((*pp_node)->next); } expect(TK_RCURLY); } -static void handle_stmt(struct stmt_node* p_node) { +static void parse_stmt(struct stmt_node* p_node) { + peek_or_panic(); switch (tok.type) { case TK_LCURLY: p_node->type = STMT_GROUP; @@ -145,45 +158,37 @@ static void handle_stmt(struct stmt_node* p_node) { break; } else if (scope_get_type(scope, NULL, tok.data.ident)) { p_node->type = STMT_VAR_DECL; - handle_var_decl(&p_node->as._var_decl); + parse_var_decl(&p_node->as._var_decl); break; } default: p_node->type = STMT_EXPR; - handle_expr(&p_node->as._expr); + parse_expr(&p_node->as._expr); } expect(TK_SEMI); } static void parse_arg_list(struct var_decl_node** pp_arg) { for (;;) { - expect(TK_IDENT); - *pp_arg = protected_alloc(sizeof(struct var_decl_node)); - handle_var_decl(*pp_arg); + parse_var_decl(*pp_arg); pp_arg = &((*pp_arg)->next); - if (!lexer_peek(&tok)) - PARSER_PANIC("unexpected EOF in argument list"); - + peek_or_panic(); if (tok.type == TK_RPAREN) break; expect(TK_COMMA); } } static void parse_fn_decl(struct fn_decl_node* p_node) { - expect(TK_IDENT); - handle_type(&p_node->return_type); + parse_type(&p_node->return_type); expect(TK_IDENT); p_node->name = tok.data.ident; expect(TK_LPAREN); - if (!lexer_peek(&tok)) - PARSER_PANIC("unexpected EOF in function declaration"); - - + peek_or_panic(); if (tok.type != TK_RPAREN) parse_arg_list(&p_node->args_head); expect(TK_RPAREN); |
