git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Cleanup.
commitfc75da083643c390212688c1fe8a0fea23f13736 authorjoneshf <jones3.hardy@gmail.com> dateThu 20 Feb 2014, 20:54 (13 years ago) parent63c67fd
1 file changed+51−24
psci/Main.hs+51−24
psci/Main.hs+51−24
@@ -13,7 +13,7 @@
1313--
1414-----------------------------------------------------------------------------
1515
16−{-# LANGUAGE FlexibleContexts #-}
16+{-# LANGUAGE DoAndIfThenElse, FlexibleContexts #-}
1717
1818module Main where
1919
@@ -30,7 +30,7 @@ import Data.Maybe (mapMaybe)
3030import Data.Traversable (traverse)
3131
3232import System.Console.Haskeline
33−import System.Directory (findExecutable)
33+import System.Directory (doesFileExist, findExecutable)
3434import System.Exit
3535import System.Environment.XDG.BaseDir
3636import System.Process
@@ -38,7 +38,7 @@ import System.Process
3838import qualified Language.PureScript as P
3939import qualified Paths_purescript as Paths
4040import qualified System.IO.UTF8 as U (readFile)
41−import qualified Text.Parsec as Parsec (Parsec, eof)
41+import qualified Text.Parsec as Parsec (Parsec, ParseError, eof)
4242
4343-- |
4444-- The PSCI state.
@@ -113,9 +113,7 @@ getPreludeFilename = Paths.getDataFileName "prelude/prelude.purs"
113113-- Loads a file for use with imports.
114114--
115115loadModule :: FilePath -> IO (Either String [P.Module])
116−loadModule moduleFile = do
117− moduleText <- U.readFile moduleFile
118− return . either (Left . show) Right $ P.runIndentParser "" P.parseModules moduleText
116+loadModule = fmap (either (Left . show) Right . parseModules) . U.readFile
119117
120118-- Messages
121119
@@ -212,46 +210,75 @@ handleDeclaration value (PSCI imports loadedModules lets) = do
212210
213211-- Parser helpers
214212
213+-- |
214+-- PSCI version of the indent parser.
215+-- This really does nothing except provide a shorter alias.
216+--
217+parser :: Parsec.Parsec String P.ParseState a -> String -> Either Parsec.ParseError a
218+parser = P.runIndentParser ""
219+
220+-- |
221+-- Parser for any other valid expression.
222+--
223+parseExpression :: String -> Either Parsec.ParseError P.Value
224+parseExpression = parser (P.whiteSpace *> P.parseValue <* Parsec.eof)
225+
215226-- |
216227-- Parser for our PSCI version of @let@.
217228-- This is essentially let from do-notation.
218229-- However, since we don't support the @Eff@ monad, we actually want the normal @let@.
219230--
220−parseLet :: Parsec.Parsec String P.ParseState (P.Value -> P.Value)
221−parseLet = P.Let <$> (P.reserved "let" *> P.indented *> P.parseBinder)
222− <*> (P.indented *> P.reservedOp "=" *> P.parseValue)
231+parseLet :: String -> Either Parsec.ParseError (P.Value -> P.Value)
232+parseLet = parser $
233+ P.Let <$> (P.reserved "let" *> P.indented *> P.parseBinder)
234+ <*> (P.indented *> P.reservedOp "=" *> P.parseValue)
223235
224236-- |
225−-- Parser for any other valid expression.
237+-- Parser for PSCI modules.
226238--
227−parseExpression :: Parsec.Parsec String P.ParseState P.Value
228−parseExpression = P.whiteSpace *> P.parseValue <* Parsec.eof
239+parseModules :: String -> Either Parsec.ParseError [P.Module]
240+parseModules = parser P.parseModules
229241
230242-- Commands
231243
232244-- |
233−-- Performs an action for each meta-command given, and also for expressions..
245+-- Performs an action for each meta-command given, and also for expressions.
234246--
235247handleCommand :: Command -> StateT PSCI (InputT IO) ()
236248handleCommand Empty = return ()
237249handleCommand (Expression ls) =
238− case P.runIndentParser "" parseLet (unlines ls) of
250+ let expr = unlines ls
251+ in case parseLet expr of
239252 Left _ ->
240− case P.runIndentParser "" parseExpression (unlines ls) of
241− Left err -> inputTToState $ outputStrLn (show err)
242− Right decl -> get >>= inputTToState . handleDeclaration decl
253+ either outprintT (\decl -> get >>= inputTToState . handleDeclaration decl)
254+ (parseExpression expr)
243255 Right l -> modify (updateLets l)
244−handleCommand Help = inputTToState $ outputStrLn helpMessage
256+handleCommand Help = outputTStrLn helpMessage
245257handleCommand (Import moduleName) = modify (updateImports moduleName)
246258handleCommand (LoadFile filePath) = do
247− mf <- ioToState $ loadModule filePath
248− case mf of
249− Left err -> inputTToState $ outputStrLn err
250− Right mf' -> modify (updateModules mf')
259+ exists <- ioToState $ doesFileExist filePath
260+ if exists then
261+ ioToState (loadModule filePath) >>= either outputTStrLn (modify . updateModules)
262+ else
263+ outputTStrLn $ "Couldn't locate: " ++ filePath
251264handleCommand Reload = do
252265 (Right prelude) <- ioToState $ getPreludeFilename >>= loadModule
253266 put (PSCI defaultImports prelude [])
254−handleCommand Unknown = inputTToState $ outputStrLn "Unknown command"
267+handleCommand Unknown = outputTStrLn "Unknown command"
268+
269+-- Command helpers
270+
271+-- |
272+-- Lifts the output call to the StateT.
273+--
274+outputTStrLn :: String -> StateT PSCI (InputT IO) ()
275+outputTStrLn = inputTToState . outputStrLn
276+
277+-- |
278+-- The corresponding @print@ version for the StateT.
279+--
280+outprintT :: Show a => a -> StateT PSCI (InputT IO) ()
281+outprintT = outputTStrLn . show
255282
256283-- |
257284-- The PSCI main loop.
@@ -270,5 +297,5 @@ main = do
270297 go = do
271298 c <- inputTToState getCommand
272299 case c of
273− Quit -> inputTToState $ outputStrLn quitMessage
300+ Quit -> outputTStrLn quitMessage
274301 _ -> handleCommand c >> go