diff options
Diffstat (limited to 'type_checker.c')
| -rw-r--r-- | type_checker.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/type_checker.c b/type_checker.c index 8a07f2a..5905c83 100644 --- a/type_checker.c +++ b/type_checker.c @@ -15,7 +15,6 @@ static struct ast* ast_ref; static struct scope* scope; static void type_check_expr(struct expr_node* node); -static void type_check_lval(struct lval_node* node); static void type_check_stmt(struct stmt_node* node); static void type_check_group(struct group_node* node); @@ -78,13 +77,25 @@ static const struct type_def* resolve_var_ref(struct var_ref_node* node) { } static void type_check_var_decl(struct var_decl_node* node) { - node->def_ref->resolved_type = resolve_type_ref(&node->type); + const struct type_def* lval_type = resolve_type_ref(&node->type); + node->def_ref->resolved_type = lval_type; + if (node->initial_value != NULL) { + type_check_expr(node->initial_value); + assert_cast_compatible(lval_type, node->initial_value->resolved_type); + } } static const struct type_def* resolve_assign(struct assign_node* node) { - type_check_lval(&node->lval); + switch (node->lval->type) { + case EXPR_VAR_REF: + break; + default: + TYPE_PANIC("expression is not assignable"); + } + + type_check_expr(node->lval); type_check_expr(node->rval); - const struct type_def* lval_type = node->lval.resolved_type; + const struct type_def* lval_type = node->lval->resolved_type; const struct type_def* rval_type = node->rval->resolved_type; assert_cast_compatible(lval_type, rval_type); @@ -92,9 +103,12 @@ static const struct type_def* resolve_assign(struct assign_node* node) { } static const struct type_def* resolve_call(struct call_node* node) { - struct args_decl_node* arg_decl = node->called_fn_ref->args; - struct args_eval_node* arg_eval = node->args; + struct decl_list_node* arg_decl = node->called_fn_ref->args; + struct expr_list_node* arg_eval = node->args; while (arg_decl != NULL && arg_eval != NULL) { + if (arg_decl->decl->initial_value != NULL) + TYPE_PANIC("C does not support default arguments"); + type_check_var_decl(arg_decl->decl); const struct type_def* decl_type = arg_decl->decl->def_ref->resolved_type; @@ -127,18 +141,6 @@ static const struct type_def* resolve_binary(struct binary_node* node) { return node->lhs->resolved_type; } -static void type_check_lval(struct lval_node* node) { - switch (node->type) { - case LVAL_VAR_DECL: - type_check_var_decl(&node->inner.var_decl); - node->resolved_type = node->inner.var_decl.def_ref->resolved_type; - break; - case LVAL_VAR_REF: - node->resolved_type = resolve_var_ref(&node->inner.var_ref); - break; - } -} - static void type_check_expr(struct expr_node* node) { switch (node->type) { case EXPR_INT_LIT: @@ -185,10 +187,25 @@ static void type_check_if(struct if_node* node) { exit_scope(node->scope); } +static void type_check_expr_list(struct expr_list_node* node) { + for (; node != NULL; node = node->next) type_check_expr(node->expr); +} + +static void type_check_loop_init(struct loop_init_node* node) { + switch (node->type) { + case INIT_EXPR_LIST: + type_check_expr_list(node->expr_list); + break; + case INIT_DECL: + type_check_var_decl(node->decl); + break; + } +} + static void type_check_loop(struct loop_node* node) { enter_scope(node->scope); - if (node->init != NULL) type_check_expr(node->init); + if (node->init != NULL) type_check_loop_init(node->init); if (node->cond != NULL) type_check_expr(node->cond); if (node->incr != NULL) type_check_expr(node->incr); type_check_stmt(node->body); @@ -238,7 +255,7 @@ static void type_check_fn_decl(struct fn_decl_node* node) { node->resolved_return_type = resolve_type_ref(&node->return_type); - for (struct args_decl_node* arg_decl = node->args; + for (struct decl_list_node* arg_decl = node->args; arg_decl != NULL; arg_decl = arg_decl->next) type_check_var_decl(arg_decl->decl); |
