@@ -29,6 +29,8 @@ import qualified Data.Map as M
2929
3030import Control.Applicative
3131import Control.Monad
32+import Control.Monad.IO.Class (MonadIO, liftIO)
33+import Control.Monad.Error.Class (throwError)
3234import Control.Monad.Except (ExceptT(..), MonadError, runExceptT)
3335import Control.Monad.Reader (MonadReader, ReaderT, runReaderT)
3436import Control.Monad.Trans.Class
@@ -180,24 +182,26 @@ newtype PSCI a = PSCI { runPSCI :: InputT (StateT PSCiState IO) a } deriving (Fu
180182psciIO :: IO a -> PSCI a
181183psciIO io = PSCI . lift $ lift io
182184
183−newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ExceptT String IO) a }
184− deriving (Functor, Applicative, Monad, MonadError String, MonadReader (P.Options P.Make))
185+newtype Make a = Make { unMake :: ReaderT (P.Options P.Make) (ExceptT P.MultipleErrors IO) a }
186+ deriving (Functor, Applicative, Monad, MonadIO, MonadError P.MultipleErrors, MonadReader (P.Options P.Make))
185187
186−runMake :: Make a -> IO (Either String a)
188+runMake :: Make a -> IO (Either P.MultipleErrors a)
187189runMake = runExceptT . flip runReaderT options . unMake
188190
189−makeIO :: IO a -> Make a
190−makeIO = Make . lift . ExceptT . fmap (either (Left . show) Right) . tryIOError
191+makeIO :: (IOError -> P.ErrorMessage) -> IO a -> Make a
192+makeIO f io = do
193+ e <- liftIO $ tryIOError io
194+ either (throwError . P.errorMessage . f) return e
191195
192196instance P.MonadMake Make where
193− getTimestamp path = makeIO $ do
197+ getTimestamp path = makeIO (const (P.CannotGetFileInfo path)) $ do
194198 exists <- doesFileExist path
195199 traverse (const $ getModificationTime path) $ guard exists
196− readTextFile path = makeIO $ readFile path
197− writeTextFile path text = makeIO $ do
200+ readTextFile path = makeIO (const (P.CannotReadFile path)) $ readFile path
201+ writeTextFile path text = makeIO (const (P.CannotWriteFile path)) $ do
198202 mkdirp path
199203 writeFile path text
200− progress s = unless (s == "Compiling $PSCI") $ makeIO . putStrLn $ s
204+ progress s = unless (s == "Compiling $PSCI") $ liftIO . putStrLn $ s
201205
202206mkdirp :: FilePath -> IO ()
203207mkdirp = createDirectoryIfMissing True . takeDirectory
@@ -259,7 +263,7 @@ handleDeclaration val = do
259263 let nodeArgs = psciNodeFlags st ++ [indexFile]
260264 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
261265 case e of
262− Left err -> PSCI $ outputStrLn err
266+ Left errs -> printErrors errs
263267 Right _ -> do
264268 psciIO $ writeFile indexFile "require('$PSCI').main();"
265269 process <- psciIO findNodeProcess
@@ -280,7 +284,7 @@ handleDecls ds = do
280284 let m = createTemporaryModule False st' (P.ObjectLiteral [])
281285 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st' ++ [(Left P.RebuildAlways, m)]) []
282286 case e of
283− Left err -> PSCI $ outputStrLn err
287+ Left err -> printErrors err
284288 Right _ -> PSCI $ lift (put st')
285289
286290-- |
@@ -333,7 +337,7 @@ handleImport im = do
333337 let m = createTemporaryModuleForImports st
334338 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
335339 case e of
336− Left err -> PSCI $ outputStrLn err
340+ Left errs -> printErrors errs
337341 Right _ -> do
338342 PSCI $ lift $ put st
339343 return ()
@@ -347,7 +351,7 @@ handleTypeOf val = do
347351 let m = createTemporaryModule False st val
348352 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
349353 case e of
350− Left err -> PSCI $ outputStrLn err
354+ Left errs -> printErrors errs
351355 Right env' ->
352356 case M.lookup (P.ModuleName [P.ProperName "$PSCI"], P.Ident "it") (P.names env') of
353357 Just (ty, _, _) -> PSCI . outputStrLn . P.prettyPrintType $ ty
@@ -381,12 +385,16 @@ handleBrowse moduleName = do
381385 let loadedModules = psciLoadedModules st
382386 env <- psciIO . runMake $ P.make modulesDir loadedModules []
383387 case env of
384− Left err -> PSCI $ outputStrLn err
388+ Left errs -> printErrors errs
385389 Right env' ->
386390 if moduleName `notElem` (nub . map ((\ (P.Module _ modName _ _ ) -> modName) . snd)) loadedModules
387391 then PSCI $ outputStrLn $ "Module '" ++ N.runModuleName moduleName ++ "' is not valid."
388392 else printModuleSignatures moduleName env'
389393
394+-- | Pretty-print errors
395+printErrors :: P.MultipleErrors -> PSCI ()
396+printErrors = PSCI . outputStrLn . P.prettyPrintMultipleErrors False
397+
390398-- |
391399-- Takes a value and prints its kind
392400--
@@ -397,7 +405,7 @@ handleKindOf typ = do
397405 mName = P.ModuleName [P.ProperName "$PSCI"]
398406 e <- psciIO . runMake $ P.make modulesDir (psciLoadedModules st ++ [(Left P.RebuildAlways, m)]) []
399407 case e of
400− Left err -> PSCI $ outputStrLn err
408+ Left errs -> printErrors errs
401409 Right env' ->
402410 case M.lookup (P.Qualified (Just mName) $ P.ProperName "IT") (P.typeSynonyms env') of
403411 Just (_, typ') -> do