PageRenderTime 27ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/objspace/std/intobject.py

https://github.com/thepian/pypy
Python | 322 lines | 251 code | 49 blank | 22 comment | 47 complexity | 6db098a67af4b9bedcabeda43e560b86 MD5 | raw file
  1. from pypy.interpreter.error import OperationError
  2. from pypy.objspace.std.model import registerimplementation, W_Object
  3. from pypy.objspace.std.register_all import register_all
  4. from pypy.objspace.std.multimethod import FailedToImplementArgs
  5. from pypy.objspace.std.noneobject import W_NoneObject
  6. from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift, LONG_BIT, r_uint
  7. from pypy.rlib.rbigint import rbigint
  8. from pypy.objspace.std.inttype import wrapint
  9. """
  10. In order to have the same behavior running
  11. on CPython, and after RPython translation we use ovfcheck
  12. from rarithmetic to explicitly check for overflows,
  13. something CPython does not do anymore.
  14. """
  15. class W_IntObject(W_Object):
  16. __slots__ = 'intval'
  17. _immutable_ = True
  18. from pypy.objspace.std.inttype import int_typedef as typedef
  19. def __init__(w_self, intval):
  20. w_self.intval = intval
  21. def __repr__(w_self):
  22. """ representation for debugging purposes """
  23. return "%s(%d)" % (w_self.__class__.__name__, w_self.intval)
  24. def unwrap(w_self, space):
  25. return int(w_self.intval)
  26. registerimplementation(W_IntObject)
  27. # NB: This code is shared by smallintobject.py, and thus no other Int
  28. # multimethods should be invoked from these implementations. Instead, add an
  29. # alias and then teach copy_multimethods in smallintobject.py to override
  30. # it. See int__Int for example.
  31. def int_w__Int(space, w_int1):
  32. return int(w_int1.intval)
  33. def uint_w__Int(space, w_int1):
  34. intval = w_int1.intval
  35. if intval < 0:
  36. raise OperationError(space.w_ValueError,
  37. space.wrap("cannot convert negative integer to unsigned"))
  38. else:
  39. return r_uint(intval)
  40. def bigint_w__Int(space, w_int1):
  41. return rbigint.fromint(w_int1.intval)
  42. def repr__Int(space, w_int1):
  43. a = w_int1.intval
  44. res = str(a)
  45. return space.wrap(res)
  46. str__Int = repr__Int
  47. def declare_new_int_comparison(opname):
  48. import operator
  49. from pypy.tool.sourcetools import func_with_new_name
  50. op = getattr(operator, opname)
  51. def f(space, w_int1, w_int2):
  52. i = w_int1.intval
  53. j = w_int2.intval
  54. return space.newbool(op(i, j))
  55. name = "%s__Int_Int" % (opname,)
  56. return func_with_new_name(f, name), name
  57. for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']:
  58. func, name = declare_new_int_comparison(op)
  59. globals()[name] = func
  60. def hash__Int(space, w_int1):
  61. # unlike CPython, we don't special-case the value -1 in most of our
  62. # hash functions, so there is not much sense special-casing it here either.
  63. # Make sure this is consistent with the hash of floats and longs.
  64. return get_integer(space, w_int1)
  65. # coerce
  66. def coerce__Int_Int(space, w_int1, w_int2):
  67. return space.newtuple([w_int1, w_int2])
  68. def add__Int_Int(space, w_int1, w_int2):
  69. x = w_int1.intval
  70. y = w_int2.intval
  71. try:
  72. z = ovfcheck(x + y)
  73. except OverflowError:
  74. raise FailedToImplementArgs(space.w_OverflowError,
  75. space.wrap("integer addition"))
  76. return wrapint(space, z)
  77. def sub__Int_Int(space, w_int1, w_int2):
  78. x = w_int1.intval
  79. y = w_int2.intval
  80. try:
  81. z = ovfcheck(x - y)
  82. except OverflowError:
  83. raise FailedToImplementArgs(space.w_OverflowError,
  84. space.wrap("integer substraction"))
  85. return wrapint(space, z)
  86. def mul__Int_Int(space, w_int1, w_int2):
  87. x = w_int1.intval
  88. y = w_int2.intval
  89. try:
  90. z = ovfcheck(x * y)
  91. except OverflowError:
  92. raise FailedToImplementArgs(space.w_OverflowError,
  93. space.wrap("integer multiplication"))
  94. return wrapint(space, z)
  95. def floordiv__Int_Int(space, w_int1, w_int2):
  96. x = w_int1.intval
  97. y = w_int2.intval
  98. try:
  99. z = ovfcheck(x // y)
  100. except ZeroDivisionError:
  101. raise OperationError(space.w_ZeroDivisionError,
  102. space.wrap("integer division by zero"))
  103. except OverflowError:
  104. raise FailedToImplementArgs(space.w_OverflowError,
  105. space.wrap("integer division"))
  106. return wrapint(space, z)
  107. div__Int_Int = floordiv__Int_Int
  108. def truediv__Int_Int(space, w_int1, w_int2):
  109. x = float(w_int1.intval)
  110. y = float(w_int2.intval)
  111. if y == 0.0:
  112. raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float division"))
  113. return space.wrap(x / y)
  114. def mod__Int_Int(space, w_int1, w_int2):
  115. x = w_int1.intval
  116. y = w_int2.intval
  117. try:
  118. z = ovfcheck(x % y)
  119. except ZeroDivisionError:
  120. raise OperationError(space.w_ZeroDivisionError,
  121. space.wrap("integer modulo by zero"))
  122. except OverflowError:
  123. raise FailedToImplementArgs(space.w_OverflowError,
  124. space.wrap("integer modulo"))
  125. return wrapint(space, z)
  126. def divmod__Int_Int(space, w_int1, w_int2):
  127. x = w_int1.intval
  128. y = w_int2.intval
  129. try:
  130. z = ovfcheck(x // y)
  131. except ZeroDivisionError:
  132. raise OperationError(space.w_ZeroDivisionError,
  133. space.wrap("integer divmod by zero"))
  134. except OverflowError:
  135. raise FailedToImplementArgs(space.w_OverflowError,
  136. space.wrap("integer modulo"))
  137. # no overflow possible
  138. m = x % y
  139. w = space.wrap
  140. return space.newtuple([w(z), w(m)])
  141. # helper for pow()
  142. def _impl_int_int_pow(space, iv, iw, iz=0):
  143. if iw < 0:
  144. if iz != 0:
  145. raise OperationError(space.w_TypeError,
  146. space.wrap("pow() 2nd argument "
  147. "cannot be negative when 3rd argument specified"))
  148. ## bounce it, since it always returns float
  149. raise FailedToImplementArgs(space.w_ValueError,
  150. space.wrap("integer exponentiation"))
  151. temp = iv
  152. ix = 1
  153. try:
  154. while iw > 0:
  155. if iw & 1:
  156. ix = ovfcheck(ix*temp)
  157. iw >>= 1 #/* Shift exponent down by 1 bit */
  158. if iw==0:
  159. break
  160. temp = ovfcheck(temp*temp) #/* Square the value of temp */
  161. if iz:
  162. #/* If we did a multiplication, perform a modulo */
  163. ix = ix % iz;
  164. temp = temp % iz;
  165. if iz:
  166. ix = ix % iz
  167. except OverflowError:
  168. raise FailedToImplementArgs(space.w_OverflowError,
  169. space.wrap("integer exponentiation"))
  170. return wrapint(space, ix)
  171. def pow__Int_Int_Int(space, w_int1, w_int2, w_int3):
  172. x = w_int1.intval
  173. y = w_int2.intval
  174. z = w_int3.intval
  175. if z == 0:
  176. raise OperationError(space.w_ValueError,
  177. space.wrap("pow() 3rd argument cannot be 0"))
  178. return _impl_int_int_pow(space, x, y, z)
  179. def pow__Int_Int_None(space, w_int1, w_int2, w_int3):
  180. x = w_int1.intval
  181. y = w_int2.intval
  182. return _impl_int_int_pow(space, x, y)
  183. def neg__Int(space, w_int1):
  184. a = w_int1.intval
  185. try:
  186. x = ovfcheck(-a)
  187. except OverflowError:
  188. raise FailedToImplementArgs(space.w_OverflowError,
  189. space.wrap("integer negation"))
  190. return wrapint(space, x)
  191. get_negint = neg__Int
  192. def abs__Int(space, w_int1):
  193. if w_int1.intval >= 0:
  194. return get_integer(space, w_int1)
  195. else:
  196. return get_negint(space, w_int1)
  197. def nonzero__Int(space, w_int1):
  198. return space.newbool(w_int1.intval != 0)
  199. def invert__Int(space, w_int1):
  200. x = w_int1.intval
  201. a = ~x
  202. return wrapint(space, a)
  203. def lshift__Int_Int(space, w_int1, w_int2):
  204. a = w_int1.intval
  205. b = w_int2.intval
  206. if b < 0:
  207. raise OperationError(space.w_ValueError,
  208. space.wrap("negative shift count"))
  209. if a == 0 or b == 0:
  210. return get_integer(space, w_int1)
  211. if b >= LONG_BIT:
  212. raise FailedToImplementArgs(space.w_OverflowError,
  213. space.wrap("integer left shift"))
  214. try:
  215. c = ovfcheck_lshift(a, b)
  216. except OverflowError:
  217. raise FailedToImplementArgs(space.w_OverflowError,
  218. space.wrap("integer left shift"))
  219. return wrapint(space, c)
  220. def rshift__Int_Int(space, w_int1, w_int2):
  221. a = w_int1.intval
  222. b = w_int2.intval
  223. if b < 0:
  224. raise OperationError(space.w_ValueError,
  225. space.wrap("negative shift count"))
  226. if a == 0 or b == 0:
  227. return get_integer(space, w_int1)
  228. if b >= LONG_BIT:
  229. if a < 0:
  230. a = -1
  231. else:
  232. a = 0
  233. else:
  234. a = a >> b
  235. return wrapint(space, a)
  236. def and__Int_Int(space, w_int1, w_int2):
  237. a = w_int1.intval
  238. b = w_int2.intval
  239. res = a & b
  240. return wrapint(space, res)
  241. def xor__Int_Int(space, w_int1, w_int2):
  242. a = w_int1.intval
  243. b = w_int2.intval
  244. res = a ^ b
  245. return wrapint(space, res)
  246. def or__Int_Int(space, w_int1, w_int2):
  247. a = w_int1.intval
  248. b = w_int2.intval
  249. res = a | b
  250. return wrapint(space, res)
  251. # int__Int is supposed to do nothing, unless it has
  252. # a derived integer object, where it should return
  253. # an exact one.
  254. def int__Int(space, w_int1):
  255. if space.is_w(space.type(w_int1), space.w_int):
  256. return w_int1
  257. a = w_int1.intval
  258. return wrapint(space, a)
  259. get_integer = int__Int
  260. pos__Int = int__Int
  261. def index__Int(space, w_int1):
  262. return get_integer(space, w_int1)
  263. def float__Int(space, w_int1):
  264. a = w_int1.intval
  265. x = float(a)
  266. return space.newfloat(x)
  267. def oct__Int(space, w_int1):
  268. return space.wrap(oct(w_int1.intval))
  269. def hex__Int(space, w_int1):
  270. return space.wrap(hex(w_int1.intval))
  271. def getnewargs__Int(space, w_int1):
  272. return space.newtuple([wrapint(space, w_int1.intval)])
  273. register_all(vars())