module UHC.Light.Compiler.CoreRun.Run
( module Control.Monad.RWS.Strict, module Control.Monad, module UHC.Util.Error
, RunRd (..), emptyRunRd
, RunSt (..), emptyRunSt
, RunSem (..)
, rsemTopUpd
, RunT', RunT
, err
, runCoreRun, runCoreRun2
, modifyIORefM )
where
import UHC.Light.Compiler.Base.HsName.Builtin
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.Opts
import UHC.Light.Compiler.Ty
import UHC.Light.Compiler.Error
import UHC.Light.Compiler.Gam
import UHC.Light.Compiler.Gam.DataGam
import UHC.Light.Compiler.Base.Trace
import UHC.Light.Compiler.CoreRun as CR
import UHC.Light.Compiler.CoreRun.Prim
import qualified UHC.Util.FastSeq as Seq
import qualified Data.Map as Map
import qualified Data.Set as Set
import UHC.Util.Pretty
import Data.Maybe
import Data.Monoid
import Data.IORef
import System.IO
import Control.Exception
import Control.Monad
import UHC.Util.Error
import Control.Monad.RWS.Strict
data RunRd
= RunRd
emptyRunRd
= RunRd
data RunSt
= RunSt
emptyRunSt
= RunSt
class (Monad m, MonadIO m, Functor m) => RunSem r s v m a
| r s -> v a
where
rsemInitial :: m (r,s,a)
rsemSetup :: EHCOpts -> [Mod] -> Mod -> RunT' r s v m r
rsemSetupTracing :: EHCOpts -> RunT' r s v m ()
rsemSetupTracing opts = do
let dotr = CoreOpt_RunTrace `elem` ehcOptCoreOpts opts
dotre = CoreOpt_RunTraceExtensive `elem` ehcOptCoreOpts opts
rsemSetTrace (dotre || dotr) dotre
rsemSetTrace :: Bool -> Bool -> RunT' r s v m ()
rsemSetTrace _ _ = return ()
rsemTraceOnS :: RunT' r s v m (Set.Set TraceOn)
rsemTraceOnS = return Set.empty
rsemExp :: Exp -> RunT' r s v m a
rsemSExp :: SExp -> RunT' r s v m a
rsemAlt :: CR.Alt -> RunT' r s v m a
rsemAlt a = do
case a of
Alt_Alt {expr_Alt_Alt=e} -> rsemExp e
rsemEvl :: v -> RunT' r s v m a
rsemDeref :: v -> RunT' r s v m a
rsemPrim :: RunPrim -> CRArray v -> RunT' r s v m a
rsemPush :: v -> RunT' r s v m a
rsemPop :: a -> RunT' r s v m v
rsemNode :: Int -> CRMArray v -> RunT' r s v m v
rsemGcEnterRootLevel :: RunT' r s v m ()
rsemGcEnterRootLevel = return ()
rsemGcPushRoot :: v -> RunT' r s v m ()
rsemGcPushRoot _ = return ()
rsemGcLeaveRootLevel :: RunT' r s v m ()
rsemGcLeaveRootLevel = return ()
rsemTopUpd :: RunSem r s v m a => (v -> v) -> a -> RunT' r s v m a
rsemTopUpd upd x = rsemPop x >>= (rsemPush . upd)
type RunT' r s v m a = ErrorT Err (RWST r () s m) a
type RunT v m a = RunT' RunRd RunSt v m a
err :: (RunSem r s v m a, PP msg) => msg -> RunT' r s v m b
err msg = throwError $ rngLift emptyRange Err_PP $ pp msg
runCoreRun
:: forall r s v m a .
(RunSem r s v m a)
=> EHCOpts
-> [Mod]
-> Mod
-> RunT' r s v m a
-> m (Either Err v)
runCoreRun opts modImpL mod m = do
(r, s, _ :: a) <- rsemInitial
(e, _, _) <-
runRWST (runErrorT $ do
r' <- rsemSetup opts modImpL mod
local (const r') $
(m >>= rsemPop >>= rsemDeref >>= rsemPop))
r s
return e
runCoreRun2
:: forall r s v m a .
(RunSem r s v IO a)
=> EHCOpts
-> [Mod]
-> Mod
-> RunT' r s v IO a
-> IO (Either Err v)
runCoreRun2 opts modImpL mod m = do
(r, s, _ :: a) <- rsemInitial
res <- flip catch (\(e :: SomeException) -> do
hFlush stdout >> (return $ Left $ strMsg $ "runCoreRun2: " ++ show e)
) $ do
(e, _, _) <-
runRWST (runErrorT $ do
r' <- rsemSetup opts modImpL mod
local (const r') $
(m >>= rsemPop >>= rsemDeref >>= rsemPop))
r s
return e
return res
modifyIORefM :: IORef a -> (a -> IO a) -> IO ()
modifyIORefM r m = readIORef r >>= m >>= writeIORef r