module CLasH.Utils.HsTools where
import qualified Unsafe.Coerce
import qualified Maybe
import qualified GHC
import qualified HscMain
import qualified HscTypes
import qualified DynFlags
import qualified FastString
import qualified StringBuffer
import qualified MonadUtils
import Outputable ( showSDoc, ppr )
import qualified Outputable
import qualified Lexer
import qualified Parser
import qualified HsSyn
import qualified HsExpr
import qualified HsTypes
import qualified HsBinds
import qualified TcRnMonad
import qualified TcRnTypes
import qualified RnExpr
import qualified RnEnv
import qualified TcExpr
import qualified TcEnv
import qualified TcSimplify
import qualified TcTyFuns
import qualified Desugar
import qualified PrelNames
import qualified Module
import qualified OccName
import qualified RdrName
import qualified Name
import qualified SrcLoc
import qualified LoadIface
import qualified BasicTypes
import qualified CoreSyn
import qualified Id
import qualified Type
import qualified TyCon
toCore ::
HsSyn.HsExpr RdrName.RdrName
-> GHC.Ghc CoreSyn.CoreExpr
toCore expr = do
env <- GHC.getSession
let icontext = HscTypes.hsc_IC env
(binds, tc_expr) <- HscTypes.ioMsgMaybe $ MonadUtils.liftIO $
TcRnMonad.initTcPrintErrors env PrelNames.iNTERACTIVE $ do
(tc_expr, insts) <- TcRnMonad.getLIE $ do
(rn_expr, freevars) <- RnExpr.rnExpr expr
(res, _) <- TcExpr.tcInferRho (SrcLoc.noLoc rn_expr)
return res
binds <- TcSimplify.tcSimplifyTop insts
return (binds, tc_expr)
let letexpr = SrcLoc.noLoc $ HsExpr.HsLet
(HsBinds.HsValBinds $ HsBinds.ValBindsOut [(BasicTypes.NonRecursive, binds)] [])
tc_expr
let rdr_env = HscTypes.ic_rn_gbl_env icontext
HscTypes.ioMsgMaybe $ Desugar.deSugarExpr env PrelNames.iNTERACTIVE rdr_env HscTypes.emptyTypeEnv letexpr
mkId :: RdrName.RdrName -> GHC.Ghc Id.Id
mkId rdr_name = do
env <- GHC.getSession
HscTypes.ioMsgMaybe $ MonadUtils.liftIO $
TcRnMonad.initTcPrintErrors env PrelNames.iNTERACTIVE $
TcRnMonad.setOptM DynFlags.Opt_ImplicitImportQualified $ do
name <- RnEnv.lookupGlobalOccRn rdr_name
TcEnv.tcLookupId name
normalizeType ::
HscTypes.HscEnv
-> Type.Type
-> IO Type.Type
normalizeType env ty = do
(err, nty) <- MonadUtils.liftIO $
TcRnMonad.initTcPrintErrors env PrelNames.iNTERACTIVE $ do
(_, nty) <- TcTyFuns.tcNormaliseFamInst ty
return nty
let normalized_ty = Maybe.fromJust nty
return normalized_ty
coreToHsType :: Type.Type -> HsTypes.LHsType RdrName.RdrName
coreToHsType ty = case Type.splitTyConApp_maybe ty of
Just (tycon, tys) ->
foldl (\t a -> SrcLoc.noLoc $ HsTypes.HsAppTy t a) tycon_ty (map coreToHsType tys)
where
tycon_name = TyCon.tyConName tycon
mod_name = Module.moduleName $ Name.nameModule tycon_name
occ_name = Name.nameOccName tycon_name
tycon_rdrname = RdrName.mkRdrQual mod_name occ_name
tycon_ty = SrcLoc.noLoc $ HsTypes.HsTyVar tycon_rdrname
Nothing -> error "HsTools.coreToHsType Cannot translate non-tycon type"
execCore :: CoreSyn.CoreExpr -> GHC.Ghc a
execCore expr = do
dflags <- GHC.getSessionDynFlags
GHC.setSessionDynFlags dflags
env <- GHC.getSession
let srcspan = SrcLoc.noSrcSpan
hval <- MonadUtils.liftIO $ HscMain.compileExpr env srcspan expr
let res = Unsafe.Coerce.unsafeCoerce hval :: Int
return $ Unsafe.Coerce.unsafeCoerce hval
hsUndef :: HsExpr.LHsExpr RdrName.RdrName
hsUndef = SrcLoc.noLoc $ HsExpr.HsVar PrelNames.undefined_RDR
hsTypedUndef :: HsTypes.LHsType RdrName.RdrName -> HsExpr.LHsExpr RdrName.RdrName
hsTypedUndef ty = SrcLoc.noLoc $ HsExpr.ExprWithTySig hsUndef ty
mkRdrName :: String -> String -> RdrName.RdrName
mkRdrName mod var =
RdrName.mkRdrQual (Module.mkModuleName mod) (OccName.mkVarOcc var)
hscParseType = hscParseThing Parser.parseType
hscParseStmt = hscParseThing Parser.parseStmt
hscParseThing :: Lexer.P thing -> DynFlags.DynFlags -> String -> GHC.Ghc thing
hscParseThing parser dflags str = do
buf <- MonadUtils.liftIO $ StringBuffer.stringToStringBuffer str
let loc = SrcLoc.mkSrcLoc (FastString.fsLit "<interactive>") 1 0
let Lexer.POk _ thing = Lexer.unP parser (Lexer.mkPState buf loc dflags)
return thing
importModule :: Module.ModuleName -> TcRnTypes.RnM ()
importModule mod = do
let reason = Outputable.text "Hardcoded import"
let pkg = Nothing
iface <- LoadIface.loadSrcInterface reason mod False pkg
let deps = HscTypes.mi_deps iface
let orphs = HscTypes.dep_orphs deps
let finsts = HscTypes.dep_finsts deps
LoadIface.loadOrphanModules orphs False
LoadIface.loadOrphanModules finsts True