@@ -17,9 +17,11 @@ import Control.Monad.Supply.Class (MonadSupply, freshName)
1717
1818import Data.Maybe (fromMaybe)
1919import Data.Monoid ((<>))
20+import Data.String (IsString, fromString)
2021import Data.Text (Text)
2122import qualified Data.Text as T
2223
24+import Language.PureScript.PSString (PSString)
2325import Language.PureScript.CodeGen.JS.AST
2426import Language.PureScript.CodeGen.JS.Optimizer.Common
2527import qualified Language.PureScript.Constants as C
@@ -33,7 +35,6 @@ shouldInline (JSVar _ _) = True
3335shouldInline (JSNumericLiteral _ _) = True
3436shouldInline (JSStringLiteral _ _) = True
3537shouldInline (JSBooleanLiteral _ _) = True
36−shouldInline (JSAccessor _ _ val) = shouldInline val
3738shouldInline (JSIndexer _ index val) = shouldInline index && shouldInline val
3839shouldInline _ = False
3940
@@ -82,17 +83,17 @@ inlineCommonValues = everywhereOnJS convert
8283 where
8384 convert :: JS -> JS
8485 convert (JSApp ss fn [dict])
85− | isDict' [semiringNumber, semiringInt] dict && isFn fnZero fn = JSNumericLiteral ss (Left 0)
86− | isDict' [semiringNumber, semiringInt] dict && isFn fnOne fn = JSNumericLiteral ss (Left 1)
87− | isDict boundedBoolean dict && isFn fnBottom fn = JSBooleanLiteral ss False
88− | isDict boundedBoolean dict && isFn fnTop fn = JSBooleanLiteral ss True
86+ | isDict' [semiringNumber, semiringInt] dict && isDict fnZero fn = JSNumericLiteral ss (Left 0)
87+ | isDict' [semiringNumber, semiringInt] dict && isDict fnOne fn = JSNumericLiteral ss (Left 1)
88+ | isDict boundedBoolean dict && isDict fnBottom fn = JSBooleanLiteral ss False
89+ | isDict boundedBoolean dict && isDict fnTop fn = JSBooleanLiteral ss True
8990 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))
9192 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 && isFn fnMultiply fn = intOp ss Multiply x y
94− | isDict euclideanRingInt dict && isFn fnDivide fn = intOp ss Divide x y
95− | isDict ringInt dict && isFn fnSubtract fn = intOp ss Subtract x y
93+ | isDict semiringInt dict && isDict fnAdd fn = intOp ss Add x y
94+ | isDict semiringInt dict && isDict fnMultiply fn = intOp ss Multiply x y
95+ | isDict euclideanRingInt dict && isDict fnDivide fn = intOp ss Divide x y
96+ | isDict ringInt dict && isDict fnSubtract fn = intOp ss Subtract x y
9697 convert other = other
9798 fnZero = (C.dataSemiring, C.zero)
9899 fnOne = (C.dataSemiring, C.one)
@@ -168,29 +169,29 @@ inlineCommonOperators = applyAll $
168169 ] ++
169170 [ fn | i <- [0..10], fn <- [ mkFn i, runFn i ] ]
170171 where
171− binary :: (Text, Text) -> (Text, Text) -> BinaryOperator -> JS -> JS
172+ binary :: (Text, PSString) -> (Text, PSString) -> BinaryOperator -> JS -> JS
172173 binary dict fns op = everywhereOnJS convert
173174 where
174175 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
176177 convert other = other
177− binary' :: Text -> Text -> BinaryOperator -> JS -> JS
178+ binary' :: Text -> PSString -> BinaryOperator -> JS -> JS
178179 binary' moduleName opString op = everywhereOnJS convert
179180 where
180181 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
182183 convert other = other
183− unary :: (Text, Text) -> (Text, Text) -> UnaryOperator -> JS -> JS
184+ unary :: (Text, PSString) -> (Text, PSString) -> UnaryOperator -> JS -> JS
184185 unary dicts fns op = everywhereOnJS convert
185186 where
186187 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
188189 convert other = other
189− unary' :: Text -> Text -> UnaryOperator -> JS -> JS
190+ unary' :: Text -> PSString -> UnaryOperator -> JS -> JS
190191 unary' moduleName fnName op = everywhereOnJS convert
191192 where
192193 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
194195 convert other = other
195196 mkFn :: Int -> JS -> JS
196197 mkFn 0 = everywhereOnJS convert
@@ -214,7 +215,8 @@ inlineCommonOperators = applyAll $
214215
215216 isNFn :: Text -> Int -> JS -> Bool
216217 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)
218220 isNFn _ _ _ = False
219221
220222 runFn :: Int -> JS -> JS
@@ -235,12 +237,14 @@ inlineCommonOperators = applyAll $
235237 convert (JSApp _ (JSApp _ op' [x]) [y]) | p op' = f x y
236238 convert other = other
237239
238− isModFn :: (Text, Text) -> JS -> Bool
239− isModFn (m, op) (JSAccessor _ op' (JSVar _ m')) = m == m' && op == op'
240+ isModFn :: (Text, PSString) -> JS -> Bool
241+ isModFn (m, op) (JSIndexer _ (JSStringLiteral _ op') (JSVar _ m')) =
242+ m == m' && op == op'
240243 isModFn _ _ = False
241244
242− isModFnWithDict :: (Text, Text) -> JS -> Bool
243− isModFnWithDict (m, op) (JSApp _ (JSAccessor _ op' (JSVar _ m')) [JSVar _ _]) = m == m' && op == op'
245+ isModFnWithDict :: (Text, PSString) -> JS -> Bool
246+ isModFnWithDict (m, op) (JSApp _ (JSIndexer _ (JSStringLiteral _ op') (JSVar _ m')) [JSVar _ _]) =
247+ m == m' && op == op'
244248 isModFnWithDict _ _ = False
245249
246250-- (f <<< g $ x) = f (g x)
@@ -261,118 +265,118 @@ inlineFnComposition = everywhereOnJSTopDownM convert
261265 return $ JSFunction ss Nothing [arg] (JSBlock ss [JSReturn Nothing $ JSApp Nothing y [JSApp Nothing x [JSVar Nothing arg]]])
262266 convert other = return other
263267 isFnCompose :: JS -> JS -> Bool
264− isFnCompose dict' fn = isDict semigroupoidFn dict' && isFn fnCompose fn
268+ isFnCompose dict' fn = isDict semigroupoidFn dict' && isDict fnCompose fn
265269 isFnComposeFlipped :: JS -> JS -> Bool
266− isFnComposeFlipped dict' fn = isDict semigroupoidFn dict' && isFn fnComposeFlipped fn
267− fnCompose :: (Text, Text)
270+ isFnComposeFlipped dict' fn = isDict semigroupoidFn dict' && isDict fnComposeFlipped fn
271+ fnCompose :: forall a b. (IsString a, IsString b) => (a, b)
268272 fnCompose = (C.controlSemigroupoid, C.compose)
269− fnComposeFlipped :: (Text, Text)
273+ fnComposeFlipped :: forall a b. (IsString a, IsString b) => (a, b)
270274 fnComposeFlipped = (C.controlSemigroupoid, C.composeFlipped)
271275
272−semiringNumber :: (Text, Text)
276+semiringNumber :: forall a b. (IsString a, IsString b) => (a, b)
273277semiringNumber = (C.dataSemiring, C.semiringNumber)
274278
275−semiringInt :: (Text, Text)
279+semiringInt :: forall a b. (IsString a, IsString b) => (a, b)
276280semiringInt = (C.dataSemiring, C.semiringInt)
277281
278−ringNumber :: (Text, Text)
282+ringNumber :: forall a b. (IsString a, IsString b) => (a, b)
279283ringNumber = (C.dataRing, C.ringNumber)
280284
281−ringInt :: (Text, Text)
285+ringInt :: forall a b. (IsString a, IsString b) => (a, b)
282286ringInt = (C.dataRing, C.ringInt)
283287
284−euclideanRingNumber :: (Text, Text)
288+euclideanRingNumber :: forall a b. (IsString a, IsString b) => (a, b)
285289euclideanRingNumber = (C.dataEuclideanRing, C.euclideanRingNumber)
286290
287−euclideanRingInt :: (Text, Text)
291+euclideanRingInt :: forall a b. (IsString a, IsString b) => (a, b)
288292euclideanRingInt = (C.dataEuclideanRing, C.euclideanRingInt)
289293
290−eqNumber :: (Text, Text)
294+eqNumber :: forall a b. (IsString a, IsString b) => (a, b)
291295eqNumber = (C.dataEq, C.eqNumber)
292296
293−eqInt :: (Text, Text)
297+eqInt :: forall a b. (IsString a, IsString b) => (a, b)
294298eqInt = (C.dataEq, C.eqInt)
295299
296−eqString :: (Text, Text)
300+eqString :: forall a b. (IsString a, IsString b) => (a, b)
297301eqString = (C.dataEq, C.eqString)
298302
299−eqChar :: (Text, Text)
303+eqChar :: forall a b. (IsString a, IsString b) => (a, b)
300304eqChar = (C.dataEq, C.eqChar)
301305
302−eqBoolean :: (Text, Text)
306+eqBoolean :: forall a b. (IsString a, IsString b) => (a, b)
303307eqBoolean = (C.dataEq, C.eqBoolean)
304308
305−ordBoolean :: (Text, Text)
309+ordBoolean :: forall a b. (IsString a, IsString b) => (a, b)
306310ordBoolean = (C.dataOrd, C.ordBoolean)
307311
308−ordNumber :: (Text, Text)
312+ordNumber :: forall a b. (IsString a, IsString b) => (a, b)
309313ordNumber = (C.dataOrd, C.ordNumber)
310314
311−ordInt :: (Text, Text)
315+ordInt :: forall a b. (IsString a, IsString b) => (a, b)
312316ordInt = (C.dataOrd, C.ordInt)
313317
314−ordString :: (Text, Text)
318+ordString :: forall a b. (IsString a, IsString b) => (a, b)
315319ordString = (C.dataOrd, C.ordString)
316320
317−ordChar :: (Text, Text)
321+ordChar :: forall a b. (IsString a, IsString b) => (a, b)
318322ordChar = (C.dataOrd, C.ordChar)
319323
320−semigroupString :: (Text, Text)
324+semigroupString :: forall a b. (IsString a, IsString b) => (a, b)
321325semigroupString = (C.dataSemigroup, C.semigroupString)
322326
323−boundedBoolean :: (Text, Text)
327+boundedBoolean :: forall a b. (IsString a, IsString b) => (a, b)
324328boundedBoolean = (C.dataBounded, C.boundedBoolean)
325329
326−heytingAlgebraBoolean :: (Text, Text)
330+heytingAlgebraBoolean :: forall a b. (IsString a, IsString b) => (a, b)
327331heytingAlgebraBoolean = (C.dataHeytingAlgebra, C.heytingAlgebraBoolean)
328332
329−semigroupoidFn :: (Text, Text)
333+semigroupoidFn :: forall a b. (IsString a, IsString b) => (a, b)
330334semigroupoidFn = (C.controlSemigroupoid, C.semigroupoidFn)
331335
332−opAdd :: (Text, Text)
336+opAdd :: forall a b. (IsString a, IsString b) => (a, b)
333337opAdd = (C.dataSemiring, C.add)
334338
335−opMul :: (Text, Text)
339+opMul :: forall a b. (IsString a, IsString b) => (a, b)
336340opMul = (C.dataSemiring, C.mul)
337341
338−opEq :: (Text, Text)
342+opEq :: forall a b. (IsString a, IsString b) => (a, b)
339343opEq = (C.dataEq, C.eq)
340344
341−opNotEq :: (Text, Text)
345+opNotEq :: forall a b. (IsString a, IsString b) => (a, b)
342346opNotEq = (C.dataEq, C.notEq)
343347
344−opLessThan :: (Text, Text)
348+opLessThan :: forall a b. (IsString a, IsString b) => (a, b)
345349opLessThan = (C.dataOrd, C.lessThan)
346350
347−opLessThanOrEq :: (Text, Text)
351+opLessThanOrEq :: forall a b. (IsString a, IsString b) => (a, b)
348352opLessThanOrEq = (C.dataOrd, C.lessThanOrEq)
349353
350−opGreaterThan :: (Text, Text)
354+opGreaterThan :: forall a b. (IsString a, IsString b) => (a, b)
351355opGreaterThan = (C.dataOrd, C.greaterThan)
352356
353−opGreaterThanOrEq :: (Text, Text)
357+opGreaterThanOrEq :: forall a b. (IsString a, IsString b) => (a, b)
354358opGreaterThanOrEq = (C.dataOrd, C.greaterThanOrEq)
355359
356−opAppend :: (Text, Text)
360+opAppend :: forall a b. (IsString a, IsString b) => (a, b)
357361opAppend = (C.dataSemigroup, C.append)
358362
359−opSub :: (Text, Text)
363+opSub :: forall a b. (IsString a, IsString b) => (a, b)
360364opSub = (C.dataRing, C.sub)
361365
362−opNegate :: (Text, Text)
366+opNegate :: forall a b. (IsString a, IsString b) => (a, b)
363367opNegate = (C.dataRing, C.negate)
364368
365−opDiv :: (Text, Text)
369+opDiv :: forall a b. (IsString a, IsString b) => (a, b)
366370opDiv = (C.dataEuclideanRing, C.div)
367371
368−opMod :: (Text, Text)
372+opMod :: forall a b. (IsString a, IsString b) => (a, b)
369373opMod = (C.dataEuclideanRing, C.mod)
370374
371−opConj :: (Text, Text)
375+opConj :: forall a b. (IsString a, IsString b) => (a, b)
372376opConj = (C.dataHeytingAlgebra, C.conj)
373377
374−opDisj :: (Text, Text)
378+opDisj :: forall a b. (IsString a, IsString b) => (a, b)
375379opDisj = (C.dataHeytingAlgebra, C.disj)
376380
377−opNot :: (Text, Text)
381+opNot :: forall a b. (IsString a, IsString b) => (a, b)
378382opNot = (C.dataHeytingAlgebra, C.not)