summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-07-26 19:20:30 -0700
committerCarson Fleming <cflems@cflems.net>2026-07-26 19:20:30 -0700
commit4f9d0247549b06ddb25b76bb425541190105cb48 (patch)
tree56f191c3611fc7509e6350138ce03c20956b656f /parser.c
parent6a169de321b131e73b86967a1a8564365217275a (diff)
downloadccc-4f9d0247549b06ddb25b76bb425541190105cb48.tar.gz
functioning type system perhaps?
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c165
1 files changed, 91 insertions, 74 deletions
diff --git a/parser.c b/parser.c
index 7bad30f..c2eadbe 100644
--- a/parser.c
+++ b/parser.c
@@ -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;