@@ -15,6 +15,7 @@
1515
1616module Language.PureScript.CodeGen.JS.Optimizer.Inliner (
1717 inlineVariables,
18+ inlineValues,
1819 inlineOperator,
1920 inlineCommonOperators,
2021 etaConvert,
@@ -79,6 +80,15 @@ inlineVariables = everywhereOnJS $ removeFromBlock go
7980 go (map (replaceIdent var js) sts)
8081 go (s:sts) = s : go sts
8182
83+inlineValues :: JS -> JS
84+inlineValues = everywhereOnJS convert
85+ where
86+ convert :: JS -> JS
87+ convert (JSApp fn [dict]) | isPreludeDict C.semiringNumber dict && isPreludeFn C.zero fn = JSNumericLiteral (Left 0)
88+ convert (JSApp fn [dict]) | isPreludeDict C.semiringNumber dict && isPreludeFn C.one fn = JSNumericLiteral (Left 1)
89+ convert (JSApp (JSApp fn [x]) [y]) | isPreludeFn (C.%) fn = JSBinary Modulus x y
90+ convert other = other
91+
8292inlineOperator :: (String, String) -> (JS -> JS -> JS) -> JS -> JS
8393inlineOperator (m, op) f = everywhereOnJS convert
8494 where
@@ -91,12 +101,11 @@ inlineOperator (m, op) f = everywhereOnJS convert
91101
92102inlineCommonOperators :: JS -> JS
93103inlineCommonOperators = applyAll $
94− [ binary C.numNumber (C.+) Add
95− , binary C.numNumber (C.-) Subtract
96− , binary C.numNumber (C.*) Multiply
97− , binary C.numNumber (C./) Divide
98− , binary C.numNumber (C.%) Modulus
99− , unary C.numNumber C.negate Negate
104+ [ binary C.semiringNumber (C.+) Add
105+ , binary C.semiringNumber (C.*) Multiply
106+ , binary C.ringNumber (C.-) Subtract
107+ , unary C.ringNumber C.negate Negate
108+ , binary C.moduloRingNumber (C./) Divide
100109
101110 , binary C.ordNumber (C.<) LessThan
102111 , binary C.ordNumber (C.>) GreaterThan
@@ -131,29 +140,20 @@ inlineCommonOperators = applyAll $
131140 binary dictName opString op = everywhereOnJS convert
132141 where
133142 convert :: JS -> JS
134− convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isOp fn && isOpDict dictName dict = JSBinary op x y
143+ convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isPreludeDict dictName dict && isPreludeFn opString fn = JSBinary op x y
135144 convert other = other
136− isOp (JSAccessor longForm (JSAccessor prelude (JSVar _))) = prelude == C.prelude && longForm == identToJs (Op opString)
137− isOp (JSIndexer (JSStringLiteral op') (JSVar prelude)) = prelude == C.prelude && opString == op'
138− isOp _ = False
139145 binaryFunction :: String -> String -> BinaryOperator -> JS -> JS
140146 binaryFunction dictName fnName op = everywhereOnJS convert
141147 where
142148 convert :: JS -> JS
143− convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isOp fn && isOpDict dictName dict = JSBinary op x y
149+ convert (JSApp (JSApp (JSApp fn [dict]) [x]) [y]) | isPreludeFn fnName fn && isPreludeDict dictName dict = JSBinary op x y
144150 convert other = other
145− isOp (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName == fnName'
146− isOp _ = False
147151 unary :: String -> String -> UnaryOperator -> JS -> JS
148152 unary dictName fnName op = everywhereOnJS convert
149153 where
150154 convert :: JS -> JS
151− convert (JSApp (JSApp fn [dict]) [x]) | isOp fn && isOpDict dictName dict = JSUnary op x
155+ convert (JSApp (JSApp fn [dict]) [x]) | isPreludeFn fnName fn && isPreludeDict dictName dict = JSUnary op x
152156 convert other = other
153− isOp (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
154− isOp _ = False
155− isOpDict dictName (JSAccessor prop (JSVar prelude)) = prelude == C.prelude && prop == dictName
156− isOpDict _ _ = False
157157 mkFn :: Int -> JS -> JS
158158 mkFn 0 = everywhereOnJS convert
159159 where
@@ -189,3 +189,13 @@ inlineCommonOperators = applyAll $
189189 go 0 acc (JSApp runFnN [fn]) | isNFn C.runFn n runFnN && length acc == n = Just (JSApp fn acc)
190190 go m acc (JSApp lhs [arg]) = go (m - 1) (arg : acc) lhs
191191 go _ _ _ = Nothing
192+
193+isPreludeDict :: String -> JS -> Bool
194+isPreludeDict dictName (JSAccessor prop (JSVar prelude)) = prelude == C.prelude && prop == dictName
195+isPreludeDict _ _ = False
196+
197+isPreludeFn :: String -> JS -> Bool
198+isPreludeFn fnName (JSAccessor fnName' (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
199+isPreludeFn fnName (JSIndexer (JSStringLiteral fnName') (JSVar prelude)) = prelude == C.prelude && fnName' == fnName
200+isPreludeFn fnName (JSAccessor longForm (JSAccessor prelude (JSVar _))) = prelude == C.prelude && longForm == identToJs (Op fnName)
201+isPreludeFn _ _ = False