-- 1. Load a set of modules with "nothing" target -- 2. Load it again with "interpreted" target -- 3. Execute some code -- a. If the recompilation checker is buggy this will die due to missing -- code -- b. If it's correct, it will recompile because the target has changed. -- -- This program must be called with GHC's libdir as the single command line -- argument. module Main where import GHC import GHC.Driver.Session import GHC.Driver.Backend import GHC.Utils.Monad ( MonadIO(..) ) import GHC.Types.Basic ( failed ) import GHC.Data.Bag ( bagToList ) import System.Environment import Control.Monad import System.IO main = do libdir : args <- getArgs runGhc (Just libdir) $ do dflags0 <- getSessionDynFlags logger <- getLogger (dflags, _, _) <- parseDynamicFlags logger dflags0 (map (mkGeneralLocated "on the commandline") args) setSessionDynFlags $ dflags { backend = noBackend , ghcLink = LinkInMemory , verbosity = 0 -- silence please } root_mod <- guessTarget "A.hs" Nothing Nothing setTargets [root_mod] ok <- load LoadAllTargets when (failed ok) $ error "Couldn't load A.hs in nothing mode" prn "target nothing: ok" dflags <- getSessionDynFlags setSessionDynFlags $ dflags { backend = interpreterBackend } ok <- load LoadAllTargets when (failed ok) $ error "Couldn't load A.hs in interpreted mode" prn "target interpreted: ok" -- set context to module "A" mg <- getModuleGraph let [mod] = [ ms_mod_name m | m <- mgModSummaries mg , moduleNameString (ms_mod_name m) == "A" ] setContext [IIModule mod] liftIO $ hFlush stdout -- make sure things above are printed before -- interactive output r <- execStmt "main" execOptions case r of ExecComplete { execResult = Right _ } -> prn "ok" ExecComplete { execResult = Left _ } -> prn "exception" ExecBreak{} -> prn "breakpoint" liftIO $ hFlush stdout return () prn :: MonadIO m => String -> m () prn = liftIO . putStrLn