berp-0.0.1: src/Berp/Interpreter/Monad.hs
-----------------------------------------------------------------------------
-- |
-- Module : Berp.Interpreter.Monad
-- Copyright : (c) 2010 Bernie Pope
-- License : BSD-style
-- Maintainer : florbitous@gmail.com
-- Stability : experimental
-- Portability : ghc
--
-- Monad type and routines for the interpreter.
--
-----------------------------------------------------------------------------
module Berp.Interpreter.Monad (Repl, runRepl, withInputState) where
import Exception (ExceptionMonad (..))
import qualified MonadUtils as MU (MonadIO, liftIO)
import Control.Monad.Trans as MT (MonadIO (..))
import Control.Monad.State.Strict (StateT (..), evalStateT, gets, mapStateT)
import GHC (GhcT, runGhcT)
import HscTypes (liftGhcT)
import System.Console.Haskeline as Haskeline (defaultSettings)
import System.Console.Haskeline.IO (initializeInput, InputState)
import Berp.Compile.Monad (Compile, runCompileMonad)
type Repl a = GhcT (StateT ReplState Compile) a
data ReplState = ReplState { repl_inputState :: !InputState }
runRepl :: Maybe FilePath -> Repl a -> IO a
runRepl filePath comp = do
initInputState <- initializeInput defaultSettings
let initReplState = ReplState { repl_inputState = initInputState }
runCompileMonad $ (flip evalStateT) initReplState $ runGhcT filePath comp
withInputState :: (InputState -> Repl a) -> Repl a
withInputState f = do
state <- liftGhcT $ gets repl_inputState
f state
-- Ugliness because GHC has its own MonadIO class
instance MU.MonadIO m => MonadIO (GhcT m) where
liftIO = MU.liftIO
instance MonadIO m => MU.MonadIO (StateT s m) where
liftIO = MT.liftIO
instance ExceptionMonad m => ExceptionMonad (StateT s m) where
gcatch f h = StateT $ \s -> gcatch (runStateT f s) (\e -> runStateT (h e) s)
gblock = mapStateT gblock
gunblock = mapStateT gunblock