Ejemplo n.º 1
0
    def descr_lshift(self, space, w_other):

        x = self.bigval

        if isinstance(w_other, W_IntObject):
            shamt = w_other.intval
            if shamt < 0:  # int must be in bigbits range
                raise oefmt(
                    space.w_ValueError,
                    "Integer %s is not a valid binop operand with Bits%d!\n"
                    "Suggestion: 0 <= x <= %s", hex(shamt), self.nbits,
                    get_long_mask(self.nbits).format(BASE16, prefix='0x'))
            return W_BigBits(self.nbits,
                             _rbigint_lshift_maskoff(x, shamt, self.nbits))

        elif isinstance(w_other, W_BigBits):
            if self.nbits != w_other.nbits:
                raise oefmt(
                    space.w_ValueError,
                    "Operands of '<<' (lshift) operation must have matching bitwidth, "
                    "but here Bits%d != Bits%d.\n", self.nbits, w_other.nbits)
            shamt = w_other.bigval
            if shamt.numdigits() > 1:
                return W_BigBits(self.nbits, NULLRBIGINT)  # rare
            shamt = shamt.digit(0)
            return W_BigBits(self.nbits,
                             _rbigint_lshift_maskoff(x, shamt, self.nbits))

        elif type(w_other) is W_LongObject:
            shamt = w_other.num
            if _rbigint_invalid_binop_operand(shamt, self.nbits):
                raise oefmt(
                    space.w_ValueError,
                    "Integer %s is not a valid binop operand with Bits%d!\n"
                    "Suggestion: 0 <= x <= %s",
                    shamt.format(BASE16, prefix='0x'), self.nbits,
                    get_long_mask(self.nbits).format(BASE16, prefix='0x'))
            if shamt.numdigits() > 1:
                return W_BigBits(self.nbits, NULLRBIGINT)  # rare
            shamt = shamt.digit(0)
            return W_BigBits(self.nbits,
                             _rbigint_lshift_maskoff(x, shamt, self.nbits))

        elif isinstance(w_other, W_SmallBits):
            raise oefmt(
                space.w_ValueError,
                "Operands of '<<' (lshift) operation must have matching bitwidth, "
                "but here Bits%d != Bits%d.\n", self.nbits, w_other.nbits)

        raise oefmt(space.w_TypeError,
                    "Please do lshift between <Bits, Bits/int/long> objects")
Ejemplo n.º 2
0
        def descr_cmp(self, space, w_other):
            x = self.bigval

            if isinstance(w_other, W_BigBits):
                if self.nbits != w_other.nbits:
                    raise oefmt(
                        space.w_ValueError,
                        "Operands of '%s' operation must have matching bitwidth, "
                        "but here Bits%d != Bits%d.\n", opname, self.nbits,
                        w_other.nbits)
                return W_SmallBits(1, llop(x, w_other.bigval))

            elif isinstance(w_other, W_SmallBits):
                raise oefmt(
                    space.w_ValueError,
                    "Operands of '%s' operation must have matching bitwidth, "
                    "but here Bits%d != Bits%d.\n", opname, self.nbits,
                    w_other.nbits)

            elif isinstance(w_other, W_IntObject):  # int MUST fit Bits64+
                return W_SmallBits(
                    1,
                    llop(x,
                         get_long_mask(self.nbits).int_and_(w_other.intval)))

            elif type(w_other) is W_LongObject:
                nbits = self.nbits
                y = w_other.num

                if _rbigint_invalid_binop_operand(y, nbits):
                    raise oefmt(
                        space.w_ValueError,
                        "Integer %s is not a valid binop operand with Bits%d!\n"
                        "Suggestion: 0 <= x <= %s",
                        y.format(BASE16, prefix='0x'), nbits,
                        get_long_mask(nbits).format(BASE16, prefix='0x'))

                return W_SmallBits(
                    1, llop(x,
                            get_long_mask(nbits).and_(w_other.num)))

            if opname == 'eq':
                # Match cpython behavior
                return W_SmallBits(1, 0)
            elif opname == 'ne':
                # Match cpython behavior
                return W_SmallBits(1, 1)

            raise oefmt(space.w_TypeError,
                        "Please compare two Bits/int/long objects")
