diff options
Diffstat (limited to 'parser.c')
| -rw-r--r-- | parser.c | 100 |
1 files changed, 57 insertions, 43 deletions
@@ -66,8 +66,8 @@ static void parse_type(struct type_node* p_node) { /* TODO: modifiers, void rules, arrays, etc. */ /* TODO: struct, union, enum */ expect(TK_IDENT); - struct type_def type_def; - if (!scope_get_type(scope, &type_def, tok.data.ident)) + struct type_def* type_def = protected_alloc(sizeof(struct type_def)); + if (!scope_get_type(scope, type_def, tok.data.ident)) PARSER_PANIC("unknown type name: %s", tok.data.ident); p_node->def = type_def; @@ -90,12 +90,12 @@ static void parse_literal(struct expr_node* p_node) { case TK_INT_LIT: expect(TK_INT_LIT); p_node->type = EXPR_INT_LIT; - p_node->as._int_lit.val = tok.data.int_lit; + p_node->inner.int_lit.val = tok.data.int_lit; break; case TK_CHAR_LIT: expect(TK_CHAR_LIT); p_node->type = EXPR_CHAR_LIT; - p_node->as._char_lit.val = tok.data.char_lit; + p_node->inner.char_lit.val = tok.data.char_lit; break; default: PARSER_PANIC("invalid literal type"); @@ -105,14 +105,16 @@ static void parse_literal(struct expr_node* p_node) { static void parse_var_ref(struct var_ref_node* p_node) { expect(TK_IDENT); p_node->ident = tok.data.ident; + if (!scope_get_var(scope, NULL, p_node->ident)) + PARSER_PANIC("use of undeclared identifier: '%s'", p_node->ident); } static void parse_expr_assign(struct expr_node* p_node) { switch (p_node->type) { case EXPR_VAR_REF: - p_node->as._assign.lval = (struct lval_node) { + p_node->inner.assign.lval = (struct lval_node) { .type = LVAL_VAR_REF, - .as._var_ref = p_node->as._var_ref, + .inner.var_ref = p_node->inner.var_ref, }; return; default: @@ -120,16 +122,17 @@ static void parse_expr_assign(struct expr_node* p_node) { } p_node->type = EXPR_ASSIGN; - p_node->as._assign.rval = protected_alloc(sizeof(struct expr_node)); + p_node->inner.assign.rval = protected_alloc(sizeof(struct expr_node)); expect(TK_ASSIGN); - parse_expr(p_node->as._assign.rval); + parse_expr(p_node->inner.assign.rval); } -static void parse_arg_evals(struct expr_node** pp_arg) { +static void parse_args_eval(struct args_eval_node** pp_arg) { for (;;) { - *pp_arg = protected_alloc(sizeof(struct expr_node)); - parse_expr(*pp_arg); + *pp_arg = protected_alloc(sizeof(struct args_eval_node)); + (*pp_arg)->expr = protected_alloc(sizeof(struct expr_node)); + parse_expr((*pp_arg)->expr); pp_arg = &((*pp_arg)->next); peek_or_panic(); @@ -142,25 +145,25 @@ static void parse_expr_call(struct expr_node* p_node) { switch (p_node->type) { case EXPR_VAR_REF: struct var_def var_def; - if (!scope_get_var(scope, &var_def, p_node->as._var_ref.ident)) + if (!scope_get_var(scope, &var_def, p_node->inner.var_ref.ident)) PARSER_PANIC( - "%s is not a known function", p_node->as._var_ref.ident); + "%s is not a known function", p_node->inner.var_ref.ident); if (var_def.loc.type != STO_FN) PARSER_PANIC("called object is not a function"); - p_node->as._call.called_fn = var_def.loc.decl; + p_node->inner.call.called_fn_ref = var_def.loc.decl; break; default: PARSER_PANIC("expression is not callable"); } p_node->type = EXPR_CALL; - p_node->as._call.args_head = NULL; + p_node->inner.call.args = NULL; expect(TK_LPAREN); peek_or_panic(); - if (tok.type != TK_RPAREN) parse_arg_evals(&p_node->as._call.args_head); + if (tok.type != TK_RPAREN) parse_args_eval(&p_node->inner.call.args); expect(TK_RPAREN); } @@ -186,7 +189,7 @@ static void parse_expr_binary(struct expr_node* p_node) { *lhs = *p_node; *p_node = (struct expr_node) { .type = EXPR_BINARY, - .as._binary = { + .inner.binary = { .lhs = lhs, .rhs = rhs, }, @@ -196,19 +199,19 @@ static void parse_expr_binary(struct expr_node* p_node) { switch (tok.type) { case TK_PLUS: expect(TK_PLUS); - p_node->as._binary.op = BINARY_ADD; + p_node->inner.binary.op = BINARY_ADD; break; case TK_NEG: expect(TK_NEG); - p_node->as._binary.op = BINARY_SUB; + p_node->inner.binary.op = BINARY_SUB; break; case TK_STAR: expect(TK_STAR); - p_node->as._binary.op = BINARY_MUL; + p_node->inner.binary.op = BINARY_MUL; break; case TK_DIV: expect(TK_DIV); - p_node->as._binary.op = BINARY_DIV; + p_node->inner.binary.op = BINARY_DIV; break; default: PARSER_PANIC("expected binary operator"); @@ -227,7 +230,7 @@ static void parse_expr(struct expr_node* p_node) { break; case TK_NEG: p_node->type = EXPR_UNARY; - parse_unary(&p_node->as._unary); + parse_unary(&p_node->inner.unary); break; case TK_INT_LIT: case TK_CHAR_LIT: @@ -237,7 +240,7 @@ static void parse_expr(struct expr_node* p_node) { break; case TK_IDENT: p_node->type = EXPR_VAR_REF; - parse_var_ref(&p_node->as._var_ref); + parse_var_ref(&p_node->inner.var_ref); break; default: PARSER_PANIC("expected expression"); @@ -265,6 +268,7 @@ 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; + scope_define_var(scope, (struct var_def) { .name = p_node->ident }); } static void parse_stmt(struct stmt_node* p_node); @@ -285,7 +289,10 @@ static void parse_return(struct return_node* p_node) { static void parse_group(struct group_node* p_node) { expect(TK_LCURLY); - struct stmt_node** pp_node = &p_node->body_head; + scope_push(&scope); + p_node->scope = scope; + + struct stmt_node** pp_node = &p_node->head; for (;;) { peek_or_panic(); if (tok.type == TK_RCURLY) break; @@ -295,6 +302,8 @@ static void parse_group(struct group_node* p_node) { pp_node = &((*pp_node)->next); } + scope_pop(&scope); + expect(TK_RCURLY); } @@ -304,9 +313,9 @@ static void parse_stmt_assign(struct stmt_node* p_node) { switch (p_node->type) { case STMT_VAR_DECL: - p_node->as._expr.as._assign.lval = (struct lval_node) { + p_node->inner.expr.inner.assign.lval = (struct lval_node) { .type = LVAL_VAR_DECL, - .as._var_decl = p_node->as._var_decl, + .inner.var_decl = p_node->inner.var_decl, }; break; default: @@ -314,12 +323,12 @@ static void parse_stmt_assign(struct stmt_node* p_node) { } p_node->type = STMT_EXPR; - p_node->as._expr.type = EXPR_ASSIGN; - p_node->as._expr.as._assign.rval = + p_node->inner.expr.type = EXPR_ASSIGN; + p_node->inner.expr.inner.assign.rval = protected_alloc(sizeof(struct expr_node)); expect(TK_ASSIGN); - parse_expr(p_node->as._expr.as._assign.rval); + parse_expr(p_node->inner.expr.inner.assign.rval); } static void parse_stmt(struct stmt_node* p_node) { @@ -330,32 +339,33 @@ static void parse_stmt(struct stmt_node* p_node) { break; case TK_LCURLY: p_node->type = STMT_GROUP; - parse_group(&p_node->as._group); + parse_group(&p_node->inner.group); return; case TK_IDENT: if (strcmp(tok.data.ident, "return") == 0) { p_node->type = STMT_RETURN; - parse_return(&p_node->as._return); + parse_return(&p_node->inner.return_); break; } else if (scope_get_type(scope, NULL, tok.data.ident)) { p_node->type = STMT_VAR_DECL; - parse_var_decl(&p_node->as._var_decl); + parse_var_decl(&p_node->inner.var_decl); break; } default: p_node->type = STMT_EXPR; - parse_expr(&p_node->as._expr); + parse_expr(&p_node->inner.expr); } parse_stmt_assign(p_node); expect(TK_SEMI); } -static void parse_arg_decls(struct var_decl_node** pp_arg) { +static void parse_args_decl(struct args_decl_node** pp_decl) { for (;;) { - *pp_arg = protected_alloc(sizeof(struct var_decl_node)); - parse_var_decl(*pp_arg); - pp_arg = &((*pp_arg)->next); + *pp_decl = protected_alloc(sizeof(struct args_decl_node)); + (*pp_decl)->decl = protected_alloc(sizeof(struct var_decl_node)); + parse_var_decl((*pp_decl)->decl); + pp_decl = &((*pp_decl)->next); peek_or_panic(); if (tok.type == TK_RPAREN) break; @@ -371,13 +381,18 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { expect(TK_LPAREN); + scope_push(&scope); + p_node->scope = scope; + peek_or_panic(); - if (tok.type != TK_RPAREN) parse_arg_decls(&p_node->args_head); + if (tok.type != TK_RPAREN) parse_args_decl(&p_node->args); expect(TK_RPAREN); parse_group(&p_node->body); + scope_pop(&scope); + scope_define_var(scope, (struct var_def) { .name = p_node->name, .loc = { @@ -391,17 +406,17 @@ static bool parse_root(struct root_node* p_node) { if (!lexer_peek(&tok)) return false; p_node->type = ROOT_FN_DECL; - parse_fn_decl(&p_node->as._fn_decl); + parse_fn_decl(&p_node->inner.fn_decl); return true; } -struct root_node* parse(const char* path) { +void parse(const char* path, struct ast* ast) { lexer_load(path); scope_push(&scope); scope_install_default_types(scope); - struct root_node* root; - struct root_node** p_node = &root; + ast->root_scope = scope; + struct root_node** p_node = &ast->root_node; for (;;) { *p_node = protected_alloc(sizeof(struct root_node)); @@ -415,5 +430,4 @@ struct root_node* parse(const char* path) { scope_pop(&scope); lexer_close(); - return root; } |
