summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-07-17 13:00:18 -0700
committerCarson Fleming <cflems@cflems.net>2026-07-17 13:00:18 -0700
commitcd1a01e2cf02ad556900219e561ebb64619fc6a5 (patch)
treed76cc861b2305a9bb84d7095cb96c490e92df315
parent424be65858999a894a18e1972fa9649fbc4c1df8 (diff)
downloadccc-cd1a01e2cf02ad556900219e561ebb64619fc6a5.tar.gz
working fib with stubbed typechecker
-rw-r--r--ast.c6
-rw-r--r--ast.h2
-rw-r--r--codegen.c11
-rw-r--r--parser.c21
-rw-r--r--scope.c16
5 files changed, 23 insertions, 33 deletions
diff --git a/ast.c b/ast.c
index f14e1ec..69173bd 100644
--- a/ast.c
+++ b/ast.c
@@ -5,16 +5,11 @@
static void expr_destroy(struct expr_node* node);
static void stmt_destroy(struct stmt_node* node);
-static void var_ref_destroy(struct var_ref_node* node) {
- free(node->ident);
-}
-
static void lval_destroy(struct lval_node* node) {
switch (node->type) {
case LVAL_VAR_DECL:
break;
case LVAL_VAR_REF:
- var_ref_destroy(&node->inner.var_ref);
break;
}
}
@@ -102,7 +97,6 @@ static void expr_destroy(struct expr_node* node) {
str_lit_destroy(&node->inner.str_lit);
break;
case EXPR_VAR_REF:
- var_ref_destroy(&node->inner.var_ref);
break;
case EXPR_ASSIGN:
assign_destroy(&node->inner.assign);
diff --git a/ast.h b/ast.h
index 1eda481..aac846c 100644
--- a/ast.h
+++ b/ast.h
@@ -28,7 +28,7 @@ struct str_lit_node {
};
struct var_ref_node {
- char* ident;
+ struct var_def* def_ref;
};
struct var_decl_node {
diff --git a/codegen.c b/codegen.c
index e1e534c..f126bda 100644
--- a/codegen.c
+++ b/codegen.c
@@ -273,20 +273,13 @@ static void emit_str_lit(
}
}
-static struct var_def* get_var(const char* name) {
- struct var_def* var_def;
- if (!scope_get_var(scope, &var_def, name))
- CGEN_PANIC("reference to undefined variable %s", name);
- return var_def;
-}
-
static void emit_var_ref(
FILE* outfile,
const struct var_ref_node* node,
const struct lval_def* dst
) {
if (dst != NULL) {
- emit_mov(outfile, dst, &get_var(node->ident)->loc);
+ emit_mov(outfile, dst, &node->def_ref->loc);
}
}
@@ -315,7 +308,7 @@ static struct lval_def emit_lval(
.type = var_def->resolved_type,
};
case LVAL_VAR_REF:
- var_def = get_var(node->inner.var_ref.ident);
+ var_def = node->inner.var_ref.def_ref;
return (struct lval_def) {
.loc = var_def->loc,
.type = var_def->resolved_type,
diff --git a/parser.c b/parser.c
index 56fbadd..a213ee4 100644
--- a/parser.c
+++ b/parser.c
@@ -113,9 +113,12 @@ static void parse_literal(struct expr_node* p_node) {
static void parse_var_ref(struct var_ref_node* p_node) {
expect(TK_IDENT);
- p_node->ident = tok.data.ident;
- if (!scope_get_var(scope, NULL, p_node->ident))
- PARSER_PANIC("use of undeclared identifier: '%s'", p_node->ident);
+ struct var_def* var_def;
+ if (!scope_get_var(scope, &var_def, tok.data.ident))
+ PARSER_PANIC("use of undeclared identifier: '%s'", tok.data.ident);
+
+ free(tok.data.ident);
+ p_node->def_ref = var_def;
}
static void parse_expr_assign(struct expr_node* p_node) {
@@ -135,6 +138,7 @@ static void parse_expr_assign(struct expr_node* p_node) {
expect(TK_ASSIGN);
parse_expr(p_node->inner.assign.rval);
+ p_node->resolved_type = p_node->inner.assign.rval->resolved_type;
}
static void parse_args_eval(struct args_eval_node** pp_arg) {
@@ -153,16 +157,13 @@ 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;
- 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);
-
- /* TODO: I would like to include functions in the resolve type rather than checking storage */
+ struct var_def* var_def = p_node->inner.var_ref.def_ref;
+ /* TODO: I would like to include functions in the resolved_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->resolved_type = var_def->loc.decl->return_type.def_ref;
break;
default:
PARSER_PANIC("expression is not callable");
@@ -251,6 +252,8 @@ static void parse_expr(struct expr_node* p_node) {
case TK_IDENT:
p_node->type = EXPR_VAR_REF;
parse_var_ref(&p_node->inner.var_ref);
+ p_node->resolved_type =
+ p_node->inner.var_ref.def_ref->resolved_type;
break;
default:
PARSER_PANIC("expected expression");
diff --git a/scope.c b/scope.c
index 119fc77..2fdadbd 100644
--- a/scope.c
+++ b/scope.c
@@ -163,7 +163,7 @@ void scope_install_default_types(struct scope* scope) {
/* TODO: don't let people make void variables */
scope_define_type(scope, (struct type_def) {
.key = {
- .name = "void",
+ .name = strdup("void"),
.how_long = 0,
.marked_signed = false,
.marked_unsigned = false,
@@ -175,7 +175,7 @@ void scope_install_default_types(struct scope* scope) {
scope_define_type(scope, (struct type_def) {
.key = {
- .name = "bool",
+ .name = strdup("bool"),
.how_long = 0,
.marked_signed = false,
.marked_unsigned = false,
@@ -187,7 +187,7 @@ void scope_install_default_types(struct scope* scope) {
scope_define_type(scope, (struct type_def) {
.key = {
- .name = "char",
+ .name = strdup("char"),
.how_long = 0,
.marked_signed = false,
.marked_unsigned = false,
@@ -199,7 +199,7 @@ void scope_install_default_types(struct scope* scope) {
scope_define_type(scope, (struct type_def) {
.key = {
- .name = "short",
+ .name = strdup("short"),
.how_long = 0,
.marked_signed = false,
.marked_unsigned = false,
@@ -211,7 +211,7 @@ void scope_install_default_types(struct scope* scope) {
scope_define_type(scope, (struct type_def) {
.key = {
- .name = "int",
+ .name = strdup("int"),
.how_long = 0,
.marked_signed = false,
.marked_unsigned = false,
@@ -223,7 +223,7 @@ void scope_install_default_types(struct scope* scope) {
scope_define_type(scope, (struct type_def) {
.key = {
- .name = "long",
+ .name = strdup("long"),
.how_long = 0,
.marked_signed = false,
.marked_unsigned = false,
@@ -235,7 +235,7 @@ void scope_install_default_types(struct scope* scope) {
scope_define_type(scope, (struct type_def) {
.key = {
- .name = "float",
+ .name = strdup("float"),
.how_long = 0,
.marked_signed = false,
.marked_unsigned = false,
@@ -247,7 +247,7 @@ void scope_install_default_types(struct scope* scope) {
scope_define_type(scope, (struct type_def) {
.key = {
- .name = "double",
+ .name = strdup("double"),
.how_long = 0,
.marked_signed = false,
.marked_unsigned = false,