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