on ba42979 help sign in
Idris-dev/js/Runtime-common.js
391 lines 12 kB history raw
1/** @constructor */
2var __IDRRT__Type = function(type) {
3 this.type = type;
4};
6var __IDRRT__Int = new __IDRRT__Type('Int');
7var __IDRRT__Char = new __IDRRT__Type('Char');
8var __IDRRT__String = new __IDRRT__Type('String');
9var __IDRRT__Integer = new __IDRRT__Type('Integer');
10var __IDRRT__Float = new __IDRRT__Type('Float');
11var __IDRRT__Ptr = new __IDRRT__Type('Pointer');
12var __IDRRT__Forgot = new __IDRRT__Type('Forgot');
15/** @constructor */
16var __IDRRT__Tailcall = function(f) { this.f = f };
17var __IDRRT__ffiWrap = function(fid) {
18 return function(arg) {
19 return __IDRRT__tailcall(function(){
20 return __IDR__APPLY0(fid, arg);
21 });
22 };
23};
25/** @constructor */
26var __IDRRT__Con = function(i,vars) {
27 this.i = i;
28 this.vars = vars;
29};
31var __IDRRT__tailcall = function(f) {
32 var __f = f;
33 var ret;
34 while (__f) {
35 f = __f;
36 __f = null;
37 ret = f();
39 if (ret instanceof __IDRRT__Tailcall) {
40 __f = ret.f;
41 } else {
42 return ret;
43 }
44 }
45};
47/*
48 BigInteger Javascript code taken from:
49 https://github.com/peterolson
50*/
51var __IDRRT__bigInt = (function () {
52 var base = 10000000, logBase = 7;
53 var sign = {
54 positive: false,
55 negative: true
56 };
58 var normalize = function (first, second) {
59 var a = first.value, b = second.value;
60 var length = a.length > b.length ? a.length : b.length;
61 for (var i = 0; i < length; i++) {
62 a[i] = a[i] || 0;
63 b[i] = b[i] || 0;
64 }
65 for (var i = length - 1; i >= 0; i--) {
66 if (a[i] === 0 && b[i] === 0) {
67 a.pop();
68 b.pop();
69 } else break;
70 }
71 if (!a.length) a = [0], b = [0];
72 first.value = a;
73 second.value = b;
74 };
76 var parse = function (text, first) {
77 if (typeof text === "object") return text;
78 text += "";
79 var s = sign.positive, value = [];
80 if (text[0] === "-") {
81 s = sign.negative;
82 text = text.slice(1);
83 }
84 var text = text.split("e");
85 if (text.length > 2) throw new Error("Invalid integer");
86 if (text[1]) {
87 var exp = text[1];
88 if (exp[0] === "+") exp = exp.slice(1);
89 exp = parse(exp);
90 if (exp.lesser(0)) throw new Error("Cannot include negative exponent part for integers");
91 while (exp.notEquals(0)) {
92 text[0] += "0";
93 exp = exp.prev();
94 }
95 }
96 text = text[0];
97 if (text === "-0") text = "0";
98 var isValid = /^([0-9][0-9]*)$/.test(text);
99 if (!isValid) throw new Error("Invalid integer");
100 while (text.length) {
101 var divider = text.length > logBase ? text.length - logBase : 0;
102 value.push(+text.slice(divider));
103 text = text.slice(0, divider);
104 }
105 var val = bigInt(value, s);
106 if (first) normalize(first, val);
107 return val;
108 };
110 var goesInto = function (a, b) {
111 var a = bigInt(a, sign.positive), b = bigInt(b, sign.positive);
112 if (a.equals(0)) throw new Error("Cannot divide by 0");
113 var n = 0;
114 do {
115 var inc = 1;
116 var c = bigInt(a.value, sign.positive), t = c.times(10);
117 while (t.lesser(b)) {
118 c = t;
119 inc *= 10;
120 t = t.times(10);
121 }
122 while (c.lesserOrEquals(b)) {
123 b = b.minus(c);
124 n += inc;
125 }
126 } while (a.lesserOrEquals(b));
128 return {
129 remainder: b.value,
130 result: n
131 };
132 };
134 var bigInt = function (value, s) {
135 var self = {
136 value: value,
137 sign: s
138 };
139 var o = {
140 value: value,
141 sign: s,
142 negate: function (m) {
143 var first = m || self;
144 return bigInt(first.value, !first.sign);
145 },
146 abs: function (m) {
147 var first = m || self;
148 return bigInt(first.value, sign.positive);
149 },
150 add: function (n, m) {
151 var s, first = self, second;
152 if (m) (first = parse(n)) && (second = parse(m));
153 else second = parse(n, first);
154 s = first.sign;
155 if (first.sign !== second.sign) {
156 first = bigInt(first.value, sign.positive);
157 second = bigInt(second.value, sign.positive);
158 return s === sign.positive ?
159 o.subtract(first, second) :
160 o.subtract(second, first);
161 }
162 normalize(first, second);
163 var a = first.value, b = second.value;
164 var result = [],
165 carry = 0;
166 for (var i = 0; i < a.length || carry > 0; i++) {
167 var sum = (a[i] || 0) + (b[i] || 0) + carry;
168 carry = sum >= base ? 1 : 0;
169 sum -= carry * base;
170 result.push(sum);
171 }
172 return bigInt(result, s);
173 },
174 plus: function (n, m) {
175 return o.add(n, m);
176 },
177 subtract: function (n, m) {
178 var first = self, second;
179 if (m) (first = parse(n)) && (second = parse(m));
180 else second = parse(n, first);
181 if (first.sign !== second.sign) return o.add(first, o.negate(second));
182 if (first.sign === sign.negative) return o.subtract(o.negate(second), o.negate(first));
183 if (o.compare(first, second) === -1) return o.negate(o.subtract(second, first));
184 var a = first.value, b = second.value;
185 var result = [],
186 borrow = 0;
187 for (var i = 0; i < a.length; i++) {
188 a[i] -= borrow;
189 borrow = a[i] < b[i] ? 1 : 0;
190 var minuend = (borrow * base) + a[i] - b[i];
191 result.push(minuend);
192 }
193 return bigInt(result, sign.positive);
194 },
195 minus: function (n, m) {
196 return o.subtract(n, m);
197 },
198 multiply: function (n, m) {
199 var s, first = self, second;
200 if (m) (first = parse(n)) && (second = parse(m));
201 else second = parse(n, first);
202 s = first.sign !== second.sign;
203 var a = first.value, b = second.value;
204 var resultSum = [];
205 for (var i = 0; i < a.length; i++) {
206 resultSum[i] = [];
207 var j = i;
208 while (j--) {
209 resultSum[i].push(0);
210 }
211 }
212 var carry = 0;
213 for (var i = 0; i < a.length; i++) {
214 var x = a[i];
215 for (var j = 0; j < b.length || carry > 0; j++) {
216 var y = b[j];
217 var product = y ? (x * y) + carry : carry;
218 carry = product > base ? Math.floor(product / base) : 0;
219 product -= carry * base;
220 resultSum[i].push(product);
221 }
222 }
223 var max = -1;
224 for (var i = 0; i < resultSum.length; i++) {
225 var len = resultSum[i].length;
226 if (len > max) max = len;
227 }
228 var result = [], carry = 0;
229 for (var i = 0; i < max || carry > 0; i++) {
230 var sum = carry;
231 for (var j = 0; j < resultSum.length; j++) {
232 sum += resultSum[j][i] || 0;
233 }
234 carry = sum > base ? Math.floor(sum / base) : 0;
235 sum -= carry * base;
236 result.push(sum);
237 }
238 return bigInt(result, s);
239 },
240 times: function (n, m) {
241 return o.multiply(n, m);
242 },
243 divmod: function (n, m) {
244 var s, first = self, second;
245 if (m) (first = parse(n)) && (second = parse(m));
246 else second = parse(n, first);
247 s = first.sign !== second.sign;
248 if (bigInt(first.value, first.sign).equals(0)) return {
249 quotient: bigInt([0], sign.positive),
250 remainder: bigInt([0], sign.positive)
251 };
252 if (second.equals(0)) throw new Error("Cannot divide by zero");
253 var a = first.value, b = second.value;
254 var result = [], remainder = [];
255 for (var i = a.length - 1; i >= 0; i--) {
256 var n = [a[i]].concat(remainder);
257 var quotient = goesInto(b, n);
258 result.push(quotient.result);
259 remainder = quotient.remainder;
260 }
261 result.reverse();
262 return {
263 quotient: bigInt(result, s),
264 remainder: bigInt(remainder, first.sign)
265 };
266 },
267 divide: function (n, m) {
268 return o.divmod(n, m).quotient;
269 },
270 over: function (n, m) {
271 return o.divide(n, m);
272 },
273 mod: function (n, m) {
274 return o.divmod(n, m).remainder;
275 },
276 pow: function (n, m) {
277 var first = self, second;
278 if (m) (first = parse(n)) && (second = parse(m));
279 else second = parse(n, first);
280 var a = first, b = second;
281 if (b.lesser(0)) return ZERO;
282 if (b.equals(0)) return ONE;
283 var result = bigInt(a.value, a.sign);
285 if (b.mod(2).equals(0)) {
286 var c = result.pow(b.over(2));
287 return c.times(c);
288 } else {
289 return result.times(result.pow(b.minus(1)));
290 }
291 },
292 next: function (m) {
293 var first = m || self;
294 return o.add(first, 1);
295 },
296 prev: function (m) {
297 var first = m || self;
298 return o.subtract(first, 1);
299 },
300 compare: function (n, m) {
301 var first = self, second;
302 if (m) (first = parse(n)) && (second = parse(m, first));
303 else second = parse(n, first);
304 normalize(first, second);
305 if (first.value.length === 1 && second.value.length === 1 && first.value[0] === 0 && second.value[0] === 0) return 0;
306 if (second.sign !== first.sign) return first.sign === sign.positive ? 1 : -1;
307 var multiplier = first.sign === sign.positive ? 1 : -1;
308 var a = first.value, b = second.value;
309 for (var i = a.length - 1; i >= 0; i--) {
310 if (a[i] > b[i]) return 1 * multiplier;
311 if (b[i] > a[i]) return -1 * multiplier;
312 }
313 return 0;
314 },
315 compareAbs: function (n, m) {
316 var first = self, second;
317 if (m) (first = parse(n)) && (second = parse(m, first));
318 else second = parse(n, first);
319 first.sign = second.sign = sign.positive;
320 return o.compare(first, second);
321 },
322 equals: function (n, m) {
323 return o.compare(n, m) === 0;
324 },
325 notEquals: function (n, m) {
326 return !o.equals(n, m);
327 },
328 lesser: function (n, m) {
329 return o.compare(n, m) < 0;
330 },
331 greater: function (n, m) {
332 return o.compare(n, m) > 0;
333 },
334 greaterOrEquals: function (n, m) {
335 return o.compare(n, m) >= 0;
336 },
337 lesserOrEquals: function (n, m) {
338 return o.compare(n, m) <= 0;
339 },
340 isPositive: function (m) {
341 var first = m || self;
342 return first.sign === sign.positive;
343 },
344 isNegative: function (m) {
345 var first = m || self;
346 return first.sign === sign.negative;
347 },
348 isEven: function (m) {
349 var first = m || self;
350 return first.value[0] % 2 === 0;
351 },
352 isOdd: function (m) {
353 var first = m || self;
354 return first.value[0] % 2 === 1;
355 },
356 toString: function (m) {
357 var first = m || self;
358 var str = "", len = first.value.length;
359 while (len--) {
360 str += (base.toString() + first.value[len]).slice(-logBase);
361 }
362 while (str[0] === "0") {
363 str = str.slice(1);
364 }
365 if (!str.length) str = "0";
366 var s = first.sign === sign.positive ? "" : "-";
367 return s + str;
368 },
369 toJSNumber: function (m) {
370 return +o.toString(m);
371 },
372 valueOf: function (m) {
373 return o.toJSNumber(m);
374 }
375 };
376 return o;
377 };
379 var ZERO = bigInt([0], sign.positive);
380 var ONE = bigInt([1], sign.positive);
381 var MINUS_ONE = bigInt([1], sign.negative);
383 var fnReturn = function (a) {
384 if (typeof a === "undefined") return ZERO;
385 return parse(a);
386 };
387 fnReturn.zero = ZERO;
388 fnReturn.one = ONE;
389 fnReturn.minusOne = MINUS_ONE;
390 return fnReturn;
391})();