on master help sign in
javascript: google closure fixes
c48896fraichoo
js/Runtime.js+360−366
@@ -1,393 +1,387 @@
1−/*
1+/** @constructor */
2− BigInteger Javascript code taken from:
2+__IDR__.Type = function(type) {
3− https://github.com/peterolson
3+ this.type = type;
4−*/
4+};
5
5
6−var __IDR__;
6+__IDR__.Int = new __IDR__.Type('Int');
7−(function(__IDR__) {
7+__IDR__.Char = new __IDR__.Type('Char');
8− /** @constructor */
8+__IDR__.String = new __IDR__.Type('String');
9− __IDR__.Type = function(type) {
9+__IDR__.Integer = new __IDR__.Type('Integer');
10− this.type = type;
10+__IDR__.Float = new __IDR__.Type('Float');
11− };
11+__IDR__.Forgot = new __IDR__.Type('Forgot');
12
12
13− __IDR__.Int = new __IDR__.Type('Int');
13+/** @constructor */
14− __IDR__.Char = new __IDR__.Type('Char');
14+__IDR__.Tailcall = function(f) { this.f = f };
15− __IDR__.String = new __IDR__.Type('String');
16− __IDR__.Integer = new __IDR__.Type('Integer');
17− __IDR__.Float = new __IDR__.Type('Float');
18− __IDR__.Forgot = new __IDR__.Type('Forgot');
19
15
16+/** @constructor */
17+__IDR__.Con = function(i,vars) {
18+ this.i = i;
19+ this.vars = vars;
20+};
20
21
21− /** @constructor */
22− __IDR__.Tailcall = function(f) { this.f = f };
22+__IDR__.tailcall = function(f) {
23+ var __f = f;
24+ var ret;
25+ while (__f) {
26+ f = __f;
27+ __f = null;
28+ ret = f();
23
29
24− /** @constructor */
30+ if (ret instanceof __IDR__.Tailcall) {
25− __IDR__.Con = function(i,vars) {
31+ __f = ret.f;
26− this.i = i;
32+ } else {
27− this.vars = vars;
33+ return ret;
34+ }
28− };
35+ }
36+};
29
37
30− __IDR__.tailcall = function(f) {
38+__IDR__.print = function(s){
31− var __f = f;
39+ var m = s.match(/(.*)\n$/);
32− var ret;
40+ console.log(m ? m[1] : s);
33− while (__f) {
41+};
34− f = __f;
35− __f = null;
36− ret = f();
37
42
38− if (ret instanceof __IDR__.Tailcall) {
43+/*
39− __f = ret.f;
44+ BigInteger Javascript code taken from:
40− } else {
45+ https://github.com/peterolson
41− return ret;
46+*/
42− }
47+__IDR__.bigInt = (function () {
43− }
48+ var base = 10000000, logBase = 7;
49+ var sign = {
50+ positive: false,
51+ negative: true
44 };
52 };
45
53
46− __IDR__.print = function(s){
54+ var normalize = function (first, second) {
47− var m = s.match(/(.*)\n$/);
55+ var a = first.value, b = second.value;
48− console.log(m ? m[1] : s);
56+ var length = a.length > b.length ? a.length : b.length;
57+ for (var i = 0; i < length; i++) {
58+ a[i] = a[i] || 0;
59+ b[i] = b[i] || 0;
60+ }
61+ for (var i = length - 1; i >= 0; i--) {
62+ if (a[i] === 0 && b[i] === 0) {
63+ a.pop();
64+ b.pop();
65+ } else break;
66+ }
67+ if (!a.length) a = [0], b = [0];
68+ first.value = a;
69+ second.value = b;
49 };
70 };
50
71
51− __IDR__.bigInt = (function () {
72+ var parse = function (text, first) {
52− var base = 10000000, logBase = 7;
73+ if (typeof text === "object") return text;
53− var sign = {
74+ text += "";
54− positive: false,
75+ var s = sign.positive, value = [];
55− negative: true
76+ if (text[0] === "-") {
56− };
77+ s = sign.negative;
57−
78+ text = text.slice(1);
58− var normalize = function (first, second) {
79+ }
59− var a = first.value, b = second.value;
80+ var text = text.split("e");
60− var length = a.length > b.length ? a.length : b.length;
81+ if (text.length > 2) throw new Error("Invalid integer");
61− for (var i = 0; i < length; i++) {
82+ if (text[1]) {
62− a[i] = a[i] || 0;
83+ var exp = text[1];
63− b[i] = b[i] || 0;
84+ if (exp[0] === "+") exp = exp.slice(1);
64− }
85+ exp = parse(exp);
65− for (var i = length - 1; i >= 0; i--) {
86+ if (exp.lesser(0)) throw new Error("Cannot include negative exponent part for integers");
66− if (a[i] === 0 && b[i] === 0) {
87+ while (exp.notEquals(0)) {
67− a.pop();
88+ text[0] += "0";
68− b.pop();
89+ exp = exp.prev();
69− } else break;
70 }
90 }
91+ }
92+ text = text[0];
93+ if (text === "-0") text = "0";
94+ var isValid = /^([0-9][0-9]*)$/.test(text);
95+ if (!isValid) throw new Error("Invalid integer");
71− if (!a.length) a = [0], b = [0];
96+ while (text.length) {
72− first.value = a;
97+ var divider = text.length > logBase ? text.length - logBase : 0;
73− second.value = b;
98+ value.push(+text.slice(divider));
99+ text = text.slice(0, divider);
100+ }
101+ var val = bigInt(value, s);
102+ if (first) normalize(first, val);
103+ return val;
74− };
104+ };
75
105
76− var parse = function (text, first) {
106+ var goesInto = function (a, b) {
77− if (typeof text === "object") return text;
78− text += "";
79− var s = sign.positive, value = [];
107+ var a = bigInt(a, sign.positive), b = bigInt(b, sign.positive);
80− if (text[0] === "-") {
108+ if (a.equals(0)) throw new Error("Cannot divide by 0");
81− s = sign.negative;
109+ var n = 0;
82− text = text.slice(1);
110+ do {
111+ var inc = 1;
112+ var c = bigInt(a.value, sign.positive), t = c.times(10);
113+ while (t.lesser(b)) {
114+ c = t;
115+ inc *= 10;
116+ t = t.times(10);
83 }
117 }
84− var text = text.split("e");
118+ while (c.lesserOrEquals(b)) {
85− if (text.length > 2) throw new Error("Invalid integer");
119+ b = b.minus(c);
86− if (text[1]) {
120+ n += inc;
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 }
121 }
105− var val = bigInt(value, s);
122+ } while (a.lesserOrEquals(b));
106− if (first) normalize(first, val);
123+
107− return val;
124+ return {
125+ remainder: b.value,
126+ result: n
108 };
127 };
128+ };
109
129
110− var goesInto = function (a, b) {
130+ var bigInt = function (value, s) {
111− var a = bigInt(a, sign.positive), b = bigInt(b, sign.positive);
131+ var self = {
112− if (a.equals(0)) throw new Error("Cannot divide by 0");
132+ value: value,
113− var n = 0;
133+ sign: s
114− do {
134+ };
115− var inc = 1;
135+ var o = {
116− var c = bigInt(a.value, sign.positive), t = c.times(10);
136+ value: value,
117− while (t.lesser(b)) {
137+ sign: s,
118− c = t;
138+ negate: function (m) {
119− inc *= 10;
139+ var first = m || self;
120− t = t.times(10);
140+ return bigInt(first.value, !first.sign);
141+ },
142+ abs: function (m) {
143+ var first = m || self;
144+ return bigInt(first.value, sign.positive);
145+ },
146+ add: function (n, m) {
147+ var s, first = self, second;
148+ if (m) (first = parse(n)) && (second = parse(m));
149+ else second = parse(n, first);
150+ s = first.sign;
151+ if (first.sign !== second.sign) {
152+ first = bigInt(first.value, sign.positive);
153+ second = bigInt(second.value, sign.positive);
154+ return s === sign.positive ?
155+ o.subtract(first, second) :
156+ o.subtract(second, first);
121 }
157 }
122− while (c.lesserOrEquals(b)) {
158+ normalize(first, second);
123− b = b.minus(c);
159+ var a = first.value, b = second.value;
124− n += inc;
160+ var result = [],
161+ carry = 0;
162+ for (var i = 0; i < a.length || carry > 0; i++) {
163+ var sum = (a[i] || 0) + (b[i] || 0) + carry;
164+ carry = sum >= base ? 1 : 0;
165+ sum -= carry * base;
166+ result.push(sum);
125 }
167 }
126− } while (a.lesserOrEquals(b));
127−
128− return {
129− remainder: b.value,
130− result: n
131− };
132− };
133−
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);
168+ return bigInt(result, s);
173− },
169+ },
174− plus: function (n, m) {
170+ plus: function (n, m) {
175− return o.add(n, m);
171+ return o.add(n, m);
176− },
172+ },
177− subtract: function (n, m) {
173+ subtract: function (n, m) {
178− var first = self, second;
174+ var first = self, second;
179− if (m) (first = parse(n)) && (second = parse(m));
175+ if (m) (first = parse(n)) && (second = parse(m));
180− else second = parse(n, first);
176+ else second = parse(n, first);
181− if (first.sign !== second.sign) return o.add(first, o.negate(second));
177+ 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));
178+ 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));
179+ if (o.compare(first, second) === -1) return o.negate(o.subtract(second, first));
184− var a = first.value, b = second.value;
180+ var a = first.value, b = second.value;
185− var result = [],
181+ var result = [],
186− borrow = 0;
182+ borrow = 0;
187− for (var i = 0; i < a.length; i++) {
183+ for (var i = 0; i < a.length; i++) {
188− a[i] -= borrow;
184+ a[i] -= borrow;
189− borrow = a[i] < b[i] ? 1 : 0;
185+ borrow = a[i] < b[i] ? 1 : 0;
190− var minuend = (borrow * base) + a[i] - b[i];
186+ var minuend = (borrow * base) + a[i] - b[i];
191− result.push(minuend);
187+ result.push(minuend);
192− }
188+ }
193− return bigInt(result, sign.positive);
189+ return bigInt(result, sign.positive);
194− },
190+ },
195− minus: function (n, m) {
191+ minus: function (n, m) {
196− return o.subtract(n, m);
192+ return o.subtract(n, m);
197− },
193+ },
198− multiply: function (n, m) {
194+ multiply: function (n, m) {
199− var s, first = self, second;
195+ var s, first = self, second;
200− if (m) (first = parse(n)) && (second = parse(m));
196+ if (m) (first = parse(n)) && (second = parse(m));
201− else second = parse(n, first);
197+ else second = parse(n, first);
202− s = first.sign !== second.sign;
198+ s = first.sign !== second.sign;
203− var a = first.value, b = second.value;
199+ var a = first.value, b = second.value;
204− var resultSum = [];
200+ var resultSum = [];
205− for (var i = 0; i < a.length; i++) {
201+ for (var i = 0; i < a.length; i++) {
206− resultSum[i] = [];
202+ resultSum[i] = [];
207− var j = i;
203+ var j = i;
208− while (j--) {
204+ 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);
205+ resultSum[i].push(0);
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 }
206 }
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− }
207+ }
208+ var carry = 0;
209+ for (var i = 0; i < a.length; i++) {
210+ var x = a[i];
211+ for (var j = 0; j < b.length || carry > 0; j++) {
212+ var y = b[j];
213+ var product = y ? (x * y) + carry : carry;
234− carry = sum > base ? Math.floor(sum / base) : 0;
214+ carry = product > base ? Math.floor(product / base) : 0;
235− sum -= carry * base;
215+ product -= carry * base;
236− result.push(sum);
216+ resultSum[i].push(product);
237 }
217 }
238− return bigInt(result, s);
239− },
218+ }
240− times: function (n, m) {
219+ var max = -1;
241− return o.multiply(n, m);
220+ for (var i = 0; i < resultSum.length; i++) {
242− },
221+ var len = resultSum[i].length;
243− divmod: function (n, m) {
222+ if (len > max) max = len;
244− var s, first = self, second;
223+ }
245− if (m) (first = parse(n)) && (second = parse(m));
224+ var result = [], carry = 0;
246− else second = parse(n, first);
225+ for (var i = 0; i < max || carry > 0; i++) {
247− s = first.sign !== second.sign;
226+ var sum = carry;
248− if (bigInt(first.value, first.sign).equals(0)) return {
227+ for (var j = 0; j < resultSum.length; j++) {
249− quotient: bigInt([0], sign.positive),
228+ sum += resultSum[j][i] || 0;
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 }
229 }
230+ carry = sum > base ? Math.floor(sum / base) : 0;
231+ sum -= carry * base;
232+ result.push(sum);
233+ }
234+ return bigInt(result, s);
235+ },
236+ times: function (n, m) {
237+ return o.multiply(n, m);
238+ },
239+ divmod: function (n, m) {
240+ var s, first = self, second;
241+ if (m) (first = parse(n)) && (second = parse(m));
242+ else second = parse(n, first);
243+ s = first.sign !== second.sign;
244+ if (bigInt(first.value, first.sign).equals(0)) return {
245+ quotient: bigInt([0], sign.positive),
246+ remainder: bigInt([0], sign.positive)
247+ };
248+ if (second.equals(0)) throw new Error("Cannot divide by zero");
249+ var a = first.value, b = second.value;
250+ var result = [], remainder = [];
251+ for (var i = a.length - 1; i >= 0; i--) {
252+ var n = [a[i]].concat(remainder);
253+ var quotient = goesInto(b, n);
254+ result.push(quotient.result);
255+ remainder = quotient.remainder;
256+ }
261− result.reverse();
257+ result.reverse();
262− return {
258+ return {
263− quotient: bigInt(result, s),
259+ quotient: bigInt(result, s),
264− remainder: bigInt(remainder, first.sign)
260+ remainder: bigInt(remainder, first.sign)
265− };
261+ };
266− },
262+ },
267− divide: function (n, m) {
263+ divide: function (n, m) {
268− return o.divmod(n, m).quotient;
264+ return o.divmod(n, m).quotient;
269− },
265+ },
270− over: function (n, m) {
266+ over: function (n, m) {
271− return o.divide(n, m);
267+ return o.divide(n, m);
272− },
268+ },
273− mod: function (n, m) {
269+ mod: function (n, m) {
274− return o.divmod(n, m).remainder;
270+ return o.divmod(n, m).remainder;
275− },
271+ },
276− pow: function (n, m) {
272+ pow: function (n, m) {
277− var first = self, second;
273+ var first = self, second;
278− if (m) (first = parse(n)) && (second = parse(m));
274+ if (m) (first = parse(n)) && (second = parse(m));
279− else second = parse(n, first);
275+ else second = parse(n, first);
280− var a = first, b = second;
276+ var a = first, b = second;
281− if (b.lesser(0)) return ZERO;
277+ if (b.lesser(0)) return ZERO;
282− if (b.equals(0)) return ONE;
278+ if (b.equals(0)) return ONE;
283− var result = bigInt(a.value, a.sign);
279+ var result = bigInt(a.value, a.sign);
284
280
285− if (b.mod(2).equals(0)) {
281+ if (b.mod(2).equals(0)) {
286− var c = result.pow(b.over(2));
282+ var c = result.pow(b.over(2));
287− return c.times(c);
283+ return c.times(c);
288− } else {
284+ } else {
289− return result.times(result.pow(b.minus(1)));
285+ return result.times(result.pow(b.minus(1)));
290− }
286+ }
291− },
287+ },
292− next: function (m) {
288+ next: function (m) {
293− var first = m || self;
289+ var first = m || self;
294− return o.add(first, 1);
290+ return o.add(first, 1);
295− },
291+ },
296− prev: function (m) {
292+ prev: function (m) {
297− var first = m || self;
293+ var first = m || self;
298− return o.subtract(first, 1);
294+ return o.subtract(first, 1);
299− },
295+ },
300− compare: function (n, m) {
296+ compare: function (n, m) {
301− var first = self, second;
297+ var first = self, second;
302− if (m) (first = parse(n)) && (second = parse(m, first));
298+ if (m) (first = parse(n)) && (second = parse(m, first));
303− else second = parse(n, first);
299+ else second = parse(n, first);
304− normalize(first, second);
300+ normalize(first, second);
305− if (first.value.length === 1 && second.value.length === 1 && first.value[0] === 0 && second.value[0] === 0) return 0;
301+ 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;
302+ if (second.sign !== first.sign) return first.sign === sign.positive ? 1 : -1;
307− var multiplier = first.sign === sign.positive ? 1 : -1;
303+ var multiplier = first.sign === sign.positive ? 1 : -1;
308− var a = first.value, b = second.value;
304+ var a = first.value, b = second.value;
309− for (var i = a.length - 1; i >= 0; i--) {
305+ for (var i = a.length - 1; i >= 0; i--) {
310− if (a[i] > b[i]) return 1 * multiplier;
306+ if (a[i] > b[i]) return 1 * multiplier;
311− if (b[i] > a[i]) return -1 * multiplier;
307+ if (b[i] > a[i]) return -1 * multiplier;
312− }
308+ }
313− return 0;
309+ return 0;
314− },
310+ },
315− compareAbs: function (n, m) {
311+ compareAbs: function (n, m) {
316− var first = self, second;
312+ var first = self, second;
317− if (m) (first = parse(n)) && (second = parse(m, first));
313+ if (m) (first = parse(n)) && (second = parse(m, first));
318− else second = parse(n, first);
314+ else second = parse(n, first);
319− first.sign = second.sign = sign.positive;
315+ first.sign = second.sign = sign.positive;
320− return o.compare(first, second);
316+ return o.compare(first, second);
321− },
317+ },
322− equals: function (n, m) {
318+ equals: function (n, m) {
323− return o.compare(n, m) === 0;
319+ return o.compare(n, m) === 0;
324− },
320+ },
325− notEquals: function (n, m) {
321+ notEquals: function (n, m) {
326− return !o.equals(n, m);
322+ return !o.equals(n, m);
327− },
323+ },
328− lesser: function (n, m) {
324+ lesser: function (n, m) {
329− return o.compare(n, m) < 0;
325+ return o.compare(n, m) < 0;
330− },
326+ },
331− greater: function (n, m) {
327+ greater: function (n, m) {
332− return o.compare(n, m) > 0;
328+ return o.compare(n, m) > 0;
333− },
329+ },
334− greaterOrEquals: function (n, m) {
330+ greaterOrEquals: function (n, m) {
335− return o.compare(n, m) >= 0;
331+ return o.compare(n, m) >= 0;
336− },
332+ },
337− lesserOrEquals: function (n, m) {
333+ lesserOrEquals: function (n, m) {
338− return o.compare(n, m) <= 0;
334+ return o.compare(n, m) <= 0;
339− },
335+ },
340− isPositive: function (m) {
336+ isPositive: function (m) {
341− var first = m || self;
337+ var first = m || self;
342− return first.sign === sign.positive;
338+ return first.sign === sign.positive;
343− },
339+ },
344− isNegative: function (m) {
340+ isNegative: function (m) {
345− var first = m || self;
341+ var first = m || self;
346− return first.sign === sign.negative;
342+ return first.sign === sign.negative;
347− },
343+ },
348− isEven: function (m) {
344+ isEven: function (m) {
349− var first = m || self;
345+ var first = m || self;
350− return first.value[0] % 2 === 0;
346+ return first.value[0] % 2 === 0;
351− },
347+ },
352− isOdd: function (m) {
348+ isOdd: function (m) {
353− var first = m || self;
349+ var first = m || self;
354− return first.value[0] % 2 === 1;
350+ return first.value[0] % 2 === 1;
355− },
351+ },
356− toString: function (m) {
352+ toString: function (m) {
357− var first = m || self;
353+ var first = m || self;
358− var str = "", len = first.value.length;
354+ var str = "", len = first.value.length;
359− while (len--) {
355+ while (len--) {
360− str += (base.toString() + first.value[len]).slice(-logBase);
356+ 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 }
357 }
358+ while (str[0] === "0") {
359+ str = str.slice(1);
360+ }
361+ if (!str.length) str = "0";
362+ var s = first.sign === sign.positive ? "" : "-";
363+ return s + str;
375− };
364+ },
365+ toJSNumber: function (m) {
366+ return +o.toString(m);
367+ },
368+ valueOf: function (m) {
376− return o;
369+ return o.toJSNumber(m);
370+ }
377 };
371 };
372+ return o;
373+ };
378
374
379− var ZERO = bigInt([0], sign.positive);
375+ var ZERO = bigInt([0], sign.positive);
380− var ONE = bigInt([1], sign.positive);
376+ var ONE = bigInt([1], sign.positive);
381− var MINUS_ONE = bigInt([1], sign.negative);
377+ var MINUS_ONE = bigInt([1], sign.negative);
382−
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− })();
392−})(__IDR__ || (__IDR__ = {}));
393
378
379+ var fnReturn = function (a) {
380+ if (typeof a === "undefined") return ZERO;
381+ return parse(a);
382+ };
383+ fnReturn.zero = ZERO;
384+ fnReturn.one = ONE;
385+ fnReturn.minusOne = MINUS_ONE;
386+ return fnReturn;
387+})();
src/IRTS/CodegenJavaScript.hs+51−122
@@ -17,51 +17,7 @@ import Data.List
17import qualified Data.Map as Map
17import qualified Data.Map as Map
18import System.IO
18import System.IO
19
19
20−type NamespaceName = String
21−type Decl = ([String], SDecl)
22−
23−data ModuleTree = Module { moduleName :: String
24− , functions :: [SDecl]
25− , subModules :: Map.Map String ModuleTree
26− }
27− | EmptyModule
28−
29−insertDecl :: ModuleTree -> Decl -> ModuleTree
30−insertDecl EmptyModule ([modname], decl) =
31− Module modname [decl] Map.empty
32−
33−insertDecl EmptyModule (m:s:ms, decl) =
34− Module m [] (Map.singleton s (insertDecl EmptyModule (s:ms, decl)))
35−
36−insertDecl mod ([modname], decl)
37− | moduleName mod == modname =
38− mod { functions = decl : functions mod }
39−
40−insertDecl mod (_:m:ms, decl)
41− | Nothing <- Map.lookup m (subModules mod) =
42− mod {
43− subModules =
44− Map.insert m (insertDecl EmptyModule (m:ms, decl)) (subModules mod)
45− }
46− | Just s <- Map.lookup m (subModules mod) =
47− mod {
48− subModules =
49− Map.insert m (insertDecl s (m:ms, decl)) (subModules mod)
50− }
51−
52−instance Show ModuleTree where
53− show EmptyModule = ""
54− show (Module name fs subs) =
55− createModule Nothing name body
56− where
57− functions = concatMap (translateDeclaration name) fs
58− submodules = Map.foldWithKey (translateSubModule name) "" subs
59− body = functions ++ submodules
60−
61− translateSubModule toplevel name mod js =
62− js ++ show mod ++ toplevel ++ "." ++ name ++ "=" ++ name ++ ";"
63−
64−idrNamespace :: NamespaceName
20+idrNamespace :: String
65idrNamespace = "__IDR__"
21idrNamespace = "__IDR__"
66
22
67codegenJavaScript
23codegenJavaScript
@@ -72,10 +28,11 @@ codegenJavaScript
72codegenJavaScript definitions filename outputType = do
28codegenJavaScript definitions filename outputType = do
73 path <- getDataDir
29 path <- getDataDir
74 idrRuntime <- readFile (path ++ "/js/Runtime.js")
30 idrRuntime <- readFile (path ++ "/js/Runtime.js")
75− writeFile filename (idrRuntime ++ output)
31+ writeFile filename (modules ++ idrRuntime ++ functions ++ mainLoop)
76 where
32 where
77− modules = foldl' insertDecl EmptyModule def
78 def = map (first translateNamespace) definitions
33 def = map (first translateNamespace) definitions
34+
35+ functions = concatMap translateDeclaration def
79
36
80 mainLoop :: String
37 mainLoop :: String
81 mainLoop = intercalate "\n" [ "\nfunction main() {"
38 mainLoop = intercalate "\n" [ "\nfunction main() {"
@@ -83,36 +40,14 @@ codegenJavaScript definitions filename outputType = do
83 , "}\n\nmain();\n"
40 , "}\n\nmain();\n"
84 ]
41 ]
85
42
86− output :: String
87− output = show modules ++ mainLoop
43+ modules =
44+ concatMap allocMod mods
45+ where
46+ allocMod m = intercalate "." m ++ " = {};\n"
47+ sortMods a b = compare (length a) (length b)
88
48
89−createModule :: Maybe String -> NamespaceName -> String -> String
49+ mods =
90−createModule toplevel modname body =
50+ drop 1 $ sortBy sortMods $ nub $ concatMap (inits . fst) def
91− concat [header modname, body, footer modname]
92− where
93− header :: NamespaceName -> String
94− header modname =
95− concatMap (++ "\n")
96− [ "\nvar " ++ modname ++ ";"
97− , "(function(" ++ modname ++ "){"
98− ]
99−
100− footer :: NamespaceName -> String
101− footer modname =
102− let m = maybe "" (++ ".") toplevel ++ modname in
103− "\n})("
104− ++ m
105− ++ " || ("
106− ++ m
107− ++ " = {})"
108− ++ ");\n"
109−
110−translateModule :: Maybe String -> ([String], SDecl) -> String
111−translateModule toplevel ([modname], decl) =
112− let body = translateDeclaration modname decl in
113− createModule toplevel modname body
114−translateModule toplevel (n:ns, decl) =
115− createModule toplevel n $ translateModule (Just n) (ns, decl)
116
51
117translateIdentifier :: String -> String
52translateIdentifier :: String -> String
118translateIdentifier =
53translateIdentifier =
@@ -160,10 +95,6 @@ translateName (UN name) = translateIdentifier name
160translateName (NS name _) = translateName name
95translateName (NS name _) = translateName name
161translateName (MN i name) = translateIdentifier name ++ show i
96translateName (MN i name) = translateIdentifier name ++ show i
162
97
163−translateQualifiedName :: Name -> String
164−translateQualifiedName name =
165− intercalate "." (translateNamespace name) ++ "." ++ translateName name
166−
167translateConstant :: Const -> String
98translateConstant :: Const -> String
168translateConstant (I i) = show i
99translateConstant (I i) = show i
169translateConstant (BI i) = "__IDR__.bigInt('" ++ show i ++ "')"
100translateConstant (BI i) = "__IDR__.bigInt('" ++ show i ++ "')"
@@ -184,18 +115,16 @@ translateParameterlist =
184 where translateParameter (MN i name) = name ++ show i
115 where translateParameter (MN i name) = name ++ show i
185 translateParameter (UN name) = name
116 translateParameter (UN name) = name
186
117
187−translateDeclaration :: NamespaceName -> SDecl -> String
118+translateDeclaration :: ([String], SDecl) -> String
188−translateDeclaration modname (SFun name params stackSize body) =
119+translateDeclaration (path, SFun name params stackSize body) =
189− modname
190− ++ "."
191− ++ translateName name
120+ intercalate "." (path ++ [translateName name])
192 ++ " = function("
121 ++ " = function("
193 ++ intercalate "," p
122 ++ intercalate "," p
194 ++ "){\n"
123 ++ "){\n"
195 ++ concatMap assignVar (zip [0..] p)
124 ++ concatMap assignVar (zip [0..] p)
196 ++ concatMap allocVar [numP..(numP+stackSize-1)]
125 ++ concatMap allocVar [numP..(numP+stackSize-1)]
197 ++ "return "
126 ++ "return "
198− ++ translateExpression modname body
127+ ++ translateExpression body
199 ++ ";\n};\n"
128 ++ ";\n};\n"
200 where
129 where
201 numP :: Int
130 numP :: Int
@@ -214,32 +143,32 @@ translateVariableName :: LVar -> String
214translateVariableName (Loc i) =
143translateVariableName (Loc i) =
215 "__var_" ++ show i
144 "__var_" ++ show i
216
145
217−translateExpression :: NamespaceName -> SExp -> String
146+translateExpression :: SExp -> String
218−translateExpression modname (SLet name value body) =
147+translateExpression (SLet name value body) =
219 "(function("
148 "(function("
220 ++ translateVariableName name
149 ++ translateVariableName name
221 ++ "){\nreturn "
150 ++ "){\nreturn "
222− ++ translateExpression modname body
151+ ++ translateExpression body
223 ++ ";\n})("
152 ++ ";\n})("
224− ++ translateExpression modname value
153+ ++ translateExpression value
225 ++ ")"
154 ++ ")"
226
155
227−translateExpression _ (SConst cst) =
156+translateExpression (SConst cst) =
228 translateConstant cst
157 translateConstant cst
229
158
230−translateExpression _ (SV var) =
159+translateExpression (SV var) =
231 translateVariableName var
160 translateVariableName var
232
161
233−translateExpression modname (SApp False name vars) =
162+translateExpression (SApp False name vars) =
234 createTailcall $ translateFunctionCall name vars
163 createTailcall $ translateFunctionCall name vars
235
164
236−translateExpression modname (SApp True name vars) =
165+translateExpression (SApp True name vars) =
237 "new __IDR__.Tailcall("
166 "new __IDR__.Tailcall("
238 ++ "function(){\n"
167 ++ "function(){\n"
239 ++ "return " ++ translateFunctionCall name vars
168 ++ "return " ++ translateFunctionCall name vars
240 ++ ";\n});"
169 ++ ";\n});"
241
170
242−translateExpression _ (SOp op vars)
171+translateExpression (SOp op vars)
243 | LPlus <- op
172 | LPlus <- op
244 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
173 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
245 | LMinus <- op
174 | LMinus <- op
@@ -392,33 +321,33 @@ translateExpression _ (SOp op vars)
392 ++ f
321 ++ f
393 ++ translateVariableName rhs
322 ++ translateVariableName rhs
394
323
395−translateExpression _ (SError msg) =
324+translateExpression (SError msg) =
396 "(function(){throw \'" ++ msg ++ "\';})();"
325 "(function(){throw \'" ++ msg ++ "\';})();"
397
326
398−translateExpression _ (SForeign _ _ "putStr" [(FString, var)]) =
327+translateExpression (SForeign _ _ "putStr" [(FString, var)]) =
399 "__IDR__.print(" ++ translateVariableName var ++ ");"
328 "__IDR__.print(" ++ translateVariableName var ++ ");"
400
329
401−translateExpression _ (SForeign _ _ fun args) =
330+translateExpression (SForeign _ _ fun args) =
402 fun
331 fun
403 ++ "("
332 ++ "("
404 ++ intercalate "," (map (translateVariableName . snd) args)
333 ++ intercalate "," (map (translateVariableName . snd) args)
405 ++ ");"
334 ++ ");"
406
335
407−translateExpression modname (SChkCase var cases) =
336+translateExpression (SChkCase var cases) =
408 "(function(e){\n"
337 "(function(e){\n"
409− ++ intercalate " else " (map (translateCase modname "e") cases)
338+ ++ intercalate " else " (map (translateCase "e") cases)
410 ++ "\n})("
339 ++ "\n})("
411 ++ translateVariableName var
340 ++ translateVariableName var
412 ++ ")"
341 ++ ")"
413
342
414−translateExpression modname (SCase var cases) =
343+translateExpression (SCase var cases) =
415 "(function(e){\n"
344 "(function(e){\n"
416− ++ intercalate " else " (map (translateCase modname "e") cases)
345+ ++ intercalate " else " (map (translateCase "e") cases)
417 ++ "\n})("
346 ++ "\n})("
418 ++ translateVariableName var
347 ++ translateVariableName var
419 ++ ")"
348 ++ ")"
420
349
421−translateExpression _ (SCon i name vars) =
350+translateExpression (SCon i name vars) =
422 concat [ "new __IDR__.Con("
351 concat [ "new __IDR__.Con("
423 , show i
352 , show i
424 , ",["
353 , ",["
@@ -426,24 +355,24 @@ translateExpression _ (SCon i name vars) =
426 , "])"
355 , "])"
427 ]
356 ]
428
357
429−translateExpression modname (SUpdate var e) =
358+translateExpression (SUpdate var e) =
430− translateVariableName var ++ " = " ++ translateExpression modname e
359+ translateVariableName var ++ " = " ++ translateExpression e
431
360
432−translateExpression modname (SProj var i) =
361+translateExpression (SProj var i) =
433 translateVariableName var ++ ".vars[" ++ show i ++"]"
362 translateVariableName var ++ ".vars[" ++ show i ++"]"
434
363
435−translateExpression _ SNothing = "null"
364+translateExpression SNothing = "null"
436
365
437−translateExpression _ e =
366+translateExpression e =
438 "(function(){throw 'Not yet implemented: "
367 "(function(){throw 'Not yet implemented: "
439 ++ filter (/= '\'') (show e)
368 ++ filter (/= '\'') (show e)
440 ++ "';})()"
369 ++ "';})()"
441
370
442−translateCase :: String -> String -> SAlt -> String
371+translateCase :: String -> SAlt -> String
443−translateCase modname _ (SDefaultCase e) =
372+translateCase _ (SDefaultCase e) =
444− createIfBlock "true" (translateExpression modname e)
373+ createIfBlock "true" (translateExpression e)
445
374
446−translateCase modname var (SConstCase ty e)
375+translateCase var (SConstCase ty e)
447 | ChType <- ty = matchHelper "Char"
376 | ChType <- ty = matchHelper "Char"
448 | StrType <- ty = matchHelper "String"
377 | StrType <- ty = matchHelper "String"
449 | IType <- ty = matchHelper "Int"
378 | IType <- ty = matchHelper "Int"
@@ -451,17 +380,17 @@ translateCase modname var (SConstCase ty e)
451 | FlType <- ty = matchHelper "Float"
380 | FlType <- ty = matchHelper "Float"
452 | Forgot <- ty = matchHelper "Forgot"
381 | Forgot <- ty = matchHelper "Forgot"
453 where
382 where
454− matchHelper tyName = translateTypeMatch modname var tyName e
383+ matchHelper tyName = translateTypeMatch var tyName e
455
384
456−translateCase modname var (SConstCase cst@(BI _) e) =
385+translateCase var (SConstCase cst@(BI _) e) =
457 let cond = var ++ ".equals(" ++ translateConstant cst ++ ")" in
386 let cond = var ++ ".equals(" ++ translateConstant cst ++ ")" in
458− createIfBlock cond (translateExpression modname e)
387+ createIfBlock cond (translateExpression e)
459
388
460−translateCase modname var (SConstCase cst e) =
389+translateCase var (SConstCase cst e) =
461 let cond = var ++ " == " ++ translateConstant cst in
390 let cond = var ++ " == " ++ translateConstant cst in
462− createIfBlock cond (translateExpression modname e)
391+ createIfBlock cond (translateExpression e)
463
392
464−translateCase modname var (SConCase a i name vars e) =
393+translateCase var (SConCase a i name vars e) =
465 let isCon = var ++ " instanceof __IDR__.Con"
394 let isCon = var ++ " instanceof __IDR__.Con"
466 isI = show i ++ " == " ++ var ++ ".i"
395 isI = show i ++ " == " ++ var ++ ".i"
467 params = intercalate "," $ map (("__var_" ++) . show) [a..(a+length vars)]
396 params = intercalate "," $ map (("__var_" ++) . show) [a..(a+length vars)]
@@ -471,11 +400,11 @@ translateCase modname var (SConCase a i name vars e) =
471 ++ params
400 ++ params
472 ++ "){\nreturn " ++ b ++ "\n})" ++ args
401 ++ "){\nreturn " ++ b ++ "\n})" ++ args
473 cond = intercalate " && " [isCon, isI] in
402 cond = intercalate " && " [isCon, isI] in
474− createIfBlock cond $ f (translateExpression modname e)
403+ createIfBlock cond $ f (translateExpression e)
475
404
476−translateTypeMatch :: String -> String -> String -> SExp -> String
405+translateTypeMatch :: String -> String -> SExp -> String
477−translateTypeMatch modname var ty exp =
406+translateTypeMatch var ty exp =
478− let e = translateExpression modname exp in
407+ let e = translateExpression exp in
479 createIfBlock (var
408 createIfBlock (var
480 ++ " instanceof __IDR__.Type && "
409 ++ " instanceof __IDR__.Type && "
481 ++ var ++ ".type == '"++ ty ++"'") e
410 ++ var ++ ".type == '"++ ty ++"'") e