content: {-# LANGUAGE CPP #-}
  module Interpreter (
    Interpreter
  , new
  , terminate
  , start
  , stop
  , reload
  ) where
  
  import           System.Process
  import           System.Process.Internals
  import           System.IO
  import           System.Posix.Signals hiding (signalProcess)
  import qualified System.Posix.Signals as Posix
  import           Control.Concurrent
  
  data Interpreter = Interpreter ProcessHandle Handle
  
  new :: FilePath -> IO Interpreter
  new src = do
    (Just hIn, Nothing, Nothing, processHandle) <- createProcess $ (proc "ghci" ["-v0", src]) {std_in = CreatePipe}
    return (Interpreter processHandle hIn)
  
  terminate :: Interpreter -> IO ()
  terminate i@(Interpreter p h) = stop i >> hClose h >> waitForProcess p >> return ()
  
  start :: Interpreter -> [String] -> IO ()
  start (Interpreter _ h) args = hPutStrLn h (unwords $ ":main" : args) >> hFlush h
  
  stop :: Interpreter -> IO ()
  stop (Interpreter p _) = signalProcess sigINT p
  
  reload :: Interpreter -> IO ()
  reload (Interpreter _ h) = hPutStrLn h ":reload" >> hFlush h
  
  signalProcess :: Signal -> ProcessHandle -> IO ()
  #if MIN_VERSION_process(1,6,0)
  signalProcess signal (ProcessHandle mvar _ _) =
  #elif MIN_VERSION_process(1,2,0)
  signalProcess signal (ProcessHandle mvar _) =
  #else
  signalProcess signal (ProcessHandle mvar) =
  #endif
    withMVar mvar $ \p -> case p of
      OpenHandle pid -> Posix.signalProcess signal pid
      _ -> return ()
  