@@ -64,6 +64,7 @@ data JS = JSRaw String
64 | JSArray [JS]
64 | JSArray [JS]
65 | JSObject [(String, JS)]
65 | JSObject [(String, JS)]
66 | JSString String
66 | JSString String
67 | JSNum JSNum
68 | JSNum JSNum
68 | JSAssign JS JS
69 | JSAssign JS JS
69 | JSAlloc String (Maybe JS)
70 | JSAlloc String (Maybe JS)
@@ -153,6 +154,9 @@ compileJS (JSObject fields) =
153compileJS (JSString str) =
154compileJS (JSString str) =
157+compileJS (JSChar chr) =
156compileJS (JSNum num)
160compileJS (JSNum num)
157 | JSInt i <- num = show i
161 | JSInt i <- num = show i
158 | JSFloat f <- num = show f
162 | JSFloat f <- num = show f
@@ -170,8 +174,16 @@ compileJS (JSIndex lhs rhs) =
170 compileJS lhs ++ "[" ++ compileJS rhs ++ "]"
174 compileJS lhs ++ "[" ++ compileJS rhs ++ "]"
172compileJS (JSCond branches) =
176compileJS (JSCond branches) =
173− intercalate " else " $ map createIfBlock branches
177+ intercalate " else " $ map createIfBlock (eliminateDeadBranches branches)
179+ eliminateDeadBranches (e@(JSTrue, _):_) = [e]
180+ eliminateDeadBranches (x:xs) = x : eliminateDeadBranches xs
181+ eliminateDeadBranches [] = []
183+ createIfBlock (JSTrue, e) =
185+ ++ "return " ++ compileJS e
175 createIfBlock (cond, e) =
187 createIfBlock (cond, e) =
176 "if (" ++ compileJS cond ++") {\n"
188 "if (" ++ compileJS cond ++") {\n"
177 ++ "return " ++ compileJS e
189 ++ "return " ++ compileJS e
@@ -233,6 +245,7 @@ jsLet name value body =
234 ) [value]
246 ) [value]
236jsSubst :: String -> JS -> JS -> JS
249jsSubst :: String -> JS -> JS -> JS
237jsSubst var new (JSVar old)
250jsSubst var new (JSVar old)
238 | var == translateVariableName old = new
251 | var == translateVariableName old = new
@@ -260,6 +273,16 @@ jsSubst var new (JSApp (JSIdent "__IDRRT__tailcall") [JSFunction [] (
260 JSReturn $ JSApp (jsSubst var new fun) (map (jsSubst var new) args)
273 JSReturn $ JSApp (jsSubst var new fun) (map (jsSubst var new) args)
276+jsSubst var new (JSApp (JSProj (JSFunction args body) "apply") vals)
277+ | var `notElem` args =
278+ JSApp (JSProj (JSFunction args (jsSubst var new body)) "apply") (
279+ map (jsSubst var new) vals
282+ JSApp (JSProj (JSFunction args body) "apply") (
283+ map (jsSubst var new) vals
263jsSubst var new (JSApp (JSProj obj field) args) =
286jsSubst var new (JSApp (JSProj obj field) args) =
264 JSApp (JSProj (jsSubst var new obj) field) $ map (jsSubst var new) args
287 JSApp (JSProj (jsSubst var new obj) field) $ map (jsSubst var new) args
@@ -293,7 +316,38 @@ jsSubst var new (JSCond conds) =
294jsSubst _ _ js = js
317jsSubst _ _ js = js
320+isJSConstant :: JS -> Bool
322+ | JSString _ <- js = True
323+ | JSChar _ <- js = True
324+ | JSNum _ <- js = True
325+ | JSType _ <- js = True
327+ | JSApp (JSIdent "__IDRRT__bigInt") _ <- js = True
296inlineJS :: JS -> JS
330inlineJS :: JS -> JS
331+inlineJS (JSApp (JSProj (JSFunction args (JSReturn body)) "apply") [
332+ JSThis,JSProj (JSIdent var) "vars"
335+ inlineApply args body 0
337+ inlineApply [] body _ = body
338+ inlineApply (a:as) body n =
340+ jsSubst a (JSIndex (JSProj (JSIdent var) "vars") (JSNum (JSInt n))) body
343+inlineJS (JSApp (JSIdent "__IDR__mEVAL0") [val])
344+ | isJSConstant val = val
346+inlineJS (JSApp (JSIdent "__IDRRT__tailcall") [
347+ JSFunction [] (JSReturn val)
349+ | isJSConstant val = val
297inlineJS (JSApp (JSFunction [] (JSSeq ret)) []) =
351inlineJS (JSApp (JSFunction [] (JSSeq ret)) []) =
298 JSApp (JSFunction [] (JSSeq (map inlineJS ret))) []
352 JSApp (JSFunction [] (JSSeq (map inlineJS ret))) []
@@ -365,6 +419,9 @@ inlineJS (JSCond cases) =
365inlineJS (JSObject fields) =
419inlineJS (JSObject fields) =
366 JSObject (map (second inlineJS) fields)
420 JSObject (map (second inlineJS) fields)
422+inlineJS (JSOp op lhs rhs) =
423+ JSOp op (inlineJS lhs) (inlineJS rhs)
368inlineJS js = js
425inlineJS js = js
370reduceJS :: [JS] -> [JS]
427reduceJS :: [JS] -> [JS]
@@ -536,6 +593,12 @@ reduceLoop reduced (cons, program) =
536 reduceCall funs (JSProj obj field) =
593 reduceCall funs (JSProj obj field) =
537 JSProj (reduceCall funs obj) field
594 JSProj (reduceCall funs obj) field
596+ reduceCall funs (JSIndex obj idx) =
597+ JSIndex (reduceCall funs obj) (reduceCall funs idx)
599+ reduceCall funs (JSOp op rhs lhs) =
600+ JSOp op (reduceCall funs rhs) (reduceCall funs lhs)
539 reduceCall funs (JSCond conds) =
602 reduceCall funs (JSCond conds) =
540 JSCond $ map (reduceCall funs *** reduceCall funs) conds
603 JSCond $ map (reduceCall funs *** reduceCall funs) conds
@@ -699,6 +762,9 @@ translateSpecialName name
699translateConstant :: Const -> JS
762translateConstant :: Const -> JS
700translateConstant (I i) = JSNum (JSInt i)
763translateConstant (I i) = JSNum (JSInt i)
701translateConstant (Fl f) = JSNum (JSFloat f)
764translateConstant (Fl f) = JSNum (JSFloat f)
765+translateConstant (Ch '\DEL') = JSChar "'\\u007F'"
766+translateConstant (Ch '\a') = JSChar "'\\u0007'"
767+translateConstant (Ch '\SO') = JSChar "'\\u000E'"
702translateConstant (Ch c) = JSString [c]
768translateConstant (Ch c) = JSString [c]
703translateConstant (Str s) = JSString s
769translateConstant (Str s) = JSString s
704translateConstant (AType (ATInt ITNative)) = JSType JSIntTy
770translateConstant (AType (ATInt ITNative)) = JSType JSIntTy
@@ -800,23 +866,16 @@ translateDeclaration (path, SFun name params stackSize body)
800 JSFunction (p ++ map snd aux) (
866 JSFunction (p ++ map snd aux) (
802 zipWith assignVar [0..] p ++
868 zipWith assignVar [0..] p ++
803− map allocVar [numP .. (numP + stackSize - 1)] ++
804 map assignAux aux ++
869 map assignAux aux ++
805 [JSReturn body]
870 [JSReturn body]
809− numP = length params
811− allocVar :: Int -> JS
812− allocVar n = JSAlloc (jsVar n) Nothing
814 assignVar :: Int -> String -> JS
873 assignVar :: Int -> String -> JS
815 assignVar n s = JSAlloc (jsVar n) (Just $ JSIdent s)
874 assignVar n s = JSAlloc (jsVar n) (Just $ JSIdent s)
817 assignAux :: (LVar, String) -> JS
876 assignAux :: (LVar, String) -> JS
818− assignAux (var, val) =
877+ assignAux (Loc var, val) =
819− JSAssign (JSIdent $ translateVariableName var) (JSIdent val)
878+ JSAlloc (jsVar var) (Just $ JSIdent val)
821 p :: [String]
880 p :: [String]
822 p = map translateName params
881 p = map translateName params