@@ -163,11 +163,9 @@ compileJS (JSTernary cond true false) =
163 f = compileJS false in
163 f = compileJS false in
164 "(" ++ c ++ ")?(" ++ t ++ "):(" ++ f ++ ")"
164 "(" ++ c ++ ")?(" ++ t ++ "):(" ++ f ++ ")"
166−jsTailcall :: JS -> JS
166+jsTailcall :: String -> [JS] -> JS
167−jsTailcall call =
167+jsTailcall fun args =
168− jsCall (idrRTNamespace ++ "tailcall") [
168+ jsCall (idrRTNamespace ++ "tailcall") [JSRaw fun, JSArray args]
169− JSFunction [] (JSReturn call)
172jsCall :: String -> [JS] -> JS
170jsCall :: String -> [JS] -> JS
173jsCall fun = JSApp (JSRaw fun)
171jsCall fun = JSApp (JSRaw fun)
@@ -212,6 +210,43 @@ jsLet name value body =
213 ) [value]
211 ) [value]
213+jsSubst :: String -> [JS] -> JS -> [JS]
215+jsSubst var (x@(JSVar old) : xs) new
216+ | var == translateVariableName old = new : xs
217+ | otherwise = x : jsSubst var xs new
220+optimizeJS :: JS -> JS
222+ (JSFunction [arg] (JSReturn ret))
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)]
230+optimizeJS (JSSeq seq) =
231+ JSSeq (map optimizeJS seq)
233+optimizeJS (JSFunction args body) =
234+ JSFunction args (optimizeJS body)
236+optimizeJS (JSApp fun args) =
237+ JSApp (optimizeJS fun) (map optimizeJS args)
239+optimizeJS (JSReturn js) =
240+ JSReturn $ optimizeJS js
242+optimizeJS (JSAlloc name (Just js)) =
243+ JSAlloc name (Just $ optimizeJS js)
247+optJS :: Int -> JS -> JS
248+optJS c = foldr (.) id $ take c $ repeat optimizeJS
215codegenJavaScript
250codegenJavaScript
216 :: JSTarget
251 :: JSTarget
217 -> [(Name, SDecl)]
252 -> [(Name, SDecl)]
@@ -241,12 +276,12 @@ codegenJavaScript target definitions filename outputType = do
241 def = map (first translateNamespace) definitions
276 def = map (first translateNamespace) definitions
243 functions :: [String]
278 functions :: [String]
244− functions = map (compileJS . translateDeclaration) def
279+ functions = map (compileJS . optJS 1 . translateDeclaration) def
246 mainLoop :: String
281 mainLoop :: String
247 mainLoop = compileJS $
282 mainLoop = compileJS $
248 JSSeq [ JSAlloc "main" $ Just $ JSFunction [] (
283 JSSeq [ JSAlloc "main" $ Just $ JSFunction [] (
249− jsTailcall $ jsCall mainFun []
284+ jsTailcall mainFun []
251 , jsCall "main" []
286 , jsCall "main" []
@@ -468,14 +503,15 @@ translateExpression (SV var) =
469translateExpression (SApp tc name vars)
504translateExpression (SApp tc name vars)
470 | False <- tc =
505 | False <- tc =
471− jsTailcall $ translateFunctionCall name vars
506+ jsTailcall (translateFunctionCall name) (map JSVar vars)
472 | True <- tc =
507 | True <- tc =
473− JSNew (idrRTNamespace ++ "Tailcall") [JSFunction [] (
508+ JSNew (idrRTNamespace ++ "Tailcall")
474− JSReturn $ translateFunctionCall name vars
509+ [ JSRaw $ translateFunctionCall name
510+ , JSArray $ map JSVar vars
477− translateFunctionCall name vars =
513+ translateFunctionCall name =
478− jsCall (translateNamespace name ++ translateName name) (map JSVar vars)
514+ translateNamespace name ++ translateName name
480translateExpression (SOp op vars)
516translateExpression (SOp op vars)
481 | LNoOp <- op = JSVar (last vars)
517 | LNoOp <- op = JSVar (last vars)