@@ -25,7 +25,7 @@ import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
2525import System.Exit
2626import System.Process
2727import System.FilePath (pathSeparator)
28−import System.Directory (getCurrentDirectory, getDirectoryContents, findExecutable)
28+import System.Directory (getCurrentDirectory, getTemporaryDirectory, getDirectoryContents, findExecutable)
2929import Text.Parsec (ParseError)
3030import qualified Paths_purescript as Paths
3131import qualified System.IO.UTF8 as U
@@ -38,62 +38,66 @@ readInput inputFiles = fmap (fmap concat . sequence) $ forM inputFiles $ \inputF
3838 text <- U.readFile inputFile
3939 return $ P.runIndentParser inputFile P.parseModules text
4040
41−compile :: P.Options -> [FilePath] -> IO (Either String String)
41+compile :: P.Options -> [FilePath] -> IO (Either String (String, String, P.Environment))
4242compile opts inputFiles = do
4343 modules <- readInput inputFiles
4444 case modules of
4545 Left parseError ->
4646 return (Left $ show parseError)
47− Right ms ->
48− case P.compile opts ms of
49− Left typeError ->
50− return (Left typeError)
51− Right (js, _, _) ->
52− return (Right js)
47+ Right ms -> return $ P.compile opts ms
5348
54−assert :: P.Options -> [FilePath] -> (Either String String -> IO (Maybe String)) -> IO ()
55−assert opts inputFiles f = do
56− e <- compile opts inputFiles
49+assert :: FilePath -> P.Options -> FilePath -> (Either String (String, String, P.Environment) -> IO (Maybe String)) -> IO ()
50+assert preludeExterns opts inputFile f = do
51+ e <- compile opts [preludeExterns, inputFile]
5752 maybeErr <- f e
5853 case maybeErr of
5954 Just err -> putStrLn err >> exitFailure
6055 Nothing -> return ()
6156
62−assertCompiles :: FilePath -> IO ()
63−assertCompiles inputFile = do
64− putStrLn $ "assert " ++ inputFile ++ " compiles successfully"
65− prelude <- preludeFilename
66− assert (P.defaultOptions { P.optionsMain = Just "Main", P.optionsModules = ["Main"] }) [prelude, inputFile] $ either (return . Just) $ \js -> do
57+assertCompiles :: FilePath -> FilePath -> FilePath -> IO ()
58+assertCompiles preludeJs preludeExterns inputFile = do
59+ putStrLn $ "Assert " ++ inputFile ++ " compiles successfully"
60+ let options = P.defaultOptions { P.optionsMain = Just "Main", P.optionsModules = ["Main"], P.optionsCodeGenModules = ["Main"] }
61+ assert preludeExterns options inputFile $ either (return . Just) $ \(js, _, _) -> do
6762 process <- findNodeProcess
68− result <- traverse (\node -> readProcessWithExitCode node [] js) process
63+ result <- traverse (\node -> readProcessWithExitCode node [] (preludeJs ++ js)) process
6964 case result of
7065 Just (ExitSuccess, out, _) -> putStrLn out >> return Nothing
7166 Just (ExitFailure _, _, err) -> return $ Just err
7267 Nothing -> return $ Just "Couldn't find node.js executable"
7368
74−findNodeProcess :: IO (Maybe String)
75−findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
76− where names = ["nodejs", "node"]
77−
78−assertDoesNotCompile :: FilePath -> IO ()
79−assertDoesNotCompile inputFile = do
80− putStrLn $ "assert " ++ inputFile ++ " does not compile"
81− assert P.defaultOptions [inputFile] $ \e ->
69+assertDoesNotCompile :: FilePath -> FilePath -> IO ()
70+assertDoesNotCompile preludeExterns inputFile = do
71+ putStrLn $ "Assert " ++ inputFile ++ " does not compile"
72+ assert preludeExterns P.defaultOptions inputFile $ \e ->
8273 case e of
8374 Left _ -> return Nothing
8475 Right _ -> return $ Just "Should not have compiled"
8576
77+findNodeProcess :: IO (Maybe String)
78+findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names
79+ where names = ["nodejs", "node"]
80+
8681main :: IO ()
8782main = do
88− cd <- getCurrentDirectory
89− putStrLn cd
90− let examples = cd ++ pathSeparator : "examples"
91− let passing = examples ++ pathSeparator : "passing"
92− passingTestCases <- getDirectoryContents passing
93− forM_ passingTestCases $ \inputFile -> when (".purs" `isSuffixOf` inputFile) $
94− assertCompiles (passing ++ pathSeparator : inputFile)
95− let failing = examples ++ pathSeparator : "failing"
96− failingTestCases <- getDirectoryContents failing
97− forM_ failingTestCases $ \inputFile -> when (".purs" `isSuffixOf` inputFile) $
98− assertDoesNotCompile (failing ++ pathSeparator : inputFile)
99− exitSuccess
83+ prelude <- preludeFilename
84+ putStrLn "Compiling Prelude"
85+ preludeResult <- compile P.defaultOptions [prelude]
86+ case preludeResult of
87+ Left err -> putStrLn err >> exitFailure
88+ Right (preludeJs, exts, _) -> do
89+ tmp <- getTemporaryDirectory
90+ let preludeExterns = tmp ++ pathSeparator : "prelude.externs"
91+ writeFile preludeExterns exts
92+ putStrLn $ "Wrote " ++ preludeExterns
93+ cd <- getCurrentDirectory
94+ let examples = cd ++ pathSeparator : "examples"
95+ let passing = examples ++ pathSeparator : "passing"
96+ passingTestCases <- getDirectoryContents passing
97+ forM_ passingTestCases $ \inputFile -> when (".purs" `isSuffixOf` inputFile) $
98+ assertCompiles preludeJs preludeExterns (passing ++ pathSeparator : inputFile)
99+ let failing = examples ++ pathSeparator : "failing"
100+ failingTestCases <- getDirectoryContents failing
101+ forM_ failingTestCases $ \inputFile -> when (".purs" `isSuffixOf` inputFile) $
102+ assertDoesNotCompile preludeExterns (failing ++ pathSeparator : inputFile)
103+ exitSuccess