Type Checking

Helper Functions

  • type_equals
  • expr_typecheck
  • stmt_typecheck
  • decl_typecheck
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
    }
}
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;
    }
}
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);
}