-- TODO: suggest the convenience functions be put into Hint proper?
module Mueval.Interpreter (interpreterSession, printInterpreterError, ModuleName) where

import Language.Haskell.Interpreter.GHC (eval, newSession, reset, setImports,
                                         setUseLanguageExtensions, typeChecks,
                                         typeOf, withSession,
                                         Interpreter, InterpreterError, ModuleName)

import Control.Monad.Trans (liftIO)
import System.Exit (exitWith, ExitCode(ExitFailure))

say :: String -> Interpreter ()
say = liftIO . putStr . take 1024

printInterpreterError :: InterpreterError -> IO ()
printInterpreterError e = do putStrLn $ take 1024 $ "Oops... " ++ (show e)
                             (exitWith $ ExitFailure 1)

interpreter :: [ModuleName] -> String -> Interpreter ()
interpreter modules expr = do setUseLanguageExtensions False -- Don't trust the extensions
                              reset -- Make sure nothing is available
                              setImports modules
                              checks <- typeChecks expr
                              if checks then do
                                          say "Expression type: "
                                          say =<< typeOf expr
                                          result <- eval expr
                                          say $ "\nresult: " ++ show result ++ "\n"
                               else error "Expression does not type check."

interpreterSession :: [ModuleName] -> String -> IO ()
interpreterSession mds expr = newSession >>= (flip withSession) (interpreter mds expr)