summaryrefslogtreecommitdiff
path: root/type_checker.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-07-30 00:20:30 -0400
committerCarson Fleming <cflems@cflems.net>2026-07-30 00:20:52 -0400
commit61531e58066e4d803624ab2c6dac84445fb75e59 (patch)
treec4ed43fdfdbd94c461e7429bbfa6cd46e4e78992 /type_checker.c
parent3445947c072a4cd533f5f3a53178f77361859123 (diff)
downloadccc-61531e58066e4d803624ab2c6dac84445fb75e59.tar.gz
casting
Diffstat (limited to 'type_checker.c')
-rw-r--r--type_checker.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/type_checker.c b/type_checker.c
index 86fe63a..0aaa584 100644
--- a/type_checker.c
+++ b/type_checker.c
@@ -81,13 +81,23 @@ static void type_check_decl_list(struct decl_list_node* node) {
type_check_decl(&node->type, cur);
}
-static const struct type* resolve_assign(struct assign_node* node) {
- switch (node->lval->type) {
+static bool is_expr_assignable(struct expr_node* node) {
+ switch (node->type) {
case EXPR_VAR_REF:
- break;
+ return true;
+ case EXPR_PAREN:
+ const struct expr_list_node* expr_list =
+ node->inner.paren.expr_list;
+ return expr_list->next == NULL
+ && is_expr_assignable(expr_list->expr);
default:
- TYPE_PANIC("expression is not assignable");
+ return false;
}
+}
+
+static const struct type* resolve_assign(struct assign_node* node) {
+ if (!is_expr_assignable(node->lval))
+ TYPE_PANIC("expression is not assignable");
type_check_expr(node->lval);
type_check_expr(node->rval);
@@ -146,6 +156,12 @@ static const struct type* resolve_paren(struct paren_node* node) {
return node->expr_list->resolved_type;
}
+static const struct type* resolve_cast(struct cast_node* node) {
+ type_check_expr(node->expr);
+ assert_cast_compatible(&node->type, node->expr->resolved_type);
+ return &node->type;
+}
+
static void type_check_expr(struct expr_node* node) {
switch (node->type) {
case EXPR_INT_LIT:
@@ -178,6 +194,9 @@ static void type_check_expr(struct expr_node* node) {
case EXPR_PAREN:
node->resolved_type = resolve_paren(&node->inner.paren);
break;
+ case EXPR_CAST:
+ node->resolved_type = resolve_cast(&node->inner.cast);
+ break;
}
}