# Type Checking - [[typing|Type System]] ## Helper Functions - `type_equals` - `expr_typecheck` - `stmt_typecheck` - `decl_typecheck` ```c int type_equals(struct type *, ...) { // Be prepared to accetp null if (a->kind != b->kind) return 0; if (a->kind == TYPE_ARRAY) return type_equals(a->subtype, b->subtype); if (a->kind == TYPE_FUNC) { // Check param_list recursively } } ``` ```c struct type *expr_typecheck(struct expr *e) { if (!e) return NULL; switch (e->kind) { case EXPR_IDENT: return e->symbol->type; break; case EXPR_INT_LITERAL: return type_create(TYPE_INTEGER, NULL, NULL) break; case EXPR_OR: L = expr_typecheck(e->left) R = expr_typecheck(e->right) if (L->kind == TYPE_BOOLEAN && R->kind == TYPE_BOOLEAN) return type_create(TYPE_BOOLEAN, 0, 0) else { /* Generate an error message using expr_print * Pick a propriet type to return * So that typechecking continues */ error_count++; } case EXPR_CALL: L = expr_typecheck(e->left); if (L->kind != TYPE_FUNCTION) { // error message return type_create(TYPE_VOID) } param_typecheck(L->params, e->right); return e->left->symbol->type->subtype; } } ``` ```c void decl_typecheck(struct decl *d) { if (!d) return; t = expr_typecheck(d->value); if (type_equals(d->type, t)) { // good } else { // error } stmt_typecheck(d->code); decl_typecheck(d->next); } ``` - [[name-resolution|Symbol resolution]] connects an identifier to a type. - Type-check for statements.