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