@@ -17,9 +17,11 @@ import Control.Monad.Supply.Class (MonadSupply, freshName)
18import Data.Maybe (fromMaybe)
18import Data.Maybe (fromMaybe)
19import Data.Monoid ((<>))
19import Data.Monoid ((<>))
20+import Data.String (IsString, fromString)
20import Data.Text (Text)
21import Data.Text (Text)
21import qualified Data.Text as T
22import qualified Data.Text as T
24+import Language.PureScript.PSString (PSString)
23import Language.PureScript.CodeGen.JS.AST
25import Language.PureScript.CodeGen.JS.AST
24import Language.PureScript.CodeGen.JS.Optimizer.Common
26import Language.PureScript.CodeGen.JS.Optimizer.Common
25import qualified Language.PureScript.Constants as C
27import qualified Language.PureScript.Constants as C
@@ -33,7 +35,6 @@ shouldInline (JSVar _ _) = True
33shouldInline (JSNumericLiteral _ _) = True
35shouldInline (JSNumericLiteral _ _) = True
34shouldInline (JSStringLiteral _ _) = True
36shouldInline (JSStringLiteral _ _) = True
35shouldInline (JSBooleanLiteral _ _) = True
37shouldInline (JSBooleanLiteral _ _) = True
36−shouldInline (JSAccessor _ _ val) = shouldInline val
37shouldInline (JSIndexer _ index val) = shouldInline index && shouldInline val
38shouldInline (JSIndexer _ index val) = shouldInline index && shouldInline val
38shouldInline _ = False
39shouldInline _ = False
@@ -82,17 +83,17 @@ inlineCommonValues = everywhereOnJS convert
83 convert :: JS -> JS
84 convert :: JS -> JS
84 convert (JSApp ss fn [dict])
85 convert (JSApp ss fn [dict])
85− | isDict' [semiringNumber, semiringInt] dict && isFn fnZero fn = JSNumericLiteral ss (Left 0)
86+ | isDict' [semiringNumber, semiringInt] dict && isDict fnZero fn = JSNumericLiteral ss (Left 0)
86− | isDict' [semiringNumber, semiringInt] dict && isFn fnOne fn = JSNumericLiteral ss (Left 1)
87+ | isDict' [semiringNumber, semiringInt] dict && isDict fnOne fn = JSNumericLiteral ss (Left 1)
87− | isDict boundedBoolean dict && isFn fnBottom fn = JSBooleanLiteral ss False
88+ | isDict boundedBoolean dict && isDict fnBottom fn = JSBooleanLiteral ss False
88− | isDict boundedBoolean dict && isFn fnTop fn = JSBooleanLiteral ss True
89+ | isDict boundedBoolean dict && isDict fnTop fn = JSBooleanLiteral ss True
89 convert (JSApp ss (JSApp _ fn [dict]) [x])
90 convert (JSApp ss (JSApp _ fn [dict]) [x])
90− | isDict ringInt dict && isFn fnNegate fn = JSBinary ss BitwiseOr (JSUnary ss Negate x) (JSNumericLiteral ss (Left 0))
91+ | isDict ringInt dict && isDict fnNegate fn = JSBinary ss BitwiseOr (JSUnary ss Negate x) (JSNumericLiteral ss (Left 0))
91 convert (JSApp ss (JSApp _ (JSApp _ fn [dict]) [x]) [y])
92 convert (JSApp ss (JSApp _ (JSApp _ fn [dict]) [x]) [y])
92− | isDict semiringInt dict && isFn fnAdd fn = intOp ss Add x y
93+ | isDict semiringInt dict && isDict fnAdd fn = intOp ss Add x y
93− | isDict semiringInt dict && isFn fnMultiply fn = intOp ss Multiply x y
94+ | isDict semiringInt dict && isDict fnMultiply fn = intOp ss Multiply x y
94− | isDict euclideanRingInt dict && isFn fnDivide fn = intOp ss Divide x y
95+ | isDict euclideanRingInt dict && isDict fnDivide fn = intOp ss Divide x y
95− | isDict ringInt dict && isFn fnSubtract fn = intOp ss Subtract x y
96+ | isDict ringInt dict && isDict fnSubtract fn = intOp ss Subtract x y
96 convert other = other
97 convert other = other
97 fnZero = (C.dataSemiring, C.zero)
98 fnZero = (C.dataSemiring, C.zero)
98 fnOne = (C.dataSemiring, C.one)
99 fnOne = (C.dataSemiring, C.one)
@@ -168,29 +169,29 @@ inlineCommonOperators = applyAll $
169 [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
170 [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
171− binary :: (Text, Text) -> (Text, Text) -> BinaryOperator -> JS -> JS
172+ binary :: (Text, PSString) -> (Text, PSString) -> BinaryOperator -> JS -> JS
172 binary dict fns op = everywhereOnJS convert
173 binary dict fns op = everywhereOnJS convert
174 convert :: JS -> JS
175 convert :: JS -> JS
175− convert (JSApp ss (JSApp _ (JSApp _ fn [dict']) [x]) [y]) | isDict dict dict' && isFn fns fn = JSBinary ss op x y
176+ convert (JSApp ss (JSApp _ (JSApp _ fn [dict']) [x]) [y]) | isDict dict dict' && isDict fns fn = JSBinary ss op x y
176 convert other = other
177 convert other = other
177− binary' :: Text -> Text -> BinaryOperator -> JS -> JS
178+ binary' :: Text -> PSString -> BinaryOperator -> JS -> JS
178 binary' moduleName opString op = everywhereOnJS convert
179 binary' moduleName opString op = everywhereOnJS convert
180 convert :: JS -> JS
181 convert :: JS -> JS
181− convert (JSApp ss (JSApp _ fn [x]) [y]) | isFn (moduleName, opString) fn = JSBinary ss op x y
182+ convert (JSApp ss (JSApp _ fn [x]) [y]) | isDict (moduleName, opString) fn = JSBinary ss op x y
182 convert other = other
183 convert other = other
183− unary :: (Text, Text) -> (Text, Text) -> UnaryOperator -> JS -> JS
184+ unary :: (Text, PSString) -> (Text, PSString) -> UnaryOperator -> JS -> JS
184 unary dicts fns op = everywhereOnJS convert
185 unary dicts fns op = everywhereOnJS convert
186 convert :: JS -> JS
187 convert :: JS -> JS
187− convert (JSApp ss (JSApp _ fn [dict']) [x]) | isDict dicts dict' && isFn fns fn = JSUnary ss op x
188+ convert (JSApp ss (JSApp _ fn [dict']) [x]) | isDict dicts dict' && isDict fns fn = JSUnary ss op x
188 convert other = other
189 convert other = other
189− unary' :: Text -> Text -> UnaryOperator -> JS -> JS
190+ unary' :: Text -> PSString -> UnaryOperator -> JS -> JS
190 unary' moduleName fnName op = everywhereOnJS convert
191 unary' moduleName fnName op = everywhereOnJS convert
192 convert :: JS -> JS
193 convert :: JS -> JS
193− convert (JSApp ss fn [x]) | isFn (moduleName, fnName) fn = JSUnary ss op x
194+ convert (JSApp ss fn [x]) | isDict (moduleName, fnName) fn = JSUnary ss op x
194 convert other = other
195 convert other = other
195 mkFn :: Int -> JS -> JS
196 mkFn :: Int -> JS -> JS
196 mkFn 0 = everywhereOnJS convert
197 mkFn 0 = everywhereOnJS convert
@@ -214,7 +215,8 @@ inlineCommonOperators = applyAll $
215 isNFn :: Text -> Int -> JS -> Bool
216 isNFn :: Text -> Int -> JS -> Bool
216 isNFn prefix n (JSVar _ name) = name == (prefix <> T.pack (show n))
217 isNFn prefix n (JSVar _ name) = name == (prefix <> T.pack (show n))
217− isNFn prefix n (JSAccessor _ name (JSVar _ dataFunctionUncurried)) | dataFunctionUncurried == C.dataFunctionUncurried = name == (prefix <> T.pack (show n))
218+ isNFn prefix n (JSIndexer _ (JSStringLiteral _ name) (JSVar _ dataFunctionUncurried)) | dataFunctionUncurried == C.dataFunctionUncurried =
219+ name == fromString (T.unpack prefix <> show n)
218 isNFn _ _ _ = False
220 isNFn _ _ _ = False
220 runFn :: Int -> JS -> JS
222 runFn :: Int -> JS -> JS
@@ -235,12 +237,14 @@ inlineCommonOperators = applyAll $
235 convert (JSApp _ (JSApp _ op' [x]) [y]) | p op' = f x y
237 convert (JSApp _ (JSApp _ op' [x]) [y]) | p op' = f x y
236 convert other = other
238 convert other = other
238− isModFn :: (Text, Text) -> JS -> Bool
240+ isModFn :: (Text, PSString) -> JS -> Bool
239− isModFn (m, op) (JSAccessor _ op' (JSVar _ m')) = m == m' && op == op'
241+ isModFn (m, op) (JSIndexer _ (JSStringLiteral _ op') (JSVar _ m')) =
242+ m == m' && op == op'
240 isModFn _ _ = False
243 isModFn _ _ = False
242− isModFnWithDict :: (Text, Text) -> JS -> Bool
245+ isModFnWithDict :: (Text, PSString) -> JS -> Bool
243− isModFnWithDict (m, op) (JSApp _ (JSAccessor _ op' (JSVar _ m')) [JSVar _ _]) = m == m' && op == op'
246+ isModFnWithDict (m, op) (JSApp _ (JSIndexer _ (JSStringLiteral _ op') (JSVar _ m')) [JSVar _ _]) =
247+ m == m' && op == op'
244 isModFnWithDict _ _ = False
248 isModFnWithDict _ _ = False
246-- (f <<< g $ x) = f (g x)
250-- (f <<< g $ x) = f (g x)
@@ -261,118 +265,118 @@ inlineFnComposition = everywhereOnJSTopDownM convert
261 return $ JSFunction ss Nothing [arg] (JSBlock ss [JSReturn Nothing $ JSApp Nothing y [JSApp Nothing x [JSVar Nothing arg]]])
265 return $ JSFunction ss Nothing [arg] (JSBlock ss [JSReturn Nothing $ JSApp Nothing y [JSApp Nothing x [JSVar Nothing arg]]])
262 convert other = return other
266 convert other = return other
263 isFnCompose :: JS -> JS -> Bool
267 isFnCompose :: JS -> JS -> Bool
264− isFnCompose dict' fn = isDict semigroupoidFn dict' && isFn fnCompose fn
268+ isFnCompose dict' fn = isDict semigroupoidFn dict' && isDict fnCompose fn
265 isFnComposeFlipped :: JS -> JS -> Bool
269 isFnComposeFlipped :: JS -> JS -> Bool
266− isFnComposeFlipped dict' fn = isDict semigroupoidFn dict' && isFn fnComposeFlipped fn
270+ isFnComposeFlipped dict' fn = isDict semigroupoidFn dict' && isDict fnComposeFlipped fn
267− fnCompose :: (Text, Text)
271+ fnCompose :: forall a b. (IsString a, IsString b) => (a, b)
268 fnCompose = (C.controlSemigroupoid, C.compose)
272 fnCompose = (C.controlSemigroupoid, C.compose)
269− fnComposeFlipped :: (Text, Text)
273+ fnComposeFlipped :: forall a b. (IsString a, IsString b) => (a, b)
270 fnComposeFlipped = (C.controlSemigroupoid, C.composeFlipped)
274 fnComposeFlipped = (C.controlSemigroupoid, C.composeFlipped)
272−semiringNumber :: (Text, Text)
276+semiringNumber :: forall a b. (IsString a, IsString b) => (a, b)
273semiringNumber = (C.dataSemiring, C.semiringNumber)
277semiringNumber = (C.dataSemiring, C.semiringNumber)
275−semiringInt :: (Text, Text)
279+semiringInt :: forall a b. (IsString a, IsString b) => (a, b)
276semiringInt = (C.dataSemiring, C.semiringInt)
280semiringInt = (C.dataSemiring, C.semiringInt)
278−ringNumber :: (Text, Text)
282+ringNumber :: forall a b. (IsString a, IsString b) => (a, b)
279ringNumber = (C.dataRing, C.ringNumber)
283ringNumber = (C.dataRing, C.ringNumber)
281−ringInt :: (Text, Text)
285+ringInt :: forall a b. (IsString a, IsString b) => (a, b)
282ringInt = (C.dataRing, C.ringInt)
286ringInt = (C.dataRing, C.ringInt)
284−euclideanRingNumber :: (Text, Text)
288+euclideanRingNumber :: forall a b. (IsString a, IsString b) => (a, b)
285euclideanRingNumber = (C.dataEuclideanRing, C.euclideanRingNumber)
289euclideanRingNumber = (C.dataEuclideanRing, C.euclideanRingNumber)
287−euclideanRingInt :: (Text, Text)
291+euclideanRingInt :: forall a b. (IsString a, IsString b) => (a, b)
288euclideanRingInt = (C.dataEuclideanRing, C.euclideanRingInt)
292euclideanRingInt = (C.dataEuclideanRing, C.euclideanRingInt)
290−eqNumber :: (Text, Text)
294+eqNumber :: forall a b. (IsString a, IsString b) => (a, b)
291eqNumber = (C.dataEq, C.eqNumber)
295eqNumber = (C.dataEq, C.eqNumber)
293−eqInt :: (Text, Text)
297+eqInt :: forall a b. (IsString a, IsString b) => (a, b)
294eqInt = (C.dataEq, C.eqInt)
298eqInt = (C.dataEq, C.eqInt)
296−eqString :: (Text, Text)
300+eqString :: forall a b. (IsString a, IsString b) => (a, b)
297eqString = (C.dataEq, C.eqString)
301eqString = (C.dataEq, C.eqString)
299−eqChar :: (Text, Text)
303+eqChar :: forall a b. (IsString a, IsString b) => (a, b)
300eqChar = (C.dataEq, C.eqChar)
304eqChar = (C.dataEq, C.eqChar)
302−eqBoolean :: (Text, Text)
306+eqBoolean :: forall a b. (IsString a, IsString b) => (a, b)
303eqBoolean = (C.dataEq, C.eqBoolean)
307eqBoolean = (C.dataEq, C.eqBoolean)
305−ordBoolean :: (Text, Text)
309+ordBoolean :: forall a b. (IsString a, IsString b) => (a, b)
306ordBoolean = (C.dataOrd, C.ordBoolean)
310ordBoolean = (C.dataOrd, C.ordBoolean)
308−ordNumber :: (Text, Text)
312+ordNumber :: forall a b. (IsString a, IsString b) => (a, b)
309ordNumber = (C.dataOrd, C.ordNumber)
313ordNumber = (C.dataOrd, C.ordNumber)
311−ordInt :: (Text, Text)
315+ordInt :: forall a b. (IsString a, IsString b) => (a, b)
312ordInt = (C.dataOrd, C.ordInt)
316ordInt = (C.dataOrd, C.ordInt)
314−ordString :: (Text, Text)
318+ordString :: forall a b. (IsString a, IsString b) => (a, b)
315ordString = (C.dataOrd, C.ordString)
319ordString = (C.dataOrd, C.ordString)
317−ordChar :: (Text, Text)
321+ordChar :: forall a b. (IsString a, IsString b) => (a, b)
318ordChar = (C.dataOrd, C.ordChar)
322ordChar = (C.dataOrd, C.ordChar)
320−semigroupString :: (Text, Text)
324+semigroupString :: forall a b. (IsString a, IsString b) => (a, b)
321semigroupString = (C.dataSemigroup, C.semigroupString)
325semigroupString = (C.dataSemigroup, C.semigroupString)
323−boundedBoolean :: (Text, Text)
327+boundedBoolean :: forall a b. (IsString a, IsString b) => (a, b)
324boundedBoolean = (C.dataBounded, C.boundedBoolean)
328boundedBoolean = (C.dataBounded, C.boundedBoolean)
326−heytingAlgebraBoolean :: (Text, Text)
330+heytingAlgebraBoolean :: forall a b. (IsString a, IsString b) => (a, b)
327heytingAlgebraBoolean = (C.dataHeytingAlgebra, C.heytingAlgebraBoolean)
331heytingAlgebraBoolean = (C.dataHeytingAlgebra, C.heytingAlgebraBoolean)
329−semigroupoidFn :: (Text, Text)
333+semigroupoidFn :: forall a b. (IsString a, IsString b) => (a, b)
330semigroupoidFn = (C.controlSemigroupoid, C.semigroupoidFn)
334semigroupoidFn = (C.controlSemigroupoid, C.semigroupoidFn)
332−opAdd :: (Text, Text)
336+opAdd :: forall a b. (IsString a, IsString b) => (a, b)
333opAdd = (C.dataSemiring, C.add)
337opAdd = (C.dataSemiring, C.add)
335−opMul :: (Text, Text)
339+opMul :: forall a b. (IsString a, IsString b) => (a, b)
336opMul = (C.dataSemiring, C.mul)
340opMul = (C.dataSemiring, C.mul)
338−opEq :: (Text, Text)
342+opEq :: forall a b. (IsString a, IsString b) => (a, b)
339opEq = (C.dataEq, C.eq)
343opEq = (C.dataEq, C.eq)
341−opNotEq :: (Text, Text)
345+opNotEq :: forall a b. (IsString a, IsString b) => (a, b)
342opNotEq = (C.dataEq, C.notEq)
346opNotEq = (C.dataEq, C.notEq)
344−opLessThan :: (Text, Text)
348+opLessThan :: forall a b. (IsString a, IsString b) => (a, b)
345opLessThan = (C.dataOrd, C.lessThan)
349opLessThan = (C.dataOrd, C.lessThan)
347−opLessThanOrEq :: (Text, Text)
351+opLessThanOrEq :: forall a b. (IsString a, IsString b) => (a, b)
348opLessThanOrEq = (C.dataOrd, C.lessThanOrEq)
352opLessThanOrEq = (C.dataOrd, C.lessThanOrEq)
350−opGreaterThan :: (Text, Text)
354+opGreaterThan :: forall a b. (IsString a, IsString b) => (a, b)
351opGreaterThan = (C.dataOrd, C.greaterThan)
355opGreaterThan = (C.dataOrd, C.greaterThan)
353−opGreaterThanOrEq :: (Text, Text)
357+opGreaterThanOrEq :: forall a b. (IsString a, IsString b) => (a, b)
354opGreaterThanOrEq = (C.dataOrd, C.greaterThanOrEq)
358opGreaterThanOrEq = (C.dataOrd, C.greaterThanOrEq)
356−opAppend :: (Text, Text)
360+opAppend :: forall a b. (IsString a, IsString b) => (a, b)
357opAppend = (C.dataSemigroup, C.append)
361opAppend = (C.dataSemigroup, C.append)
359−opSub :: (Text, Text)
363+opSub :: forall a b. (IsString a, IsString b) => (a, b)
360opSub = (C.dataRing, C.sub)
364opSub = (C.dataRing, C.sub)
362−opNegate :: (Text, Text)
366+opNegate :: forall a b. (IsString a, IsString b) => (a, b)
363opNegate = (C.dataRing, C.negate)
367opNegate = (C.dataRing, C.negate)
365−opDiv :: (Text, Text)
369+opDiv :: forall a b. (IsString a, IsString b) => (a, b)
366opDiv = (C.dataEuclideanRing, C.div)
370opDiv = (C.dataEuclideanRing, C.div)
368−opMod :: (Text, Text)
372+opMod :: forall a b. (IsString a, IsString b) => (a, b)
369opMod = (C.dataEuclideanRing, C.mod)
373opMod = (C.dataEuclideanRing, C.mod)
371−opConj :: (Text, Text)
375+opConj :: forall a b. (IsString a, IsString b) => (a, b)
372opConj = (C.dataHeytingAlgebra, C.conj)
376opConj = (C.dataHeytingAlgebra, C.conj)
374−opDisj :: (Text, Text)
378+opDisj :: forall a b. (IsString a, IsString b) => (a, b)
375opDisj = (C.dataHeytingAlgebra, C.disj)
379opDisj = (C.dataHeytingAlgebra, C.disj)
377−opNot :: (Text, Text)
381+opNot :: forall a b. (IsString a, IsString b) => (a, b)
378opNot = (C.dataHeytingAlgebra, C.not)
382opNot = (C.dataHeytingAlgebra, C.not)