Ejemplo n.º 3
0
        def descr_rbinop(self, space, w_other):
            y = self.bigval
            nbits = self.nbits

            if isinstance(w_other, W_IntObject):  # int MUST fit Bits64+
                z = llop(rbigint.fromint(w_other.intval), y)
                z = z.and_(get_long_mask(nbits))
                return W_BigBits(nbits, z)

            elif type(w_other) is W_LongObject:
                x = w_other.num
                if _rbigint_invalid_binop_operand(x, nbits):
                    raise oefmt(
                        space.w_ValueError,
                        "Integer %s is not a valid binop operand with Bits%d!\n"
                        "Suggestion: 0 <= x <= %s",
                        x.format(BASE16, prefix='0x'), nbits,
                        get_long_mask(nbits).format(BASE16, prefix='0x'))
                z = llop(x, y)
                return W_BigBits(nbits, z.and_(get_long_mask(nbits)))
Ejemplo n.º 4
0
    def _descr_ilshift(self, space, w_other):
        nbits = self.nbits

        if isinstance(w_other, W_BigBits):
            if nbits != w_other.nbits:
                if nbits > w_other.nbits:
                    raise oefmt(
                        space.w_ValueError,
                        "Bitwidth of LHS must be equal to RHS during <<= non-blocking assignment, "
                        "but here LHS Bits%d > RHS Bits%d.\n"
                        "- Suggestion: LHS <<= zext/sext(RHS, nbits/Type)",
                        nbits, w_other.nbits)
                else:
                    raise oefmt(
                        space.w_ValueError,
                        "Bitwidth of LHS must be equal to RHS during <<= non-blocking assignment, "
                        "but here LHS Bits%d < RHS Bits%d.\n"
                        "- Suggestion: LHS <<= trunc(RHS, nbits/Type)", nbits,
                        w_other.nbits)
            self.next_bigval = w_other.bigval

        elif isinstance(w_other, W_IntObject):  # int MUST fit Bits64+
            self.next_bigval = get_long_mask(nbits).int_and_(w_other.intval)

        elif isinstance(w_other, W_LongObject):
            bigval = w_other.num
            if _rbigint_check_exceed_nbits(bigval, nbits):
                raise oefmt(space.w_ValueError, "RHS value %s of <<= is too wide for LHS Bits%d!\n" \
                                                "(Bits%d only accepts %s <= value <= %s)",
                                                bigval.format(BASE16, prefix='0x'), nbits, nbits,
                                                hex(get_int_lower(nbits)), hex(get_int_mask(nbits)))

            self.next_bigval = get_long_mask(nbits).and_(bigval)

        elif isinstance(w_other, W_SmallBits):
            raise oefmt(
                space.w_ValueError,
                "Bitwidth of LHS must be equal to RHS during <<= non-blocking assignment, "
                "but here LHS Bits%d > RHS Bits%d.\n"
                "- Suggestion: LHS <<= zext/sext(RHS, nbits/Type)", nbits,
                w_other.nbits)
        else:
            w_other_bits = space.call_method(w_other, 'to_bits')
            if isinstance(w_other_bits, W_BigBits):
                if nbits != w_other_bits.nbits:
                    if nbits > w_other_bits.nbits:
                        raise oefmt(
                            space.w_ValueError,
                            "Bitwidth of LHS must be equal to RHS to_bits() during <<= non-blocking assignment, "
                            "but here LHS Bits%d > RHS Bits%d.\n"
                            "- Suggestion: LHS <<= zext/sext(RHS, nbits/Type)",
                            nbits, w_other_bits.nbits)
                    else:
                        raise oefmt(
                            space.w_ValueError,
                            "Bitwidth of LHS must be equal to RHS during <<= non-blocking assignment, "
                            "but here LHS Bits%d < RHS Bits%d.\n"
                            "- Suggestion: LHS <<= zext/sext(RHS, nbits/Type)",
                            nbits, w_other_bits.nbits)
                self.next_bigval = w_other_bits.bigval

            elif isinstance(w_other_bits, W_SmallBits):
                raise oefmt(
                    space.w_ValueError,
                    "Bitwidth of LHS must be equal to RHS to_bits() during <<= non-blocking assignment, "
                    "but here LHS Bits%d > RHS Bits%d.\n"
                    "- Suggestion: LHS <<= zext/sext(RHS, nbits/Type)", nbits,
                    w_other_bits.nbits)
            else:
                raise oefmt(space.w_ValueError,
                            "RHS to_bits() must return Bits object!")

        return self
