From b48e27f5cc31af65d8bb92d4b81cd03a60c5bcdb Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Thu, 6 Aug 2026 00:24:49 -0400 Subject: clean up yesterday's hacks + functions in type system --- parser.c | 56 +++++++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'parser.c') diff --git a/parser.c b/parser.c index c4fa8b7..d4a55d7 100644 --- a/parser.c +++ b/parser.c @@ -5,6 +5,7 @@ #include #include #include +#include #define PARSER_PANIC(format, ...) {\ fprintf(\ @@ -71,8 +72,10 @@ static struct type pointer_type_from_alias( }; case TP_PTR: return type_alias->type; + case TP_FN: + PARSER_PANIC("function pointers are not currently supported"); } - PARSER_PANIC("unhandled type of type case"); + unreachable(); } static void parse_type_ref(struct type* p_type) { @@ -196,20 +199,10 @@ static void parse_expr_list(struct expr_list_node* p_node) { } static void parse_expr_call(struct expr_node* p_node) { - switch (p_node->type) { - case EXPR_VAR_REF: - struct var_def* var_def = p_node->inner.var_ref.def_ref; - /* TODO: I would like to include functions in the type model rather than checking storage */ - if (var_def->loc.type != STO_FN) - PARSER_PANIC("called object is not a function"); - - p_node->inner.call.fn_ref = var_def->loc.decl; - break; - default: - PARSER_PANIC("expression is not callable"); - } - + struct expr_node* expr = ccc_alloc(sizeof(struct expr_node)); + *expr = *p_node; p_node->type = EXPR_CALL; + p_node->inner.call.expr = expr; p_node->inner.call.args = NULL; expect(TK_LPAREN); @@ -354,7 +347,6 @@ static void parse_decl(const struct type* type, struct decl_node* p_node) { p_node->def_ref = scope_define_var(scope, (struct var_def) { .type = type, .name = tok.data.ident, - .loc.type = STO_UNRESOLVED, }); if (p_node->def_ref == NULL) PARSER_PANIC("redefinition of '%s' in same scope", tok.data.ident); @@ -547,14 +539,17 @@ static void parse_stmt(struct stmt_node* p_node) { expect(TK_SEMI); } -static void parse_fn_arg(struct arg_decl_node* p_node) { +static void parse_arg_decl( + struct type_list* p_type, + struct arg_decl_node* p_node +) { parse_type_ref(&p_node->type); + p_type->type = &p_node->type; expect(TK_IDENT); p_node->def_ref = scope_define_var(scope, (struct var_def) { .type = &p_node->type, .name = tok.data.ident, - .loc.type = STO_UNRESOLVED, }); if (p_node->def_ref == NULL) PARSER_PANIC("redefinition of parameter '%s'", tok.data.ident); @@ -564,7 +559,8 @@ static void parse_fn_arg(struct arg_decl_node* p_node) { expect(TK_COMMA); p_node->next = ccc_alloc(sizeof(struct arg_decl_node)); - parse_fn_arg(p_node->next); + p_type->next = ccc_alloc(sizeof(struct type_list)); + parse_arg_decl(p_type->next, p_node->next); } } @@ -572,20 +568,21 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { if (scope->next_out != NULL) PARSER_PANIC("functions can only be define in the root scope"); - parse_type_ref(&p_node->return_type); + p_node->type.type = TP_FN; + p_node->type.fn.return_type = ccc_alloc(sizeof(struct type)); + parse_type_ref(p_node->type.fn.return_type); expect(TK_IDENT); + p_node->name = tok.data.ident; /* redefinition is allowed */ - scope_define_var(scope, (struct var_def) { - .name = tok.data.ident, - .loc = { - .type = STO_FN, - .decl = p_node, - }, - }); - - p_node->name = tok.data.ident; + if (!scope_get_var(scope, NULL, p_node->name)) + scope_define_var(scope, (struct var_def) { + .type = &p_node->type, + /* name is owned by the var table */ + .name = strdup(p_node->name), + .fn = {.decl = p_node}, + }); expect(TK_LPAREN); @@ -595,7 +592,8 @@ static void parse_fn_decl(struct fn_decl_node* p_node) { peek_or_panic(); if (tok.type != TK_RPAREN) { p_node->args = ccc_alloc(sizeof(struct arg_decl_node)); - parse_fn_arg(p_node->args); + p_node->type.fn.arg_types = ccc_alloc(sizeof(struct type_list)); + parse_arg_decl(p_node->type.fn.arg_types, p_node->args); } expect(TK_RPAREN); -- cgit v1.2.3