#include "ast.h" #include "scope.h" #include #include #define TYPE_PANIC(format, ...) {\ fprintf(\ stderr,\ "ccc: type error: " format "\n" __VA_OPT__(,)\ __VA_ARGS__);\ exit(1);\ } static struct scope* scope; static void type_check_group(struct group_node* node); static void type_check_expr(struct expr_node* node) {} static void type_check_var_decl(struct var_decl_node* node) {} static void type_check_return(struct return_node* node) {} static void type_check_stmt(struct stmt_node* node) { switch (node->type) { case STMT_EMPTY: break; case STMT_EXPR: type_check_expr(&node->inner.expr); break; case STMT_VAR_DECL: type_check_var_decl(&node->inner.var_decl); break; case STMT_RETURN: type_check_return(&node->inner.return_); break; case STMT_GROUP: type_check_group(&node->inner.group); break; } } static void type_check_group(struct group_node* node) { if (node->scope->next_out != scope) TYPE_PANIC("scopes are borked"); scope = node->scope; struct stmt_node* stmt = node->head; while (stmt != NULL) { type_check_stmt(stmt); stmt = stmt->next; } } static void type_check_fn_decl(struct fn_decl_node* node) { scope = node->scope; type_check_group(&node->body); } static void type_check_root(struct root_node* node) { switch (node->type) { case ROOT_FN_DECL: type_check_fn_decl(&node->inner.fn_decl); break; } } void type_check(struct ast* ast) { scope = ast->root_scope; struct root_node* node = ast->root_node; while (node != NULL) { type_check_root(node); node = node->next; } }