module Mueval.Interpreter where
import Control.Monad.Trans (liftIO)
import qualified Control.Exception (catch)
import Language.Haskell.Interpreter.GHC (eval, newSession, reset, setImports,
setOptimizations, setUseLanguageExtensions, setInstalledModsAreInScopeQualified,
typeChecks, typeOf, withSession,
Interpreter, InterpreterError, ModuleName, Optimizations(All))
import qualified Codec.Binary.UTF8.String as Codec (decodeString)
import qualified System.IO.UTF8 as UTF (putStr)
import qualified Mueval.Resources (limitResources)
say :: String -> Interpreter ()
say = liftIO . UTF.putStr . Codec.decodeString . take 1024
printInterpreterError :: InterpreterError -> IO ()
printInterpreterError = error . take 1024 . ("Oops... " ++) . show
interpreter :: Bool -> Bool -> [ModuleName] -> String -> Interpreter ()
interpreter prt exts modules expr = do
setUseLanguageExtensions exts
setOptimizations All
reset
setInstalledModsAreInScopeQualified False
setImports modules
if prt then say $ expr ++ "\n" else return ()
liftIO Mueval.Resources.limitResources
checks <- typeChecks expr
if checks then do
if prt then do say =<< typeOf expr
say "\n"
else return ()
result <- eval expr
say $ show result ++ "\n"
else error "Expression did not type check."
interpreterSession :: Bool
-> Bool
-> [ModuleName]
-> String
-> IO ()
interpreterSession prt exts mds expr = Control.Exception.catch
(newSession >>= (flip withSession) (interpreter prt exts mds expr))
(\_ -> error "Expression did not compile.")