Beispiel #1
0
def expose_struct2vector(struct):
    return values_struct.struct2vector(struct)
Beispiel #2
0
def expose_struct2vector(struct):
    return values_struct.struct2vector(struct)
Beispiel #3
0
def equal_func_impl(a, b, info, env, cont, n):
    from pycket.interpreter import return_value

    if a.eqv(b):
        return return_value(values.w_true, env, cont)

    for_chaperone = jit.promote(info).for_chaperone
    if (for_chaperone >= EqualInfo.CHAPERONE and b.is_non_interposing_chaperone()):
        return equal_func_unroll_n(a, b.get_proxied(), info, env, cont, n)

    # Enter into chaperones/impersonators if we have permission to do so
    if ((for_chaperone == EqualInfo.CHAPERONE and a.is_chaperone()) or
        (for_chaperone == EqualInfo.IMPERSONATOR and a.is_impersonator())):
        return equal_func_unroll_n(a.get_proxied(), b, info, env, cont, n)

    # If we are doing a chaperone/impersonator comparison, then we do not have
    # a chaperone-of/impersonator-of relation if `a` is not a proxy and
    # `b` is a proxy.
    if for_chaperone != EqualInfo.BASIC and not a.is_proxy() and b.is_proxy():
        return return_value(values.w_false, env, cont)

    if isinstance(a, values_string.W_String) and isinstance(b, values_string.W_String):
        is_chaperone = for_chaperone == EqualInfo.CHAPERONE
        if is_chaperone and (not a.immutable() or not b.immutable()):
            return return_value(values.w_false, env, cont)
        return return_value(values.W_Bool.make(a.equal(b)), env, cont)

    if isinstance(a, values.W_Bytes) and isinstance(b, values.W_Bytes):
        is_chaperone = info.for_chaperone == EqualInfo.CHAPERONE
        if is_chaperone and (not a.immutable() or not b.immutable()):
            return return_value(values.w_false, env, cont)
        return return_value(values.W_Bool.make(a.equal(b)), env, cont)

    if isinstance(a, values.W_Cons) and isinstance(b, values.W_Cons):
        cont = equal_car_cont(a.cdr(), b.cdr(), info, env, cont)
        return equal_func_unroll_n(a.car(), b.car(), info, env, cont, n)

    if isinstance(a, values.W_MCons) and isinstance(b, values.W_MCons):
        cont = equal_car_cont(a.cdr(), b.cdr(), info, env, cont)
        return equal_func_unroll_n(a.car(), b.car(), info, env, cont, n)

    if isinstance(a, values.W_Box) and isinstance(b, values.W_Box):
        is_chaperone = for_chaperone == EqualInfo.CHAPERONE
        if is_chaperone and (not a.immutable() or not b.immutable()):
            return return_value(values.w_false, env, cont)
        return a.unbox(env, equal_unbox_right_cont(b, info, env, cont))

    if isinstance(a, values.W_MVector) and isinstance(b, values.W_MVector):
        is_chaperone = for_chaperone == EqualInfo.CHAPERONE
        if is_chaperone and (not a.immutable() or not b.immutable()):
            return return_value(values.w_false, env, cont)
        if a.length() != b.length():
            return return_value(values.w_false, env, cont)
        return equal_vec_func(a, b, 0, info, env, cont)

    if isinstance(a, values_struct.W_RootStruct) and isinstance(b, values_struct.W_RootStruct):
        a_type = a.struct_type()
        b_type = b.struct_type()
        w_prop = a_type.read_prop(values_struct.w_prop_equal_hash)
        if w_prop:
            w_prop = b_type.read_prop(values_struct.w_prop_equal_hash)
            if w_prop:
                w_equal_proc, w_hash_proc, w_hash2_proc = equal_hash_args(w_prop)
                # FIXME: it should work with cycles properly and be an equal?-recur
                w_equal_recur = equalp.w_prim
                return w_equal_proc.call([a, b, w_equal_recur], env, cont)
        if not a_type.isopaque and not b_type.isopaque:
            # This is probably not correct even if struct2vector were done
            # correct, due to side effects, but it is close enough for now.
            # Though the racket documentation says that `equal?` can elide
            # impersonator/chaperone handlers.
            a_imm = a_type.all_fields_immutable()
            b_imm = b_type.all_fields_immutable()
            a = values_struct.struct2vector(a, immutable=a_imm)
            b = values_struct.struct2vector(b, immutable=b_imm)
            return equal_func_unroll_n(a, b, info, env, cont, n)

    if for_chaperone == EqualInfo.BASIC and a.is_proxy() and b.is_proxy():
        return equal_func_unroll_n(a.get_proxied(), b.get_proxied(), info, env, cont, n)

    if a.equal(b):
        return return_value(values.w_true, env, cont)

    return return_value(values.w_false, env, cont)