Ejemplo n.º 5
0
    def descr_setitem(self, space, w_index, w_other):
        if type(w_index) is W_SliceObject:
            if space.is_w(w_index.w_step, space.w_None):
                start, stop = _get_slice_range(space, self.nbits,
                                               w_index.w_start, w_index.w_stop)
                slice_nbits = stop - start

                if isinstance(w_other, W_SmallBits):
                    if w_other.nbits != slice_nbits:
                        if w_other.nbits < slice_nbits:
                            raise oefmt(
                                space.w_ValueError,
                                "Cannot fit a Bits%d object into a %d-bit slice [%d:%d]\n"
                                "- Suggestion: sext/zext the RHS",
                                w_other.nbits, slice_nbits, start, stop)
                        else:
                            raise oefmt(
                                space.w_ValueError,
                                "Cannot fit a Bits%d object into a %d-bit slice [%d:%d]\n"
                                "- Suggestion: trunc the RHS", w_other.nbits,
                                slice_nbits, start, stop)

                    self.bigval = setitem_long_int_helper(
                        self.bigval, w_other.intval, start, stop)

                elif isinstance(w_other, W_IntObject):
                    other = w_other.intval
                    up = get_int_mask(slice_nbits)
                    lo = get_int_lower(slice_nbits)

                    if other < lo or other > up:
                        raise oefmt(
                            space.w_ValueError,
                            "Cannot fit value %s into a Bits%d slice!\n"
                            "(Bits%d only accepts %s <= value <= %s)",
                            hex(other), slice_nbits, slice_nbits, hex(lo),
                            hex(up))
                    if slice_nbits < SHIFT:
                        other = other & get_int_mask(slice_nbits)
                        self.bigval = setitem_long_int_helper(
                            self.bigval, other, start, stop)
                    else:
                        other = get_long_mask(slice_nbits).int_and_(other)
                        self.bigval = setitem_long_long_helper(
                            self.bigval, other, start, stop)

                elif isinstance(w_other, W_BigBits):
                    if w_other.nbits != slice_nbits:
                        if w_other.nbits < slice_nbits:
                            raise oefmt(
                                space.w_ValueError,
                                "Cannot fit a Bits%d object into a %d-bit slice [%d:%d]\n"
                                "- Suggestion: sext/zext the RHS",
                                w_other.nbits, slice_nbits, start, stop)
                        else:
                            raise oefmt(
                                space.w_ValueError,
                                "Cannot fit a Bits%d object into a %d-bit slice [%d:%d]\n"
                                "- Suggestion: trunc the RHS", w_other.nbits,
                                slice_nbits, start, stop)

                    self.bigval = setitem_long_long_helper(
                        self.bigval, w_other.bigval, start, stop)

                elif isinstance(w_other, W_LongObject):
                    other = w_other.num
                    if _rbigint_check_exceed_nbits(other, slice_nbits):
                        raise oefmt(
                            space.w_ValueError,
                            "Cannot fit value %s into a Bits%d slice!\n"
                            "(Bits%d only accepts %s <= value <= %s)",
                            other.format(BASE16, prefix='0x'), slice_nbits,
                            slice_nbits, hex(get_int_lower(slice_nbits)),
                            hex(get_int_mask(slice_nbits)))
                    if slice_nbits < SHIFT:
                        other = other.int_and_(
                            get_int_mask(slice_nbits)).digit(0)
                        self.bigval = setitem_long_int_helper(
                            self.bigval, other, start, stop)

                    else:
                        other = other.and_(get_long_mask(slice_nbits))
                        self.bigval = setitem_long_long_helper(
                            self.bigval, other, start, stop)

            else:
                raise oefmt(space.w_IndexError, "Index cannot contain step")

        else:
            index = _get_index(space, self.nbits, w_index)

            # Check value bitlen. No need to check Bits, but check int/long.
            if isinstance(w_other, W_SmallBits):
                o_nbits = w_other.nbits
                if o_nbits > 1:
                    raise oefmt(
                        space.w_ValueError,
                        "Cannot fit a Bits%d object into an 1-bit slice",
                        o_nbits)
                other = w_other.intval  # must be 1-bit and don't even check

                self.bigval = _rbigint_setidx(self.bigval, index, other)

            elif isinstance(w_other, W_IntObject):
                other = w_other.intval
                if other < -1 or other > 1:
                    raise oefmt(space.w_ValueError,
                                "Value %s is too big for the 1-bit slice",
                                hex(other))

                self.bigval = _rbigint_setidx(self.bigval, index, other & 1)

            elif isinstance(w_other, W_BigBits):
                raise oefmt(space.w_ValueError,
                            "Cannot fit a Bits%d object into 1-bit slice",
                            w_other.nbits)

            elif type(w_other) is W_LongObject:
                other = w_other.num
                if other.numdigits() > 1:
                    raise oefmt(space.w_ValueError,
                                "Value %s is too big for the 1-bit slice",
                                other.format(BASE16, prefix='0x'))
                lsw = other.digit(0)
                if lsw > 1:  # -1 and 1 are both 1 here
                    raise oefmt(space.w_ValueError,
                                "Value %s is too big for the 1-bit slice",
                                other.format(BASE16, prefix='0x'))
                self.bigval = _rbigint_setidx(self.bigval, index, lsw)
            else:
                raise oefmt(
                    space.w_TypeError,
                    "Please pass in int/long/Bits value. -- setitem #4")
