/lib/js/caml_int64.js

https://github.com/BuckleScript/bucklescript · JavaScript · 595 lines · 541 code · 53 blank · 1 comment · 119 complexity · 8c4f93dc314e81e9fb035dc2a2901beb MD5 · raw file

  1. 'use strict';
  2. var Caml_primitive = require("./caml_primitive.js");
  3. function mk(lo, hi) {
  4. return [
  5. hi,
  6. (lo >>> 0)
  7. ];
  8. }
  9. var min_int = [
  10. -2147483648,
  11. 0
  12. ];
  13. var max_int = [
  14. 2147483647,
  15. 4294967295
  16. ];
  17. var one = [
  18. 0,
  19. 1
  20. ];
  21. var zero = [
  22. 0,
  23. 0
  24. ];
  25. var neg_one = [
  26. -1,
  27. 4294967295
  28. ];
  29. function neg_signed(x) {
  30. return (x & 2147483648) !== 0;
  31. }
  32. function non_neg_signed(x) {
  33. return (x & 2147483648) === 0;
  34. }
  35. function succ(param) {
  36. var x_lo = param[1];
  37. var x_hi = param[0];
  38. var lo = x_lo + 1 | 0;
  39. return mk(lo, x_hi + (
  40. lo === 0 ? 1 : 0
  41. ) | 0);
  42. }
  43. function neg(param) {
  44. var other_lo = (param[1] ^ -1) + 1 | 0;
  45. return mk(other_lo, (param[0] ^ -1) + (
  46. other_lo === 0 ? 1 : 0
  47. ) | 0);
  48. }
  49. function add_aux(param, y_lo, y_hi) {
  50. var x_lo = param[1];
  51. var lo = x_lo + y_lo | 0;
  52. var overflow = neg_signed(x_lo) && (neg_signed(y_lo) || non_neg_signed(lo)) || neg_signed(y_lo) && non_neg_signed(lo) ? 1 : 0;
  53. return mk(lo, param[0] + y_hi + overflow | 0);
  54. }
  55. function add(self, param) {
  56. return add_aux(self, param[1], param[0]);
  57. }
  58. function eq(x, y) {
  59. if (x[0] === y[0]) {
  60. return x[1] === y[1];
  61. } else {
  62. return false;
  63. }
  64. }
  65. function equal_null(x, y) {
  66. if (y !== null) {
  67. return eq(x, y);
  68. } else {
  69. return false;
  70. }
  71. }
  72. function equal_undefined(x, y) {
  73. if (y !== undefined) {
  74. return eq(x, y);
  75. } else {
  76. return false;
  77. }
  78. }
  79. function equal_nullable(x, y) {
  80. if (y == null) {
  81. return false;
  82. } else {
  83. return eq(x, y);
  84. }
  85. }
  86. function sub_aux(x, lo, hi) {
  87. var y_lo = ((lo ^ -1) + 1 >>> 0);
  88. var y_hi = (hi ^ -1) + (
  89. y_lo === 0 ? 1 : 0
  90. ) | 0;
  91. return add_aux(x, y_lo, y_hi);
  92. }
  93. function sub(self, param) {
  94. return sub_aux(self, param[1], param[0]);
  95. }
  96. function lsl_(x, numBits) {
  97. if (numBits === 0) {
  98. return x;
  99. }
  100. var lo = x[1];
  101. if (numBits >= 32) {
  102. return mk(0, (lo << (numBits - 32 | 0)));
  103. } else {
  104. return mk((lo << numBits), (lo >>> (32 - numBits | 0)) | (x[0] << numBits));
  105. }
  106. }
  107. function lsr_(x, numBits) {
  108. if (numBits === 0) {
  109. return x;
  110. }
  111. var hi = x[0];
  112. var offset = numBits - 32 | 0;
  113. if (offset === 0) {
  114. return mk(hi, 0);
  115. } else if (offset > 0) {
  116. return mk((hi >>> offset), 0);
  117. } else {
  118. return mk((hi << (-offset | 0)) | (x[1] >>> numBits), (hi >>> numBits));
  119. }
  120. }
  121. function asr_(x, numBits) {
  122. if (numBits === 0) {
  123. return x;
  124. }
  125. var hi = x[0];
  126. if (numBits < 32) {
  127. return mk((hi << (32 - numBits | 0)) | (x[1] >>> numBits), (hi >> numBits));
  128. } else {
  129. return mk((hi >> (numBits - 32 | 0)), hi >= 0 ? 0 : -1);
  130. }
  131. }
  132. function is_zero(param) {
  133. if (param[0] !== 0 || param[1] !== 0) {
  134. return false;
  135. } else {
  136. return true;
  137. }
  138. }
  139. function mul(_this, _other) {
  140. while(true) {
  141. var other = _other;
  142. var $$this = _this;
  143. var lo;
  144. var this_hi = $$this[0];
  145. var exit = 0;
  146. var exit$1 = 0;
  147. var exit$2 = 0;
  148. if (this_hi !== 0) {
  149. exit$2 = 4;
  150. } else {
  151. if ($$this[1] === 0) {
  152. return zero;
  153. }
  154. exit$2 = 4;
  155. }
  156. if (exit$2 === 4) {
  157. if (other[0] !== 0) {
  158. exit$1 = 3;
  159. } else {
  160. if (other[1] === 0) {
  161. return zero;
  162. }
  163. exit$1 = 3;
  164. }
  165. }
  166. if (exit$1 === 3) {
  167. if (this_hi !== -2147483648 || $$this[1] !== 0) {
  168. exit = 2;
  169. } else {
  170. lo = other[1];
  171. }
  172. }
  173. if (exit === 2) {
  174. var other_hi = other[0];
  175. var lo$1 = $$this[1];
  176. var exit$3 = 0;
  177. if (other_hi !== -2147483648 || other[1] !== 0) {
  178. exit$3 = 3;
  179. } else {
  180. lo = lo$1;
  181. }
  182. if (exit$3 === 3) {
  183. var other_lo = other[1];
  184. if (this_hi < 0) {
  185. if (other_hi >= 0) {
  186. return neg(mul(neg($$this), other));
  187. }
  188. _other = neg(other);
  189. _this = neg($$this);
  190. continue ;
  191. }
  192. if (other_hi < 0) {
  193. return neg(mul($$this, neg(other)));
  194. }
  195. var a48 = (this_hi >>> 16);
  196. var a32 = this_hi & 65535;
  197. var a16 = (lo$1 >>> 16);
  198. var a00 = lo$1 & 65535;
  199. var b48 = (other_hi >>> 16);
  200. var b32 = other_hi & 65535;
  201. var b16 = (other_lo >>> 16);
  202. var b00 = other_lo & 65535;
  203. var c48 = 0;
  204. var c32 = 0;
  205. var c16 = 0;
  206. var c00 = a00 * b00;
  207. c16 = (c00 >>> 16) + a16 * b00;
  208. c32 = (c16 >>> 16);
  209. c16 = (c16 & 65535) + a00 * b16;
  210. c32 = c32 + (c16 >>> 16) + a32 * b00;
  211. c48 = (c32 >>> 16);
  212. c32 = (c32 & 65535) + a16 * b16;
  213. c48 = c48 + (c32 >>> 16);
  214. c32 = (c32 & 65535) + a00 * b32;
  215. c48 = c48 + (c32 >>> 16);
  216. c32 = c32 & 65535;
  217. c48 = c48 + (a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48) & 65535;
  218. return mk(c00 & 65535 | ((c16 & 65535) << 16), c32 | (c48 << 16));
  219. }
  220. }
  221. if ((lo & 1) === 0) {
  222. return zero;
  223. } else {
  224. return min_int;
  225. }
  226. };
  227. }
  228. function xor(param, param$1) {
  229. return mk(param[1] ^ param$1[1], param[0] ^ param$1[0]);
  230. }
  231. function or_(param, param$1) {
  232. return mk(param[1] | param$1[1], param[0] | param$1[0]);
  233. }
  234. function and_(param, param$1) {
  235. return mk(param[1] & param$1[1], param[0] & param$1[0]);
  236. }
  237. function ge(param, param$1) {
  238. var other_hi = param$1[0];
  239. var hi = param[0];
  240. if (hi > other_hi) {
  241. return true;
  242. } else if (hi < other_hi) {
  243. return false;
  244. } else {
  245. return param[1] >= param$1[1];
  246. }
  247. }
  248. function neq(x, y) {
  249. return !eq(x, y);
  250. }
  251. function lt(x, y) {
  252. return !ge(x, y);
  253. }
  254. function gt(x, y) {
  255. if (x[0] > y[0]) {
  256. return true;
  257. } else if (x[0] < y[0]) {
  258. return false;
  259. } else {
  260. return x[1] > y[1];
  261. }
  262. }
  263. function le(x, y) {
  264. return !gt(x, y);
  265. }
  266. function min(x, y) {
  267. if (ge(x, y)) {
  268. return y;
  269. } else {
  270. return x;
  271. }
  272. }
  273. function max(x, y) {
  274. if (gt(x, y)) {
  275. return x;
  276. } else {
  277. return y;
  278. }
  279. }
  280. function to_float(param) {
  281. return param[0] * 0x100000000 + param[1];
  282. }
  283. function of_float(x) {
  284. if (isNaN(x) || !isFinite(x)) {
  285. return zero;
  286. } else if (x <= -9.22337203685477581e+18) {
  287. return min_int;
  288. } else if (x + 1 >= 9.22337203685477581e+18) {
  289. return max_int;
  290. } else if (x < 0) {
  291. return neg(of_float(-x));
  292. } else {
  293. return mk(x % 4294967296 | 0, x / 4294967296 | 0);
  294. }
  295. }
  296. function isSafeInteger(param) {
  297. var hi = param[0];
  298. var top11Bits = (hi >> 21);
  299. if (top11Bits === 0) {
  300. return true;
  301. } else if (top11Bits === -1) {
  302. return !(param[1] === 0 && hi === (4292870144 | 0));
  303. } else {
  304. return false;
  305. }
  306. }
  307. function to_string(self) {
  308. if (isSafeInteger(self)) {
  309. return String(to_float(self));
  310. }
  311. if (self[0] < 0) {
  312. if (eq(self, min_int)) {
  313. return "-9223372036854775808";
  314. } else {
  315. return "-" + to_string(neg(self));
  316. }
  317. }
  318. var approx_div1 = of_float(Math.floor(to_float(self) / 10));
  319. var lo = approx_div1[1];
  320. var hi = approx_div1[0];
  321. var match = sub_aux(sub_aux(self, (lo << 3), (lo >>> 29) | (hi << 3)), (lo << 1), (lo >>> 31) | (hi << 1));
  322. var rem_lo = match[1];
  323. var rem_hi = match[0];
  324. if (rem_lo === 0 && rem_hi === 0) {
  325. return to_string(approx_div1) + "0";
  326. }
  327. if (rem_hi < 0) {
  328. var rem_lo$1 = ((rem_lo ^ -1) + 1 >>> 0);
  329. var delta = Math.ceil(rem_lo$1 / 10);
  330. var remainder = 10 * delta - rem_lo$1;
  331. return to_string(sub_aux(approx_div1, delta | 0, 0)) + String(remainder | 0);
  332. }
  333. var rem_lo$2 = rem_lo;
  334. var delta$1 = Math.floor(rem_lo$2 / 10);
  335. var remainder$1 = rem_lo$2 - 10 * delta$1;
  336. return to_string(add_aux(approx_div1, delta$1 | 0, 0)) + String(remainder$1 | 0);
  337. }
  338. function div(_self, _other) {
  339. while(true) {
  340. var other = _other;
  341. var self = _self;
  342. var self_hi = self[0];
  343. var exit = 0;
  344. var exit$1 = 0;
  345. if (other[0] !== 0 || other[1] !== 0) {
  346. exit$1 = 2;
  347. } else {
  348. throw {
  349. RE_EXN_ID: "Division_by_zero",
  350. Error: new Error()
  351. };
  352. }
  353. if (exit$1 === 2) {
  354. if (self_hi !== -2147483648) {
  355. if (self_hi !== 0) {
  356. exit = 1;
  357. } else {
  358. if (self[1] === 0) {
  359. return zero;
  360. }
  361. exit = 1;
  362. }
  363. } else if (self[1] !== 0) {
  364. exit = 1;
  365. } else {
  366. if (eq(other, one) || eq(other, neg_one)) {
  367. return self;
  368. }
  369. if (eq(other, min_int)) {
  370. return one;
  371. }
  372. var half_this = asr_(self, 1);
  373. var approx = lsl_(div(half_this, other), 1);
  374. var exit$2 = 0;
  375. if (approx[0] !== 0) {
  376. exit$2 = 3;
  377. } else {
  378. if (approx[1] === 0) {
  379. if (other[0] < 0) {
  380. return one;
  381. } else {
  382. return neg(one);
  383. }
  384. }
  385. exit$2 = 3;
  386. }
  387. if (exit$2 === 3) {
  388. var rem = sub(self, mul(other, approx));
  389. return add(approx, div(rem, other));
  390. }
  391. }
  392. }
  393. if (exit === 1) {
  394. var other_hi = other[0];
  395. var exit$3 = 0;
  396. if (other_hi !== -2147483648) {
  397. exit$3 = 2;
  398. } else {
  399. if (other[1] === 0) {
  400. return zero;
  401. }
  402. exit$3 = 2;
  403. }
  404. if (exit$3 === 2) {
  405. if (self_hi < 0) {
  406. if (other_hi >= 0) {
  407. return neg(div(neg(self), other));
  408. }
  409. _other = neg(other);
  410. _self = neg(self);
  411. continue ;
  412. }
  413. if (other_hi < 0) {
  414. return neg(div(self, neg(other)));
  415. }
  416. var res = zero;
  417. var rem$1 = self;
  418. while(ge(rem$1, other)) {
  419. var approx$1 = Caml_primitive.caml_float_max(1, Math.floor(to_float(rem$1) / to_float(other)));
  420. var log2 = Math.ceil(Math.log(approx$1) / Math.LN2);
  421. var delta = log2 <= 48 ? 1 : Math.pow(2, log2 - 48);
  422. var approxRes = of_float(approx$1);
  423. var approxRem = mul(approxRes, other);
  424. while(approxRem[0] < 0 || gt(approxRem, rem$1)) {
  425. approx$1 = approx$1 - delta;
  426. approxRes = of_float(approx$1);
  427. approxRem = mul(approxRes, other);
  428. };
  429. if (is_zero(approxRes)) {
  430. approxRes = one;
  431. }
  432. res = add(res, approxRes);
  433. rem$1 = sub(rem$1, approxRem);
  434. };
  435. return res;
  436. }
  437. }
  438. };
  439. }
  440. function mod_(self, other) {
  441. return sub(self, mul(div(self, other), other));
  442. }
  443. function div_mod(self, other) {
  444. var quotient = div(self, other);
  445. return [
  446. quotient,
  447. sub(self, mul(quotient, other))
  448. ];
  449. }
  450. function compare(self, other) {
  451. var v = Caml_primitive.caml_nativeint_compare(self[0], other[0]);
  452. if (v === 0) {
  453. return Caml_primitive.caml_nativeint_compare(self[1], other[1]);
  454. } else {
  455. return v;
  456. }
  457. }
  458. function of_int32(lo) {
  459. return mk(lo, lo < 0 ? -1 : 0);
  460. }
  461. function to_int32(x) {
  462. return x[1] | 0;
  463. }
  464. function to_hex(x) {
  465. var x_lo = x[1];
  466. var x_hi = x[0];
  467. var aux = function (v) {
  468. return (v >>> 0).toString(16);
  469. };
  470. if (x_hi === 0 && x_lo === 0) {
  471. return "0";
  472. }
  473. if (x_lo === 0) {
  474. return aux(x_hi) + "00000000";
  475. }
  476. if (x_hi === 0) {
  477. return aux(x_lo);
  478. }
  479. var lo = aux(x_lo);
  480. var pad = 8 - lo.length | 0;
  481. if (pad <= 0) {
  482. return aux(x_hi) + lo;
  483. } else {
  484. return aux(x_hi) + ("0".repeat(pad) + lo);
  485. }
  486. }
  487. function discard_sign(x) {
  488. return [
  489. 2147483647 & x[0],
  490. x[1]
  491. ];
  492. }
  493. function float_of_bits(x) {
  494. return (function(lo,hi){ return (new Float64Array(new Int32Array([lo,hi]).buffer))[0]})(x[1], x[0]);
  495. }
  496. function bits_of_float(x) {
  497. var match = (function(x){return new Int32Array(new Float64Array([x]).buffer)})(x);
  498. return mk(match[0], match[1]);
  499. }
  500. exports.mk = mk;
  501. exports.succ = succ;
  502. exports.min_int = min_int;
  503. exports.max_int = max_int;
  504. exports.one = one;
  505. exports.zero = zero;
  506. exports.neg_one = neg_one;
  507. exports.of_int32 = of_int32;
  508. exports.to_int32 = to_int32;
  509. exports.add = add;
  510. exports.neg = neg;
  511. exports.sub = sub;
  512. exports.lsl_ = lsl_;
  513. exports.lsr_ = lsr_;
  514. exports.asr_ = asr_;
  515. exports.is_zero = is_zero;
  516. exports.mul = mul;
  517. exports.xor = xor;
  518. exports.or_ = or_;
  519. exports.and_ = and_;
  520. exports.ge = ge;
  521. exports.eq = eq;
  522. exports.neq = neq;
  523. exports.lt = lt;
  524. exports.gt = gt;
  525. exports.le = le;
  526. exports.equal_null = equal_null;
  527. exports.equal_undefined = equal_undefined;
  528. exports.equal_nullable = equal_nullable;
  529. exports.min = min;
  530. exports.max = max;
  531. exports.to_float = to_float;
  532. exports.of_float = of_float;
  533. exports.div = div;
  534. exports.mod_ = mod_;
  535. exports.compare = compare;
  536. exports.float_of_bits = float_of_bits;
  537. exports.bits_of_float = bits_of_float;
  538. exports.div_mod = div_mod;
  539. exports.to_hex = to_hex;
  540. exports.discard_sign = discard_sign;
  541. exports.to_string = to_string;
  542. /* No side effect */