packages feed

hpage-0.1.1: src/Language/Haskell/Interpreter/Server.hs

module Language.Haskell.Interpreter.Server (
    start, stop, runIn, asyncRunIn, flush, ServerHandle
    ) where

import Control.Concurrent.MVar
import Control.Monad.Error
import Control.Monad.Loops
import Control.Concurrent.Process
import Language.Haskell.Interpreter

newtype ServerHandle = SH {handle :: Handle (Either Stop (InterpreterT IO ()))}

data Stop = Stop

instance MonadInterpreter m => MonadInterpreter (ReceiverT r m) where
    fromSession = lift . fromSession
    modifySessionRef a = lift . (modifySessionRef a)
    runGhc = lift . runGhc 

start :: IO ServerHandle
start = (spawn $ makeProcess runInterpreter interpreter) >>= return . SH
    where interpreter =
            do
                setImports ["Prelude"]
                iterateWhile id $ do
                                    v <- recv
                                    case v of
                                        Left Stop ->
                                            return False
                                        Right acc ->
                                            lift acc >> return True

asyncRunIn :: ServerHandle -> InterpreterT IO a -> IO (MVar (Either InterpreterError a))
asyncRunIn server action = do
                                resVar <- liftIO newEmptyMVar
                                sendTo (handle server) $ Right $ try action >>= liftIO . putMVar resVar
                                return resVar

runIn :: ServerHandle -> InterpreterT IO a -> IO (Either InterpreterError a)
runIn server action = runHere $ do
                                    me <- self
                                    sendTo (handle server) $ Right $ try action >>= sendTo me
                                    recv

flush :: ServerHandle -> IO (Either InterpreterError ())
flush server = runIn server $ return ()

try :: InterpreterT IO b -> InterpreterT IO (Either InterpreterError b)
try a = (a >>= return . Right) `catchError` (return . Left)

stop :: ServerHandle -> IO ()
stop server = sendTo (handle server) $ Left Stop