on master help sign in
Merge pull request #155 from raichoo/javascript
a601cc6Edwin Brady
CHANGELOG+1−1
@@ -22,7 +22,7 @@ User visible changes:
22* Added System.Concurrency modules
22* Added System.Concurrency modules
23* Added 'postulate' declarations
23* Added 'postulate' declarations
24* Allow type annotations on 'let' tactic
24* Allow type annotations on 'let' tactic
25−* EXPERIMENTAL JavaScript generation, with --javascript option
25+* EXPERIMENTAL JavaScript generation, with '--target javascript' option
26
26
27Internal changes:
27Internal changes:
28
28
src/IRTS/CodegenC.hs+2
@@ -322,5 +322,7 @@ doOp v LStdErr [] = v ++ "MKPTR(vm, stderr)"
322doOp v LFork [x] = v ++ "MKPTR(vm, vmThread(vm, " ++ cname (MN 0 "EVAL") ++ ", " ++ creg x ++ "))"
322doOp v LFork [x] = v ++ "MKPTR(vm, vmThread(vm, " ++ cname (MN 0 "EVAL") ++ ", " ++ creg x ++ "))"
323doOp v LPar [x] = v ++ creg x -- "MKPTR(vm, vmThread(vm, " ++ cname (MN 0 "EVAL") ++ ", " ++ creg x ++ "))"
323doOp v LPar [x] = v ++ creg x -- "MKPTR(vm, vmThread(vm, " ++ cname (MN 0 "EVAL") ++ ", " ++ creg x ++ "))"
324doOp v LVMPtr [] = v ++ "MKPTR(vm, vm)"
324doOp v LVMPtr [] = v ++ "MKPTR(vm, vm)"
325+doOp v LChInt args = v ++ creg (last args)
326+doOp v LIntCh args = v ++ creg (last args)
325doOp v LNoOp args = v ++ creg (last args)
327doOp v LNoOp args = v ++ creg (last args)
326doOp _ _ _ = "FAIL"
328doOp _ _ _ = "FAIL"
src/IRTS/CodegenJavaScript.hs+173−51
@@ -1,5 +1,10 @@
1{-# LANGUAGE PatternGuards #-}
1{-# LANGUAGE PatternGuards #-}
2
2
3+{-
4+ BigInteger Javascript code taken from:
5+ https://github.com/peterolson/BigInteger.js
6+-}
7+
3module IRTS.CodegenJavaScript (codegenJavaScript) where
8module IRTS.CodegenJavaScript (codegenJavaScript) where
4
9
5import Idris.AbsSyntax
10import Idris.AbsSyntax
@@ -46,7 +51,15 @@ codegenJavaScript definitions filename outputType =
46idrRuntime :: String
51idrRuntime :: String
47idrRuntime =
52idrRuntime =
48 createModule Nothing idrNamespace $ concat
53 createModule Nothing idrNamespace $ concat
49− [ "__IDR__.IntType = { type: 'IntType' };"
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__.Forgot = new __IDR__.Type('Forgot');"
61+
62+ , "__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);"
50
63
51 , "__IDR__.Tailcall = function(f) { this.f = f };"
64 , "__IDR__.Tailcall = function(f) { this.f = f };"
52
65
@@ -108,32 +121,40 @@ translateIdentifier =
108 concatMap replaceBadChars
121 concatMap replaceBadChars
109 where replaceBadChars :: Char -> String
122 where replaceBadChars :: Char -> String
110 replaceBadChars ' ' = "_"
123 replaceBadChars ' ' = "_"
111− replaceBadChars '@' = "__at__"
124+ replaceBadChars '_' = "__"
125+ replaceBadChars '@' = "_at"
112− replaceBadChars '[' = "__OSB__"
126+ replaceBadChars '[' = "_OSB"
113− replaceBadChars ']' = "__CSB__"
127+ replaceBadChars ']' = "_CSB"
114− replaceBadChars '(' = "__OP__"
128+ replaceBadChars '(' = "_OP"
115− replaceBadChars ')' = "__CP__"
129+ replaceBadChars ')' = "_CP"
116− replaceBadChars '{' = "__OB__"
130+ replaceBadChars '{' = "_OB"
117− replaceBadChars '}' = "__CB__"
131+ replaceBadChars '}' = "_CB"
118− replaceBadChars '!' = "__bang__"
132+ replaceBadChars '!' = "_bang"
119− replaceBadChars '#' = "__hash__"
133+ replaceBadChars '#' = "_hash"
120− replaceBadChars '.' = "__dot__"
134+ replaceBadChars '.' = "_dot"
121− replaceBadChars ',' = "__comma__"
135+ replaceBadChars ',' = "_comma"
122− replaceBadChars ':' = "__colon__"
136+ replaceBadChars ':' = "_colon"
123− replaceBadChars '+' = "__plus__"
137+ replaceBadChars '+' = "_plus"
124− replaceBadChars '-' = "__minus__"
138+ replaceBadChars '-' = "_minus"
139+ replaceBadChars '*' = "_times"
125− replaceBadChars '<' = "__lt__"
140+ replaceBadChars '<' = "_lt"
126− replaceBadChars '>' = "__gt__"
141+ replaceBadChars '>' = "_gt"
127− replaceBadChars '=' = "__eq__"
142+ replaceBadChars '=' = "_eq"
128− replaceBadChars '|' = "__pipe__"
143+ replaceBadChars '|' = "_pipe"
144+ replaceBadChars '&' = "_amp"
145+ replaceBadChars '/' = "_SL"
129− replaceBadChars '\'' = "__apo__"
146+ replaceBadChars '\\' = "_BSL"
147+ replaceBadChars '%' = "_per"
148+ replaceBadChars '?' = "_que"
149+ replaceBadChars '~' = "_til"
150+ replaceBadChars '\'' = "_apo"
130 replaceBadChars c
151 replaceBadChars c
131− | isDigit c = "__" ++ [c] ++ "__"
152+ | isDigit c = "_" ++ [c] ++ "_"
132 | otherwise = [c]
153 | otherwise = [c]
133
154
134translateNamespace :: Name -> [String]
155translateNamespace :: Name -> [String]
135translateNamespace (UN _) = [idrNamespace]
156translateNamespace (UN _) = [idrNamespace]
136−translateNamespace (NS _ ns) = map translateIdentifier ns
157+translateNamespace (NS _ ns) = idrNamespace : map translateIdentifier ns
137translateNamespace (MN _ _) = [idrNamespace]
158translateNamespace (MN _ _) = [idrNamespace]
138
159
139translateName :: Name -> String
160translateName :: Name -> String
@@ -147,11 +168,16 @@ translateQualifiedName name =
147
168
148translateConstant :: Const -> String
169translateConstant :: Const -> String
149translateConstant (I i) = show i
170translateConstant (I i) = show i
150−translateConstant (BI i) = show i
171+translateConstant (BI i) = "__IDR__.bigInt('" ++ show i ++ "')"
151translateConstant (Fl f) = show f
172translateConstant (Fl f) = show f
152translateConstant (Ch c) = show c
173translateConstant (Ch c) = show c
153translateConstant (Str s) = show s
174translateConstant (Str s) = show s
154−translateConstant IType = "__IDR__.IntType"
175+translateConstant IType = "__IDR__.Int"
176+translateConstant ChType = "__IDR__.Char"
177+translateConstant StrType = "__IDR__.String"
178+translateConstant BIType = "__IDR__.Integer"
179+translateConstant FlType = "__IDR__.Float"
180+translateConstant Forgot = "__IDR__.Forgot"
155translateConstant c =
181translateConstant c =
156 "(function(){throw 'Unimplemented Const: " ++ show c ++ "';})()"
182 "(function(){throw 'Unimplemented Const: " ++ show c ++ "';})()"
157
183
@@ -210,12 +236,10 @@ translateExpression modname (SApp False name vars) =
210 createTailcall $ translateFunctionCall name vars
236 createTailcall $ translateFunctionCall name vars
211
237
212translateExpression modname (SApp True name vars) =
238translateExpression modname (SApp True name vars) =
213− "(function(){\n"
214− ++ "return new __IDR__.Tailcall("
239+ "new __IDR__.Tailcall("
215 ++ "function(){\n"
240 ++ "function(){\n"
216 ++ "return " ++ translateFunctionCall name vars
241 ++ "return " ++ translateFunctionCall name vars
217 ++ ";\n});"
242 ++ ";\n});"
218− ++ "\n})()"
219
243
220translateExpression _ (SOp op vars)
244translateExpression _ (SOp op vars)
221 | LPlus <- op
245 | LPlus <- op
@@ -238,6 +262,39 @@ translateExpression _ (SOp op vars)
238 , (lhs:rhs:_) <- vars = translateBinaryOp ">" lhs rhs
262 , (lhs:rhs:_) <- vars = translateBinaryOp ">" lhs rhs
239 | LGe <- op
263 | LGe <- op
240 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
264 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
265+ | LAnd <- op
266+ , (lhs:rhs:_) <- vars = translateBinaryOp "&" lhs rhs
267+ | LOr <- op
268+ , (lhs:rhs:_) <- vars = translateBinaryOp "|" lhs rhs
269+ | LXOr <- op
270+ , (lhs:rhs:_) <- vars = translateBinaryOp "^" lhs rhs
271+ | LSHL <- op
272+ , (lhs:rhs:_) <- vars = translateBinaryOp "<<" rhs lhs
273+ | LSHR <- op
274+ , (lhs:rhs:_) <- vars = translateBinaryOp ">>" rhs lhs
275+ | LCompl <- op
276+ , (arg:_) <- vars = '~' : translateVariableName arg
277+
278+ | LBPlus <- op
279+ , (lhs:rhs:_) <- vars = translateBinaryOp ".add(" lhs rhs ++ ")"
280+ | LBMinus <- op
281+ , (lhs:rhs:_) <- vars = translateBinaryOp ".minus(" lhs rhs ++ ")"
282+ | LBTimes <- op
283+ , (lhs:rhs:_) <- vars = translateBinaryOp ".times(" lhs rhs ++ ")"
284+ | LBDiv <- op
285+ , (lhs:rhs:_) <- vars = translateBinaryOp ".divide(" lhs rhs ++ ")"
286+ | LBMod <- op
287+ , (lhs:rhs:_) <- vars = translateBinaryOp ".mod(" lhs rhs ++ ")"
288+ | LBEq <- op
289+ , (lhs:rhs:_) <- vars = translateBinaryOp ".equals(" lhs rhs ++ ")"
290+ | LBLt <- op
291+ , (lhs:rhs:_) <- vars = translateBinaryOp ".lesser(" lhs rhs ++ ")"
292+ | LBLe <- op
293+ , (lhs:rhs:_) <- vars = translateBinaryOp ".lesserOrEquals(" lhs rhs ++ ")"
294+ | LBGt <- op
295+ , (lhs:rhs:_) <- vars = translateBinaryOp ".greater(" lhs rhs ++ ")"
296+ | LBGe <- op
297+ , (lhs:rhs:_) <- vars = translateBinaryOp ".greaterOrEquals(" lhs rhs ++ ")"
241
298
242 | LFPlus <- op
299 | LFPlus <- op
243 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
300 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
@@ -258,35 +315,78 @@ translateExpression _ (SOp op vars)
258 | LFGe <- op
315 | LFGe <- op
259 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
316 , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
260
317
261− | LBPlus <- op
262− , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
263− | LBMinus <- op
264− , (lhs:rhs:_) <- vars = translateBinaryOp "-" lhs rhs
265− | LBTimes <- op
266− , (lhs:rhs:_) <- vars = translateBinaryOp "*" lhs rhs
267− | LBDiv <- op
268− , (lhs:rhs:_) <- vars = translateBinaryOp "/" lhs rhs
269− | LBMod <- op
270− , (lhs:rhs:_) <- vars = translateBinaryOp "%" lhs rhs
271− | LBEq <- op
272− , (lhs:rhs:_) <- vars = translateBinaryOp "==" lhs rhs
273− | LBLt <- op
274− , (lhs:rhs:_) <- vars = translateBinaryOp "<" lhs rhs
275− | LBLe <- op
276− , (lhs:rhs:_) <- vars = translateBinaryOp "<=" lhs rhs
277− | LBGt <- op
278− , (lhs:rhs:_) <- vars = translateBinaryOp ">" lhs rhs
279− | LBGe <- op
280− , (lhs:rhs:_) <- vars = translateBinaryOp ">=" lhs rhs
281−
282 | LStrConcat <- op
318 | LStrConcat <- op
283 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
319 , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
284 | LStrEq <- op
320 | LStrEq <- op
285− , (lhs:rhs:_) <- vars = translateBinaryOp "=" lhs rhs
321+ , (lhs:rhs:_) <- vars = translateBinaryOp "==" lhs rhs
322+ | LStrLt <- op
323+ , (lhs:rhs:_) <- vars = translateBinaryOp "<" lhs rhs
324+ | LStrLen <- op
325+ , (arg:_) <- vars = translateVariableName arg ++ ".length"
286
326
327+ | LStrInt <- op
328+ , (arg:_) <- vars = "parseInt(" ++ translateVariableName arg ++ ")"
287 | LIntStr <- op
329 | LIntStr <- op
288− , (arg:_) <- vars = "String(" ++ translateVariableName arg ++ ");"
330+ , (arg:_) <- vars = "String(" ++ translateVariableName arg ++ ")"
289−
331+ | LIntBig <- op
332+ , (arg:_) <- vars = "__IDR__.bigint(" ++ translateVariableName arg ++ ")"
333+ | LBigInt <- op
334+ , (arg:_) <- vars = translateVariableName arg ++ ".valueOf()"
335+ | LBigStr <- op
336+ , (arg:_) <- vars = translateVariableName arg ++ ".toString()"
337+ | LStrBig <- op
338+ , (arg:_) <- vars = "__IDR__.bigint(" ++ translateVariableName arg ++ ")"
339+ | LFloatStr <- op
340+ , (arg:_) <- vars = "String(" ++ translateVariableName arg ++ ")"
341+ | LStrFloat <- op
342+ , (arg:_) <- vars = "parseFloat(" ++ translateVariableName arg ++ ")"
343+ | LIntFloat <- op
344+ , (arg:_) <- vars = translateVariableName arg
345+ | LFloatInt <- op
346+ , (arg:_) <- vars = translateVariableName arg
347+ | LChInt <- op
348+ , (arg:_) <- vars = translateVariableName arg ++ ".charCodeAt(0)"
349+ | LIntCh <- op
350+ , (arg:_) <- vars =
351+ "String.fromCharCode(" ++ translateVariableName arg ++ ")"
352+
353+ | LFExp <- op
354+ , (arg:_) <- vars = "Math.exp(" ++ translateVariableName arg ++ ")"
355+ | LFLog <- op
356+ , (arg:_) <- vars = "Math.log(" ++ translateVariableName arg ++ ")"
357+ | LFSin <- op
358+ , (arg:_) <- vars = "Math.sin(" ++ translateVariableName arg ++ ")"
359+ | LFCos <- op
360+ , (arg:_) <- vars = "Math.cos(" ++ translateVariableName arg ++ ")"
361+ | LFTan <- op
362+ , (arg:_) <- vars = "Math.tan(" ++ translateVariableName arg ++ ")"
363+ | LFASin <- op
364+ , (arg:_) <- vars = "Math.asin(" ++ translateVariableName arg ++ ")"
365+ | LFACos <- op
366+ , (arg:_) <- vars = "Math.acos(" ++ translateVariableName arg ++ ")"
367+ | LFATan <- op
368+ , (arg:_) <- vars = "Math.atan(" ++ translateVariableName arg ++ ")"
369+ | LFSqrt <- op
370+ , (arg:_) <- vars = "Math.sqrt(" ++ translateVariableName arg ++ ")"
371+ | LFFloor <- op
372+ , (arg:_) <- vars = "Math.floor(" ++ translateVariableName arg ++ ")"
373+ | LFCeil <- op
374+ , (arg:_) <- vars = "Math.ceil(" ++ translateVariableName arg ++ ")"
375+
376+ | LStrCons <- op
377+ , (lhs:rhs:_) <- vars = translateBinaryOp "+" lhs rhs
378+ | LStrHead <- op
379+ , (arg:_) <- vars = translateVariableName arg ++ "[0]"
380+ | LStrRev <- op
381+ , (arg:_) <- vars = let v = translateVariableName arg in
382+ v ++ "split('').reverse().join('')"
383+ | LStrIndex <- op
384+ , (lhs:rhs:_) <- vars = let l = translateVariableName lhs
385+ r = translateVariableName rhs in
386+ l ++ "[" ++ r ++ "]"
387+ | LStrTail <- op
388+ , (arg:_) <- vars = let v = translateVariableName arg in
389+ v ++ ".substr(1," ++ v ++ ".length-1)"
290 where
390 where
291 translateBinaryOp :: String -> LVar -> LVar -> String
391 translateBinaryOp :: String -> LVar -> LVar -> String
292 translateBinaryOp f lhs rhs =
392 translateBinaryOp f lhs rhs =
@@ -346,6 +446,20 @@ translateCase :: String -> String -> SAlt -> String
346translateCase modname _ (SDefaultCase e) =
446translateCase modname _ (SDefaultCase e) =
347 createIfBlock "true" (translateExpression modname e)
447 createIfBlock "true" (translateExpression modname e)
348
448
449+translateCase modname var (SConstCase ty e)
450+ | ChType <- ty = matchHelper "Char"
451+ | StrType <- ty = matchHelper "String"
452+ | IType <- ty = matchHelper "Int"
453+ | BIType <- ty = matchHelper "Integer"
454+ | FlType <- ty = matchHelper "Float"
455+ | Forgot <- ty = matchHelper "Forgot"
456+ where
457+ matchHelper tyName = translateTypeMatch modname var tyName e
458+
459+translateCase modname var (SConstCase cst@(BI _) e) =
460+ let cond = var ++ ".equals(" ++ translateConstant cst ++ ")" in
461+ createIfBlock cond (translateExpression modname e)
462+
349translateCase modname var (SConstCase cst e) =
463translateCase modname var (SConstCase cst e) =
350 let cond = var ++ " == " ++ translateConstant cst in
464 let cond = var ++ " == " ++ translateConstant cst in
351 createIfBlock cond (translateExpression modname e)
465 createIfBlock cond (translateExpression modname e)
@@ -362,6 +476,14 @@ translateCase modname var (SConCase a i name vars e) =
362 cond = intercalate " && " [isCon, isI] in
476 cond = intercalate " && " [isCon, isI] in
363 createIfBlock cond $ f (translateExpression modname e)
477 createIfBlock cond $ f (translateExpression modname e)
364
478
479+translateTypeMatch :: String -> String -> String -> SExp -> String
480+translateTypeMatch modname var ty exp =
481+ let e = translateExpression modname exp in
482+ createIfBlock (var
483+ ++ " instanceof __IDR__.Type && "
484+ ++ var ++ ".type == '"++ ty ++"'") e
485+
486+
365createIfBlock cond e =
487createIfBlock cond e =
366 "if (" ++ cond ++") {\n"
488 "if (" ++ cond ++") {\n"
367 ++ "return " ++ e
489 ++ "return " ++ e
src/IRTS/Lang.hs+1−1
@@ -37,7 +37,7 @@ data PrimFn = LPlus | LMinus | LTimes | LDiv | LMod
37 | LBEq | LBLt | LBLe | LBGt | LBGe
37 | LBEq | LBLt | LBLe | LBGt | LBGe
38 | LStrConcat | LStrLt | LStrEq | LStrLen
38 | LStrConcat | LStrLt | LStrEq | LStrLen
39 | LIntFloat | LFloatInt | LIntStr | LStrInt | LFloatStr | LStrFloat
39 | LIntFloat | LFloatInt | LIntStr | LStrInt | LFloatStr | LStrFloat
40− | LIntBig | LBigInt | LStrBig | LBigStr
40+ | LIntBig | LBigInt | LStrBig | LBigStr | LChInt | LIntCh
41 | LPrintNum | LPrintStr | LReadStr
41 | LPrintNum | LPrintStr | LReadStr
42
42
43 | LW8 | LW16
43 | LW8 | LW16
src/Idris/Primitives.hs+2−2
@@ -144,9 +144,9 @@ primitives =
144 Prim (UN "prim__intToStr") (ty [IType] StrType) 1 (c_intToStr)
144 Prim (UN "prim__intToStr") (ty [IType] StrType) 1 (c_intToStr)
145 (1, LIntStr) total,
145 (1, LIntStr) total,
146 Prim (UN "prim__charToInt") (ty [ChType] IType) 1 (c_charToInt)
146 Prim (UN "prim__charToInt") (ty [ChType] IType) 1 (c_charToInt)
147− (1, LNoOp) total,
147+ (1, LChInt) total,
148 Prim (UN "prim__intToChar") (ty [IType] ChType) 1 (c_intToChar)
148 Prim (UN "prim__intToChar") (ty [IType] ChType) 1 (c_intToChar)
149− (1, LNoOp) total,
149+ (1, LIntCh) total,
150 Prim (UN "prim__intToBigInt") (ty [IType] BIType) 1 (c_intToBigInt)
150 Prim (UN "prim__intToBigInt") (ty [IType] BIType) 1 (c_intToBigInt)
151 (1, LIntBig) total,
151 (1, LIntBig) total,
152 Prim (UN "prim__bigIntToInt") (ty [BIType] IType) 1 (c_bigIntToInt)
152 Prim (UN "prim__bigIntToInt") (ty [BIType] IType) 1 (c_bigIntToInt)
src/Idris/REPL.hs−1
@@ -430,7 +430,6 @@ parseArgs ("--noprelude":ns) = NoPrelude : (parseArgs ns)
430parseArgs ("--check":ns) = NoREPL : (parseArgs ns)
430parseArgs ("--check":ns) = NoREPL : (parseArgs ns)
431parseArgs ("-o":n:ns) = NoREPL : Output n : (parseArgs ns)
431parseArgs ("-o":n:ns) = NoREPL : Output n : (parseArgs ns)
432parseArgs ("-no":n:ns) = NoREPL : NewOutput n : (parseArgs ns)
432parseArgs ("-no":n:ns) = NoREPL : NewOutput n : (parseArgs ns)
433−parseArgs ("--javascript":ns) = UseTarget ToJavaScript : (parseArgs ns)
434parseArgs ("--typecase":ns) = TypeCase : (parseArgs ns)
433parseArgs ("--typecase":ns) = TypeCase : (parseArgs ns)
435parseArgs ("--typeintype":ns) = TypeInType : (parseArgs ns)
434parseArgs ("--typeintype":ns) = TypeInType : (parseArgs ns)
436parseArgs ("--total":ns) = DefaultTotal : (parseArgs ns)
435parseArgs ("--total":ns) = DefaultTotal : (parseArgs ns)
src/Main.hs+1−2
@@ -92,5 +92,4 @@ usagemsg = "Idris version " ++ ver ++ "\n" ++
92 "\t--libdir Show library install directory and exit\n" ++
92 "\t--libdir Show library install directory and exit\n" ++
93 "\t--link Show C library directories and exit (for C linking)\n" ++
93 "\t--link Show C library directories and exit (for C linking)\n" ++
94 "\t--include Show C include directories and exit (for C linking)\n" ++
94 "\t--include Show C include directories and exit (for C linking)\n" ++
95− "\t--target [target] Type the target: C, Java, bytecode\n" ++
95+ "\t--target [target] Type the target: C, Java, bytecode, javascript\n"
96− "\t--javascript Compile to JavaScript rather than to native code\n"