/lib/es6/caml_int64.js

https://github.com/BuckleScript/bucklescript · JavaScript · 598 lines · 542 code · 55 blank · 1 comment · 119 complexity · c86079b49ea1565e30bf7825bba38b85 MD5 · raw file

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