git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Remove psc, DCE module, simplify options.
commit12f585ba1a661f5cee347535e60f6744e71877dd authorPhil Freeman <paf31@cantab.net> dateSat 27 Jun 2015, 13:53 (11 years ago) parenta11335e
14 files changed+31−521
psc-make/Main.hs+7−7 psc-make/Make.hs+3−3 psc/Main.hs−231 psci/Make.hs+4−4 purescript.cabal−11 src/Language/PureScript.hs+3−94 src/Language/PureScript/CodeGen/JS.hs+4−16 src/Language/PureScript/CodeGen/JS/Optimizer.hs+2−2 src/Language/PureScript/CodeGen/JS/Optimizer/MagicDo.hs+1−1 src/Language/PureScript/CodeGen/JS/Optimizer/TCO.hs+1−1 src/Language/PureScript/DeadCodeElimination.hs−102 src/Language/PureScript/Options.hs+5−47 src/Language/PureScript/TypeChecker/Entailment.hs+1−1 src/Language/PureScript/TypeChecker/Synonyms.hs−1
psc-make/Main.hs+7−7
@@ -42,7 +42,7 @@ data PSCMakeOptions = PSCMakeOptions
4242 { pscmInput :: [FilePath]
4343 , pscmForeignInput :: [FilePath]
4444 , pscmOutputDir :: FilePath
45− , pscmOpts :: P.Options P.Make
45+ , pscmOpts :: P.Options
4646 , pscmUsePrefix :: Bool
4747 }
4848
@@ -53,6 +53,9 @@ data InputOptions = InputOptions
5353compile :: PSCMakeOptions -> IO ()
5454compile (PSCMakeOptions inputGlob inputForeignGlob outputDir opts usePrefix) = do
5555 input <- concat <$> mapM glob inputGlob
56+ when (null input) $ do
57+ putStrLn "psc-make: No input files."
58+ exitFailure
5659 moduleFiles <- readInput (InputOptions input)
5760 inputForeign <- concat <$> mapM glob inputForeignGlob
5861 foreignFiles <- forM inputForeign (\inFile -> (inFile,) <$> readFile inFile)
@@ -145,18 +148,15 @@ noPrefix = switch $
145148 <> help "Do not include comment header"
146149
147150
148−options :: Parser (P.Options P.Make)
151+options :: Parser P.Options
149152options = P.Options <$> noTco
150153 <*> noMagicDo
151154 <*> pure Nothing
152155 <*> noOpts
153156 <*> verboseErrors
154157 <*> (not <$> comments)
155− <*> additionalOptions
156− where
157− additionalOptions =
158− P.MakeOptions <$> requirePath
159−
158+ <*> requirePath
159+
160160pscMakeOptions :: Parser PSCMakeOptions
161161pscMakeOptions = PSCMakeOptions <$> many inputFile
162162 <*> many inputForeignFile
psc-make/Make.hs+3−3
@@ -46,10 +46,10 @@ import qualified Language.PureScript.CodeGen.JS as J
4646import qualified Language.PureScript.CoreFn as CF
4747import qualified Paths_purescript as Paths
4848
49−newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (WriterT P.MultipleErrors (ExceptT P.MultipleErrors IO)) a }
50− deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadWriter P.MultipleErrors, MonadReader (P.Options P.Make))
49+newtype Make a = Make { unMake :: ReaderT P.Options (WriterT P.MultipleErrors (ExceptT P.MultipleErrors IO)) a }
50+ deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadWriter P.MultipleErrors, MonadReader P.Options)
5151
52−runMake :: P.Options P.Make -> Make a -> IO (Either P.MultipleErrors (a, P.MultipleErrors))
52+runMake :: P.Options -> Make a -> IO (Either P.MultipleErrors (a, P.MultipleErrors))
5353runMake opts = runExceptT . runWriterT . flip runReaderT opts . unMake
5454
5555makeIO :: (IOError -> P.ErrorMessage) -> IO a -> Make a
psc/Main.hsdeleted−231
@@ -1,231 +0,0 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Main
4−-- Copyright : (c) Phil Freeman 2013
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- |
12−--
13−-----------------------------------------------------------------------------
14−
15−{-# LANGUAGE DataKinds #-}
16−{-# LANGUAGE FlexibleContexts #-}
17−{-# LANGUAGE RecordWildCards #-}
18−{-# LANGUAGE ScopedTypeVariables #-}
19−{-# LANGUAGE TupleSections #-}
20−
21−module Main where
22−
23−import Control.Applicative
24−import Control.Monad
25−import Control.Monad.Error.Class (MonadError(..))
26−import Control.Monad.Reader
27−import Control.Monad.Writer
28−
29−import Data.Maybe (fromMaybe)
30−import Data.Version (showVersion)
31−
32−import Options.Applicative as Opts
33−
34−import System.Directory (createDirectoryIfMissing)
35−import System.Exit (exitSuccess, exitFailure)
36−import System.FilePath (takeDirectory)
37−import System.FilePath.Glob (glob)
38−import System.IO (hPutStrLn, stderr)
39−
40−import qualified Data.Map as M
41−import qualified Language.PureScript as P
42−import qualified Paths_purescript as Paths
43−
44−data PSCOptions = PSCOptions
45− { pscInput :: [FilePath]
46− , pscForeignInput :: [FilePath]
47− , pscOpts :: P.Options P.Compile
48− , pscStdIn :: Bool
49− , pscOutput :: Maybe FilePath
50− , pscExterns :: Maybe FilePath
51− , pscUsePrefix :: Bool
52− }
53−
54−data InputOptions = InputOptions
55− { ioUseStdIn :: Bool
56− , ioInputFiles :: [FilePath]
57− }
58−
59−readInput :: InputOptions -> IO [(Maybe FilePath, String)]
60−readInput InputOptions{..}
61− | ioUseStdIn = return . (Nothing ,) <$> getContents
62− | otherwise = forM ioInputFiles $ \inFile -> (Just inFile, ) <$> readFile inFile
63−
64−type PSC = ReaderT (P.Options P.Compile) (WriterT P.MultipleErrors (Either P.MultipleErrors))
65−
66−runPSC :: P.Options P.Compile -> PSC a -> Either P.MultipleErrors (a, P.MultipleErrors)
67−runPSC opts rwe = runWriterT (runReaderT rwe opts)
68−
69−compile :: PSCOptions -> IO ()
70−compile (PSCOptions inputGlob inputForeignGlob opts stdin output externs usePrefix) = do
71− let prefix = ["Generated by psc version " ++ showVersion Paths.version | usePrefix]
72− input <- concat <$> mapM glob inputGlob
73− moduleFiles <- readInput (InputOptions stdin input)
74− inputForeign <- concat <$> mapM glob inputForeignGlob
75− foreignFiles <- forM inputForeign (\inFile -> (inFile,) <$> readFile inFile)
76− case runWriterT (parseInputs moduleFiles foreignFiles) of
77− Left errs -> do
78− hPutStrLn stderr (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
79− exitFailure
80− Right ((ms, foreigns), warnings) -> do
81− when (P.nonEmpty warnings) $
82− hPutStrLn stderr (P.prettyPrintMultipleWarnings (P.optionsVerboseErrors opts) warnings)
83− case runPSC opts (P.compileJS ms foreigns prefix) of
84− Left errs -> do
85− hPutStrLn stderr (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)
86− exitFailure
87− Right ((js, exts, _), warnings') -> do
88− when (P.nonEmpty warnings') $
89− hPutStrLn stderr (P.prettyPrintMultipleWarnings (P.optionsVerboseErrors opts) warnings')
90− case output of
91− Just path -> mkdirp path >> writeFile path js
92− Nothing -> putStrLn js
93− case externs of
94− Just path -> mkdirp path >> writeFile path exts
95− Nothing -> return ()
96− exitSuccess
97−
98−parseInputs :: (Functor m, Applicative m, MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m)
99− => [(Maybe FilePath, String)] -> [(FilePath, P.ForeignJS)] -> m ([P.Module], M.Map P.ModuleName (FilePath, P.ForeignJS))
100−parseInputs modules foreigns =
101− (,) <$> (map snd <$> P.parseModulesFromFiles (fromMaybe "") modules)
102− <*> P.parseForeignModulesFromFiles foreigns
103−
104−mkdirp :: FilePath -> IO ()
105−mkdirp = createDirectoryIfMissing True . takeDirectory
106−
107−codeGenModule :: Parser String
108−codeGenModule = strOption $
109− long "codegen"
110− <> help "A list of modules for which Javascript and externs should be generated. This argument can be used multiple times."
111−
112−dceModule :: Parser String
113−dceModule = strOption $
114− short 'm'
115− <> long "module"
116− <> help "Enables dead code elimination, all code which is not a transitive dependency of a specified module will be removed. This argument can be used multiple times."
117−
118−browserNamespace :: Parser String
119−browserNamespace = strOption $
120− long "browser-namespace"
121− <> Opts.value "PS"
122− <> showDefault
123− <> help "Specify the namespace that PureScript modules will be exported to when running in the browser."
124−
125−verboseErrors :: Parser Bool
126−verboseErrors = switch $
127− short 'v'
128− <> long "verbose-errors"
129− <> help "Display verbose error messages"
130−
131−noOpts :: Parser Bool
132−noOpts = switch $
133− long "no-opts"
134− <> help "Skip the optimization phase."
135−
136−runMain :: Parser (Maybe String)
137−runMain = optional $ noArgs <|> withArgs
138− where
139− defaultVal = "Main"
140− noArgs = flag' defaultVal (long "main")
141− withArgs = strOption $
142− long "main"
143− <> help (concat [
144− "Generate code to run the main method in the specified module. ",
145− "(no argument: \"", defaultVal, "\")"
146− ])
147−
148−noMagicDo :: Parser Bool
149−noMagicDo = switch $
150− long "no-magic-do"
151− <> help "Disable the optimization that overloads the do keyword to generate efficient code specifically for the Eff monad."
152−
153−noTco :: Parser Bool
154−noTco = switch $
155− long "no-tco"
156− <> help "Disable tail call optimizations"
157−
158−comments :: Parser Bool
159−comments = switch $
160− short 'c'
161− <> long "comments"
162− <> help "Include comments in the generated code."
163−
164−useStdIn :: Parser Bool
165−useStdIn = switch $
166− short 's'
167− <> long "stdin"
168− <> help "Read from standard input"
169−
170−inputFile :: Parser FilePath
171−inputFile = strArgument $
172− metavar "FILE"
173− <> help "The input .purs file(s)"
174−
175−inputForeignFile :: Parser FilePath
176−inputForeignFile = strOption $
177− short 'f'
178− <> long "ffi"
179− <> help "The input .js file(s) providing foreign import implementations"
180−
181−outputFile :: Parser (Maybe FilePath)
182−outputFile = optional . strOption $
183− short 'o'
184− <> long "output"
185− <> help "The output .js file"
186−
187−externsFile :: Parser (Maybe FilePath)
188−externsFile = optional . strOption $
189− short 'e'
190− <> long "externs"
191− <> help "The output .e.purs file"
192−
193−noPrefix :: Parser Bool
194−noPrefix = switch $
195− short 'p'
196− <> long "no-prefix"
197− <> help "Do not include comment header"
198−
199−options :: Parser (P.Options P.Compile)
200−options = P.Options <$> noTco
201− <*> noMagicDo
202− <*> runMain
203− <*> noOpts
204− <*> verboseErrors
205− <*> (not <$> comments)
206− <*> additionalOptions
207− where
208− additionalOptions =
209− P.CompileOptions <$> browserNamespace
210− <*> many dceModule
211− <*> many codeGenModule
212−
213−pscOptions :: Parser PSCOptions
214−pscOptions = PSCOptions <$> many inputFile
215− <*> many inputForeignFile
216− <*> options
217− <*> useStdIn
218− <*> outputFile
219− <*> externsFile
220− <*> (not <$> noPrefix)
221−
222−main :: IO ()
223−main = execParser opts >>= compile
224− where
225− opts = info (version <*> helper <*> pscOptions) infoModList
226− infoModList = fullDesc <> headerInfo <> footerInfo
227− headerInfo = header "psc - Compiles PureScript to Javascript"
228− footerInfo = footer $ "psc " ++ showVersion Paths.version
229−
230− version :: Parser (a -> a)
231− version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psci/Make.hs+4−4
@@ -42,14 +42,14 @@ import qualified Language.PureScript.CoreFn as CF
4242
4343import IO (mkdirp)
4444
45−options :: P.Options P.Make
46−options = P.Options False False Nothing False False False (P.MakeOptions Nothing)
45+options :: P.Options
46+options = P.Options False False Nothing False False False Nothing
4747
4848modulesDir :: FilePath
4949modulesDir = ".psci_modules" ++ pathSeparator : "node_modules"
5050
51−newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (WriterT P.MultipleErrors (ExceptT P.MultipleErrors IO)) a }
52− deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadWriter P.MultipleErrors, MonadReader (P.Options P.Make))
51+newtype Make a = Make { unMake :: ReaderT P.Options (WriterT P.MultipleErrors (ExceptT P.MultipleErrors IO)) a }
52+ deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadWriter P.MultipleErrors, MonadReader P.Options)
5353
5454runMake :: Make a -> IO (Either P.MultipleErrors a)
5555runMake = runExceptT . fmap fst . runWriterT . flip runReaderT options . unMake
purescript.cabal−11
@@ -78,7 +78,6 @@ library
7878 Language.PureScript.CoreFn.Module
7979 Language.PureScript.CoreFn.Traversals
8080 Language.PureScript.Comments
81− Language.PureScript.DeadCodeElimination
8281 Language.PureScript.Environment
8382 Language.PureScript.Errors
8483 Language.PureScript.Kinds
@@ -145,16 +144,6 @@ library
145144 other-modules: Paths_purescript
146145 ghc-options: -Wall -O2
147146
148−executable psc
149− build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
150− mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
151− transformers -any, Glob >= 0.7 && < 0.8
152− main-is: Main.hs
153− buildable: True
154− hs-source-dirs: psc
155− other-modules:
156− ghc-options: -Wall -O2 -fno-warn-unused-do-bind
157−
158147executable psc-make
159148 build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,
160149 mtl -any, optparse-applicative >= 0.10.0, parsec -any, purescript -any,
src/Language/PureScript.hs+3−94
@@ -20,9 +20,6 @@
2020
2121module Language.PureScript
2222 ( module P
23− , compile
24− , compile'
25− , compileJS
2623 , RebuildPolicy(..)
2724 , MakeActions(..)
2825 , SupplyVar()
@@ -32,7 +29,7 @@ module Language.PureScript
3229 ) where
3330
3431import Data.Function (on)
35−import Data.List (sortBy, groupBy, intercalate)
32+import Data.List (sortBy, groupBy)
3633import Data.Maybe (fromMaybe)
3734import Data.Time.Clock
3835import Data.Version (Version)
@@ -45,12 +42,11 @@ import Control.Monad
4542import Control.Monad.Error.Class (MonadError(..))
4643import Control.Monad.Reader
4744import Control.Monad.Writer
48−import Control.Monad.Supply.Class (MonadSupply, fresh)
45+import Control.Monad.Supply.Class (fresh)
4946
5047import Language.PureScript.AST as P
5148import Language.PureScript.Comments as P
5249import Language.PureScript.CodeGen.Externs (moduleToPs)
53−import Language.PureScript.DeadCodeElimination as P
5450import Language.PureScript.Environment as P
5551import Language.PureScript.Errors as P
5652import Language.PureScript.Kinds as P
@@ -67,96 +63,9 @@ import Language.PureScript.TypeChecker as P
6763import Language.PureScript.Types as P
6864import qualified Language.PureScript.CoreFn as CoreFn
6965import qualified Language.PureScript.Constants as C
70−import qualified Language.PureScript.CodeGen.JS as J
7166
7267import qualified Paths_purescript as Paths
7368
74−-- |
75−-- Compile a collection of modules
76−--
77−-- The compilation pipeline proceeds as follows:
78−--
79−-- * Sort the modules based on module dependencies, checking for cyclic dependencies.
80−--
81−-- * Perform a set of desugaring passes.
82−--
83−-- * Type check, and elaborate values to include type annotations and type class dictionaries.
84−--
85−-- * Regroup values to take into account new value dependencies introduced by elaboration.
86−--
87−-- * Eliminate dead code.
88−--
89−-- * Generate Javascript, and perform optimization passes.
90−--
91−-- * Pretty-print the generated Javascript
92−--
93−compile :: (Functor m, Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m, MonadReader (Options Compile) m)
94− => [Module] -> m ([CoreFn.Module CoreFn.Ann], Environment, SupplyVar, Externs)
95−compile = compile' initEnvironment
96−
97−compile' :: (Functor m, Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m, MonadReader (Options Compile) m)
98− => Environment -> [Module] -> m ([CoreFn.Module CoreFn.Ann], Environment, SupplyVar, Externs)
99−compile' env ms = do
100− additional <- asks optionsAdditional
101− mainModuleIdent <- asks (fmap moduleNameFromString . optionsMain)
102− (sorted, _) <- sortModules $ map importPrim ms
103− mapM_ lint sorted
104− (desugared, nextVar) <- runSupplyT 0 $ desugar sorted
105− (elaborated, env') <- runCheck' env $ forM desugared $ typeCheckModule mainModuleIdent
106− regrouped <- createBindingGroupsModule . collapseBindingGroupsModule $ elaborated
107− let corefn = map (CoreFn.moduleToCoreFn env') regrouped
108− entryPoints = moduleNameFromString `map` entryPointModules additional
109− elim = if null entryPoints then corefn else eliminateDeadCode entryPoints corefn
110− renamed = renameInModules elim
111− codeGenModuleNames = moduleNameFromString `map` codeGenModules additional
112− modulesToCodeGen = if null codeGenModuleNames then renamed else filter (\(CoreFn.Module _ mn _ _ _ _) -> mn `elem` codeGenModuleNames) renamed
113− exts = intercalate "\n" . map (`moduleToPs` env') $ regrouped
114− return (modulesToCodeGen, env', nextVar, exts)
115−
116−-- |
117−-- Compile a collection of modules to JavaScript and externs files
118−--
119−compileJS :: forall m. (Functor m, Applicative m, MonadError P.MultipleErrors m, MonadWriter P.MultipleErrors m, MonadReader (P.Options P.Compile) m)
120− => [P.Module] -> M.Map P.ModuleName (FilePath, P.ForeignJS) -> [String] -> m (String, String, Environment)
121−compileJS ms foreigns prefix = do
122− (modulesToCodeGen, env, nextVar, exts) <- compile ms
123− js <- concat <$> evalSupplyT nextVar (P.parU modulesToCodeGen codegenModule)
124− js' <- generateMain env js
125− let pjs = unlines $ map ("// " ++) prefix ++ [P.prettyPrintJS js']
126− return (pjs, exts, env)
127−
128− where
129−
130− codegenModule :: (Functor n, Applicative n, MonadError P.MultipleErrors n, MonadWriter P.MultipleErrors n, MonadReader (P.Options P.Compile) n, MonadSupply n)
131− => CoreFn.Module CoreFn.Ann -> n [J.JS]
132− codegenModule m =
133− let requiresForeign = not $ null (CoreFn.moduleForeign m)
134− mn = CoreFn.moduleName m
135− in case mn `M.lookup` foreigns of
136− Just (path, js)
137− | not requiresForeign -> do
138− tell $ P.errorMessage $ P.UnnecessaryFFIModule mn path
139− J.moduleToJs m Nothing
140− | otherwise -> J.moduleToJs m $ Just $
141− J.JSApp (J.JSFunction Nothing [] $
142− J.JSBlock [ J.JSVariableIntroduction "exports" (Just $ J.JSObjectLiteral [])
143− , J.JSRaw js
144− , J.JSReturn (J.JSVar "exports")
145− ]) []
146− Nothing | requiresForeign -> throwError . P.errorMessage $ P.MissingFFIModule mn
147− | otherwise -> J.moduleToJs m Nothing
148−
149− generateMain :: P.Environment -> [J.JS] -> m [J.JS]
150− generateMain env js = do
151− mainName <- asks P.optionsMain
152− additional <- asks P.optionsAdditional
153− case P.moduleNameFromString <$> mainName of
154− Just mmi -> do
155− when ((mmi, P.Ident C.main) `M.notMember` P.names env) $
156− throwError . P.errorMessage $ P.NameIsUndefined (P.Ident C.main)
157− return $ js ++ [J.mainCall mmi (P.browserNamespace additional)]
158− _ -> return js
159−
16069-- |
16170-- Actions that require implementations when running in "make" mode.
16271--
@@ -212,7 +121,7 @@ data RebuildPolicy
212121-- If timestamps have not changed, the externs file can be used to provide the module's types without
213122-- having to typecheck the module again.
214123--
215−make :: forall m. (Functor m, Applicative m, Monad m, MonadReader (P.Options P.Make) m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
124+make :: forall m. (Functor m, Applicative m, Monad m, MonadReader P.Options m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
216125 => MakeActions m
217126 -> [(Either RebuildPolicy FilePath, Module)]
218127 -> m Environment
src/Language/PureScript/CodeGen/JS.hs+4−16
@@ -50,14 +50,12 @@ import System.FilePath.Posix ((</>))
5050-- Generate code in the simplified Javascript intermediate representation for all declarations in a
5151-- module.
5252--
53−moduleToJs :: forall m mode. (Applicative m, Monad m, MonadReader (Options mode) m, MonadSupply m)
53+moduleToJs :: forall m. (Applicative m, Monad m, MonadReader Options m, MonadSupply m)
5454 => Module Ann -> Maybe JS -> m [JS]
5555moduleToJs (Module coms mn imps exps foreigns decls) foreign = do
56− additional <- asks optionsAdditional
5756 jsImports <- T.traverse importToJs . delete (ModuleName [ProperName C.prim]) . (\\ [mn]) $ imps
5857 jsDecls <- mapM bindToJs decls
5958 optimized <- T.traverse (T.traverse optimize) jsDecls
60− let isModuleEmpty = null exps
6159 comments <- not <$> asks optionsNoComments
6260 let strict = JSStringLiteral "use strict"
6361 let header = if comments && not (null coms) then JSComment coms strict else strict
@@ -67,15 +65,7 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign = do
6765 let standardExps = exps \\ foreignExps
6866 let exps' = JSObjectLiteral $ map (runIdent &&& JSVar . identToJs) standardExps
6967 ++ map (runIdent &&& foreignIdent) foreignExps
70− return $ case additional of
71− MakeOptions _ -> moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
72− CompileOptions ns _ _ | not isModuleEmpty ->
73− [ JSVariableIntroduction ns
74− (Just (JSBinary Or (JSVar ns) (JSObjectLiteral [])) )
75− , JSAssignment (JSAccessor (moduleNameToJs mn) (JSVar ns))
76− (JSApp (JSFunction Nothing [] (JSBlock (moduleBody ++ [JSReturn exps']))) [])
77− ]
78− _ -> []
68+ return $ moduleBody ++ [JSAssignment (JSAccessor "exports" (JSVar "module")) exps']
7969
8070 where
8171
@@ -84,10 +74,8 @@ moduleToJs (Module coms mn imps exps foreigns decls) foreign = do
8474 --
8575 importToJs :: ModuleName -> m JS
8676 importToJs mn' = do
87− additional <- asks optionsAdditional
88− let moduleBody = case additional of
89− MakeOptions path -> JSApp (JSVar "require") [JSStringLiteral (maybe id (</>) path $ runModuleName mn')]
90− CompileOptions ns _ _ -> JSAccessor (moduleNameToJs mn') (JSVar ns)
77+ path <- asks optionsRequirePath
78+ let moduleBody = JSApp (JSVar "require") [JSStringLiteral (maybe id (</>) path $ runModuleName mn')]
9179 return $ JSVariableIntroduction (moduleNameToJs mn') (Just moduleBody)
9280
9381 -- |
src/Language/PureScript/CodeGen/JS/Optimizer.hs+2−2
@@ -55,12 +55,12 @@ import Language.PureScript.CodeGen.JS.Optimizer.Blocks
5555-- |
5656-- Apply a series of optimizer passes to simplified Javascript code
5757--
58−optimize :: (Monad m, MonadReader (Options mode) m, Applicative m, MonadSupply m) => JS -> m JS
58+optimize :: (Monad m, MonadReader Options m, Applicative m, MonadSupply m) => JS -> m JS
5959optimize js = do
6060 noOpt <- asks optionsNoOptimizations
6161 if noOpt then return js else optimize' js
6262
63−optimize' :: (Monad m, MonadReader (Options mode) m, Applicative m, MonadSupply m) => JS -> m JS
63+optimize' :: (Monad m, MonadReader Options m, Applicative m, MonadSupply m) => JS -> m JS
6464optimize' js = do
6565 opts <- ask
6666 untilFixedPoint (inlineArrComposition . applyAll
src/Language/PureScript/CodeGen/JS/Optimizer/MagicDo.hs+1−1
@@ -27,7 +27,7 @@ import Language.PureScript.Names
2727import Language.PureScript.Options
2828import qualified Language.PureScript.Constants as C
2929
30−magicDo :: Options mode -> JS -> JS
30+magicDo :: Options -> JS -> JS
3131magicDo opts | optionsNoMagicDo opts = id
3232 | otherwise = inlineST . magicDo'
3333
src/Language/PureScript/CodeGen/JS/Optimizer/TCO.hs+1−1
@@ -23,7 +23,7 @@ import Language.PureScript.CodeGen.JS.AST
2323-- |
2424-- Eliminate tail calls
2525--
26−tco :: Options mode -> JS -> JS
26+tco :: Options -> JS -> JS
2727tco opts | optionsNoTco opts = id
2828 | otherwise = tco'
2929
src/Language/PureScript/DeadCodeElimination.hsdeleted−102
@@ -1,102 +0,0 @@
1−-----------------------------------------------------------------------------
2−--
3−-- Module : Language.PureScript.DeadCodeElimination
4−-- Copyright : (c) 2014 Phil Freeman
5−-- License : MIT
6−--
7−-- Maintainer : Phil Freeman <paf31@cantab.net>
8−-- Stability : experimental
9−-- Portability :
10−--
11−-- | Dead code elimination.
12−--
13−-----------------------------------------------------------------------------
14−
15−module Language.PureScript.DeadCodeElimination (
16− eliminateDeadCode
17−) where
18−
19−import Data.Graph
20−import Data.List
21−import Data.Maybe (mapMaybe)
22−
23−import Language.PureScript.CoreFn
24−import Language.PureScript.Names
25−
26−-- |
27−-- Eliminate all declarations which are not a transitive dependency of the entry point module
28−--
29−eliminateDeadCode :: [ModuleName] -> [Module a] -> [Module a]
30−eliminateDeadCode entryPoints ms = map go ms
31− where
32− go (Module coms mn imps exps foreigns ds) = Module coms mn imps exps' foreigns' ds'
33− where
34− ds' = filter (isUsed mn graph vertexFor entryPointVertices) ds
35− foreigns' = filter (isUsed' mn graph vertexFor entryPointVertices . foreignIdent) foreigns
36− names = concatMap bindIdents ds' ++ map foreignIdent foreigns'
37− exps' = filter (`elem` names) exps
38− declarations = concatMap declarationsByModule ms
39− (graph, _, vertexFor) = graphFromEdges $ map (\(key, deps) -> (key, key, deps)) declarations
40− entryPointVertices = mapMaybe (vertexFor . fst) . filter (\((mn, _), _) -> mn `elem` entryPoints) $ declarations
41−
42−-- |
43−-- Extract declaration names for a binding group.
44−--
45−bindIdents :: Bind a -> [Ident]
46−bindIdents (NonRec name _) = [name]
47−bindIdents (Rec names) = map fst names
48−
49−-- |
50−-- Extract the ident for a foreign declaration.
51−--
52−foreignIdent :: ForeignDecl -> Ident
53−foreignIdent = fst
54−
55−-- |
56−-- Key type to use in graph
57−--
58−type Key = (ModuleName, Ident)
59−
60−-- |
61−-- Find dependencies for each member in a module.
62−--
63−declarationsByModule :: Module a -> [(Key, [Key])]
64−declarationsByModule (Module _ mn _ _ fs ds) =
65− let fs' = map ((\name -> ((mn, name), [])) . foreignIdent) fs
66− in fs' ++ concatMap go ds
67− where
68− go :: Bind a -> [(Key, [Key])]
69− go d@(NonRec name _) = [((mn, name), dependencies d)]
70− go d@(Rec names') = map (\(name, _) -> ((mn, name), dependencies d)) names'
71−
72−-- |
73−-- Find all referenced values within a binding group.
74−--
75−dependencies :: Bind a -> [Key]
76−dependencies =
77− let (f, _, _, _) = everythingOnValues (++) (const []) values binders (const [])
78− in nub . f
79− where
80− values :: Expr a -> [Key]
81− values (Var _ (Qualified (Just mn) ident)) = [(mn, ident)]
82− values _ = []
83− binders :: Binder a -> [Key]
84− binders (ConstructorBinder _ _ (Qualified (Just mn) ident) _) = [(mn, Ident $ runProperName ident)]
85− binders _ = []
86−
87−-- |
88−-- Check whether a binding group is used.
89−--
90−isUsed :: ModuleName -> Graph -> (Key -> Maybe Vertex) -> [Vertex] -> Bind a -> Bool
91−isUsed mn graph vertexFor entryPointVertices (NonRec name _) =
92− isUsed' mn graph vertexFor entryPointVertices name
93−isUsed mn graph vertexFor entryPointVertices (Rec ds) =
94− any (isUsed' mn graph vertexFor entryPointVertices . fst) ds
95−
96−-- |
97−-- Check whether a named declaration is used.
98−--
99−isUsed' :: ModuleName -> Graph -> (Key -> Maybe Vertex) -> [Vertex] -> Ident -> Bool
100−isUsed' mn graph vertexFor entryPointVertices name =
101− let Just v' = vertexFor (mn, name)
102− in any (\v -> path graph v v') entryPointVertices
src/Language/PureScript/Options.hs+5−47
@@ -13,79 +13,37 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE GADTs, DataKinds, StandaloneDeriving #-}
17−
1816module Language.PureScript.Options where
1917
20−-- |
21−-- Indicates the mode of the compiler. Lifted using DataKinds to refine the Options type.
22−--
23−data Mode = Compile | Make
24−
25−-- |
26−-- Per-mode options
27−--
28−data ModeOptions mode where
29− CompileOptions :: String -> [String] -> [String] -> ModeOptions Compile
30− MakeOptions :: Maybe FilePath -> ModeOptions Make
31−
32−browserNamespace :: ModeOptions Compile -> String
33−browserNamespace (CompileOptions ns _ _) = ns
34−
35−entryPointModules :: ModeOptions Compile -> [String]
36−entryPointModules (CompileOptions _ ms _) = ms
37−
38−codeGenModules :: ModeOptions Compile -> [String]
39−codeGenModules (CompileOptions _ _ ms) = ms
40−
41−requirePath :: ModeOptions Make -> Maybe FilePath
42−requirePath (MakeOptions mp) = mp
43−
44−deriving instance Show (ModeOptions mode)
45−
4618-- |
4719-- The data type of compiler options
4820--
49−data Options mode = Options {
21+data Options = Options {
5022 -- |
5123 -- Disable tail-call elimination
52− --
5324 optionsNoTco :: Bool
5425 -- |
5526 -- Disable inlining of calls to return and bind for the Eff monad
56− --
5727 , optionsNoMagicDo :: Bool
5828 -- |
5929 -- When specified, checks the type of `main` in the module, and generate a call to run main
6030 -- after the module definitions.
61− --
6231 , optionsMain :: Maybe String
6332 -- |
6433 -- Skip all optimizations
65− --
6634 , optionsNoOptimizations :: Bool
6735 -- |
6836 -- Verbose error message
69− --
7037 , optionsVerboseErrors :: Bool
7138 -- |
7239 -- Remove the comments from the generated js
7340 , optionsNoComments :: Bool
7441 -- |
75− -- Specify the namespace that PureScript modules will be exported to when running in the
76− -- browser.
77− --
78− , optionsAdditional :: ModeOptions mode
42+ -- The path to prepend to require statements
43+ , optionsRequirePath :: Maybe FilePath
7944 } deriving Show
8045
81−-- |
82−-- Default compiler options
83−--
84−defaultCompileOptions :: Options Compile
85−defaultCompileOptions = Options False False Nothing False False False (CompileOptions "PS" [] [])
86−
8746-- |
8847-- Default make options
89−--
90−defaultMakeOptions :: Options Make
91−defaultMakeOptions = Options False False Nothing False False False (MakeOptions Nothing)
48+defaultOptions :: Options
49+defaultOptions = Options False False Nothing False False False Nothing
src/Language/PureScript/TypeChecker/Entailment.hs+1−1
@@ -21,7 +21,7 @@ module Language.PureScript.TypeChecker.Entailment (
2121
2222import Data.Function (on)
2323import Data.List
24−import Data.Maybe (fromMaybe, maybeToList)
24+import Data.Maybe (maybeToList)
2525import Data.Foldable (foldMap)
2626import qualified Data.Map as M
2727
src/Language/PureScript/TypeChecker/Synonyms.hs−1
@@ -28,7 +28,6 @@ import Data.Maybe (fromMaybe)
2828import qualified Data.Map as M
2929
3030import Control.Applicative
31−import Control.Monad
3231import Control.Monad.Error.Class (MonadError(..))
3332import Control.Monad.State
3433