@@ -163,11 +163,9 @@ compileJS (JSTernary cond true false) =
163163 f = compileJS false in
164164 "(" ++ c ++ ")?(" ++ t ++ "):(" ++ f ++ ")"
165165
166−jsTailcall :: JS -> JS
167−jsTailcall call =
168− jsCall (idrRTNamespace ++ "tailcall") [
169− JSFunction [] (JSReturn call)
170− ]
166+jsTailcall :: String -> [JS] -> JS
167+jsTailcall fun args =
168+ jsCall (idrRTNamespace ++ "tailcall") [JSRaw fun, JSArray args]
171169
172170jsCall :: String -> [JS] -> JS
173171jsCall fun = JSApp (JSRaw fun)
@@ -212,6 +210,43 @@ jsLet name value body =
212210 )
213211 ) [value]
214212
213+jsSubst :: String -> [JS] -> JS -> [JS]
214+jsSubst _ [] _ = []
215+jsSubst var (x@(JSVar old) : xs) new
216+ | var == translateVariableName old = new : xs
217+ | otherwise = x : jsSubst var xs new
218+jsSubst _ xs _ = xs
219+
220+optimizeJS :: JS -> JS
221+optimizeJS (JSApp
222+ (JSFunction [arg] (JSReturn ret))
223+ [val]
224+ )
225+ | JSNew con [tag, JSArray vals] <- ret =
226+ JSNew con [tag, JSArray $ jsSubst arg vals (optimizeJS val)]
227+ | JSApp (JSRaw tc@"__IDRRT__tailcall") [fun, JSArray args] <- ret =
228+ JSApp (JSRaw tc) [fun, JSArray $ jsSubst arg args (optimizeJS val)]
229+
230+optimizeJS (JSSeq seq) =
231+ JSSeq (map optimizeJS seq)
232+
233+optimizeJS (JSFunction args body) =
234+ JSFunction args (optimizeJS body)
235+
236+optimizeJS (JSApp fun args) =
237+ JSApp (optimizeJS fun) (map optimizeJS args)
238+
239+optimizeJS (JSReturn js) =
240+ JSReturn $ optimizeJS js
241+
242+optimizeJS (JSAlloc name (Just js)) =
243+ JSAlloc name (Just $ optimizeJS js)
244+
245+optimizeJS js = js
246+
247+optJS :: Int -> JS -> JS
248+optJS c = foldr (.) id $ take c $ repeat optimizeJS
249+
215250codegenJavaScript
216251 :: JSTarget
217252 -> [(Name, SDecl)]
@@ -241,12 +276,12 @@ codegenJavaScript target definitions filename outputType = do
241276 def = map (first translateNamespace) definitions
242277
243278 functions :: [String]
244− functions = map (compileJS . translateDeclaration) def
279+ functions = map (compileJS . optJS 1 . translateDeclaration) def
245280
246281 mainLoop :: String
247282 mainLoop = compileJS $
248283 JSSeq [ JSAlloc "main" $ Just $ JSFunction [] (
249− jsTailcall $ jsCall mainFun []
284+ jsTailcall mainFun []
250285 )
251286 , jsCall "main" []
252287 ]
@@ -468,14 +503,15 @@ translateExpression (SV var) =
468503
469504translateExpression (SApp tc name vars)
470505 | False <- tc =
471− jsTailcall $ translateFunctionCall name vars
506+ jsTailcall (translateFunctionCall name) (map JSVar vars)
472507 | True <- tc =
473− JSNew (idrRTNamespace ++ "Tailcall") [JSFunction [] (
474− JSReturn $ translateFunctionCall name vars
475− )]
508+ JSNew (idrRTNamespace ++ "Tailcall")
509+ [ JSRaw $ translateFunctionCall name
510+ , JSArray $ map JSVar vars
511+ ]
476512 where
477− translateFunctionCall name vars =
478− jsCall (translateNamespace name ++ translateName name) (map JSVar vars)
513+ translateFunctionCall name =
514+ translateNamespace name ++ translateName name
479515
480516translateExpression (SOp op vars)
481517 | LNoOp <- op = JSVar (last vars)