# 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.