{-# LANGUAGE FlexibleInstances, CPP, PatternGuards #-} -- | Lower level building blocks for custom code generation. module Language.Haskell.GHC.Simple.Impl ( Ghc, PkgKey, liftIO, toSimplifiedStg, toModMetadata, modulePkgKey, pkgKeyString ) where -- GHC scaffolding import BinIface import GHC hiding (Warning) import GhcMonad (liftIO) import HscMain import HscTypes import TidyPgm import CorePrep import StgSyn import CoreSyn import CoreToStg import SimplStg import DriverPipeline #if __GLASGOW_HASKELL__ >= 800 import qualified Module as M (moduleUnitId, unitIdString, UnitId) #elif __GLASGOW_HASKELL__ >= 710 import qualified Module as M (modulePackageKey, packageKeyString, PackageKey) #else import qualified Module as M (modulePackageId, packageIdString, PackageId) #endif import Control.Monad import Data.IORef import System.FilePath (takeDirectory) import System.Directory (doesFileExist, createDirectoryIfMissing) import Language.Haskell.GHC.Simple.Types instance Intermediate [StgBinding] where prepare = toSimplifiedStg instance Intermediate CgGuts where prepare _ = return instance Intermediate CoreProgram where prepare ms cgguts = do env <- hsc_env `fmap` getPipeState liftIO $ prepareCore env (hsc_dflags env) ms cgguts -- | Package ID/key of a module. modulePkgKey :: Module -> PkgKey -- | String representation of a package ID/key. pkgKeyString :: PkgKey -> String #if __GLASGOW_HASKELL__ >= 800 -- | Synonym for 'M.UnitId', to bridge a slight incompatibility between -- GHC 7.8/7.10/8.0. type PkgKey = M.UnitId modulePkgKey = M.moduleUnitId pkgKeyString = M.unitIdString #elif __GLASGOW_HASKELL__ >= 710 -- | Synonym for 'M.PackageKey', to bridge a slight incompatibility between -- GHC 7.8 and 7.10. type PkgKey = M.PackageKey modulePkgKey = M.modulePackageKey pkgKeyString = M.packageKeyString #else -- | Synonym for 'M.PackageId', to bridge a slight incompatibility between -- GHC 7.8 and 7.10. type PkgKey = M.PackageId modulePkgKey = M.modulePackageId pkgKeyString = M.packageIdString #endif -- | Build a 'ModMetadata' out of a 'ModSummary'. toModMetadata :: CompConfig -> ModSummary -> ModMetadata toModMetadata cfg ms = ModMetadata { mmSummary = ms, mmName = moduleNameString $ ms_mod_name ms, mmPackageKey = pkgKeyString . modulePkgKey $ ms_mod ms, mmSourceIsHsBoot = ms_hsc_src ms == HsBootFile, mmSourceFile = ml_hs_file $ ms_location ms, mmInterfaceFile = ml_hi_file $ ms_location ms } -- | Compile a 'ModSummary' into a list of simplified 'StgBinding's. -- See -- for more information about STG and how it relates to core and Haskell. toSimplifiedStg :: ModSummary -> CgGuts -> CompPipeline [StgBinding] toSimplifiedStg ms cgguts = do env <- hsc_env `fmap` getPipeState let dfs = hsc_dflags env liftIO $ do prog <- prepareCore env dfs ms cgguts stg <- coreToStg dfs (ms_mod ms) prog fst `fmap` stg2stg dfs (ms_mod ms) stg -- | Prepare a core module for code generation. prepareCore :: HscEnv -> DynFlags -> ModSummary -> CgGuts -> IO CoreProgram prepareCore env dfs _ms p = do #if __GLASGOW_HASKELL__ >= 800 liftIO $ corePrepPgm env (ms_mod _ms) (ms_location _ms) (cg_binds p) (cg_tycons p) #elif __GLASGOW_HASKELL__ >= 710 liftIO $ corePrepPgm env (ms_location _ms) (cg_binds p) (cg_tycons p) #else liftIO $ corePrepPgm dfs env (cg_binds p) (cg_tycons p) #endif