int.js 35 KB

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