git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Embed the Prelude. Fix #673
b7dd289Phil Freeman
bundle/README−10
@@ -16,15 +16,5 @@ This bundle contains the following executables:
16- psci The PureScript interactive module (requires NodeJS)
16- psci The PureScript interactive module (requires NodeJS)
17- psc-docs A documentation generator
17- psc-docs A documentation generator
18
18
19−and the following additional files:
20−
21−- prelude.purs The Prelude (standard library source code)
22−
23Copy these files anywhere on your PATH.
19Copy these files anywhere on your PATH.
24
20
25−The PureScript compiler will look for the Prelude in the following locations:
26−
27−- ~/.purescript/prelude/prelude.purs or
28− C:/Documents And Settings/<user name>/Application Data/purescript/prelude/prelude.purs
29−- The directory of the compiler executable
30−
bundle/build.sh−1
@@ -26,7 +26,6 @@ cp ../dist/build/psc/psc build/purescript/
26cp ../dist/build/psci/psci build/purescript/
26cp ../dist/build/psci/psci build/purescript/
27cp ../dist/build/psc-make/psc-make build/purescript/
27cp ../dist/build/psc-make/psc-make build/purescript/
28cp ../dist/build/psc-docs/psc-docs build/purescript/
28cp ../dist/build/psc-docs/psc-docs build/purescript/
29−cp ../prelude/prelude.purs build/purescript/
30cp README build/purescript/
29cp README build/purescript/
31cp ../LICENSE build/purescript/
30cp ../LICENSE build/purescript/
32
31
psc-docs/Main.hs+7−9
@@ -29,19 +29,17 @@ import System.IO (stderr)
29
29
30docgen :: Bool -> [FilePath] -> IO ()
30docgen :: Bool -> [FilePath] -> IO ()
31docgen showHierarchy input = do
31docgen showHierarchy input = do
32− ms <- mapM parseFile (nub input)
32+ e <- P.parseModulesFromFiles <$> mapM parseFile (nub input)
33− U.putStrLn . runDocs $ (renderModules showHierarchy) (concat ms)
33+ case e of
34− exitSuccess
35−
36−parseFile :: FilePath -> IO [P.Module]
37−parseFile input = do
38− text <- U.readFile input
39− case P.runIndentParser input P.parseModules text of
40 Left err -> do
34 Left err -> do
41 U.hPutStr stderr $ show err
35 U.hPutStr stderr $ show err
42 exitFailure
36 exitFailure
43 Right ms -> do
37 Right ms -> do
44− return ms
38+ U.putStrLn . runDocs $ (renderModules showHierarchy) (map snd ms)
39+ exitSuccess
40+
41+parseFile :: FilePath -> IO (FilePath, String)
42+parseFile input = (,) input <$> U.readFile input
45
43
46type Docs = Writer [String] ()
44type Docs = Writer [String] ()
47
45
psc-make/Main.hs+12−21
@@ -12,13 +12,14 @@
12--
12--
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE DataKinds, GeneralizedNewtypeDeriving #-}
15+{-# LANGUAGE DataKinds, GeneralizedNewtypeDeriving, TupleSections #-}
16
16
17module Main where
17module Main where
18
18
19import Control.Applicative
19import Control.Applicative
20import Control.Monad.Error
20import Control.Monad.Error
21
21
22+import Data.Bool (bool)
22import Data.Version (showVersion)
23import Data.Version (showVersion)
23
24
24import System.Console.CmdTheLine
25import System.Console.CmdTheLine
@@ -28,19 +29,14 @@ import System.FilePath (takeDirectory)
28import System.Exit (exitSuccess, exitFailure)
29import System.Exit (exitSuccess, exitFailure)
29import System.IO.Error (tryIOError)
30import System.IO.Error (tryIOError)
30
31
31−import Text.Parsec (ParseError)
32−
33import qualified Language.PureScript as P
32import qualified Language.PureScript as P
34import qualified Paths_purescript as Paths
33import qualified Paths_purescript as Paths
35import qualified System.IO.UTF8 as U
34import qualified System.IO.UTF8 as U
36
35
37−readInput :: [FilePath] -> IO (Either ParseError [(FilePath, P.Module)])
36+readInput :: Bool -> [FilePath] -> IO [(FilePath, String)]
38−readInput input = fmap collect $ forM input $ \inputFile -> do
37+readInput excludePrelude input = do
39− text <- U.readFile inputFile
38+ content <- forM input $ \inputFile -> (inputFile, ) <$> U.readFile inputFile
40− return $ (inputFile, P.runIndentParser inputFile P.parseModules text)
39+ return $ bool (("<prelude>", P.prelude) :) id excludePrelude content
41− where
42− collect :: [(FilePath, Either ParseError [P.Module])] -> Either ParseError [(FilePath, P.Module)]
43− collect = fmap concat . sequence . map (\(fp, e) -> fmap (map ((,) fp)) e)
44
40
45newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Applicative, Monad, MonadIO, MonadError String)
41newtype Make a = Make { unMake :: ErrorT String IO a } deriving (Functor, Applicative, Monad, MonadIO, MonadError String)
46
42
@@ -66,9 +62,9 @@ instance P.MonadMake Make where
66 liftError = either throwError return
62 liftError = either throwError return
67 progress = makeIO . U.putStrLn
63 progress = makeIO . U.putStrLn
68
64
69−compile :: FilePath -> [FilePath] -> FilePath -> P.Options P.Make -> Bool -> IO ()
65+compile :: [FilePath] -> FilePath -> P.Options P.Make -> Bool -> IO ()
70−compile prelude input outputDir opts usePrefix = do
66+compile input outputDir opts usePrefix = do
71− modules <- readInput allInputFiles
67+ modules <- P.parseModulesFromFiles <$> readInput (P.optionsNoPrelude opts) input
72 case modules of
68 case modules of
73 Left err -> do
69 Left err -> do
74 U.print err
70 U.print err
@@ -86,9 +82,6 @@ compile prelude input outputDir opts usePrefix = do
86 then ["Generated by psc-make version " ++ showVersion Paths.version]
82 then ["Generated by psc-make version " ++ showVersion Paths.version]
87 else []
83 else []
88
84
89− allInputFiles | P.optionsNoPrelude opts = input
90− | otherwise = prelude : input
91−
92mkdirp :: FilePath -> IO ()
85mkdirp :: FilePath -> IO ()
93mkdirp = createDirectoryIfMissing True . takeDirectory
86mkdirp = createDirectoryIfMissing True . takeDirectory
94
87
@@ -127,8 +120,8 @@ noPrefix :: Term Bool
127noPrefix = value $ flag $ (optInfo ["p", "no-prefix" ])
120noPrefix = value $ flag $ (optInfo ["p", "no-prefix" ])
128 { optDoc = "Do not include comment header"}
121 { optDoc = "Do not include comment header"}
129
122
130−term :: FilePath -> Term (IO ())
123+term :: Term (IO ())
131−term prelude = compile prelude <$> inputFiles <*> outputDirectory <*> options <*> (not <$> noPrefix)
124+term = compile <$> inputFiles <*> outputDirectory <*> options <*> (not <$> noPrefix)
132
125
133termInfo :: TermInfo
126termInfo :: TermInfo
134termInfo = defTI
127termInfo = defTI
@@ -138,7 +131,5 @@ termInfo = defTI
138 }
131 }
139
132
140main :: IO ()
133main :: IO ()
141−main = do
142− prelude <- P.preludeFilename
143− run (term prelude, termInfo)
134+main = run (term, termInfo)
144
135
psc/Main.hs+13−25
@@ -12,13 +12,14 @@
12--
12--
13-----------------------------------------------------------------------------
13-----------------------------------------------------------------------------
14
14
15−{-# LANGUAGE DataKinds, GeneralizedNewtypeDeriving #-}
15+{-# LANGUAGE DataKinds, GeneralizedNewtypeDeriving, TupleSections #-}
16
16
17module Main where
17module Main where
18
18
19import Control.Applicative
19import Control.Applicative
20import Control.Monad.Error
20import Control.Monad.Error
21
21
22+import Data.Bool (bool)
22import Data.Version (showVersion)
23import Data.Version (showVersion)
23
24
24import System.Console.CmdTheLine
25import System.Console.CmdTheLine
@@ -27,26 +28,19 @@ import System.FilePath (takeDirectory)
27import System.Exit (exitSuccess, exitFailure)
28import System.Exit (exitSuccess, exitFailure)
28import System.IO (stderr)
29import System.IO (stderr)
29
30
30−import Text.Parsec (ParseError)
31−
32import qualified Language.PureScript as P
31import qualified Language.PureScript as P
33import qualified Paths_purescript as Paths
32import qualified Paths_purescript as Paths
34import qualified System.IO.UTF8 as U
33import qualified System.IO.UTF8 as U
35
34
36−readInput :: Maybe [FilePath] -> IO (Either ParseError [(FilePath, P.Module)])
35+readInput :: Bool -> Bool -> [FilePath] -> IO [(FilePath, String)]
37−readInput Nothing = do
38− text <- getContents
36+readInput _ True _ = return . ("<stdin>" ,) <$> getContents
39− return $ map ((,) undefined) <$> P.runIndentParser "" P.parseModules text
37+readInput excludePrelude _ input = do
40−readInput (Just input) = fmap collect $ forM input $ \inputFile -> do
41− text <- U.readFile inputFile
38+ content <- forM input $ \inputFile -> (inputFile, ) <$> U.readFile inputFile
42− return $ (inputFile, P.runIndentParser inputFile P.parseModules text)
39+ return $ bool (("<prelude>", P.prelude) :) id excludePrelude content
43− where
44− collect :: [(FilePath, Either ParseError [P.Module])] -> Either ParseError [(FilePath, P.Module)]
45− collect = fmap concat . sequence . map (\(fp, e) -> fmap (map ((,) fp)) e)
46
40
47−compile :: FilePath -> P.Options P.Compile -> Bool -> [FilePath] -> Maybe FilePath -> Maybe FilePath -> Bool -> IO ()
41+compile :: P.Options P.Compile -> Bool -> [FilePath] -> Maybe FilePath -> Maybe FilePath -> Bool -> IO ()
48−compile prelude opts stdin input output externs usePrefix = do
42+compile opts stdin input output externs usePrefix = do
49− modules <- readInput stdInOrInputFiles
43+ modules <- P.parseModulesFromFiles <$> readInput (P.optionsNoPrelude opts) stdin input
50 case modules of
44 case modules of
51 Left err -> do
45 Left err -> do
52 U.hPutStr stderr $ show err
46 U.hPutStr stderr $ show err
@@ -65,10 +59,6 @@ compile prelude opts stdin input output externs usePrefix = do
65 Nothing -> return ()
59 Nothing -> return ()
66 exitSuccess
60 exitSuccess
67 where
61 where
68− stdInOrInputFiles :: Maybe [FilePath]
69− stdInOrInputFiles | stdin = Nothing
70− | P.optionsNoPrelude opts = Just input
71− | otherwise = Just $ prelude : input
72 prefix = if usePrefix
62 prefix = if usePrefix
73 then ["Generated by psc version " ++ showVersion Paths.version]
63 then ["Generated by psc version " ++ showVersion Paths.version]
74 else []
64 else []
@@ -137,8 +127,8 @@ options = P.Options <$> noPrelude <*> noTco <*> noMagicDo <*> runMain <*> noOpts
137 where
127 where
138 additionalOptions = P.CompileOptions <$> browserNamespace <*> dceModules <*> codeGenModules
128 additionalOptions = P.CompileOptions <$> browserNamespace <*> dceModules <*> codeGenModules
139
129
140−term :: FilePath -> Term (IO ())
130+term :: Term (IO ())
141−term prelude = compile prelude <$> options <*> useStdIn <*> inputFiles <*> outputFile <*> externsFile <*> (not <$> noPrefix)
131+term = compile <$> options <*> useStdIn <*> inputFiles <*> outputFile <*> externsFile <*> (not <$> noPrefix)
142
132
143termInfo :: TermInfo
133termInfo :: TermInfo
144termInfo = defTI
134termInfo = defTI
@@ -148,8 +138,6 @@ termInfo = defTI
148 }
138 }
149
139
150main :: IO ()
140main :: IO ()
151−main = do
152− prelude <- P.preludeFilename
153− run (term prelude, termInfo)
141+main = run (term, termInfo)
154
142
155
143
psci/Main.hs+16−8
@@ -127,6 +127,17 @@ getHistoryFilename = do
127loadModule :: FilePath -> IO (Either String [P.Module])
127loadModule :: FilePath -> IO (Either String [P.Module])
128loadModule filename = either (Left . show) Right . P.runIndentParser filename P.parseModules <$> U.readFile filename
128loadModule filename = either (Left . show) Right . P.runIndentParser filename P.parseModules <$> U.readFile filename
129
129
130+-- |
131+-- Load all modules, including the Prelude
132+--
133+loadAllModules :: [FilePath] -> IO (Either ParseError [(FilePath, P.Module)])
134+loadAllModules files = do
135+ filesAndContent <- forM files $ \filename -> do
136+ content <- U.readFile filename
137+ return (filename, content)
138+ return $ P.parseModulesFromFiles $ ("<prelude>", P.prelude) : filesAndContent
139+
140+
130-- |
141-- |
131-- Expands tilde in path.
142-- Expands tilde in path.
132--
143--
@@ -447,10 +458,9 @@ handleCommand (LoadFile filePath) = do
447 PSCI . outputStrLn $ "Couldn't locate: " ++ filePath
458 PSCI . outputStrLn $ "Couldn't locate: " ++ filePath
448handleCommand Reset = do
459handleCommand Reset = do
449 files <- psciImportedFilenames <$> PSCI (lift get)
460 files <- psciImportedFilenames <$> PSCI (lift get)
450− filesAndModules <- mapM (\file -> fmap (fmap (map ((,) file))) . psciIO . loadModule $ file) files
461+ modulesOrFirstError <- psciIO $ loadAllModules files
451− let modulesOrFirstError = fmap concat $ sequence filesAndModules
452 case modulesOrFirstError of
462 case modulesOrFirstError of
453− Left err -> psciIO $ putStrLn err >> exitFailure
463+ Left err -> psciIO $ putStrLn (show err) >> exitFailure
454 Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules [])
464 Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules [])
455handleCommand (TypeOf val) = handleTypeOf val
465handleCommand (TypeOf val) = handleTypeOf val
456handleCommand (KindOf typ) = handleKindOf typ
466handleCommand (KindOf typ) = handleKindOf typ
@@ -489,15 +499,13 @@ loadUserConfig = do
489loop :: Bool -> [FilePath] -> IO ()
499loop :: Bool -> [FilePath] -> IO ()
490loop singleLineMode files = do
500loop singleLineMode files = do
491 config <- loadUserConfig
501 config <- loadUserConfig
492− preludeFilename <- P.preludeFilename
493− filesAndModules <- mapM (\file -> fmap (fmap (map ((,) file))) . loadModule $ file) (preludeFilename : files)
494− let modulesOrFirstError = fmap concat $ sequence filesAndModules
502+ modulesOrFirstError <- loadAllModules files
495 case modulesOrFirstError of
503 case modulesOrFirstError of
496− Left err -> putStrLn err >> exitFailure
504+ Left err -> putStrLn (show err) >> exitFailure
497 Right modules -> do
505 Right modules -> do
498 historyFilename <- getHistoryFilename
506 historyFilename <- getHistoryFilename
499 let settings = defaultSettings {historyFile = Just historyFilename}
507 let settings = defaultSettings {historyFile = Just historyFilename}
500− flip evalStateT (PSCiState (preludeFilename : files) defaultImports modules []) . runInputT (setComplete completion settings) $ do
508+ flip evalStateT (PSCiState files defaultImports modules []) . runInputT (setComplete completion settings) $ do
501 outputStrLn prologueMessage
509 outputStrLn prologueMessage
502 traverse_ (mapM_ (runPSCI . handleCommand)) config
510 traverse_ (mapM_ (runPSCI . handleCommand)) config
503 go
511 go
purescript.cabal+12−8
@@ -14,8 +14,6 @@ Homepage: http://www.purescript.org/
14author: Phil Freeman <paf31@cantab.net>,
14author: Phil Freeman <paf31@cantab.net>,
15 Gary Burgess <gary.burgess@gmail.com>,
15 Gary Burgess <gary.burgess@gmail.com>,
16 Hardy Jones <jones3.hardy@gmail.com>
16 Hardy Jones <jones3.hardy@gmail.com>
17−data-files: prelude/prelude.purs
18−data-dir: ""
19
17
20extra-source-files: examples/passing/*.purs
18extra-source-files: examples/passing/*.purs
21 , examples/failing/*.purs
19 , examples/failing/*.purs
@@ -25,14 +23,20 @@ source-repository head
25 location: https://github.com/purescript/purescript.git
23 location: https://github.com/purescript/purescript.git
26
24
27library
25library
26+ build-depends: base >=4 && <5,
27+ cmdtheline == 0.2.*,
28+ containers -any,
28− build-depends: base >=4 && <5, cmdtheline == 0.2.*, containers -any, unordered-containers -any,
29+ unordered-containers -any,
29− directory >= 1.2, filepath -any, mtl >= 2.1.0 && < 2.3.0, parsec -any,
30+ directory >= 1.2,
31+ filepath -any,
32+ mtl >= 2.1.0 && < 2.3.0,
33+ parsec -any,
30− transformers >= 0.3 && < 0.5, utf8-string -any,
34+ transformers >= 0.3 && < 0.5,
35+ utf8-string -any,
31 pattern-arrows >= 0.0.2 && < 0.1,
36 pattern-arrows >= 0.0.2 && < 0.1,
32− monad-unify >= 0.2.2 && < 0.3,
37+ monad-unify >= 0.2.2 && < 0.3,
38+ file-embed >= 0.0.7 && < 0.0.8,
33 time -any
39 time -any
34− if (!os(windows))
35− build-depends: unix -any
36 exposed-modules: Language.PureScript
40 exposed-modules: Language.PureScript
37 Language.PureScript.Constants
41 Language.PureScript.Constants
38 Language.PureScript.Options
42 Language.PureScript.Options
src/Language/PureScript.hs+14−29
@@ -13,9 +13,9 @@
13--
13--
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
15
15
16−{-# LANGUAGE DataKinds #-}
16+{-# LANGUAGE DataKinds, QuasiQuotes, TemplateHaskell #-}
17
17
18−module Language.PureScript (module P, compile, compile', MonadMake(..), make, preludeFilename) where
18+module Language.PureScript (module P, compile, compile', MonadMake(..), make, prelude) where
19
19
20import Language.PureScript.Types as P
20import Language.PureScript.Types as P
21import Language.PureScript.Kinds as P
21import Language.PureScript.Kinds as P
@@ -36,21 +36,22 @@ import Language.PureScript.Supply as P
36import Language.PureScript.Renamer as P
36import Language.PureScript.Renamer as P
37
37
38import qualified Language.PureScript.Constants as C
38import qualified Language.PureScript.Constants as C
39−import qualified Paths_purescript as Paths
40
39
41import Data.List (sortBy, groupBy, intercalate)
40import Data.List (sortBy, groupBy, intercalate)
42import Data.Time.Clock
41import Data.Time.Clock
43import Data.Function (on)
42import Data.Function (on)
44import Data.Maybe (fromMaybe)
43import Data.Maybe (fromMaybe)
44+import Data.FileEmbed (embedFile)
45+
45import Control.Monad.Error
46import Control.Monad.Error
46import Control.Arrow ((&&&))
47import Control.Arrow ((&&&))
47import Control.Applicative
48import Control.Applicative
49+
48import qualified Data.Map as M
50import qualified Data.Map as M
49import qualified Data.Set as S
51import qualified Data.Set as S
52+import qualified Data.ByteString.UTF8 as BU
50
53
51−import System.FilePath ((</>), pathSeparator, takeDirectory)
54+import System.FilePath ((</>))
52−import System.Directory (getAppUserDataDirectory, doesFileExist)
53−import System.Environment (getProgName)
54
55
55-- |
56-- |
56-- Compile a collection of modules
57-- Compile a collection of modules
@@ -146,8 +147,8 @@ make outputDir opts ms prefix = do
146 toRebuild <- foldM (\s (Module moduleName' _ _) -> do
147 toRebuild <- foldM (\s (Module moduleName' _ _) -> do
147 let filePath = runModuleName moduleName'
148 let filePath = runModuleName moduleName'
148
149
149− jsFile = outputDir ++ pathSeparator : filePath ++ pathSeparator : "index.js"
150+ jsFile = outputDir </> filePath </> "index.js"
150− externsFile = outputDir ++ pathSeparator : filePath ++ pathSeparator : "externs.purs"
151+ externsFile = outputDir </> filePath </> "externs.purs"
151 inputFile = fromMaybe (error "Input file is undefined in make") $ M.lookup moduleName' filePathMap
152 inputFile = fromMaybe (error "Input file is undefined in make") $ M.lookup moduleName' filePathMap
152
153
153 jsTimestamp <- getTimestamp jsFile
154 jsTimestamp <- getTimestamp jsFile
@@ -173,8 +174,8 @@ make outputDir opts ms prefix = do
173 go env' ms'
174 go env' ms'
174 go env ((True, m@(Module moduleName' _ exps)) : ms') = do
175 go env ((True, m@(Module moduleName' _ exps)) : ms') = do
175 let filePath = runModuleName moduleName'
176 let filePath = runModuleName moduleName'
176− jsFile = outputDir ++ pathSeparator : filePath ++ pathSeparator : "index.js"
177+ jsFile = outputDir </> filePath </> "index.js"
177− externsFile = outputDir ++ pathSeparator : filePath ++ pathSeparator : "externs.purs"
178+ externsFile = outputDir </> filePath </> "externs.purs"
178
179
179 lift . progress $ "Compiling " ++ runModuleName moduleName'
180 lift . progress $ "Compiling " ++ runModuleName moduleName'
180
181
@@ -201,7 +202,7 @@ make outputDir opts ms prefix = do
201 toRebuild' = toRebuild `S.union` S.fromList deps
202 toRebuild' = toRebuild `S.union` S.fromList deps
202 (:) (True, m) <$> rebuildIfNecessary graph toRebuild' ms'
203 (:) (True, m) <$> rebuildIfNecessary graph toRebuild' ms'
203 rebuildIfNecessary graph toRebuild (Module moduleName' _ _ : ms') = do
204 rebuildIfNecessary graph toRebuild (Module moduleName' _ _ : ms') = do
204− let externsFile = outputDir ++ pathSeparator : runModuleName moduleName' ++ pathSeparator : "externs.purs"
205+ let externsFile = outputDir </> runModuleName moduleName' </> "externs.purs"
205 externs <- readTextFile externsFile
206 externs <- readTextFile externsFile
206 externsModules <- liftError . either (Left . show) Right $ P.runIndentParser externsFile P.parseModules externs
207 externsModules <- liftError . either (Left . show) Right $ P.runIndentParser externsFile P.parseModules externs
207 case externsModules of
208 case externsModules of
@@ -232,21 +233,5 @@ importPrim = addDefaultImport (ModuleName [ProperName C.prim])
232importPrelude :: Module -> Module
233importPrelude :: Module -> Module
233importPrelude = addDefaultImport (ModuleName [ProperName C.prelude])
234importPrelude = addDefaultImport (ModuleName [ProperName C.prelude])
234
235
235−preludeFilename :: IO FilePath
236+prelude :: String
236−preludeFilename = do
237+prelude = BU.toString $(embedFile "prelude/prelude.purs")
237− fs <- sequence [localPrelude, appPrelude, cabalPrelude]
238− es <- filterM doesFileExist fs
239− case es of
240− (x : _) -> return x
241− _ -> error "No Prelude found."
242− where
243− localPrelude :: IO FilePath
244− localPrelude = ((</> "prelude.purs") . takeDirectory) <$> getProgName
245−
246− appPrelude :: IO FilePath
247− appPrelude = do
248− appDir <- getAppUserDataDirectory "purescript"
249− return $ appDir </> "prelude" </> "prelude.purs"
250−
251− cabalPrelude :: IO FilePath
252− cabalPrelude = Paths.getDataFileName "prelude/prelude.purs"
src/Language/PureScript/Parser.hs+1−1
@@ -31,4 +31,4 @@ import Language.PureScript.Parser.Common as P
31import Language.PureScript.Parser.Types as P
31import Language.PureScript.Parser.Types as P
32import Language.PureScript.Parser.State as P
32import Language.PureScript.Parser.State as P
33import Language.PureScript.Parser.Kinds as P
33import Language.PureScript.Parser.Kinds as P
34−import Language.PureScript.Parser.Declarations as P
34+import Language.PureScript.Parser.Declarations as P
src/Language/PureScript/Parser/Declarations.hs+10
@@ -19,6 +19,7 @@ module Language.PureScript.Parser.Declarations (
19 parseDeclaration,
19 parseDeclaration,
20 parseModule,
20 parseModule,
21 parseModules,
21 parseModules,
22+ parseModulesFromFiles,
22 parseValue,
23 parseValue,
23 parseGuard,
24 parseGuard,
24 parseBinder,
25 parseBinder,
@@ -26,6 +27,7 @@ module Language.PureScript.Parser.Declarations (
26) where
27) where
27
28
28import Data.Maybe (isJust, fromMaybe)
29import Data.Maybe (isJust, fromMaybe)
30+import Data.Traversable (forM)
29
31
30import Control.Applicative
32import Control.Applicative
31import Control.Arrow ((+++))
33import Control.Arrow ((+++))
@@ -230,6 +232,14 @@ parseModule = do
230 decls <- mark (P.many (same *> parseDeclaration))
232 decls <- mark (P.many (same *> parseDeclaration))
231 return $ Module name decls exports
233 return $ Module name decls exports
232
234
235+parseModulesFromFiles :: [(FilePath, String)] -> Either P.ParseError [(FilePath, Module)]
236+parseModulesFromFiles input = fmap collect . forM input $ \(filename, content) -> do
237+ ms <- runIndentParser filename parseModules content
238+ return (filename, ms)
239+ where
240+ collect :: [(FilePath, [Module])] -> [(FilePath, Module)]
241+ collect xs = [ (fp, m) | (fp, ms) <- xs, m <- ms ]
242+
233-- |
243-- |
234-- Parse a collection of modules
244-- Parse a collection of modules
235--
245--
tests/Main.hs+14−9
@@ -22,6 +22,7 @@ import Data.List (isSuffixOf)
22import Data.Traversable (traverse)
22import Data.Traversable (traverse)
23import Control.Monad
23import Control.Monad
24import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
24import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
25+import Control.Applicative
25import System.Exit
26import System.Exit
26import System.Process
27import System.Process
27import System.FilePath (pathSeparator)
28import System.FilePath (pathSeparator)
@@ -29,18 +30,24 @@ import System.Directory (getCurrentDirectory, getTemporaryDirectory, getDirector
29import Text.Parsec (ParseError)
30import Text.Parsec (ParseError)
30import qualified System.IO.UTF8 as U
31import qualified System.IO.UTF8 as U
31
32
32−readInput :: [FilePath] -> IO (Either ParseError [P.Module])
33+readInput :: [FilePath] -> IO [(FilePath, String)]
33−readInput inputFiles = fmap (fmap concat . sequence) $ forM inputFiles $ \inputFile -> do
34+readInput inputFiles = forM inputFiles $ \inputFile -> do
34 text <- U.readFile inputFile
35 text <- U.readFile inputFile
35− return $ P.runIndentParser inputFile P.parseModules text
36+ return (inputFile, text)
37+
38+loadPrelude :: Either String (String, String, P.Environment)
39+loadPrelude =
40+ case P.parseModulesFromFiles [("<prelude>", P.prelude)] of
41+ Left parseError -> Left (show parseError)
42+ Right ms -> P.compile (P.defaultCompileOptions { P.optionsAdditional = P.CompileOptions "Tests" [] [] }) (map snd ms) []
36
43
37compile :: P.Options P.Compile -> [FilePath] -> IO (Either String (String, String, P.Environment))
44compile :: P.Options P.Compile -> [FilePath] -> IO (Either String (String, String, P.Environment))
38compile opts inputFiles = do
45compile opts inputFiles = do
39− modules <- readInput inputFiles
46+ modules <- P.parseModulesFromFiles <$> readInput inputFiles
40 case modules of
47 case modules of
41 Left parseError ->
48 Left parseError ->
42 return (Left $ show parseError)
49 return (Left $ show parseError)
43− Right ms -> return $ P.compile opts ms []
50+ Right ms -> return $ P.compile opts (map snd ms) []
44
51
45assert :: FilePath -> P.Options P.Compile -> FilePath -> (Either String (String, String, P.Environment) -> IO (Maybe String)) -> IO ()
52assert :: FilePath -> P.Options P.Compile -> FilePath -> (Either String (String, String, P.Environment) -> IO (Maybe String)) -> IO ()
46assert preludeExterns opts inputFile f = do
53assert preludeExterns opts inputFile f = do
@@ -79,10 +86,8 @@ findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
79
86
80main :: IO ()
87main :: IO ()
81main = do
88main = do
82− prelude <- P.preludeFilename
83− putStrLn "Compiling Prelude"
89+ putStrLn "Compiling Prelude"
84− preludeResult <- compile (P.defaultCompileOptions { P.optionsAdditional = P.CompileOptions "Tests" [] [] }) [prelude]
90+ case loadPrelude of
85− case preludeResult of
86 Left err -> putStrLn err >> exitFailure
91 Left err -> putStrLn err >> exitFailure
87 Right (preludeJs, exts, _) -> do
92 Right (preludeJs, exts, _) -> do
88 tmp <- getTemporaryDirectory
93 tmp <- getTemporaryDirectory