1313--
1414-----------------------------------------------------------------------------
1515
16- {-# LANGUAGE GADTs, ViewPatterns, FlexibleContexts #-}
16+ {-# LANGUAGE GADTs #-}
17+ {-# LANGUAGE ViewPatterns #-}
18+ {-# LANGUAGE FlexibleContexts #-}
19+ {-# LANGUAGE ScopedTypeVariables #-}
1720
1821module Language.PureScript.CodeGen.JS (
1922 module AST ,
@@ -28,8 +31,7 @@ import qualified Data.Traversable as T (traverse)
2831import Control.Applicative
2932import Control.Arrow ((&&&) )
3033import Control.Monad (foldM , replicateM , forM )
31- import Control.Monad.Reader (MonadReader , asks , lift )
32- import Control.Monad.Supply
34+ import Control.Monad.Reader (MonadReader , asks )
3335import Control.Monad.Supply.Class
3436
3537import Language.PureScript.CodeGen.JS.AST as AST
@@ -45,14 +47,14 @@ import qualified Language.PureScript.Constants as C
4547-- Generate code in the simplified Javascript intermediate representation for all declarations in a
4648-- module.
4749--
48- moduleToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
49- => Module Ann -> SupplyT m [JS ]
50+ moduleToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m , MonadSupply m )
51+ => Module Ann -> m [JS ]
5052moduleToJs (Module name imps exps foreigns decls) = do
51- additional <- lift $ asks optionsAdditional
52- jsImports <- lift . T. traverse importToJs . delete (ModuleName [ProperName C. prim]) . (\\ [name]) $ imps
53+ additional <- asks optionsAdditional
54+ jsImports <- T. traverse importToJs . delete (ModuleName [ProperName C. prim]) . (\\ [name]) $ imps
5355 let foreigns' = mapMaybe (\ (_, js, _) -> js) foreigns
5456 jsDecls <- mapM (bindToJs name) decls
55- optimized <- lift $ T. traverse (T. traverse optimize) jsDecls
57+ optimized <- T. traverse (T. traverse optimize) jsDecls
5658 let isModuleEmpty = null exps
5759 let moduleBody = JSStringLiteral " use strict" : jsImports ++ foreigns' ++ concat optimized
5860 let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) exps
@@ -80,8 +82,8 @@ importToJs mn = do
8082-- |
8183-- Generate code in the simplified Javascript intermediate representation for a declaration
8284--
83- bindToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
84- => ModuleName -> Bind Ann -> SupplyT m [JS ]
85+ bindToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m , MonadSupply m )
86+ => ModuleName -> Bind Ann -> m [JS ]
8587bindToJs mp (NonRec ident val) = return <$> nonRecToJS mp ident val
8688bindToJs mp (Rec vals) = forM vals (uncurry (nonRecToJS mp))
8789
@@ -91,10 +93,10 @@ bindToJs mp (Rec vals) = forM vals (uncurry (nonRecToJS mp))
9193--
9294-- The main purpose of this function is to handle code generation for comments.
9395--
94- nonRecToJS :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
95- => ModuleName -> Ident -> Expr Ann -> SupplyT m JS
96+ nonRecToJS :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m , MonadSupply m )
97+ => ModuleName -> Ident -> Expr Ann -> m JS
9698nonRecToJS m i e@ (extractAnn -> (_, com, _, _)) | not (null com) = do
97- withoutComment <- lift $ asks optionsNoComments
99+ withoutComment <- asks optionsNoComments
98100 if withoutComment
99101 then nonRecToJS m i (modifyAnn removeComments e)
100102 else JSComment com <$> nonRecToJS m i (modifyAnn removeComments e)
@@ -126,8 +128,8 @@ accessorString prop | identNeedsEscaping prop = JSIndexer (JSStringLiteral prop)
126128-- |
127129-- Generate code in the simplified Javascript intermediate representation for a value or expression.
128130--
129- valueToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
130- => ModuleName -> Expr Ann -> SupplyT m JS
131+ valueToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m , MonadSupply m )
132+ => ModuleName -> Expr Ann -> m JS
131133valueToJs m (Literal _ l) =
132134 literalToValueJS m l
133135valueToJs m (Var (_, _, _, Just (IsConstructor _ [] )) name) =
@@ -195,11 +197,12 @@ valueToJs _ (Constructor _ _ (ProperName ctor) fields) =
195197 in return $ iife ctor [ constructor
196198 , JSAssignment (JSAccessor " create" (JSVar ctor)) createFn
197199 ]
200+
198201iife :: String -> [JS ] -> JS
199202iife v exprs = JSApp (JSFunction Nothing [] (JSBlock $ exprs ++ [JSReturn $ JSVar v])) []
200203
201- literalToValueJS :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
202- => ModuleName -> Literal (Expr Ann ) -> SupplyT m JS
204+ literalToValueJS :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m , MonadSupply m )
205+ => ModuleName -> Literal (Expr Ann ) -> m JS
203206literalToValueJS _ (NumericLiteral n) = return $ JSNumericLiteral n
204207literalToValueJS _ (StringLiteral s) = return $ JSStringLiteral s
205208literalToValueJS _ (BooleanLiteral b) = return $ JSBooleanLiteral b
@@ -209,7 +212,7 @@ literalToValueJS m (ObjectLiteral ps) = JSObjectLiteral <$> mapM (sndM (valueToJ
209212-- |
210213-- Shallow copy an object.
211214--
212- extendObj :: (Functor m , Applicative m , Monad m ) => JS -> [(String , JS )] -> SupplyT m JS
215+ extendObj :: (Applicative m , Monad m , MonadSupply m ) => JS -> [(String , JS )] -> m JS
213216extendObj obj sts = do
214217 newObj <- freshName
215218 key <- freshName
@@ -246,8 +249,8 @@ qualifiedToJS _ f (Qualified _ a) = JSVar $ identToJs (f a)
246249-- Generate code in the simplified Javascript intermediate representation for pattern match binders
247250-- and guards.
248251--
249- bindersToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
250- => ModuleName -> [CaseAlternative Ann ] -> [JS ] -> SupplyT m JS
252+ bindersToJs :: forall m mode . (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m , MonadSupply m )
253+ => ModuleName -> [CaseAlternative Ann ] -> [JS ] -> m JS
251254bindersToJs m binders vals = do
252255 valNames <- replicateM (length vals) freshName
253256 let assignments = zipWith JSVariableIntroduction valNames (map Just vals)
@@ -257,16 +260,14 @@ bindersToJs m binders vals = do
257260 return $ JSApp (JSFunction Nothing [] (JSBlock (assignments ++ concat jss ++ [JSThrow $ JSUnary JSNew $ JSApp (JSVar " Error" ) [JSStringLiteral " Failed pattern match" ]])))
258261 []
259262 where
260- go :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
261- => [String ] -> [JS ] -> [Binder Ann ] -> SupplyT m [JS ]
263+ go :: [String ] -> [JS ] -> [Binder Ann ] -> m [JS ]
262264 go _ done [] = return done
263265 go (v: vs) done' (b: bs) = do
264266 done'' <- go vs done' bs
265267 binderToJs m v done'' b
266268 go _ _ _ = error " Invalid arguments to bindersToJs"
267269
268- guardsToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
269- => Either [(Guard Ann , Expr Ann )] (Expr Ann ) -> SupplyT m [JS ]
270+ guardsToJs :: Either [(Guard Ann , Expr Ann )] (Expr Ann ) -> m [JS ]
270271 guardsToJs (Left gs) = forM gs $ \ (cond, val) -> do
271272 cond' <- valueToJs m cond
272273 done <- valueToJs m val
@@ -277,8 +278,8 @@ bindersToJs m binders vals = do
277278-- Generate code in the simplified Javascript intermediate representation for a pattern match
278279-- binder.
279280--
280- binderToJs :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
281- => ModuleName -> String -> [JS ] -> Binder Ann -> SupplyT m [JS ]
281+ binderToJs :: forall m mode . (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m , MonadSupply m )
282+ => ModuleName -> String -> [JS ] -> Binder Ann -> m [JS ]
282283binderToJs _ _ done (NullBinder {}) = return done
283284binderToJs m varName done (LiteralBinder _ l) =
284285 literalToBinderJS m varName done l
@@ -295,8 +296,7 @@ binderToJs m varName done (ConstructorBinder (_, _, _, Just (IsConstructor ctorT
295296 (JSBlock js)
296297 Nothing ]
297298 where
298- go :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
299- => [(Ident , Binder Ann )] -> [JS ] -> SupplyT m [JS ]
299+ go :: [(Ident , Binder Ann )] -> [JS ] -> m [JS ]
300300 go [] done' = return done'
301301 go ((field, binder) : remain) done' = do
302302 argVar <- freshName
@@ -326,8 +326,8 @@ binderToJs m varName done (NamedBinder _ ident binder) = do
326326 js <- binderToJs m varName done binder
327327 return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)
328328
329- literalToBinderJS :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
330- => ModuleName -> String -> [JS ] -> Literal (Binder Ann ) -> SupplyT m [JS ]
329+ literalToBinderJS :: forall m mode . (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m , MonadSupply m )
330+ => ModuleName -> String -> [JS ] -> Literal (Binder Ann ) -> m [JS ]
331331literalToBinderJS _ varName done (NumericLiteral num) =
332332 return [JSIfElse (JSBinary EqualTo (JSVar varName) (JSNumericLiteral num)) (JSBlock done) Nothing ]
333333literalToBinderJS _ varName done (StringLiteral str) =
@@ -338,8 +338,7 @@ literalToBinderJS _ varName done (BooleanLiteral False) =
338338 return [JSIfElse (JSUnary Not (JSVar varName)) (JSBlock done) Nothing ]
339339literalToBinderJS m varName done (ObjectLiteral bs) = go done bs
340340 where
341- go :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
342- => [JS ] -> [(String , Binder Ann )] -> SupplyT m [JS ]
341+ go :: [JS ] -> [(String , Binder Ann )] -> m [JS ]
343342 go done' [] = return done'
344343 go done' ((prop, binder): bs') = do
345344 propVar <- freshName
@@ -350,8 +349,7 @@ literalToBinderJS m varName done (ArrayLiteral bs) = do
350349 js <- go done 0 bs
351350 return [JSIfElse (JSBinary EqualTo (JSAccessor " length" (JSVar varName)) (JSNumericLiteral (Left (fromIntegral $ length bs)))) (JSBlock js) Nothing ]
352351 where
353- go :: (Functor m , Applicative m , Monad m , MonadReader (Options mode ) m )
354- => [JS ] -> Integer -> [Binder Ann ] -> SupplyT m [JS ]
352+ go :: [JS ] -> Integer -> [Binder Ann ] -> m [JS ]
355353 go done' _ [] = return done'
356354 go done' index (binder: bs') = do
357355 elVar <- freshName
0 commit comments