types.c
// Compatibility checks must already have been done before calling this
Compatibility checks must already have been done before calling this
Compatibility checks must already have been done before calling this
Type *composite_type(Type *type1, Type *type2) {
    if (type1->type == TYPE_ARRAY) {
        if (type1->array_size) return type1;
        else if (type2->array_size) return type2;
        else return type1;
    }
    if (type1->type == TYPE_PTR)
        return make_pointer(composite_type(type1->target, type2->target));
    if (type1->type == TYPE_FUNCTION) {
        if (type1->function->param_count == 0 && type2->function->param_count != 0)
            return type2;
        else if (type2->function->param_count == 0 && type1->function->param_count != 0)
            return type1;
        else {
            if (type1->function->param_count != type2->function->param_count)
                error("Incompatible types");
            Type *result = new_type(TYPE_FUNCTION);
            result->target = type1->target;
            Function *function = malloc(sizeof(Function));
            *function = *type1->function;
            function->return_type = type1->function->return_type;
            result->function = function;
            for (int i = 0; i < function->param_count; i++) {
                Type *type = composite_type(type1->function->param_types[i], type2->function->param_types[i]);
                function->param_types[i] = type;
            }
            return result;
        }
    }
    return type1;
}
Type * composite_type ( Type * type1 , Type * type2 ) { if ( type1 -> type == TYPE_ARRAY ) { if ( type1 -> array_size ) return type1 ; else if ( type2 -> array_size ) return type2 ; else return type1 ; } if ( type1 -> type == TYPE_PTR ) return make_pointer ( composite_type ( type1 -> target , type2 -> target ) ) ; if ( type1 -> type == TYPE_FUNCTION ) { if ( type1 -> function -> param_count == 0 && type2 -> function -> param_count != 0 ) return type2 ; else if ( type2 -> function -> param_count == 0 && type1 -> function -> param_count != 0 ) return type1 ; else { if ( type1 -> function -> param_count != type2 -> function -> param_count ) error ( " " ) ; Type * result = new_type ( TYPE_FUNCTION ) ; result -> target = type1 -> target ; Function * function = malloc ( sizeof ( Function ) ) ; * function = * type1 -> function ; function -> return_type = type1 -> function -> return_type ; result -> function = function ; for ( int i = 0 ; i < function -> param_count ; i ++ ) { Type * type = composite_type ( type1 -> function -> param_types [ i ] , type2 -> function -> param_types [ i ] ) ; function -> param_types [ i ] = type ; } return result ; } } return type1 ; }
Compatibility checks must already have been done before calling this
Compatibility checks must already have been done before calling this
// Implicit else, the type->type matches