on master help sign in
Merge branch 'googleclosure' of https://github.com/raichoo/Idris-dev into raichoo-googleclosure

Conflicts: src/IRTS/CodegenJavaScript.hs

commit95607a59c7c6dad01d76fdc00ced030947ea0c55 authorEdwin Brady <ecb10@st-andrews.ac.uk> dateSun 27 Jan 2013, 18:00 (14 years ago) parenteca33c63c62143
7 files changed+487−201
idris.cabal+2 js/Runtime.js+399 src/IRTS/CodegenJavaScript.hs+81−196 tutorial/idris-tutorial.pdf tutorial/interp.tex+1−1 tutorial/intro.tex+1−1 tutorial/starting.tex+3−3
idris.cabal+2
@@ -47,6 +47,7 @@ Build-type: Custom
4747Data-files: rts/libidris_rts.a rts/idris_rts.h rts/idris_gc.h
4848 rts/idris_stdfgn.h rts/idris_main.c rts/idris_gmp.h
4949 rts/libtest.c
50+ js/Runtime.js
5051Extra-source-files: lib/Makefile lib/*.idr lib/Prelude/*.idr
5152 lib/Network/*.idr lib/Control/*.idr
5253 lib/Control/Monad/*.idr lib/Language/*.idr
@@ -55,6 +56,7 @@ Extra-source-files: lib/Makefile lib/*.idr lib/Prelude/*.idr
5556 tutorial/examples/*.idr lib/base.ipkg
5657 config.mk
5758 rts/*.c rts/*.h rts/Makefile
59+ js/*.js
5860
5961source-repository head
6062 type: git
js/Runtime.jsnew file+399
@@ -0,0 +1,399 @@
1+var __IDRRT__ = {};
2+
3+/** @constructor */
4+__IDRRT__.Type = function(type) {
5+ this.type = type;
6+};
7+
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__.Forgot = new __IDRRT__.Type('Forgot');
14+
15+/** @constructor */
16+__IDRRT__.Tailcall = function(f) { this.f = f };
17+
18+/** @constructor */
19+__IDRRT__.Con = function(i,vars) {
20+ this.i = i;
21+ this.vars = vars;
22+};
23+
24+__IDRRT__.tailcall = function(f) {
25+ var __f = f;
26+ var ret;
27+ while (__f) {
28+ f = __f;
29+ __f = null;
30+ ret = f();
31+
32+ if (ret instanceof __IDRRT__.Tailcall) {
33+ __f = ret.f;
34+ } else {
35+ return ret;
36+ }
37+ }
38+};
39+
40+__IDRRT__.print = (function(){
41+ if (require) {
42+ var util = require('util');
43+ return function(s) {
44+ util.print(s);
45+ };
46+ } else {
47+ return function(s) {
48+ console.log(s);
49+ };
50+ }
51+})();
52+
53+/*
54+ BigInteger Javascript code taken from:
55+ https://github.com/peterolson
56+*/
57+__IDRRT__.bigInt = (function () {
58+ var base = 10000000, logBase = 7;
59+ var sign = {
60+ positive: false,
61+ negative: true
62+ };
63+
64+ var normalize = function (first, second) {
65+ var a = first.value, b = second.value;
66+ var length = a.length > b.length ? a.length : b.length;
67+ for (var i = 0; i < length; i++) {
68+ a[i] = a[i] || 0;
69+ b[i] = b[i] || 0;
70+ }
71+ for (var i = length - 1; i >= 0; i--) {
72+ if (a[i] === 0 && b[i] === 0) {
73+ a.pop();
74+ b.pop();
75+ } else break;
76+ }
77+ if (!a.length) a = [0], b = [0];
78+ first.value = a;
79+ second.value = b;
80+ };
81+
82+ var parse = function (text, first) {
83+ if (typeof text === "object") return text;
84+ text += "";
85+ var s = sign.positive, value = [];
86+ if (text[0] === "-") {
87+ s = sign.negative;
88+ text = text.slice(1);
89+ }
90+ var text = text.split("e");
91+ if (text.length > 2) throw new Error("Invalid integer");
92+ if (text[1]) {
93+ var exp = text[1];
94+ if (exp[0] === "+") exp = exp.slice(1);
95+ exp = parse(exp);
96+ if (exp.lesser(0)) throw new Error("Cannot include negative exponent part for integers");
97+ while (exp.notEquals(0)) {
98+ text[0] += "0";
99+ exp = exp.prev();
100+ }
101+ }
102+ text = text[0];
103+ if (text === "-0") text = "0";
104+ var isValid = /^([0-9][0-9]*)$/.test(text);
105+ if (!isValid) throw new Error("Invalid integer");
106+ while (text.length) {
107+ var divider = text.length > logBase ? text.length - logBase : 0;
108+ value.push(+text.slice(divider));
109+ text = text.slice(0, divider);
110+ }
111+ var val = bigInt(value, s);
112+ if (first) normalize(first, val);
113+ return val;
114+ };
115+
116+ var goesInto = function (a, b) {
117+ var a = bigInt(a, sign.positive), b = bigInt(b, sign.positive);
118+ if (a.equals(0)) throw new Error("Cannot divide by 0");
119+ var n = 0;
120+ do {
121+ var inc = 1;
122+ var c = bigInt(a.value, sign.positive), t = c.times(10);
123+ while (t.lesser(b)) {
124+ c = t;
125+ inc *= 10;
126+ t = t.times(10);
127+ }
128+ while (c.lesserOrEquals(b)) {
129+ b = b.minus(c);
130+ n += inc;
131+ }
132+ } while (a.lesserOrEquals(b));
133+
134+ return {
135+ remainder: b.value,
136+ result: n
137+ };
138+ };
139+
140+ var bigInt = function (value, s) {
141+ var self = {
142+ value: value,
143+ sign: s
144+ };
145+ var o = {
146+ value: value,
147+ sign: s,
148+ negate: function (m) {
149+ var first = m || self;
150+ return bigInt(first.value, !first.sign);
151+ },
152+ abs: function (m) {
153+ var first = m || self;
154+ return bigInt(first.value, sign.positive);
155+ },
156+ add: function (n, m) {
157+ var s, first = self, second;
158+ if (m) (first = parse(n)) && (second = parse(m));
159+ else second = parse(n, first);
160+ s = first.sign;
161+ if (first.sign !== second.sign) {
162+ first = bigInt(first.value, sign.positive);
163+ second = bigInt(second.value, sign.positive);
164+ return s === sign.positive ?
165+ o.subtract(first, second) :
166+ o.subtract(second, first);
167+ }
168+ normalize(first, second);
169+ var a = first.value, b = second.value;
170+ var result = [],
171+ carry = 0;
172+ for (var i = 0; i < a.length || carry > 0; i++) {
173+ var sum = (a[i] || 0) + (b[i] || 0) + carry;
174+ carry = sum >= base ? 1 : 0;
175+ sum -= carry * base;
176+ result.push(sum);
177+ }
178+ return bigInt(result, s);
179+ },
180+ plus: function (n, m) {
181+ return o.add(n, m);
182+ },
183+ subtract: function (n, m) {
184+ var first = self, second;
185+ if (m) (first = parse(n)) && (second = parse(m));
186+ else second = parse(n, first);
187+ if (first.sign !== second.sign) return o.add(first, o.negate(second));
188+ if (first.sign === sign.negative) return o.subtract(o.negate(second), o.negate(first));
189+ if (o.compare(first, second) === -1) return o.negate(o.subtract(second, first));
190+ var a = first.value, b = second.value;
191+ var result = [],
192+ borrow = 0;
193+ for (var i = 0; i < a.length; i++) {
194+ a[i] -= borrow;
195+ borrow = a[i] < b[i] ? 1 : 0;
196+ var minuend = (borrow * base) + a[i] - b[i];
197+ result.push(minuend);
198+ }
199+ return bigInt(result, sign.positive);
200+ },
201+ minus: function (n, m) {
202+ return o.subtract(n, m);
203+ },
204+ multiply: function (n, m) {
205+ var s, first = self, second;
206+ if (m) (first = parse(n)) && (second = parse(m));
207+ else second = parse(n, first);
208+ s = first.sign !== second.sign;
209+ var a = first.value, b = second.value;
210+ var resultSum = [];
211+ for (var i = 0; i < a.length; i++) {
212+ resultSum[i] = [];
213+ var j = i;
214+ while (j--) {
215+ resultSum[i].push(0);
216+ }
217+ }
218+ var carry = 0;
219+ for (var i = 0; i < a.length; i++) {
220+ var x = a[i];
221+ for (var j = 0; j < b.length || carry > 0; j++) {
222+ var y = b[j];
223+ var product = y ? (x * y) + carry : carry;
224+ carry = product > base ? Math.floor(product / base) : 0;
225+ product -= carry * base;
226+ resultSum[i].push(product);
227+ }
228+ }
229+ var max = -1;
230+ for (var i = 0; i < resultSum.length; i++) {
231+ var len = resultSum[i].length;
232+ if (len > max) max = len;
233+ }
234+ var result = [], carry = 0;
235+ for (var i = 0; i < max || carry > 0; i++) {
236+ var sum = carry;
237+ for (var j = 0; j < resultSum.length; j++) {
238+ sum += resultSum[j][i] || 0;
239+ }
240+ carry = sum > base ? Math.floor(sum / base) : 0;
241+ sum -= carry * base;
242+ result.push(sum);
243+ }
244+ return bigInt(result, s);
245+ },
246+ times: function (n, m) {
247+ return o.multiply(n, m);
248+ },
249+ divmod: function (n, m) {
250+ var s, first = self, second;
251+ if (m) (first = parse(n)) && (second = parse(m));
252+ else second = parse(n, first);
253+ s = first.sign !== second.sign;
254+ if (bigInt(first.value, first.sign).equals(0)) return {
255+ quotient: bigInt([0], sign.positive),
256+ remainder: bigInt([0], sign.positive)
257+ };
258+ if (second.equals(0)) throw new Error("Cannot divide by zero");
259+ var a = first.value, b = second.value;
260+ var result = [], remainder = [];
261+ for (var i = a.length - 1; i >= 0; i--) {
262+ var n = [a[i]].concat(remainder);
263+ var quotient = goesInto(b, n);
264+ result.push(quotient.result);
265+ remainder = quotient.remainder;
266+ }
267+ result.reverse();
268+ return {
269+ quotient: bigInt(result, s),
270+ remainder: bigInt(remainder, first.sign)
271+ };
272+ },
273+ divide: function (n, m) {
274+ return o.divmod(n, m).quotient;
275+ },
276+ over: function (n, m) {
277+ return o.divide(n, m);
278+ },
279+ mod: function (n, m) {
280+ return o.divmod(n, m).remainder;
281+ },
282+ pow: function (n, m) {
283+ var first = self, second;
284+ if (m) (first = parse(n)) && (second = parse(m));
285+ else second = parse(n, first);
286+ var a = first, b = second;
287+ if (b.lesser(0)) return ZERO;
288+ if (b.equals(0)) return ONE;
289+ var result = bigInt(a.value, a.sign);
290+
291+ if (b.mod(2).equals(0)) {
292+ var c = result.pow(b.over(2));
293+ return c.times(c);
294+ } else {
295+ return result.times(result.pow(b.minus(1)));
296+ }
297+ },
298+ next: function (m) {
299+ var first = m || self;
300+ return o.add(first, 1);
301+ },
302+ prev: function (m) {
303+ var first = m || self;
304+ return o.subtract(first, 1);
305+ },
306+ compare: function (n, m) {
307+ var first = self, second;
308+ if (m) (first = parse(n)) && (second = parse(m, first));
309+ else second = parse(n, first);
310+ normalize(first, second);
311+ if (first.value.length === 1 && second.value.length === 1 && first.value[0] === 0 && second.value[0] === 0) return 0;
312+ if (second.sign !== first.sign) return first.sign === sign.positive ? 1 : -1;
313+ var multiplier = first.sign === sign.positive ? 1 : -1;
314+ var a = first.value, b = second.value;
315+ for (var i = a.length - 1; i >= 0; i--) {
316+ if (a[i] > b[i]) return 1 * multiplier;
317+ if (b[i] > a[i]) return -1 * multiplier;
318+ }
319+ return 0;
320+ },
321+ compareAbs: function (n, m) {
322+ var first = self, second;
323+ if (m) (first = parse(n)) && (second = parse(m, first));
324+ else second = parse(n, first);
325+ first.sign = second.sign = sign.positive;
326+ return o.compare(first, second);
327+ },
328+ equals: function (n, m) {
329+ return o.compare(n, m) === 0;
330+ },
331+ notEquals: function (n, m) {
332+ return !o.equals(n, m);
333+ },
334+ lesser: function (n, m) {
335+ return o.compare(n, m) < 0;
336+ },
337+ greater: function (n, m) {
338+ return o.compare(n, m) > 0;
339+ },
340+ greaterOrEquals: function (n, m) {
341+ return o.compare(n, m) >= 0;
342+ },
343+ lesserOrEquals: function (n, m) {
344+ return o.compare(n, m) <= 0;
345+ },
346+ isPositive: function (m) {
347+ var first = m || self;
348+ return first.sign === sign.positive;
349+ },
350+ isNegative: function (m) {
351+ var first = m || self;
352+ return first.sign === sign.negative;
353+ },
354+ isEven: function (m) {
355+ var first = m || self;
356+ return first.value[0] % 2 === 0;
357+ },
358+ isOdd: function (m) {
359+ var first = m || self;
360+ return first.value[0] % 2 === 1;
361+ },
362+ toString: function (m) {
363+ var first = m || self;
364+ var str = "", len = first.value.length;
365+ while (len--) {
366+ str += (base.toString() + first.value[len]).slice(-logBase);
367+ }
368+ while (str[0] === "0") {
369+ str = str.slice(1);
370+ }
371+ if (!str.length) str = "0";
372+ var s = first.sign === sign.positive ? "" : "-";
373+ return s + str;
374+ },
375+ toJSNumber: function (m) {
376+ return +o.toString(m);
377+ },
378+ valueOf: function (m) {
379+ return o.toJSNumber(m);
380+ }
381+ };
382+ return o;
383+ };
384+
385+ var ZERO = bigInt([0], sign.positive);
386+ var ONE = bigInt([1], sign.positive);
387+ var MINUS_ONE = bigInt([1], sign.negative);
388+
389+ var fnReturn = function (a) {
390+ if (typeof a === "undefined") return ZERO;
391+ return parse(a);
392+ };
393+ fnReturn.zero = ZERO;
394+ fnReturn.one = ONE;
395+ fnReturn.minusOne = MINUS_ONE;
396+ return fnReturn;
397+})();
398+
399+var __IDR__ = {};
src/IRTS/CodegenJavaScript.hs+81−196
@@ -1,10 +1,5 @@
11{-# LANGUAGE PatternGuards #-}
22
3−{-
4− BigInteger Javascript code taken from:
5− https://github.com/peterolson/BigInteger.js
6−-}
7−
83module IRTS.CodegenJavaScript (codegenJavaScript) where
94
105import Idris.AbsSyntax
@@ -19,11 +14,10 @@ import Util.System
1914import Control.Arrow
2015import Data.Char
2116import Data.List
17+import qualified Data.Map as Map
2218import System.IO
2319
24−type NamespaceName = String
25−
26−idrNamespace :: NamespaceName
20+idrNamespace :: String
2721idrNamespace = "__IDR__"
2822
2923codegenJavaScript
@@ -31,10 +25,14 @@ codegenJavaScript
3125 -> FilePath
3226 -> OutputType
3327 -> IO ()
34−codegenJavaScript definitions filename outputType =
35− writeFile filename output
28+codegenJavaScript definitions filename outputType = do
29+ path <- getDataDir
30+ idrRuntime <- readFile (path ++ "/js/Runtime.js")
31+ writeFile filename (idrRuntime ++ modules ++ functions ++ mainLoop)
3632 where
3733 def = map (first translateNamespace) definitions
34+
35+ functions = concatMap translateDeclaration def
3836
3937 mainLoop :: String
4038 mainLoop = intercalate "\n" [ "\nfunction main() {"
@@ -42,80 +40,14 @@ codegenJavaScript definitions filename outputType =
4240 , "}\n\nmain();\n"
4341 ]
4442
45− output :: String
46− output = concat [ idrRuntime
47− , concatMap (translateModule Nothing) def
48− , mainLoop
49− ]
50−
51−idrRuntime :: String
52−idrRuntime =
53− createModule Nothing idrNamespace $ concat
54− [ "__IDR__.Type = function(type) { this.type = type; };"
55− , "__IDR__.Int = new __IDR__.Type('Int');"
56− , "__IDR__.Char = new __IDR__.Type('Char');"
57− , "__IDR__.String = new __IDR__.Type('String');"
58− , "__IDR__.Integer = new __IDR__.Type('Integer');"
59− , "__IDR__.Float = new __IDR__.Type('Float');"
60− , "__IDR__.Pointer = new __IDR__.Type('Pointer');"
61− , "__IDR__.Forgot = new __IDR__.Type('Forgot');"
62−
63− , "__IDR__.bigInt=function(){var e=1e7,t=7,n={positive:!1,negative:!0},r=function(e,t){var n=e.value,r=t.value,i=n.length>r.length?n.length:r.length;for(var s=0;s<i;s++)n[s]=n[s]||0,r[s]=r[s]||0;for(var s=i-1;s>=0;s--){if(n[s]!==0||r[s]!==0)break;n.pop(),r.pop()}n.length||(n=[0],r=[0]),e.value=n,t.value=r},i=function(e,s){if(typeof e=='object')return e;e+='';var u=n.positive,a=[];e[0]==='-'&&(u=n.negative,e=e.slice(1));var e=e.split('e');if(e.length>2)throw new Error('Invalid integer');if(e[1]){var f=e[1];f[0]==='+'&&(f=f.slice(1)),f=i(f);if(f.lesser(0))throw new Error('Cannot include negative exponent part for integers');while(f.notEquals(0))e[0]+='0',f=f.prev()}e=e[0],e==='-0'&&(e='0');var l=/^([1-9][0-9]*)$|^0$/.test(e);if(!l)throw new Error('Invalid integer');while(e.length){var c=e.length>t?e.length-t:0;a.push(+e.slice(c)),e=e.slice(0,c)}var h=o(a,u);return s&&r(s,h),h},s=function(e,t){var e=o(e,n.positive),t=o(t,n.positive);if(e.equals(0))throw new Error('Cannot divide by 0');var r=0;do{var i=1,s=o(e.value,n.positive),u=s.times(10);while(u.lesser(t))s=u,i*=10,u=u.times(10);while(s.lesserOrEquals(t))t=t.minus(s),r+=i}while(e.lesserOrEquals(t));return{remainder:t.value,result:r}},o=function(f,l){var c={value:f,sign:l},h={value:f,sign:l,negate:function(e){var t=e||c;return o(t.value,!t.sign)},abs:function(e){var t=e||c;return o(t.value,n.positive)},add:function(t,s){var u,a=c,f;s?(a=i(t))&&(f=i(s)):f=i(t,a),u=a.sign;if(a.sign!==f.sign)return a=o(a.value,n.positive),f=o(f.value,n.positive),u===n.positive?h.subtract(a,f):h.subtract(f,a);r(a,f);var l=a.value,p=f.value,d=[],v=0;for(var m=0;m<l.length||v>0;m++){var g=l[m]+p[m]+v;v=g>e?1:0,g-=v*e,d.push(g)}return o(d,u)},plus:function(e,t){return h.add(e,t)},subtract:function(t,r){var s=c,u;r?(s=i(t))&&(u=i(r)):u=i(t,s);if(s.sign!==u.sign)return h.add(s,h.negate(u));if(s.sign===n.negative)return h.subtract(h.negate(u),h.negate(s));if(h.compare(s,u)===-1)return h.negate(h.subtract(u,s));var a=s.value,f=u.value,l=[],p=0;for(var d=0;d<a.length;d++){a[d]-=p,p=a[d]<f[d]?1:0;var v=p*e+a[d]-f[d];l.push(v)}return o(l,n.positive)},minus:function(e,t){return h.subtract(e,t)},multiply:function(t,n){var r,s=c,u;n?(s=i(t))&&(u=i(n)):u=i(t,s),r=s.sign!==u.sign;var a=s.value,f=u.value,l=[];for(var h=0;h<a.length;h++){l[h]=[];var p=h;while(p--)l[h].push(0)}var d=0;for(var h=0;h<a.length;h++){var v=a[h];for(var p=0;p<f.length||d>0;p++){var m=f[p],g=m?v*m+d:d;d=g>e?Math.floor(g/e):0,g-=d*e,l[h].push(g)}}var y=-1;for(var h=0;h<l.length;h++){var b=l[h].length;b>y&&(y=b)}var w=[],d=0;for(var h=0;h<y||d>0;h++){var E=d;for(var p=0;p<l.length;p++)E+=l[p][h]||0;d=E>e?Math.floor(E/e):0,E-=d*e,w.push(E)}return o(w,r)},times:function(e,t){return h.multiply(e,t)},divmod:function(e,t){var r,u=c,a;t?(u=i(e))&&(a=i(t)):a=i(e,u),r=u.sign!==a.sign;if(o(u.value,u.sign).equals(0))return{quotient:o([0],n.positive),remainder:o([0],n.positive)};if(a.equals(0))throw new Error('Cannot divide by zero');var f=u.value,l=a.value,h=[],p=[];for(var d=f.length-1;d>=0;d--){var e=[f[d]].concat(p),v=s(l,e);h.push(v.result),p=v.remainder}return h.reverse(),{quotient:o(h,r),remainder:o(p,u.sign)}},divide:function(e,t){return h.divmod(e,t).quotient},over:function(e,t){return h.divide(e,t)},mod:function(e,t){return h.divmod(e,t).remainder},pow:function(e,t){var n=c,r;t?(n=i(e))&&(r=i(t)):r=i(e,n);var s=n,f=r;if(f.lesser(0))return u;if(f.equals(0))return a;var l=o(s.value,s.sign);if(f.mod(2).equals(0)){var h=l.pow(f.over(2));return h.times(h)}return l.times(l.pow(f.minus(1)))},next:function(e){var t=e||c;return h.add(t,1)},prev:function(e){var t=e||c;return h.subtract(t,1)},compare:function(e,t){var s=c,o;t?(s=i(e))&&(o=i(t,s)):o=i(e,s),r(s,o);if(s.value.length===1&&o.value.length===1&&s.value[0]===0&&o.value[0]===0)return 0;if(o.sign!==s.sign)return s.sign===n.positive?1:-1;var u=s.sign===n.positive?1:-1,a=s.value,f=o.value;for(var l=a.length-1;l>=0;l--){if(a[l]>f[l])return 1*u;if(f[l]>a[l])return-1*u}return 0},compareAbs:function(e,t){var r=c,s;return t?(r=i(e))&&(s=i(t,r)):s=i(e,r),r.sign=s.sign=n.positive,h.compare(r,s)},equals:function(e,t){return h.compare(e,t)===0},notEquals:function(e,t){return!h.equals(e,t)},lesser:function(e,t){return h.compare(e,t)<0},greater:function(e,t){return h.compare(e,t)>0},greaterOrEquals:function(e,t){return h.compare(e,t)>=0},lesserOrEquals:function(e,t){return h.compare(e,t)<=0},isPositive:function(e){var t=e||c;return t.sign===n.positive},isNegative:function(e){var t=e||c;return t.sign===n.negative},isEven:function(e){var t=e||c;return t.value[0]%2===0},isOdd:function(e){var t=e||c;return t.value[0]%2===1},toString:function(r){var i=r||c,s='',o=i.value.length;while(o--)s+=(e.toString()+i.value[o]).slice(-t);while(s[0]==='0')s=s.slice(1);s.length||(s='0');var u=i.sign===n.positive?'':'-';return u+s},toJSNumber:function(e){return+h.toString(e)},valueOf:function(e){return h.toJSNumber(e)}};return h},u=o([0],n.positive),a=o([1],n.positive),f=o([1],n.negative),l=function(e){return typeof e=='undefined'?u:i(e)};return l.zero=u,l.one=a,l.minusOne=f,l}();typeof module!='undefined'&&(module.exports=__IDR__.bigInt);"
64−
65− , "__IDR__.Tailcall = function(f) { this.f = f };"
66−
67− , "__IDR__.Con = function(i,name,vars)"
68− , "{this.i = i;this.name = name;this.vars = vars;};\n"
69−
70− , "__IDR__.tailcall = function(f){\n"
71− ++ "var __f = f;\n"
72− ++ "while (__f) {\n"
73− ++ "var f = __f;\n"
74− ++ "__f = null;\n"
75− ++ "var ret = f();\n"
76− ++ "if (ret instanceof __IDR__.Tailcall) {\n"
77− ++ "__f = ret.f;"
78− ++ "\n} else {\n"
79− ++ "return ret;"
80− ++ "\n}"
81− ++ "\n}"
82− ++ "\n};\n"
83−
84− , "var newline_regex =/(.*)\\n$/;\n"
85−
86− , "__IDR__.print = function(s){\n"
87− ++ "var m = s.match(newline_regex);\n"
88− ++ "console.log(m ? m[1] : s);"
89− ++ "\n};\n"
90− ]
91−
92−createModule :: Maybe String -> NamespaceName -> String -> String
93−createModule toplevel modname body =
94− concat [header modname, body, footer modname]
95− where
96− header :: NamespaceName -> String
97− header modname =
98− concatMap (++ "\n")
99− [ "\nvar " ++ modname ++ ";"
100− , "(function(" ++ modname ++ "){"
101− ]
102−
103− footer :: NamespaceName -> String
104− footer modname =
105− let m = maybe "" (++ ".") toplevel ++ modname in
106− "\n})("
107− ++ m
108− ++ " || ("
109− ++ m
110− ++ " = {})"
111− ++ ");\n"
112−
113−translateModule :: Maybe String -> ([String], SDecl) -> String
114−translateModule toplevel ([modname], decl) =
115− let body = translateDeclaration modname decl in
116− createModule toplevel modname body
117−translateModule toplevel (n:ns, decl) =
118− createModule toplevel n $ translateModule (Just n) (ns, decl)
43+ modules =
44+ concatMap allocMod mods
45+ where
46+ allocMod m = intercalate "." m ++ " = {};\n"
47+ sortMods a b = compare (length a) (length b)
48+
49+ mods =
50+ drop 1 $ sortBy sortMods $ nub $ concatMap (inits . fst) def
11951
12052translateIdentifier :: String -> String
12153translateIdentifier =
@@ -163,24 +95,19 @@ translateName (UN name) = translateIdentifier name
16395translateName (NS name _) = translateName name
16496translateName (MN i name) = translateIdentifier name ++ show i
16597
166−translateQualifiedName :: Name -> String
167−translateQualifiedName name =
168− intercalate "." (translateNamespace name) ++ "." ++ translateName name
169−
17098translateConstant :: Const -> String
171−translateConstant (I i) = show i
172−translateConstant (BI i) = "__IDR__.bigInt('" ++ show i ++ "')"
173−translateConstant (Fl f) = show f
174−translateConstant (Ch c) = show c
175−translateConstant (Str s) = show s
176−translateConstant IType = "__IDR__.Int"
177−translateConstant ChType = "__IDR__.Char"
178−translateConstant StrType = "__IDR__.String"
179−translateConstant BIType = "__IDR__.Integer"
180−translateConstant FlType = "__IDR__.Float"
181−translateConstant PtrType = "__IDR__.Pointer"
182−translateConstant Forgot = "__IDR__.Forgot"
183−translateConstant c =
99+translateConstant (I i) = show i
100+translateConstant (BI i) = "__IDRRT__.bigInt('" ++ show i ++ "')"
101+translateConstant (Fl f) = show f
102+translateConstant (Ch c) = show c
103+translateConstant (Str s) = show s
104+translateConstant IType = "__IDRRT__.Int"
105+translateConstant ChType = "__IDRRT__.Char"
106+translateConstant StrType = "__IDRRT__.String"
107+translateConstant BIType = "__IDRRT__.Integer"
108+translateConstant FlType = "__IDRRT__.Float"
109+translateConstant Forgot = "__IDRRT__.Forgot"
110+translateConstant c =
184111 "(function(){throw 'Unimplemented Const: " ++ show c ++ "';})()"
185112
186113translateParameterlist =
@@ -188,18 +115,16 @@ translateParameterlist =
188115 where translateParameter (MN i name) = name ++ show i
189116 translateParameter (UN name) = name
190117
191−translateDeclaration :: NamespaceName -> SDecl -> String
192−translateDeclaration modname (SFun name params stackSize body) =
193− modname
194− ++ "."
195− ++ translateName name
118+translateDeclaration :: ([String], SDecl) -> String
119+translateDeclaration (path, SFun name params stackSize body) =
120+ intercalate "." (path ++ [translateName name])
196121 ++ " = function("
197122 ++ intercalate "," p
198123 ++ "){\n"
199124 ++ concatMap assignVar (zip [0..] p)
200125 ++ concatMap allocVar [numP..(numP+stackSize-1)]
201126 ++ "return "
202− ++ translateExpression modname body
127+ ++ translateExpression body
203128 ++ ";\n};\n"
204129 where
205130 numP :: Int
@@ -218,32 +143,32 @@ translateVariableName :: LVar -> String
218143translateVariableName (Loc i) =
219144 "__var_" ++ show i
220145
221−translateExpression :: NamespaceName -> SExp -> String
222−translateExpression modname (SLet name value body) =
146+translateExpression :: SExp -> String
147+translateExpression (SLet name value body) =
223148 "(function("
224149 ++ translateVariableName name
225150 ++ "){\nreturn "
226− ++ translateExpression modname body
151+ ++ translateExpression body
227152 ++ ";\n})("
228− ++ translateExpression modname value
153+ ++ translateExpression value
229154 ++ ")"
230155
231−translateExpression _ (SConst cst) =
156+translateExpression (SConst cst) =
232157 translateConstant cst
233158
234−translateExpression _ (SV var) =
159+translateExpression (SV var) =
235160 translateVariableName var
236161
237−translateExpression modname (SApp False name vars) =
162+translateExpression (SApp False name vars) =
238163 createTailcall $ translateFunctionCall name vars
239164
240−translateExpression modname (SApp True name vars) =
241− "new __IDR__.Tailcall("
165+translateExpression (SApp True name vars) =
166+ "new __IDRRT__.Tailcall("
242167 ++ "function(){\n"
243168 ++ "return " ++ translateFunctionCall name vars
244169 ++ ";\n});"
245170
246−translateExpression _ (SOp op vars)
171+translateExpression (SOp op vars)
247172 | LPlus <- op
248173 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
249174 | LMinus <- op
@@ -331,13 +256,13 @@ translateExpression _ (SOp op vars)
331256 | LIntStr <- op
332257 , (arg:_) <- vars = "String(" ++ translateVariableName arg ++ ")"
333258 | LIntBig <- op
334− , (arg:_) <- vars = "__IDR__.bigint(" ++ translateVariableName arg ++ ")"
259+ , (arg:_) <- vars = "__IDRRT__.bigInt(" ++ translateVariableName arg ++ ")"
335260 | LBigInt <- op
336261 , (arg:_) <- vars = translateVariableName arg ++ ".valueOf()"
337262 | LBigStr <- op
338263 , (arg:_) <- vars = translateVariableName arg ++ ".toString()"
339264 | LStrBig <- op
340− , (arg:_) <- vars = "__IDR__.bigint(" ++ translateVariableName arg ++ ")"
265+ , (arg:_) <- vars = "__IDRRT__.bigInt(" ++ translateVariableName arg ++ ")"
341266 | LFloatStr <- op
342267 , (arg:_) <- vars = "String(" ++ translateVariableName arg ++ ")"
343268 | LStrFloat <- op
@@ -396,98 +321,58 @@ translateExpression _ (SOp op vars)
396321 ++ f
397322 ++ translateVariableName rhs
398323
399−translateExpression _ (SError msg) =
324+translateExpression (SError msg) =
400325 "(function(){throw \'" ++ msg ++ "\';})();"
401326
402−translateExpression _ (SForeign _ _ "putStr" [(FString, var)]) =
403− "__IDR__.print(" ++ translateVariableName var ++ ");"
404−
405−translateExpression _ (SForeign _ _ fun args)
406− | "." `isPrefixOf` fun, "[]=" `isSuffixOf` fun
407− , (obj:idx:val:[]) <- args =
408− concat [object obj, field, index idx, assign val]
327+translateExpression (SForeign _ _ "putStr" [(FString, var)]) =
328+ "__IDRRT__.print(" ++ translateVariableName var ++ ");"
409329
410− | "." `isPrefixOf` fun, "[]" `isSuffixOf` fun
411− , (obj:idx:[]) <- args =
412− concat [object obj, field, index idx]
413−
414− | "." `isPrefixOf` fun, "=" `isSuffixOf` fun
415− , (obj:val:[]) <- args =
416− concat [object obj, field, assign val]
417−
418− | "." `isPrefixOf` fun
419− , (obj:[]) <- args =
420− object obj ++ field
421−
422− | "." `isPrefixOf` fun
423− , (obj:[(FUnit, _)]) <- args =
424− concat [object obj, method, "()"]
425−
426− | "." `isPrefixOf` fun
427− , (obj:as) <- args =
428− concat [object obj, method, arguments as]
429−
430− | "[]=" == fun
431− , (idx:val:[]) <- args =
432− concat [array, index idx, assign val]
433−
434− | "[]" == fun
435− , (idx:[]) <- args =
436− array ++ index idx
330+translateExpression (SForeign _ _ fun args) =
331+ fun
332+ ++ "("
333+ ++ intercalate "," (map (translateVariableName . snd) args)
334+ ++ ");"
437335
438− | otherwise = fun ++ arguments args
439− where
440− name = filter (`notElem` "[]=") fun
441− method = name
442− field = name
443− array = name
444− object o = translateVariableName (snd o)
445− index i = "[" ++ translateVariableName (snd i) ++ "]"
446− assign v = '=' : translateVariableName (snd v)
447− arguments as =
448− '(' : intercalate "," (map (translateVariableName . snd) as) ++ ")"
449−
450−translateExpression modname (SChkCase var cases) =
336+translateExpression (SChkCase var cases) =
451337 "(function(e){\n"
452− ++ intercalate " else " (map (translateCase modname "e") cases)
338+ ++ intercalate " else " (map (translateCase "e") cases)
453339 ++ "\n})("
454340 ++ translateVariableName var
455341 ++ ")"
456342
457−translateExpression modname (SCase var cases) =
343+translateExpression (SCase var cases) =
458344 "(function(e){\n"
459− ++ intercalate " else " (map (translateCase modname "e") cases)
345+ ++ intercalate " else " (map (translateCase "e") cases)
460346 ++ "\n})("
461347 ++ translateVariableName var
462348 ++ ")"
463349
464−translateExpression _ (SCon i name vars) =
465− concat [ "new __IDR__.Con("
350+translateExpression (SCon i name vars) =
351+ concat [ "new __IDRRT__.Con("
466352 , show i
467− , ","
468− , '\'' : translateQualifiedName name ++ "\',["
353+ , ",["
469354 , intercalate "," $ map translateVariableName vars
470355 , "])"
471356 ]
472357
473−translateExpression modname (SUpdate var e) =
474− translateVariableName var ++ " = " ++ translateExpression modname e
358+translateExpression (SUpdate var e) =
359+ translateVariableName var ++ " = " ++ translateExpression e
475360
476−translateExpression modname (SProj var i) =
361+translateExpression (SProj var i) =
477362 translateVariableName var ++ ".vars[" ++ show i ++"]"
478363
479−translateExpression _ SNothing = "null"
364+translateExpression SNothing = "null"
480365
481−translateExpression _ e =
366+translateExpression e =
482367 "(function(){throw 'Not yet implemented: "
483368 ++ filter (/= '\'') (show e)
484369 ++ "';})()"
485370
486−translateCase :: String -> String -> SAlt -> String
487−translateCase modname _ (SDefaultCase e) =
488− createIfBlock "true" (translateExpression modname e)
371+translateCase :: String -> SAlt -> String
372+translateCase _ (SDefaultCase e) =
373+ createIfBlock "true" (translateExpression e)
489374
490−translateCase modname var (SConstCase ty e)
375+translateCase var (SConstCase ty e)
491376 | ChType <- ty = matchHelper "Char"
492377 | StrType <- ty = matchHelper "String"
493378 | IType <- ty = matchHelper "Int"
@@ -496,18 +381,18 @@ translateCase modname var (SConstCase ty e)
496381 | PtrType <- ty = matchHelper "Pointer"
497382 | Forgot <- ty = matchHelper "Forgot"
498383 where
499− matchHelper tyName = translateTypeMatch modname var tyName e
384+ matchHelper tyName = translateTypeMatch var tyName e
500385
501−translateCase modname var (SConstCase cst@(BI _) e) =
386+translateCase var (SConstCase cst@(BI _) e) =
502387 let cond = var ++ ".equals(" ++ translateConstant cst ++ ")" in
503− createIfBlock cond (translateExpression modname e)
388+ createIfBlock cond (translateExpression e)
504389
505−translateCase modname var (SConstCase cst e) =
390+translateCase var (SConstCase cst e) =
506391 let cond = var ++ " == " ++ translateConstant cst in
507− createIfBlock cond (translateExpression modname e)
392+ createIfBlock cond (translateExpression e)
508393
509−translateCase modname var (SConCase a i name vars e) =
510− let isCon = var ++ " instanceof __IDR__.Con"
394+translateCase var (SConCase a i name vars e) =
395+ let isCon = var ++ " instanceof __IDRRT__.Con"
511396 isI = show i ++ " == " ++ var ++ ".i"
512397 params = intercalate "," $ map (("__var_" ++) . show) [a..(a+length vars)]
513398 args = ".apply(this," ++ var ++ ".vars)"
@@ -516,13 +401,13 @@ translateCase modname var (SConCase a i name vars e) =
516401 ++ params
517402 ++ "){\nreturn " ++ b ++ "\n})" ++ args
518403 cond = intercalate " && " [isCon, isI] in
519− createIfBlock cond $ f (translateExpression modname e)
404+ createIfBlock cond $ f (translateExpression e)
520405
521−translateTypeMatch :: String -> String -> String -> SExp -> String
522−translateTypeMatch modname var ty exp =
523− let e = translateExpression modname exp in
406+translateTypeMatch :: String -> String -> SExp -> String
407+translateTypeMatch var ty exp =
408+ let e = translateExpression exp in
524409 createIfBlock (var
525− ++ " instanceof __IDR__.Type && "
410+ ++ " instanceof __IDRRT__.Type && "
526411 ++ var ++ ".type == '"++ ty ++"'") e
527412
528413
@@ -532,7 +417,7 @@ createIfBlock cond e =
532417 ++ ";\n}"
533418
534419createTailcall call =
535− "__IDR__.tailcall(function(){return " ++ call ++ "})"
420+ "__IDRRT__.tailcall(function(){return " ++ call ++ "})"
536421
537422translateFunctionCall name vars =
538423 concat (intersperse "." $ translateNamespace name)
tutorial/idris-tutorial.pdf

Binary file not shown.

tutorial/interp.tex+1−1
@@ -344,7 +344,7 @@ at the \Idris{} interactive environment is shown in Figure \ref{factrun}.
344344$ idris interp.idr
345345 ____ __ _
346346 / _/___/ /____(_)____
347− / // __ / ___/ / ___/ Version 0.9.5
347+ / // __ / ___/ / ___/ Version 0.9.6
348348 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
349349 /___/\__,_/_/ /_/____/ Type :? for help
350350
tutorial/intro.tex+1−1
@@ -62,7 +62,7 @@ verifying systems software.
6262\subsection{Example Code}
6363
6464This tutorial includes some example code, which has been tested with \Idris{} version
65−0.9.5. The files are available in the \Idris{} distribution,
65+0.9.6. The files are available in the \Idris{} distribution,
6666so that you can try them out easily,
6767under \texttt{tutorial/examples}. However, it is strongly recommended that you
6868type them in yourself, rather than simply loading and reading them.
tutorial/starting.tex+3−3
@@ -79,7 +79,7 @@ environment. You should see something like the following:
7979$ idris
8080 ____ __ _
8181 / _/___/ /____(_)____
82− / // __ / ___/ / ___/ Version 0.9.5
82+ / // __ / ___/ / ___/ Version 0.9.6
8383 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
8484 /___/\__,_/_/ /_/____/ Type :? for help
8585
@@ -99,7 +99,7 @@ as shown in Figure \ref{cmds}. Figure \ref{run1} shows an example run in which
9999the program is compiled to the executable \texttt{hello}.
100100
101101\begin{SaveVerbatim}{cmds}
102−Idris version 0.9.5
102+Idris version 0.9.6
103103-------------------
104104
105105 Command Arguments Purpose
@@ -134,7 +134,7 @@ Idris version 0.9.5
134134$ idris hello.idr
135135 ____ __ _
136136 / _/___/ /____(_)____
137− / // __ / ___/ / ___/ Version 0.9.5
137+ / // __ / ___/ / ___/ Version 0.9.6
138138 _/ // /_/ / / / (__ ) http://www.idris-lang.org/
139139 /___/\__,_/_/ /_/____/ Type :? for help
140140