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