summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c67
1 files changed, 45 insertions, 22 deletions
diff --git a/parser.c b/parser.c
index 9a3e7f3..56fbadd 100644
--- a/parser.c
+++ b/parser.c
@@ -61,15 +61,25 @@ static void expect_kw(const char* kw) {
tok.data.ident = NULL;
}
-static void parse_type(struct type_node* p_node) {
+static void parse_type_ref(struct type_ref_node* p_node) {
/* TODO: modifiers, void rules, arrays, etc. */
/* TODO: struct, union, enum */
expect(TK_IDENT);
- struct type_def* type_def = protected_alloc(sizeof(struct type_def));
- if (!scope_get_type(scope, type_def, tok.data.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);
- p_node->def = type_def;
+ free(tok.data.ident);
+ p_node->def_ref = type_def;
peek_or_panic();
p_node->ptr_level = 0;
@@ -143,15 +153,16 @@ static void parse_args_eval(struct args_eval_node** pp_arg) {
static void parse_expr_call(struct expr_node* p_node) {
switch (p_node->type) {
case EXPR_VAR_REF:
- struct var_def var_def;
+ struct var_def* var_def;
if (!scope_get_var(scope, &var_def, p_node->inner.var_ref.ident))
PARSER_PANIC(
"%s is not a known function", p_node->inner.var_ref.ident);
- if (var_def.loc.type != STO_FN)
+ /* TODO: I would like to include functions in the resolve type rather than checking storage */
+ if (var_def->loc.type != STO_FN)
PARSER_PANIC("called object is not a function");
- p_node->inner.call.called_fn_ref = var_def.loc.decl;
+ p_node->inner.call.called_fn_ref = var_def->loc.decl;
break;
default:
PARSER_PANIC("expression is not callable");
@@ -264,14 +275,16 @@ static void parse_expr(struct expr_node* p_node) {
}
static void parse_var_decl(struct var_decl_node* p_node) {
- parse_type(&p_node->type);
+ parse_type_ref(&p_node->type);
expect(TK_IDENT);
- p_node->ident = tok.data.ident;
- scope_define_var(scope, (struct var_def) {
- .name = p_node->ident,
+
+ p_node->def_ref = scope_define_var(scope, (struct var_def) {
+ .name = tok.data.ident,
.loc.type = STO_UNRESOLVED,
- .sz = 0, /* unknown */
+ .resolved_type = p_node->type.def_ref,
});
+ if (p_node->def_ref == NULL)
+ PARSER_PANIC("redefinition of '%s'", tok.data.ident);
}
static void parse_stmt(struct stmt_node* p_node);
@@ -372,7 +385,15 @@ 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, tok.data.ident)) {
+ } else if (scope_get_type(
+ scope,
+ NULL,
+ &(struct type_key) {
+ .name = tok.data.ident,
+ .how_long = 0,
+ .marked_signed = false,
+ .marked_unsigned = false,
+ })) {
p_node->type = STMT_VAR_DECL;
parse_var_decl(&p_node->inner.var_decl);
break;
@@ -400,18 +421,20 @@ static void parse_args_decl(struct args_decl_node** pp_decl) {
}
static void parse_fn_decl(struct fn_decl_node* p_node) {
- parse_type(&p_node->return_type);
+ parse_type_ref(&p_node->return_type);
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,
- },
- });
+ if (scope_define_var(scope, (struct var_def) {
+ .name = tok.data.ident,
+ .loc = {
+ .type = STO_FN,
+ .decl = p_node,
+ },
+ }) == NULL)
+ PARSER_PANIC("redefinition of '%s'", tok.data.ident)
+
+ p_node->name = tok.data.ident;
expect(TK_LPAREN);