@@ -17,45 +17,40 @@
1717
1818module Main where
1919
20−import Commands
20+import Data.Foldable (traverse_)
21+import Data.List (intercalate, isPrefixOf, nub, sortBy, sort)
22+import Data.Maybe (mapMaybe)
23+import Data.Traversable (traverse)
24+import Data.Version (showVersion)
25+import qualified Data.Map as M
2126
2227import Control.Applicative
2328import Control.Monad
29+import Control.Monad.Error (ErrorT(..), MonadError)
30+import Control.Monad.Error.Class (MonadError(..))
2431import Control.Monad.Trans.Class
2532import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
2633import Control.Monad.Trans.State.Strict
2734import qualified Control.Monad.Trans.State.Lazy as L
28−import Control.Monad.Error (ErrorT(..), MonadError)
29−import Control.Monad.Error.Class (MonadError(..))
30−
31−import Data.List (intercalate, isPrefixOf, nub, sortBy, sort)
32−import Data.Maybe (mapMaybe)
33−import Data.Foldable (traverse_)
34−import Data.Version (showVersion)
35−import Data.Traversable (traverse)
36−
37−import Parser
3835
39−import System.IO.Error (tryIOError)
4036import System.Console.Haskeline
41−import System.Directory
42− (createDirectoryIfMissing, getModificationTime, doesFileExist,
43− findExecutable, getHomeDirectory, getCurrentDirectory)
44−import System.Process (readProcessWithExitCode)
37+import System.Directory (createDirectoryIfMissing, getModificationTime, doesFileExist, findExecutable, getHomeDirectory, getCurrentDirectory)
4538import System.Exit
46−import System.FilePath
47− (pathSeparator, takeDirectory, (</>), isPathSeparator)
39+import System.FilePath (pathSeparator, takeDirectory, (</>), isPathSeparator)
40+import System.IO.Error (tryIOError)
41+import System.Process (readProcessWithExitCode)
4842import qualified System.Console.CmdTheLine as Cmd
43+import qualified System.IO.UTF8 as U (writeFile, putStrLn, print, readFile)
4944
5045import Text.Parsec (ParseError)
5146
52−import qualified Data.Map as M
5347import qualified Language.PureScript as P
54−import qualified Paths_purescript as Paths
55−import qualified System.IO.UTF8 as U
56− (writeFile, putStrLn, print, readFile)
57−import qualified Language.PureScript.Names as N
5848import qualified Language.PureScript.Declarations as D
49+import qualified Language.PureScript.Names as N
50+import qualified Paths_purescript as Paths
51+
52+import Commands
53+import Parser
5954
6055-- |
6156-- The PSCI state.
@@ -132,7 +127,7 @@ loadModule filename = either (Left . show) Right . P.runIndentParser filename P.
132127--
133128loadAllModules :: [FilePath] -> IO (Either ParseError [(Either P.RebuildPolicy FilePath, P.Module)])
134129loadAllModules files = do
135− filesAndContent <- forM files $ \filename -> do
130+ filesAndContent <- forM files $ \filename -> do
136131 content <- U.readFile filename
137132 return (Right filename, content)
138133 return $ P.parseModulesFromFiles (either (const "") id) $ (Left P.RebuildNever, P.prelude) : filesAndContent
@@ -236,9 +231,9 @@ makeIO = Make . ErrorT . fmap (either (Left . show) Right) . tryIOError
236231instance P.MonadMake Make where
237232 getTimestamp path = makeIO $ do
238233 exists <- doesFileExist path
239− case exists of
240− True -> Just <$> getModificationTime path
241− False -> return Nothing
234+ if exists
235+ then Just <$> getModificationTime path
236+ else return Nothing
242237 readTextFile path = makeIO $ U.readFile path
243238 writeTextFile path text = makeIO $ do
244239 mkdirp path
@@ -307,7 +302,7 @@ handleDeclaration value = do
307302 case e of
308303 Left err -> PSCI $ outputStrLn err
309304 Right _ -> do
310− psciIO $ writeFile indexFile $ "require('$PSCI').main();"
305+ psciIO $ writeFile indexFile "require('$PSCI').main();"
311306 process <- psciIO findNodeProcess
312307 result <- psciIO $ traverse (\node -> readProcessWithExitCode node [indexFile] "") process
313308 case result of
@@ -315,6 +310,20 @@ handleDeclaration value = do
315310 Just (ExitFailure _, _, err) -> PSCI $ outputStrLn err
316311 Nothing -> PSCI $ outputStrLn "Couldn't find node.js"
317312
313+-- |
314+-- Takes a let declaration and updates the environment, then run a make. If the declaration fails,
315+-- restore the pre-let environment.
316+--
317+handleLet :: (P.Expr -> P.Expr) -> PSCI ()
318+handleLet l = do
319+ st <- PSCI $ lift get
320+ let st' = updateLets l st
321+ let m = createTemporaryModule False st' (P.ObjectLiteral [])
322+ e <- psciIO . runMake $ P.make modulesDir options (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
323+ case e of
324+ Left err -> PSCI $ outputStrLn err
325+ Right _ -> PSCI $ lift (put st')
326+
318327-- |
319328-- Show actual loaded modules in psci.
320329--
@@ -444,7 +453,7 @@ handleCommand :: Command -> PSCI ()
444453handleCommand (Expression val) = handleDeclaration val
445454handleCommand Help = PSCI $ outputStrLn helpMessage
446455handleCommand (Import moduleName) = handleImport moduleName
447−handleCommand (Let l) = PSCI $ lift $ modify (updateLets l)
456+handleCommand (Let l) = handleLet l
448457handleCommand (LoadFile filePath) = do
449458 absPath <- psciIO $ expandTilde filePath
450459 exists <- psciIO $ doesFileExist absPath
@@ -460,7 +469,7 @@ handleCommand Reset = do
460469 files <- psciImportedFilenames <$> PSCI (lift get)
461470 modulesOrFirstError <- psciIO $ loadAllModules files
462471 case modulesOrFirstError of
463− Left err -> psciIO $ putStrLn (show err) >> exitFailure
472+ Left err -> psciIO $ print err >> exitFailure
464473 Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules [])
465474handleCommand (TypeOf val) = handleTypeOf val
466475handleCommand (KindOf typ) = handleKindOf typ
@@ -501,7 +510,7 @@ loop singleLineMode files = do
501510 config <- loadUserConfig
502511 modulesOrFirstError <- loadAllModules files
503512 case modulesOrFirstError of
504− Left err -> putStrLn (show err) >> exitFailure
513+ Left err -> print err >> exitFailure
505514 Right modules -> do
506515 historyFilename <- getHistoryFilename
507516 let settings = defaultSettings { historyFile = Just historyFilename }