Ejemplo n.º 6
0
 def descr_invert(self, space):
     return W_BigBits(self.nbits,
                      get_long_mask(self.nbits).sub(self.bigval))
Ejemplo n.º 7
0
        def descr_binop(self, space, w_other):
            # add, sub, mul
            x = self.bigval
            nbits = self.nbits

            if ovf:
                if isinstance(w_other, W_BigBits):
                    if nbits != w_other.nbits:
                        raise oefmt(
                            space.w_ValueError,
                            "Operands of '%s' operation must have matching bitwidth, "
                            "but here Bits%d != Bits%d.\n", opname, nbits,
                            w_other.nbits)
                    z = llop(x, w_other.bigval)
                    if opname == "sub": z = z.and_(get_long_mask(nbits))
                    else: z = _rbigint_maskoff_high(z, nbits)
                    return W_BigBits(nbits, z)

                elif isinstance(w_other, W_IntObject):  # int MUST fit Bits64+
                    z = liop(x, w_other.intval)
                    if opname == "sub": z = z.and_(get_long_mask(nbits))
                    else: z = _rbigint_maskoff_high(z, nbits)
                    return W_BigBits(nbits, z)

                elif isinstance(w_other, W_LongObject):
                    y = w_other.num
                    if _rbigint_invalid_binop_operand(y, nbits):
                        raise oefmt(
                            space.w_ValueError,
                            "Integer %s is not a valid binop operand with Bits%d!\n"
                            "Suggestion: 0 <= x <= %s",
                            y.format(BASE16, prefix='0x'), nbits,
                            get_long_mask(nbits).format(BASE16, prefix='0x'))

                    z = llop(x, y)
                    if opname == "sub": z = z.and_(get_long_mask(nbits))
                    else: z = _rbigint_maskoff_high(z, nbits)
                    return W_BigBits(nbits, z)

                elif isinstance(w_other, W_SmallBits):
                    raise oefmt(
                        space.w_ValueError,
                        "Operands of '%s' operation must have matching bitwidth, "
                        "but here Bits%d != Bits%d.\n", opname, nbits,
                        w_other.nbits)

            # and, or, xor, no overflow
            # opname should be in COMMUTATIVE_OPS
            else:
                if isinstance(w_other, W_BigBits):
                    if nbits != w_other.nbits:
                        raise oefmt(
                            space.w_ValueError,
                            "Operands of '%s' operation must have matching bitwidth, "
                            "but here Bits%d != Bits%d.\n", opname, nbits,
                            w_other.nbits)
                    return W_BigBits(nbits, llop(x, w_other.bigval))

                elif isinstance(w_other, W_IntObject):  # int MUST fit Bits64+
                    return W_BigBits(nbits, liop(x, w_other.intval))

                elif isinstance(w_other, W_LongObject):
                    y = w_other.num
                    if _rbigint_invalid_binop_operand(y, nbits):
                        raise oefmt(
                            space.w_ValueError,
                            "Integer %s is not a valid binop operand with Bits%d!\n"
                            "Suggestion: 0 <= x <= %s",
                            y.format(BASE16, prefix='0x'), nbits,
                            get_long_mask(nbits).format(BASE16, prefix='0x'))
                    return W_BigBits(nbits, llop(x, y))

                elif isinstance(w_other, W_SmallBits):
                    raise oefmt(
                        space.w_ValueError,
                        "Operands of '%s' operation must have matching bitwidth, "
                        "but here Bits%d != Bits%d.\n", opname, nbits,
                        w_other.nbits)
            raise oefmt(space.w_TypeError,
                        "Please do %s between Bits and Bits/int/long objects",
                        opname)