summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-08-06 00:24:49 -0400
committerCarson Fleming <cflems@cflems.net>2026-08-06 00:24:49 -0400
commitb48e27f5cc31af65d8bb92d4b81cd03a60c5bcdb (patch)
tree0901fba9ff451968d758ed47b57ff99d1330fb8a /parser.c
parenta207a7f39514f03ddfafbe39e52a3fae57a414b4 (diff)
downloadccc-b48e27f5cc31af65d8bb92d4b81cd03a60c5bcdb.tar.gz
clean up yesterday's hacks + functions in type system
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c56
1 files changed, 27 insertions, 29 deletions
diff --git a/parser.c b/parser.c
index c4fa8b7..d4a55d7 100644
--- a/parser.c
+++ b/parser.c
@@ -5,6 +5,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <stddef.h>
#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);