@@ -22,6 +22,8 @@ module Language.PureScript.Optimizer.Inliner (
22 evaluateIifes
22 evaluateIifes
25+import Data.Maybe (fromMaybe)
25import Language.PureScript.CodeGen.JS.AST
27import Language.PureScript.CodeGen.JS.AST
26import Language.PureScript.CodeGen.Common (identToJs)
28import Language.PureScript.CodeGen.Common (identToJs)
27import Language.PureScript.Optimizer.Common
29import Language.PureScript.Optimizer.Common
@@ -88,7 +90,7 @@ inlineOperator (m, op) f = everywhereOnJS convert
88 isOp _ = False
90 isOp _ = False
90inlineCommonOperators :: JS -> JS
92inlineCommonOperators :: JS -> JS
91−inlineCommonOperators = applyAll
93+inlineCommonOperators = applyAll $
92 [ binary C.numNumber (C.+) Add
94 [ binary C.numNumber (C.+) Add
93 , binary C.numNumber (C.-) Subtract
95 , binary C.numNumber (C.-) Subtract
94 , binary C.numNumber (C.*) Multiply
96 , binary C.numNumber (C.*) Multiply
@@ -121,7 +123,8 @@ inlineCommonOperators = applyAll
121 , binary C.boolLikeBoolean (C.&&) And
123 , binary C.boolLikeBoolean (C.&&) And
122 , binary C.boolLikeBoolean (C.||) Or
124 , binary C.boolLikeBoolean (C.||) Or
123 , unary C.boolLikeBoolean C.not Not
125 , unary C.boolLikeBoolean C.not Not
127+ [ fn | i <- [0..5], fn <- [ mkFn i, runFn i ] ]
126 binary :: String -> String -> BinaryOperator -> JS -> JS
129 binary :: String -> String -> BinaryOperator -> JS -> JS
127 binary dictName opString op = everywhereOnJS convert
130 binary dictName opString op = everywhereOnJS convert
@@ -150,3 +153,39 @@ inlineCommonOperators = applyAll
150 isOp _ = False
153 isOp _ = False
151 isOpDict dictName (JSApp (JSAccessor prop (JSVar prelude)) [JSObjectLiteral []]) = prelude == C.prelude && prop == dictName
154 isOpDict dictName (JSApp (JSAccessor prop (JSVar prelude)) [JSObjectLiteral []]) = prelude == C.prelude && prop == dictName
152 isOpDict _ _ = False
155 isOpDict _ _ = False
157+ mkFn :: Int -> JS -> JS
158+ mkFn 0 = everywhereOnJS convert
161+ convert (JSApp mkFnN [JSFunction Nothing [_] (JSBlock [JSReturn ret])]) | isNFn C.mkFn 0 mkFnN =
162+ JSFunction Nothing [] (JSBlock [JSReturn ret])
163+ convert other = other
164+ mkFn n = everywhereOnJS convert
167+ convert orig@(JSApp mkFnN [fn]) | isNFn C.mkFn n mkFnN =
168+ case collectArgs n [] fn of
169+ Just (args, ret) -> JSFunction Nothing args (JSBlock [JSReturn ret])
171+ convert other = other
172+ collectArgs :: Int -> [String] -> JS -> Maybe ([String], JS)
173+ collectArgs 0 acc ret | length acc == n = Just (reverse acc, ret)
174+ collectArgs m acc (JSFunction Nothing [oneArg] (JSBlock [JSReturn ret])) = collectArgs (m - 1) (oneArg : acc) ret
175+ collectArgs _ _ _ = Nothing
177+ isNFn :: String -> Int -> JS -> Bool
178+ isNFn prefix n (JSVar name) = name == (prefix ++ show n)
179+ isNFn prefix n (JSAccessor name (JSVar dataFunction)) | dataFunction == C.dataFunction = name == (prefix ++ show n)
182+ runFn :: Int -> JS -> JS
183+ runFn n = everywhereOnJS convert
186+ convert js = fromMaybe js $ go n [] js
188+ go :: Int -> [JS] -> JS -> Maybe JS
189+ go 0 acc (JSApp runFnN [fn]) | isNFn C.runFn n runFnN && length acc == n = Just (JSApp fn acc)
190+ go m acc (JSApp lhs [arg]) = go (m - 1) (arg : acc) lhs