Source: int.js

  1. /* jslint nomen: true, bitwise: true */
  2. /* global Sk: true */
  3. /**
  4. * @namespace Sk.builtin
  5. */
  6. /**
  7. * @constructor
  8. * Sk.builtin.int_
  9. *
  10. * @description
  11. * Constructor for Python int. If provided number is greater than integer threshold, will return a Python long instead.
  12. *
  13. * type int, all integers are created with this method, it is also used
  14. * for the builtin int()
  15. *
  16. * Takes also implemented `__int__` and `__trunc__` methods for x into account
  17. * and tries to use `__index__` and/or `__int__` if base is not a number
  18. *
  19. * @extends {Sk.builtin.numtype}
  20. *
  21. * @param {!(Object|number)} x Python object or Javascript number to convert to Python int
  22. * @param {!(Object|number|Sk.builtin.none)=} base Optional base, can only be used when x is Sk.builtin.str
  23. * @return {(Sk.builtin.int_|Sk.builtin.lng)} Python int (or long, if overflow)
  24. */
  25. Sk.builtin.int_ = function (x, base) {
  26. var val;
  27. var func;
  28. var ret; // return value
  29. var magicName; // name of magic method
  30. if (!(this instanceof Sk.builtin.int_)) {
  31. return new Sk.builtin.int_(x, base);
  32. }
  33. if (this instanceof Sk.builtin.bool) {
  34. return this;
  35. }
  36. if (x instanceof Sk.builtin.int_ && base === undefined) {
  37. this.v = x.v;
  38. return this;
  39. }
  40. // if base is not of type int, try calling .__index__
  41. if(base !== Sk.builtin.none.none$ && base !== undefined && !Sk.builtin.checkInt(base)) {
  42. if (Sk.builtin.checkFloat(base)) {
  43. throw new Sk.builtin.TypeError("integer argument expected, got " + Sk.abstr.typeName(base));
  44. } else if (base.__index__) {
  45. base = Sk.misceval.callsimArray(base.__index__, [base]);
  46. } else if(base.__int__) {
  47. base = Sk.misceval.callsimArray(base.__int__, [base]);
  48. } else {
  49. throw new Sk.builtin.AttributeError(Sk.abstr.typeName(base) + " instance has no attribute '__index__' or '__int__'");
  50. }
  51. }
  52. if (x instanceof Sk.builtin.str) {
  53. base = Sk.builtin.asnum$(base);
  54. if (base === Sk.builtin.none.none$) {
  55. base = 10;
  56. }
  57. val = Sk.str2number(x.v, base, parseInt, function (x) {
  58. return -x;
  59. }, "int");
  60. if ((val > Sk.builtin.int_.threshold$) || (val < -Sk.builtin.int_.threshold$)) {
  61. // Too big for int, convert to long
  62. return new Sk.builtin.lng(x, base);
  63. }
  64. this.v = val;
  65. return this;
  66. }
  67. if (base !== undefined && base !== Sk.builtin.none.none$) {
  68. throw new Sk.builtin.TypeError("int() can't convert non-string with explicit base");
  69. }
  70. if (x === undefined || x === Sk.builtin.none) {
  71. x = 0;
  72. }
  73. /**
  74. * try calling special methods:
  75. * 1. __int__
  76. * 2. __trunc__
  77. */
  78. if(x !== undefined && (x.tp$getattr && (func = x.tp$getattr(Sk.builtin.str.$int_)))) {
  79. // calling a method which contains im_self and im_func
  80. // causes skulpt to automatically map the im_self as first argument
  81. ret = Sk.misceval.callsimArray(func);
  82. magicName = "__int__";
  83. } else if(x !== undefined && x.__int__) {
  84. // required for internal types
  85. // __int__ method is on prototype
  86. ret = Sk.misceval.callsimArray(x.__int__, [x]);
  87. magicName = "__int__";
  88. } else if(x !== undefined && (x.tp$getattr && (func = x.tp$getattr(Sk.builtin.str.$trunc)))) {
  89. ret = Sk.misceval.callsimArray(func);
  90. magicName = "__trunc__";
  91. } else if(x !== undefined && x.__trunc__) {
  92. ret = Sk.misceval.callsimArray(x.__trunc__, [x]);
  93. magicName = "__trunc__";
  94. }
  95. // check return type of magic methods
  96. if(ret !== undefined && !Sk.builtin.checkInt(ret)) {
  97. throw new Sk.builtin.TypeError(magicName + " returned non-Integral (type " + Sk.abstr.typeName(ret)+")");
  98. } else if(ret !== undefined){
  99. x = ret; // valid return value, proceed in function
  100. }
  101. // check type even without magic numbers
  102. if(!Sk.builtin.checkNumber(x)) {
  103. throw new Sk.builtin.TypeError("int() argument must be a string or a number, not '" + Sk.abstr.typeName(x) + "'");
  104. }
  105. x = Sk.builtin.asnum$(x);
  106. if (x > Sk.builtin.int_.threshold$ || x < -Sk.builtin.int_.threshold$) {
  107. return new Sk.builtin.lng(x);
  108. }
  109. if ((x > -1) && (x < 1)) {
  110. x = 0;
  111. }
  112. this.v = parseInt(x, base);
  113. return this;
  114. };
  115. Sk.builtin.int_.$shiftconsts = [0.5, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648, 4294967296, 8589934592, 17179869184, 34359738368, 68719476736, 137438953472, 274877906944, 549755813888, 1099511627776, 2199023255552, 4398046511104, 8796093022208, 17592186044416, 35184372088832, 70368744177664, 140737488355328, 281474976710656, 562949953421312, 1125899906842624, 2251799813685248, 4503599627370496, 9007199254740992];
  116. Sk.abstr.setUpInheritance("int", Sk.builtin.int_, Sk.builtin.numtype);
  117. /* NOTE: See constants used for kwargs in constants.js */
  118. Sk.builtin.int_.prototype.nb$int_ = function () {
  119. return this;
  120. };
  121. Sk.builtin.int_.prototype.nb$float_ = function() {
  122. return new Sk.builtin.float_(this.v);
  123. };
  124. Sk.builtin.int_.prototype.nb$lng = function () {
  125. return new Sk.builtin.lng(this.v);
  126. };
  127. /**
  128. * Python wrapper of `__trunc__` dunder method.
  129. *
  130. * @instance
  131. */
  132. Sk.builtin.int_.prototype.__trunc__ = new Sk.builtin.func(function(self) {
  133. return self;
  134. });
  135. /**
  136. * Python wrapper of `__index__` dunder method.
  137. *
  138. * @instance
  139. */
  140. Sk.builtin.int_.prototype.__index__ = new Sk.builtin.func(function(self) {
  141. return self;
  142. });
  143. /**
  144. * Python wrapper of `__complex__` dunder method.
  145. *
  146. * @instance
  147. */
  148. Sk.builtin.int_.prototype.__complex__ = new Sk.builtin.func(function(self) {
  149. return Sk.builtin.NotImplemented.NotImplemented$;
  150. });
  151. /**
  152. * Return this instance's Javascript value.
  153. *
  154. * Javascript function, returns Javascript object.
  155. *
  156. * @return {number} This instance's value.
  157. */
  158. Sk.builtin.int_.prototype.tp$index = function () {
  159. return this.v;
  160. };
  161. /** @override */
  162. Sk.builtin.int_.prototype.tp$hash = function () {
  163. //the hash of all numbers should be an int and since javascript doesn't really
  164. //care every number can be an int.
  165. return new Sk.builtin.int_(this.v);
  166. };
  167. /**
  168. * Threshold to determine when types should be converted to long.
  169. *
  170. * Note: be sure to check against threshold in both positive and negative directions.
  171. *
  172. * @type {number}
  173. */
  174. Sk.builtin.int_.threshold$ = Math.pow(2, 53) - 1;
  175. /**
  176. * Returns a copy of this instance.
  177. *
  178. * Javascript function, returns Python object.
  179. *
  180. * @return {Sk.builtin.int_} The copy
  181. */
  182. Sk.builtin.int_.prototype.clone = function () {
  183. return new Sk.builtin.int_(this.v);
  184. };
  185. /** @override */
  186. Sk.builtin.int_.prototype.nb$add = function (other) {
  187. var thisAsLong, thisAsFloat;
  188. var result;
  189. if (other instanceof Sk.builtin.int_) {
  190. result = this.v + other.v;
  191. if (result > Sk.builtin.int_.threshold$ ||
  192. result < -Sk.builtin.int_.threshold$) {
  193. thisAsLong = new Sk.builtin.lng(this.v);
  194. return thisAsLong.nb$add(other);
  195. }
  196. return new Sk.builtin.int_(result);
  197. }
  198. if (other instanceof Sk.builtin.lng) {
  199. thisAsLong = new Sk.builtin.lng(this.v);
  200. return thisAsLong.nb$add(other);
  201. }
  202. if (other instanceof Sk.builtin.float_) {
  203. thisAsFloat = new Sk.builtin.float_(this.v);
  204. return thisAsFloat.nb$add(other);
  205. }
  206. return Sk.builtin.NotImplemented.NotImplemented$;
  207. };
  208. /** @override */
  209. Sk.builtin.int_.prototype.nb$reflected_add = function (other) {
  210. // Should not automatically call this.nb$add, as nb$add may have
  211. // been overridden by a subclass
  212. return Sk.builtin.int_.prototype.nb$add.call(this, other);
  213. };
  214. /** @override */
  215. Sk.builtin.int_.prototype.nb$subtract = function (other) {
  216. var thisAsLong, thisAsFloat;
  217. var result;
  218. if (other instanceof Sk.builtin.int_) {
  219. result = this.v - other.v;
  220. if (result > Sk.builtin.int_.threshold$ ||
  221. result < -Sk.builtin.int_.threshold$) {
  222. thisAsLong = new Sk.builtin.lng(this.v);
  223. return thisAsLong.nb$subtract(other);
  224. }
  225. return new Sk.builtin.int_(result);
  226. }
  227. if (other instanceof Sk.builtin.lng) {
  228. thisAsLong = new Sk.builtin.lng(this.v);
  229. return thisAsLong.nb$subtract(other);
  230. }
  231. if (other instanceof Sk.builtin.float_) {
  232. thisAsFloat = new Sk.builtin.float_(this.v);
  233. return thisAsFloat.nb$subtract(other);
  234. }
  235. return Sk.builtin.NotImplemented.NotImplemented$;
  236. };
  237. /** @override */
  238. Sk.builtin.int_.prototype.nb$reflected_subtract = function (other) {
  239. // Should not automatically call this.nb$add, as nb$add may have
  240. // been overridden by a subclass
  241. var negative_this = this.nb$negative();
  242. return Sk.builtin.int_.prototype.nb$add.call(negative_this, other);
  243. };
  244. /** @override */
  245. Sk.builtin.int_.prototype.nb$multiply = function (other) {
  246. var product, thisAsLong, thisAsFloat;
  247. if (other instanceof Sk.builtin.int_) {
  248. product = this.v * other.v;
  249. if (product > Sk.builtin.int_.threshold$ ||
  250. product < -Sk.builtin.int_.threshold$) {
  251. thisAsLong = new Sk.builtin.lng(this.v);
  252. return thisAsLong.nb$multiply(other);
  253. } else {
  254. return new Sk.builtin.int_(product);
  255. }
  256. }
  257. if (other instanceof Sk.builtin.lng) {
  258. thisAsLong = new Sk.builtin.lng(this.v);
  259. return thisAsLong.nb$multiply(other);
  260. }
  261. if (other instanceof Sk.builtin.float_) {
  262. thisAsFloat = new Sk.builtin.float_(this.v);
  263. return thisAsFloat.nb$multiply(other);
  264. }
  265. return Sk.builtin.NotImplemented.NotImplemented$;
  266. };
  267. /** @override */
  268. Sk.builtin.int_.prototype.nb$reflected_multiply = function (other) {
  269. // Should not automatically call this.nb$multiply, as nb$multiply may have
  270. // been overridden by a subclass
  271. return Sk.builtin.int_.prototype.nb$multiply.call(this, other);
  272. };
  273. /** @override */
  274. Sk.builtin.int_.prototype.nb$divide = function (other) {
  275. var thisAsLong, thisAsFloat;
  276. if (Sk.__future__.division) {
  277. thisAsFloat = new Sk.builtin.float_(this.v);
  278. return thisAsFloat.nb$divide(other);
  279. }
  280. if (other instanceof Sk.builtin.int_) {
  281. return this.nb$floor_divide(other);
  282. }
  283. if (other instanceof Sk.builtin.lng) {
  284. thisAsLong = new Sk.builtin.lng(this.v);
  285. return thisAsLong.nb$divide(other);
  286. }
  287. if (other instanceof Sk.builtin.float_) {
  288. thisAsFloat = new Sk.builtin.float_(this.v);
  289. return thisAsFloat.nb$divide(other);
  290. }
  291. return Sk.builtin.NotImplemented.NotImplemented$;
  292. };
  293. /** @override */
  294. Sk.builtin.int_.prototype.nb$reflected_divide = function (other) {
  295. return this.nb$reflected_floor_divide(other);
  296. };
  297. /** @override */
  298. Sk.builtin.int_.prototype.nb$floor_divide = function (other) {
  299. var thisAsLong, thisAsFloat;
  300. if (other instanceof Sk.builtin.int_) {
  301. if (other.v === 0) {
  302. throw new Sk.builtin.ZeroDivisionError("integer division or modulo by zero");
  303. }
  304. return new Sk.builtin.int_(Math.floor(this.v / other.v));
  305. }
  306. if (other instanceof Sk.builtin.lng) {
  307. thisAsLong = new Sk.builtin.lng(this.v);
  308. return thisAsLong.nb$floor_divide(other);
  309. }
  310. if (other instanceof Sk.builtin.float_) {
  311. thisAsFloat = new Sk.builtin.float_(this.v);
  312. return thisAsFloat.nb$floor_divide(other);
  313. }
  314. return Sk.builtin.NotImplemented.NotImplemented$;
  315. };
  316. /** @override */
  317. Sk.builtin.int_.prototype.nb$reflected_floor_divide = function (other) {
  318. if (other instanceof Sk.builtin.int_) {
  319. return other.nb$divide(this);
  320. }
  321. return Sk.builtin.NotImplemented.NotImplemented$;
  322. };
  323. /** @override */
  324. Sk.builtin.int_.prototype.nb$remainder = function (other) {
  325. var thisAsLong, thisAsFloat;
  326. var tmp;
  327. var divResult;
  328. if (other instanceof Sk.builtin.int_) {
  329. // Javacript logic on negatives doesn't work for Python... do this instead
  330. divResult = Sk.abstr.numberBinOp(this, other, "FloorDiv");
  331. tmp = Sk.abstr.numberBinOp(divResult, other, "Mult");
  332. tmp = Sk.abstr.numberBinOp(this, tmp, "Sub");
  333. tmp = tmp.v;
  334. if (other.v < 0 && tmp === 0) {
  335. tmp = -0.0; // otherwise the sign gets lost by javascript modulo
  336. } else if (tmp === 0 && Infinity/tmp === -Infinity) {
  337. tmp = 0.0;
  338. }
  339. return new Sk.builtin.int_(tmp);
  340. }
  341. if (other instanceof Sk.builtin.lng) {
  342. thisAsLong = new Sk.builtin.lng(this.v);
  343. return thisAsLong.nb$remainder(other);
  344. }
  345. if (other instanceof Sk.builtin.float_) {
  346. thisAsFloat = new Sk.builtin.float_(this.v);
  347. return thisAsFloat.nb$remainder(other);
  348. }
  349. return Sk.builtin.NotImplemented.NotImplemented$;
  350. };
  351. /** @override */
  352. Sk.builtin.int_.prototype.nb$reflected_remainder = function (other) {
  353. if (other instanceof Sk.builtin.int_) {
  354. return other.nb$remainder(this);
  355. }
  356. return Sk.builtin.NotImplemented.NotImplemented$;
  357. };
  358. /** @override */
  359. Sk.builtin.int_.prototype.nb$divmod = function (other) {
  360. var thisAsLong, thisAsFloat;
  361. if (other instanceof Sk.builtin.int_) {
  362. return new Sk.builtin.tuple([
  363. this.nb$floor_divide(other),
  364. this.nb$remainder(other)
  365. ]);
  366. }
  367. if (other instanceof Sk.builtin.lng) {
  368. thisAsLong = new Sk.builtin.lng(this.v);
  369. return thisAsLong.nb$divmod(other);
  370. }
  371. if (other instanceof Sk.builtin.float_) {
  372. thisAsFloat = new Sk.builtin.float_(this.v);
  373. return thisAsFloat.nb$divmod(other);
  374. }
  375. return Sk.builtin.NotImplemented.NotImplemented$;
  376. };
  377. /** @override */
  378. Sk.builtin.int_.prototype.nb$reflected_divmod = function (other) {
  379. if (other instanceof Sk.builtin.int_) {
  380. return new Sk.builtin.tuple([
  381. other.nb$floor_divide(this),
  382. other.nb$remainder(this)
  383. ]);
  384. }
  385. return Sk.builtin.NotImplemented.NotImplemented$;
  386. };
  387. /** @override */
  388. Sk.builtin.int_.prototype.nb$power = function (other, mod) {
  389. var power, ret, thisAsLong, thisAsFloat;
  390. if (other instanceof Sk.builtin.int_ && (mod === undefined || mod instanceof Sk.builtin.int_)) {
  391. power = Math.pow(this.v, other.v);
  392. if (power > Sk.builtin.int_.threshold$ ||
  393. power < -Sk.builtin.int_.threshold$) {
  394. thisAsLong = new Sk.builtin.lng(this.v);
  395. ret = thisAsLong.nb$power(other, mod);
  396. } else if (other.v < 0) {
  397. ret = new Sk.builtin.float_(power);
  398. } else {
  399. ret = new Sk.builtin.int_(power);
  400. }
  401. if (mod !== undefined) {
  402. if (other.v < 0) {
  403. throw new Sk.builtin.TypeError("pow() 2nd argument cannot be negative when 3rd argument specified");
  404. }
  405. return ret.nb$remainder(mod);
  406. } else {
  407. return ret;
  408. }
  409. }
  410. if (other instanceof Sk.builtin.lng) {
  411. thisAsLong = new Sk.builtin.lng(this.v);
  412. return thisAsLong.nb$power(other);
  413. }
  414. if (other instanceof Sk.builtin.float_) {
  415. thisAsFloat = new Sk.builtin.float_(this.v);
  416. return thisAsFloat.nb$power(other);
  417. }
  418. return Sk.builtin.NotImplemented.NotImplemented$;
  419. };
  420. /** @override */
  421. Sk.builtin.int_.prototype.nb$reflected_power = function (other, mod) {
  422. if (other instanceof Sk.builtin.int_) {
  423. return other.nb$power(this, mod);
  424. }
  425. return Sk.builtin.NotImplemented.NotImplemented$;
  426. };
  427. /** @override */
  428. Sk.builtin.int_.prototype.nb$abs = function () {
  429. return new Sk.builtin.int_(Math.abs(this.v));
  430. };
  431. /**
  432. * Compute the bitwise AND of this instance and a Python object (i.e. this & other).
  433. *
  434. * Returns NotImplemented if bitwise AND operation between int and other type is unsupported.
  435. *
  436. * Javscript function, returns Python object.
  437. *
  438. * @param {!Sk.builtin.object} other The Python object to AND with this one
  439. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the conjunction
  440. */
  441. Sk.builtin.int_.prototype.nb$and = function (other) {
  442. var thisAsLong, thisAsFloat;
  443. if (other instanceof Sk.builtin.int_) {
  444. var tmp;
  445. other = Sk.builtin.asnum$(other);
  446. tmp = this.v & other;
  447. if ((tmp !== undefined) && (tmp < 0)) {
  448. tmp = tmp + 4294967296; // convert back to unsigned
  449. }
  450. if (tmp !== undefined) {
  451. return new Sk.builtin.int_(tmp);
  452. }
  453. }
  454. if (other instanceof Sk.builtin.lng) {
  455. thisAsLong = new Sk.builtin.lng(this.v);
  456. return thisAsLong.nb$and(other);
  457. }
  458. return Sk.builtin.NotImplemented.NotImplemented$;
  459. };
  460. Sk.builtin.int_.prototype.nb$reflected_and = Sk.builtin.int_.prototype.nb$and;
  461. /**
  462. * Compute the bitwise OR of this instance and a Python object (i.e. this | other).
  463. *
  464. * Returns NotImplemented if bitwise OR operation between int and other type is unsupported.
  465. *
  466. * Javscript function, returns Python object.
  467. *
  468. * @param {!Sk.builtin.object} other The Python object to OR with this one
  469. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the disjunction
  470. */
  471. Sk.builtin.int_.prototype.nb$or = function (other) {
  472. var thisAsLong;
  473. if (other instanceof Sk.builtin.int_) {
  474. var tmp;
  475. other = Sk.builtin.asnum$(other);
  476. tmp = this.v | other;
  477. if ((tmp !== undefined) && (tmp < 0)) {
  478. tmp = tmp + 4294967296; // convert back to unsigned
  479. }
  480. if (tmp !== undefined) {
  481. return new Sk.builtin.int_(tmp);
  482. }
  483. }
  484. if (other instanceof Sk.builtin.lng) {
  485. thisAsLong = new Sk.builtin.lng(this.v);
  486. return thisAsLong.nb$and(other);
  487. }
  488. return Sk.builtin.NotImplemented.NotImplemented$;
  489. };
  490. Sk.builtin.int_.prototype.nb$reflected_or = Sk.builtin.int_.prototype.nb$or;
  491. /**
  492. * Compute the bitwise XOR of this instance and a Python object (i.e. this ^ other).
  493. *
  494. * Returns NotImplemented if bitwise XOR operation between int and other type is unsupported.
  495. *
  496. * Javscript function, returns Python object.
  497. *
  498. * @param {!Sk.builtin.object} other The Python object to XOR with this one
  499. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the exclusive disjunction
  500. */
  501. Sk.builtin.int_.prototype.nb$xor = function (other) {
  502. var thisAsLong;
  503. if (other instanceof Sk.builtin.int_) {
  504. var tmp;
  505. other = Sk.builtin.asnum$(other);
  506. tmp = this.v ^ other;
  507. if ((tmp !== undefined) && (tmp < 0)) {
  508. tmp = tmp + 4294967296; // convert back to unsigned
  509. }
  510. if (tmp !== undefined) {
  511. return new Sk.builtin.int_(tmp);
  512. }
  513. }
  514. if (other instanceof Sk.builtin.lng) {
  515. thisAsLong = new Sk.builtin.lng(this.v);
  516. return thisAsLong.nb$xor(other);
  517. }
  518. return Sk.builtin.NotImplemented.NotImplemented$;
  519. };
  520. Sk.builtin.int_.prototype.nb$reflected_xor = Sk.builtin.int_.prototype.nb$xor;
  521. /**
  522. * Compute the bitwise left shift of this instance by a Python object (i.e. this << other).
  523. *
  524. * Returns NotImplemented if bitwise left shift operation between int and other type is unsupported.
  525. *
  526. * Javscript function, returns Python object.
  527. *
  528. * @param {!Sk.builtin.object} other The Python object by which to left shift
  529. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the left shift
  530. */
  531. Sk.builtin.int_.prototype.nb$lshift = function (other) {
  532. var thisAsLong;
  533. if (this.v === 0) {
  534. return this;
  535. }
  536. if (other instanceof Sk.builtin.int_) {
  537. var tmp;
  538. var shift = Sk.builtin.asnum$(other);
  539. if (shift !== undefined) {
  540. if (shift < 0) {
  541. throw new Sk.builtin.ValueError("negative shift count");
  542. }
  543. if (shift > 53) {
  544. return new Sk.builtin.lng(this.v).nb$lshift(new Sk.builtin.int_(shift));
  545. }
  546. tmp = this.v * 2 * Sk.builtin.int_.$shiftconsts[shift];
  547. if (tmp > Sk.builtin.int_.threshold$ || tmp < -Sk.builtin.int_.threshold$) {
  548. // Fail, recompute with longs
  549. return new Sk.builtin.lng(tmp);
  550. }
  551. }
  552. if (tmp !== undefined) {
  553. tmp = /** @type {number} */ (tmp);
  554. return new Sk.builtin.int_(tmp);
  555. }
  556. }
  557. if (other instanceof Sk.builtin.lng) {
  558. thisAsLong = new Sk.builtin.lng(this.v);
  559. return thisAsLong.nb$lshift(other);
  560. }
  561. return Sk.builtin.NotImplemented.NotImplemented$;
  562. };
  563. Sk.builtin.int_.prototype.nb$reflected_lshift = function (other) {
  564. if (other instanceof Sk.builtin.int_) {
  565. return other.nb$lshift(this);
  566. }
  567. return Sk.builtin.NotImplemented.NotImplemented$;
  568. };
  569. /**
  570. * Compute the bitwise right shift of this instance by a Python object (i.e. this >> other).
  571. *
  572. * Returns NotImplemented if bitwise right shift operation between int and other type is unsupported.
  573. *
  574. * Javscript function, returns Python object.
  575. *
  576. * @param {!Sk.builtin.object} other The Python object by which to right shift
  577. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the right shift
  578. */
  579. Sk.builtin.int_.prototype.nb$rshift = function (other) {
  580. var thisAsLong;
  581. if (other instanceof Sk.builtin.int_) {
  582. var tmp;
  583. var shift = Sk.builtin.asnum$(other);
  584. if (shift !== undefined) {
  585. if (shift < 0) {
  586. throw new Sk.builtin.ValueError("negative shift count");
  587. }
  588. tmp = this.v >> shift;
  589. if ((this.v > 0) && (tmp < 0)) {
  590. // Fix incorrect sign extension
  591. tmp = tmp & (Math.pow(2, 32 - shift) - 1);
  592. }
  593. }
  594. if (tmp !== undefined) {
  595. tmp = /** @type {number} */ (tmp);
  596. return new Sk.builtin.int_(tmp);
  597. }
  598. }
  599. if (other instanceof Sk.builtin.lng) {
  600. thisAsLong = new Sk.builtin.lng(this.v);
  601. return thisAsLong.nb$rshift(other);
  602. }
  603. return Sk.builtin.NotImplemented.NotImplemented$;
  604. };
  605. Sk.builtin.int_.prototype.nb$reflected_rshift = function (other) {
  606. if (other instanceof Sk.builtin.int_) {
  607. return other.nb$rshift(this);
  608. }
  609. return Sk.builtin.NotImplemented.NotImplemented$;
  610. };
  611. /**
  612. * Compute the bitwise inverse of this instance (i.e. ~this).
  613. *
  614. * Javscript function, returns Python object.
  615. *
  616. * @return {Sk.builtin.int_} The result of the inversion
  617. */
  618. Sk.builtin.int_.prototype.nb$invert = function () {
  619. return new Sk.builtin.int_(~this.v);
  620. };
  621. /** @override */
  622. Sk.builtin.int_.prototype.nb$inplace_add = Sk.builtin.int_.prototype.nb$add;
  623. /** @override */
  624. Sk.builtin.int_.prototype.nb$inplace_subtract = Sk.builtin.int_.prototype.nb$subtract;
  625. /** @override */
  626. Sk.builtin.int_.prototype.nb$inplace_multiply = Sk.builtin.int_.prototype.nb$multiply;
  627. /** @override */
  628. Sk.builtin.int_.prototype.nb$inplace_divide = Sk.builtin.int_.prototype.nb$divide;
  629. /** @override */
  630. Sk.builtin.int_.prototype.nb$inplace_remainder = Sk.builtin.int_.prototype.nb$remainder;
  631. /** @override */
  632. Sk.builtin.int_.prototype.nb$inplace_floor_divide = Sk.builtin.int_.prototype.nb$floor_divide;
  633. /** @override */
  634. Sk.builtin.int_.prototype.nb$inplace_power = Sk.builtin.int_.prototype.nb$power;
  635. /**
  636. * @function
  637. * @name nb$inplace_and
  638. * @memberOf Sk.builtin.int_.prototype
  639. * @description
  640. * Compute the bitwise AND of this instance and a Python object (i.e. this &= other).
  641. *
  642. * Returns NotImplemented if inplace bitwise AND operation between int and other type is unsupported.
  643. *
  644. * Javscript function, returns Python object.
  645. *
  646. * @param {!Sk.builtin.object} other The Python object to AND with this one
  647. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the conjunction
  648. */
  649. Sk.builtin.int_.prototype.nb$inplace_and = Sk.builtin.int_.prototype.nb$and;
  650. /**
  651. * @function
  652. * @name nb$inplace_or
  653. * @memberOf Sk.builtin.int_.prototype
  654. * @description
  655. * Compute the bitwise OR of this instance and a Python object (i.e. this |= other).
  656. *
  657. * Returns NotImplemented if inplace bitwise OR operation between int and other type is unsupported.
  658. *
  659. * Javscript function, returns Python object.
  660. *
  661. * @param {!Sk.builtin.object} other The Python object to OR with this one
  662. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the disjunction
  663. */
  664. Sk.builtin.int_.prototype.nb$inplace_or = Sk.builtin.int_.prototype.nb$or;
  665. /**
  666. * @function
  667. * @name nb$inplace_xor
  668. * @memberOf Sk.builtin.int_.prototype
  669. * @description
  670. * Compute the bitwise XOR of this instance and a Python object (i.e. this ^= other).
  671. *
  672. * Returns NotImplemented if inplace bitwise XOR operation between int and other type is unsupported.
  673. *
  674. * Javscript function, returns Python object.
  675. *
  676. * @param {!Sk.builtin.object} other The Python object to XOR with this one
  677. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the exclusive disjunction
  678. */
  679. Sk.builtin.int_.prototype.nb$inplace_xor = Sk.builtin.int_.prototype.nb$xor;
  680. /**
  681. * @function
  682. * @name nb$inplace_lshift
  683. * @memberOf Sk.builtin.int_.prototype
  684. * @description
  685. * Compute the bitwise left shift of this instance by a Python object (i.e. this <<= other).
  686. *
  687. * Returns NotImplemented if inplace bitwise left shift operation between int and other type is unsupported.
  688. *
  689. * Javscript function, returns Python object.
  690. *
  691. * @param {!Sk.builtin.object} other The Python object by which to left shift
  692. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the left shift
  693. */
  694. Sk.builtin.int_.prototype.nb$inplace_lshift = Sk.builtin.int_.prototype.nb$lshift;
  695. /**
  696. * @function
  697. * @name nb$inplace_rshift
  698. * @memberOf Sk.builtin.int_.prototype
  699. * @description
  700. * Compute the bitwise right shift of this instance by a Python object (i.e. this >>= other).
  701. *
  702. * Returns NotImplemented if inplace bitwise right shift operation between int and other type is unsupported.
  703. *
  704. * Javscript function, returns Python object.
  705. *
  706. * @param {!Sk.builtin.object} other The Python object by which to right shift
  707. * @return {(Sk.builtin.int_|Sk.builtin.lng|Sk.builtin.NotImplemented)} The result of the right shift
  708. */
  709. Sk.builtin.int_.prototype.nb$inplace_rshift = Sk.builtin.int_.prototype.nb$rshift;
  710. /**
  711. * @override
  712. *
  713. * @return {Sk.builtin.int_} A copy of this instance with the value negated.
  714. */
  715. Sk.builtin.int_.prototype.nb$negative = function () {
  716. return new Sk.builtin.int_(-this.v);
  717. };
  718. /** @override */
  719. Sk.builtin.int_.prototype.nb$positive = function () {
  720. return this.clone();
  721. };
  722. /** @override */
  723. Sk.builtin.int_.prototype.nb$nonzero = function () {
  724. return this.v !== 0;
  725. };
  726. /** @override */
  727. Sk.builtin.int_.prototype.nb$isnegative = function () {
  728. return this.v < 0;
  729. };
  730. /** @override */
  731. Sk.builtin.int_.prototype.nb$ispositive = function () {
  732. return this.v >= 0;
  733. };
  734. /**
  735. * Compare this instance's value to another Python object's value.
  736. *
  737. * Returns NotImplemented if comparison between int and other type is unsupported.
  738. *
  739. * Javscript function, returns Javascript object or Sk.builtin.NotImplemented.
  740. *
  741. * @return {(number|Sk.builtin.NotImplemented)} negative if this < other, zero if this == other, positive if this > other
  742. */
  743. Sk.builtin.int_.prototype.numberCompare = function (other) {
  744. if (other instanceof Sk.builtin.int_) {
  745. return this.v - other.v;
  746. }
  747. if (other instanceof Sk.builtin.lng) {
  748. return -other.longCompare(this);
  749. }
  750. if (other instanceof Sk.builtin.float_) {
  751. return -other.numberCompare(this);
  752. }
  753. return Sk.builtin.NotImplemented.NotImplemented$;
  754. };
  755. // Despite what jshint may want us to do, these two functions need to remain
  756. // as == and != Unless you modify the logic of numberCompare do not change
  757. // these.
  758. /** @override */
  759. Sk.builtin.int_.prototype.ob$eq = function (other) {
  760. if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
  761. other instanceof Sk.builtin.float_) {
  762. return new Sk.builtin.bool(this.numberCompare(other) == 0); //jshint ignore:line
  763. } else if (other instanceof Sk.builtin.none) {
  764. return Sk.builtin.bool.false$;
  765. } else {
  766. return Sk.builtin.NotImplemented.NotImplemented$;
  767. }
  768. };
  769. /** @override */
  770. Sk.builtin.int_.prototype.ob$ne = function (other) {
  771. if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
  772. other instanceof Sk.builtin.float_) {
  773. return new Sk.builtin.bool(this.numberCompare(other) != 0); //jshint ignore:line
  774. } else if (other instanceof Sk.builtin.none) {
  775. return Sk.builtin.bool.true$;
  776. } else {
  777. return Sk.builtin.NotImplemented.NotImplemented$;
  778. }
  779. };
  780. /** @override */
  781. Sk.builtin.int_.prototype.ob$lt = function (other) {
  782. if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
  783. other instanceof Sk.builtin.float_) {
  784. return new Sk.builtin.bool(this.numberCompare(other) < 0);
  785. } else {
  786. return Sk.builtin.NotImplemented.NotImplemented$;
  787. }
  788. };
  789. /** @override */
  790. Sk.builtin.int_.prototype.ob$le = function (other) {
  791. if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
  792. other instanceof Sk.builtin.float_) {
  793. return new Sk.builtin.bool(this.numberCompare(other) <= 0);
  794. } else {
  795. return Sk.builtin.NotImplemented.NotImplemented$;
  796. }
  797. };
  798. /** @override */
  799. Sk.builtin.int_.prototype.ob$gt = function (other) {
  800. if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
  801. other instanceof Sk.builtin.float_) {
  802. return new Sk.builtin.bool(this.numberCompare(other) > 0);
  803. } else {
  804. return Sk.builtin.NotImplemented.NotImplemented$;
  805. }
  806. };
  807. /** @override */
  808. Sk.builtin.int_.prototype.ob$ge = function (other) {
  809. if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
  810. other instanceof Sk.builtin.float_) {
  811. return new Sk.builtin.bool(this.numberCompare(other) >= 0);
  812. } else {
  813. return Sk.builtin.NotImplemented.NotImplemented$;
  814. }
  815. };
  816. /**
  817. * Round this instance to a given number of digits, or zero if omitted.
  818. *
  819. * Implements `__round__` dunder method.
  820. *
  821. * Javascript function, returns Python object.
  822. *
  823. * @param {Sk.builtin.int_} self This instance.
  824. * @param {Object|number=} ndigits The number of digits after the decimal point to which to round.
  825. * @return {Sk.builtin.int_} The rounded integer.
  826. */
  827. Sk.builtin.int_.prototype.round$ = function (self, ndigits) {
  828. Sk.builtin.pyCheckArgsLen("__round__", arguments.length, 1, 2);
  829. var result, multiplier, number, num10, rounded, bankRound, ndigs;
  830. if ((ndigits !== undefined) && !Sk.misceval.isIndex(ndigits)) {
  831. throw new Sk.builtin.TypeError("'" + Sk.abstr.typeName(ndigits) + "' object cannot be interpreted as an index");
  832. }
  833. number = Sk.builtin.asnum$(self);
  834. if (ndigits === undefined) {
  835. ndigs = 0;
  836. } else {
  837. ndigs = Sk.misceval.asIndex(ndigits);
  838. }
  839. if (Sk.__future__.bankers_rounding) {
  840. num10 = number * Math.pow(10, ndigs);
  841. rounded = Math.round(num10);
  842. bankRound = (((((num10>0)?num10:(-num10))%1)===0.5)?(((0===(rounded%2)))?rounded:(rounded-1)):rounded);
  843. result = bankRound / Math.pow(10, ndigs);
  844. return new Sk.builtin.int_(result);
  845. } else {
  846. multiplier = Math.pow(10, ndigs);
  847. result = Math.round(number * multiplier) / multiplier;
  848. return new Sk.builtin.int_(result);
  849. }
  850. };
  851. Sk.builtin.int_.prototype.__format__= function (obj, format_spec) {
  852. var formatstr;
  853. Sk.builtin.pyCheckArgsLen("__format__", arguments.length, 2, 2);
  854. if (!Sk.builtin.checkString(format_spec)) {
  855. if (Sk.__future__.exceptions) {
  856. throw new Sk.builtin.TypeError("format() argument 2 must be str, not " + Sk.abstr.typeName(format_spec));
  857. } else {
  858. throw new Sk.builtin.TypeError("format expects arg 2 to be string or unicode, not " + Sk.abstr.typeName(format_spec));
  859. }
  860. } else {
  861. formatstr = Sk.ffi.remapToJs(format_spec);
  862. if (formatstr !== "") {
  863. throw new Sk.builtin.NotImplementedError("format spec is not yet implemented");
  864. }
  865. }
  866. return new Sk.builtin.str(obj);
  867. };
  868. Sk.builtin.int_.prototype.conjugate = new Sk.builtin.func(function (self) {
  869. return new Sk.builtin.int_(self.v);
  870. });
  871. /** @override */
  872. Sk.builtin.int_.prototype["$r"] = function () {
  873. return new Sk.builtin.str(this.str$(10, true));
  874. };
  875. /**
  876. * Return the string representation of this instance.
  877. *
  878. * Javascript function, returns Python object.
  879. *
  880. * @return {Sk.builtin.str} The Python string representation of this instance.
  881. */
  882. Sk.builtin.int_.prototype.tp$str = function () {
  883. return new Sk.builtin.str(this.str$(10, true));
  884. };
  885. /**
  886. * Convert this instance's value to a Javascript string.
  887. *
  888. * Javascript function, returns Javascript object.
  889. *
  890. * @param {number} base The base of the value.
  891. * @param {boolean} sign true if the value should be signed, false otherwise.
  892. * @return {string} The Javascript string representation of this instance.
  893. */
  894. Sk.builtin.int_.prototype.str$ = function (base, sign) {
  895. var tmp;
  896. var work;
  897. if (sign === undefined) {
  898. sign = true;
  899. }
  900. work = sign ? this.v : Math.abs(this.v);
  901. if (base === undefined || base === 10) {
  902. tmp = work.toString();
  903. } else {
  904. tmp = work.toString(base);
  905. }
  906. return tmp;
  907. };
  908. /**
  909. * Takes a JavaScript string and returns a number using the parser and negater
  910. * functions (for int/long right now)
  911. * @param {string} s Javascript string to convert to a number.
  912. * @param {(number)} base The base of the number.
  913. * @param {function(*, (number|undefined)): number} parser Function which should take
  914. * a string that is a postive number which only contains characters that are
  915. * valid in the given base and a base and return a number.
  916. * @param {function((number|Sk.builtin.biginteger)): number} negater Function which should take a
  917. * number and return its negation
  918. * @param {string} fname The name of the calling function, to be used in error messages
  919. * @return {number} The number equivalent of the string in the given base
  920. */
  921. Sk.str2number = function (s, base, parser, negater, fname) {
  922. var origs = s,
  923. neg = false,
  924. i,
  925. ch,
  926. val;
  927. // strip whitespace from ends
  928. // s = s.trim();
  929. s = s.replace(/^\s+|\s+$/g, "");
  930. // check for minus sign
  931. if (s.charAt(0) === "-") {
  932. neg = true;
  933. s = s.substring(1);
  934. }
  935. // check for plus sign
  936. if (s.charAt(0) === "+") {
  937. s = s.substring(1);
  938. }
  939. if (base === null || base === undefined) {
  940. base = 10;
  941. } // default radix is 10, not dwim
  942. if (base < 2 || base > 36) {
  943. if (base !== 0) {
  944. throw new Sk.builtin.ValueError(fname + "() base must be >= 2 and <= 36");
  945. }
  946. }
  947. if (s.substring(0, 2).toLowerCase() === "0x") {
  948. if (base === 16 || base === 0) {
  949. s = s.substring(2);
  950. base = 16;
  951. } else if (base < 34) {
  952. throw new Sk.builtin.ValueError("invalid literal for " + fname + "() with base " + base + ": '" + origs + "'");
  953. }
  954. } else if (s.substring(0, 2).toLowerCase() === "0b") {
  955. if (base === 2 || base === 0) {
  956. s = s.substring(2);
  957. base = 2;
  958. } else if (base < 12) {
  959. throw new Sk.builtin.ValueError("invalid literal for " + fname + "() with base " + base + ": '" + origs + "'");
  960. }
  961. } else if (s.substring(0, 2).toLowerCase() === "0o") {
  962. if (base === 8 || base === 0) {
  963. s = s.substring(2);
  964. base = 8;
  965. } else if (base < 25) {
  966. throw new Sk.builtin.ValueError("invalid literal for " + fname + "() with base " + base + ": '" + origs + "'");
  967. }
  968. } else if (s.charAt(0) === "0") {
  969. if (s === "0") {
  970. return 0;
  971. }
  972. if (base === 8 || base === 0) {
  973. base = 8;
  974. }
  975. }
  976. if (base === 0) {
  977. base = 10;
  978. }
  979. if (s.length === 0) {
  980. throw new Sk.builtin.ValueError("invalid literal for " + fname + "() with base " + base + ": '" + origs + "'");
  981. }
  982. // check all characters are valid
  983. for (i = 0; i < s.length; i = i + 1) {
  984. ch = s.charCodeAt(i);
  985. val = base;
  986. if ((ch >= 48) && (ch <= 57)) {
  987. // 0-9
  988. val = ch - 48;
  989. } else if ((ch >= 65) && (ch <= 90)) {
  990. // A-Z
  991. val = ch - 65 + 10;
  992. } else if ((ch >= 97) && (ch <= 122)) {
  993. // a-z
  994. val = ch - 97 + 10;
  995. }
  996. if (val >= base) {
  997. throw new Sk.builtin.ValueError("invalid literal for " + fname + "() with base " + base + ": '" + origs + "'");
  998. }
  999. }
  1000. // parse number
  1001. val = parser(s, base);
  1002. if (neg) {
  1003. val = negater(val);
  1004. }
  1005. return val;
  1006. };
  1007. Sk.exportSymbol("Sk.builtin.int_", Sk.builtin.int_);