git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #707 from purescript/psci-let
15f6df4Phil Freeman
psci/Main.hs+40−31
@@ -17,45 +17,40 @@
17
17
18module Main where
18module Main where
19
19
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
21
26
22import Control.Applicative
27import Control.Applicative
23import Control.Monad
28import Control.Monad
29+import Control.Monad.Error (ErrorT(..), MonadError)
30+import Control.Monad.Error.Class (MonadError(..))
24import Control.Monad.Trans.Class
31import Control.Monad.Trans.Class
25import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
32import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT)
26import Control.Monad.Trans.State.Strict
33import Control.Monad.Trans.State.Strict
27import qualified Control.Monad.Trans.State.Lazy as L
34import 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
38
35
39−import System.IO.Error (tryIOError)
40import System.Console.Haskeline
36import System.Console.Haskeline
41−import System.Directory
42− (createDirectoryIfMissing, getModificationTime, doesFileExist,
37+import System.Directory (createDirectoryIfMissing, getModificationTime, doesFileExist, findExecutable, getHomeDirectory, getCurrentDirectory)
43− findExecutable, getHomeDirectory, getCurrentDirectory)
44−import System.Process (readProcessWithExitCode)
45import System.Exit
38import 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)
48import qualified System.Console.CmdTheLine as Cmd
42import qualified System.Console.CmdTheLine as Cmd
43+import qualified System.IO.UTF8 as U (writeFile, putStrLn, print, readFile)
49
44
50import Text.Parsec (ParseError)
45import Text.Parsec (ParseError)
51
46
52−import qualified Data.Map as M
53import qualified Language.PureScript as P
47import 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
58import qualified Language.PureScript.Declarations as D
48import 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
59
54
60-- |
55-- |
61-- The PSCI state.
56-- The PSCI state.
@@ -132,7 +127,7 @@ loadModule filename = either (Left . show) Right . P.runIndentParser filename P.
132--
127--
133loadAllModules :: [FilePath] -> IO (Either ParseError [(Either P.RebuildPolicy FilePath, P.Module)])
128loadAllModules :: [FilePath] -> IO (Either ParseError [(Either P.RebuildPolicy FilePath, P.Module)])
134loadAllModules files = do
129loadAllModules files = do
135− filesAndContent <- forM files $ \filename -> do
130+ filesAndContent <- forM files $ \filename -> do
136 content <- U.readFile filename
131 content <- U.readFile filename
137 return (Right filename, content)
132 return (Right filename, content)
138 return $ P.parseModulesFromFiles (either (const "") id) $ (Left P.RebuildNever, P.prelude) : filesAndContent
133 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
236instance P.MonadMake Make where
231instance P.MonadMake Make where
237 getTimestamp path = makeIO $ do
232 getTimestamp path = makeIO $ do
238 exists <- doesFileExist path
233 exists <- doesFileExist path
239− case exists of
234+ if exists
240− True -> Just <$> getModificationTime path
235+ then Just <$> getModificationTime path
241− False -> return Nothing
236+ else return Nothing
242 readTextFile path = makeIO $ U.readFile path
237 readTextFile path = makeIO $ U.readFile path
243 writeTextFile path text = makeIO $ do
238 writeTextFile path text = makeIO $ do
244 mkdirp path
239 mkdirp path
@@ -307,7 +302,7 @@ handleDeclaration value = do
307 case e of
302 case e of
308 Left err -> PSCI $ outputStrLn err
303 Left err -> PSCI $ outputStrLn err
309 Right _ -> do
304 Right _ -> do
310− psciIO $ writeFile indexFile $ "require('$PSCI').main();"
305+ psciIO $ writeFile indexFile "require('$PSCI').main();"
311 process <- psciIO findNodeProcess
306 process <- psciIO findNodeProcess
312 result <- psciIO $ traverse (\node -> readProcessWithExitCode node [indexFile] "") process
307 result <- psciIO $ traverse (\node -> readProcessWithExitCode node [indexFile] "") process
313 case result of
308 case result of
@@ -315,6 +310,20 @@ handleDeclaration value = do
315 Just (ExitFailure _, _, err) -> PSCI $ outputStrLn err
310 Just (ExitFailure _, _, err) -> PSCI $ outputStrLn err
316 Nothing -> PSCI $ outputStrLn "Couldn't find node.js"
311 Nothing -> PSCI $ outputStrLn "Couldn't find node.js"
317
312
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+
318-- |
327-- |
319-- Show actual loaded modules in psci.
328-- Show actual loaded modules in psci.
320--
329--
@@ -444,7 +453,7 @@ handleCommand :: Command -> PSCI ()
444handleCommand (Expression val) = handleDeclaration val
453handleCommand (Expression val) = handleDeclaration val
445handleCommand Help = PSCI $ outputStrLn helpMessage
454handleCommand Help = PSCI $ outputStrLn helpMessage
446handleCommand (Import moduleName) = handleImport moduleName
455handleCommand (Import moduleName) = handleImport moduleName
447−handleCommand (Let l) = PSCI $ lift $ modify (updateLets l)
456+handleCommand (Let l) = handleLet l
448handleCommand (LoadFile filePath) = do
457handleCommand (LoadFile filePath) = do
449 absPath <- psciIO $ expandTilde filePath
458 absPath <- psciIO $ expandTilde filePath
450 exists <- psciIO $ doesFileExist absPath
459 exists <- psciIO $ doesFileExist absPath
@@ -460,7 +469,7 @@ handleCommand Reset = do
460 files <- psciImportedFilenames <$> PSCI (lift get)
469 files <- psciImportedFilenames <$> PSCI (lift get)
461 modulesOrFirstError <- psciIO $ loadAllModules files
470 modulesOrFirstError <- psciIO $ loadAllModules files
462 case modulesOrFirstError of
471 case modulesOrFirstError of
463− Left err -> psciIO $ putStrLn (show err) >> exitFailure
472+ Left err -> psciIO $ print err >> exitFailure
464 Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules [])
473 Right modules -> PSCI . lift $ put (PSCiState files defaultImports modules [])
465handleCommand (TypeOf val) = handleTypeOf val
474handleCommand (TypeOf val) = handleTypeOf val
466handleCommand (KindOf typ) = handleKindOf typ
475handleCommand (KindOf typ) = handleKindOf typ
@@ -501,7 +510,7 @@ loop singleLineMode files = do
501 config <- loadUserConfig
510 config <- loadUserConfig
502 modulesOrFirstError <- loadAllModules files
511 modulesOrFirstError <- loadAllModules files
503 case modulesOrFirstError of
512 case modulesOrFirstError of
504− Left err -> putStrLn (show err) >> exitFailure
513+ Left err -> print err >> exitFailure
505 Right modules -> do
514 Right modules -> do
506 historyFilename <- getHistoryFilename
515 historyFilename <- getHistoryFilename
507 let settings = defaultSettings { historyFile = Just historyFilename }
516 let settings = defaultSettings { historyFile = Just historyFilename }
src/Language/PureScript/Constants.hs+3
@@ -153,6 +153,9 @@ mkFn = "mkFn"
153runFn :: String
153runFn :: String
154runFn = "runFn"
154runFn = "runFn"
155
155
156+unit :: String
157+unit = "unit"
158+
156-- Prim values
159-- Prim values
157
160
158undefined :: String
161undefined :: String