diff options
Diffstat (limited to 'parser.c')
| -rw-r--r-- | parser.c | 165 |
1 files changed, 91 insertions, 74 deletions
@@ -1,6 +1,7 @@ -#include "parser.h" -#include "lexer.h" +#include "type.h" #include "scope.h" +#include "lexer.h" +#include "parser.h" #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -19,15 +20,6 @@ static struct token tok; static struct scope* scope; -static void* protected_alloc(size_t sz) { - void* ptr = calloc(1, sz); - if (ptr == NULL) { - fprintf(stderr, "ccc: out of memory\n"); - exit(1); - } - return ptr; -} - static void unexpected_token(enum token_type expected) { /* TODO: print what token was expected */ PARSER_PANIC("unexpected token; expected %d", expected); @@ -61,33 +53,61 @@ static void expect_kw(const char* kw) { tok.data.ident = NULL; } -static void parse_type_ref(struct type_ref_node* p_node) { +static struct type pointer_type_from_alias( + const struct type_alias* type_alias +) { + switch (type_alias->type.type) { + case TP_DATA: + return (struct type) { + .type = TP_PTR, + .pointer.data_type = type_alias->type.data.data_type, + .pointer.ptr_level = 0, + }; + case TP_PTR: + return type_alias->type; + } + PARSER_PANIC("unhandled type of type case"); +} + +static void parse_type_ref(struct type* p_type) { /* TODO: modifiers, void rules, arrays, etc. */ /* TODO: struct, union, enum */ expect(TK_IDENT); - const struct type_def* type_def; - if (!scope_get_type( - scope, - &type_def, - &(struct type_key) { - .name = tok.data.ident, - /* TODO: parse modifiers */ - .how_long = 0, - .marked_signed = 0, - .marked_unsigned = 0, - })) - PARSER_PANIC("unknown type name: %s", tok.data.ident); + const struct data_type* primitive_type = NULL; + const struct type_alias* type_alias = NULL; - free(tok.data.ident); - p_node->type = (struct type_ref) { - .raw_type = type_def, - .ptr_level = 0, - }; + for (integral_t i = 0; primitive_types[i] != NULL; i++) { + if (strcmp(tok.data.ident, primitive_types[i]->name) == 0) { + primitive_type = primitive_types[i]; + break; + } + } + scope_get_type(scope, &type_alias, tok.data.ident); + if (primitive_type == NULL && type_alias == NULL) + PARSER_PANIC("unknown type name: '%s'", tok.data.ident); + + free(tok.data.ident); peek_or_panic(); + + if (tok.type == TK_STAR) { + if (type_alias != NULL) *p_type = pointer_type_from_alias(type_alias); + else *p_type = (struct type) { + .type = TP_PTR, + .pointer.data_type = primitive_type, + .pointer.ptr_level = 0, + }; + } else { + if (type_alias != NULL) *p_type = type_alias->type; + else *p_type = (struct type) { + .type = TP_DATA, + .data.data_type = primitive_type, + }; + } + while (tok.type == TK_STAR) { expect(TK_STAR); - p_node->type.ptr_level++; + p_type->pointer.ptr_level++; peek_or_panic(); } } @@ -124,7 +144,7 @@ static void parse_var_ref(struct var_ref_node* p_node) { } static void parse_expr_assign(struct expr_node* p_node) { - struct expr_node* lval = protected_alloc(sizeof(struct expr_node)); + struct expr_node* lval = ccc_alloc(sizeof(struct expr_node)); *lval = *p_node; p_node->type = EXPR_ASSIGN; @@ -132,20 +152,20 @@ static void parse_expr_assign(struct expr_node* p_node) { a_node->lval = lval; expect(TK_ASSIGN); - a_node->rval = protected_alloc(sizeof(struct expr_node)); + a_node->rval = ccc_alloc(sizeof(struct expr_node)); parse_expr(a_node->rval); } static void parse_expr_list(struct expr_list_node* p_node) { for (;;) { - p_node->expr = protected_alloc(sizeof(struct expr_node)); + p_node->expr = ccc_alloc(sizeof(struct expr_node)); parse_expr(p_node->expr); peek_or_panic(); if (tok.type != TK_COMMA) break; expect(TK_COMMA); - p_node->next = protected_alloc(sizeof(struct expr_list_node)); + p_node->next = ccc_alloc(sizeof(struct expr_list_node)); p_node = p_node->next; } } @@ -171,7 +191,7 @@ static void parse_expr_call(struct expr_node* p_node) { peek_or_panic(); if (tok.type != TK_RPAREN) { p_node->inner.call.args = - protected_alloc(sizeof(struct expr_list_node)); + ccc_alloc(sizeof(struct expr_list_node)); parse_expr_list(p_node->inner.call.args); } expect(TK_RPAREN); @@ -188,13 +208,13 @@ static void parse_unary(struct unary_node* p_node) { PARSER_PANIC("expected unary operator"); } - p_node->expr = protected_alloc(sizeof(struct expr_node)); + p_node->expr = ccc_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)); + struct expr_node* lhs = ccc_alloc(sizeof(struct expr_node)); + struct expr_node* rhs = ccc_alloc(sizeof(struct expr_node)); *lhs = *p_node; *p_node = (struct expr_node) { @@ -279,7 +299,7 @@ static void parse_var_decl(struct var_decl_node* p_node) { expect(TK_IDENT); p_node->def_ref = scope_define_var(scope, (struct var_def) { - .type = &p_node->type.type, + .type = &p_node->type, .name = tok.data.ident, .loc.type = STO_UNRESOLVED, }); @@ -289,7 +309,7 @@ static void parse_var_decl(struct var_decl_node* p_node) { peek_or_panic(); if (tok.type == TK_ASSIGN) { expect(TK_ASSIGN); - p_node->initial_value = protected_alloc(sizeof(struct expr_node)); + p_node->initial_value = ccc_alloc(sizeof(struct expr_node)); parse_expr(p_node->initial_value); } } @@ -305,7 +325,7 @@ static void parse_return(struct return_node* p_node) { return; } - p_node->ret_val = protected_alloc(sizeof(struct expr_node)); + p_node->ret_val = ccc_alloc(sizeof(struct expr_node)); parse_expr(p_node->ret_val); } @@ -320,7 +340,7 @@ static void parse_group(struct group_node* p_node) { peek_or_panic(); if (tok.type == TK_RCURLY) break; - *pp_node = protected_alloc(sizeof(struct stmt_node)); + *pp_node = ccc_alloc(sizeof(struct stmt_node)); parse_stmt(*pp_node); pp_node = &((*pp_node)->next); } @@ -337,18 +357,18 @@ static void parse_if(struct if_node* p_node) { p_node->scope = scope; expect(TK_LPAREN); - p_node->cond = protected_alloc(sizeof(struct expr_node)); + p_node->cond = ccc_alloc(sizeof(struct expr_node)); parse_expr(p_node->cond); expect(TK_RPAREN); - p_node->true_branch = protected_alloc(sizeof(struct stmt_node)); + p_node->true_branch = ccc_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) { expect_kw("else"); - p_node->false_branch = protected_alloc(sizeof(struct stmt_node)); + p_node->false_branch = ccc_alloc(sizeof(struct stmt_node)); parse_stmt(p_node->false_branch); } @@ -362,31 +382,37 @@ static void parse_while(struct loop_node* p_node) { p_node->scope = scope; expect(TK_LPAREN); - p_node->cond = protected_alloc(sizeof(struct expr_node)); + p_node->cond = ccc_alloc(sizeof(struct expr_node)); parse_expr(p_node->cond); expect(TK_RPAREN); - p_node->body = protected_alloc(sizeof(struct stmt_node)); + p_node->body = ccc_alloc(sizeof(struct stmt_node)); parse_stmt(p_node->body); scope_pop(&scope); } +static bool is_type_token() { + if (tok.type != TK_IDENT) return false; + + /* check primitive types */ + for (integral_t i = 0; primitive_types[i] != NULL; i++) { + if (strcmp(tok.data.ident, primitive_types[i]->name) == 0) return true; + } + + /* check type aliases */ + return scope_get_type(scope, NULL, tok.data.ident); +} + static void parse_loop_init(struct loop_init_node* p_node) { peek_or_panic(); - if (tok.type != TK_IDENT - || !scope_get_type(scope, NULL, &(struct type_key) { - .name = tok.data.ident, - .how_long = 0, - .marked_signed = false, - .marked_unsigned = false, - })) { + if (!is_type_token()) { p_node->type = INIT_EXPR_LIST; - p_node->expr_list = protected_alloc(sizeof(struct expr_list_node)); + p_node->expr_list = ccc_alloc(sizeof(struct expr_list_node)); parse_expr_list(p_node->expr_list); } else { p_node->type = INIT_DECL; - p_node->decl = protected_alloc(sizeof(struct var_decl_node)); + p_node->decl = ccc_alloc(sizeof(struct var_decl_node)); parse_var_decl(p_node->decl); } } @@ -400,24 +426,24 @@ static void parse_for(struct loop_node* p_node) { expect(TK_LPAREN); peek_or_panic(); if (tok.type != TK_SEMI) { - p_node->init = protected_alloc(sizeof(struct loop_init_node)); + p_node->init = ccc_alloc(sizeof(struct loop_init_node)); parse_loop_init(p_node->init); } expect(TK_SEMI); peek_or_panic(); if (tok.type != TK_SEMI) { - p_node->cond = protected_alloc(sizeof(struct expr_node)); + p_node->cond = ccc_alloc(sizeof(struct expr_node)); parse_expr(p_node->cond); } expect(TK_SEMI); peek_or_panic(); if (tok.type != TK_RPAREN) { - p_node->incr = protected_alloc(sizeof(struct expr_node)); + p_node->incr = ccc_alloc(sizeof(struct expr_node)); parse_expr(p_node->incr); } expect(TK_RPAREN); - p_node->body = protected_alloc(sizeof(struct stmt_node)); + p_node->body = ccc_alloc(sizeof(struct stmt_node)); parse_stmt(p_node->body); scope_pop(&scope); @@ -450,15 +476,7 @@ static void parse_stmt(struct stmt_node* p_node) { p_node->type = STMT_RETURN; parse_return(&p_node->inner.return_); break; - } else if (scope_get_type( - scope, - NULL, - &(struct type_key) { - .name = tok.data.ident, - .how_long = 0, - .marked_signed = false, - .marked_unsigned = false, - })) { + } else if (is_type_token()) { p_node->type = STMT_VAR_DECL; parse_var_decl(&p_node->inner.var_decl); break; @@ -473,14 +491,14 @@ static void parse_stmt(struct stmt_node* p_node) { static void parse_decl_list(struct decl_list_node* p_node) { for (;;) { - p_node->decl = protected_alloc(sizeof(struct var_decl_node)); + p_node->decl = ccc_alloc(sizeof(struct var_decl_node)); parse_var_decl(p_node->decl); peek_or_panic(); if (tok.type != TK_COMMA) break; expect(TK_COMMA); - p_node->next = protected_alloc(sizeof(struct decl_list_node)); + p_node->next = ccc_alloc(sizeof(struct decl_list_node)); p_node = p_node->next; } } @@ -511,7 +529,7 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { peek_or_panic(); if (tok.type != TK_RPAREN) { - p_node->args = protected_alloc(sizeof(struct decl_list_node)); + p_node->args = ccc_alloc(sizeof(struct decl_list_node)); parse_decl_list(p_node->args); } @@ -534,12 +552,11 @@ void parse(const char* path, struct ast* ast) { lexer_load(path); scope_push(&scope); ast->root_scope = scope; - scope_install_default_types(ast); struct root_node** p_node = &ast->root_node; for (;;) { - *p_node = protected_alloc(sizeof(struct root_node)); + *p_node = ccc_alloc(sizeof(struct root_node)); if (!parse_root(*p_node)) { free(*p_node); *p_node = NULL; |
