{-# LANGUAGE MagicHash #-}
module Debugger (pprintClosureCommand, showTerm, pprTypeAndContents) where
import GhcPrelude
import Linker
import RtClosureInspect
import GHCi
import GHCi.RemoteTypes
import GhcMonad
import HscTypes
import Id
import IfaceSyn ( showToHeader )
import IfaceEnv( newInteractiveBinder )
import Name
import Var hiding ( varName )
import VarSet
import UniqSet
import Type
import GHC
import Outputable
import PprTyThing
import ErrUtils
import MonadUtils
import DynFlags
import Exception
import Control.Monad
import Data.List
import Data.Maybe
import Data.IORef
pprintClosureCommand :: GhcMonad m => Bool -> Bool -> String -> m ()
pprintClosureCommand :: Bool -> Bool -> String -> m ()
pprintClosureCommand bindThings :: Bool
bindThings force :: Bool
force str :: String
str = do
[TyThing]
tythings <- ([Maybe TyThing] -> [TyThing]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe TyThing] -> [TyThing])
-> ([[Maybe TyThing]] -> [Maybe TyThing])
-> [[Maybe TyThing]]
-> [TyThing]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Maybe TyThing]] -> [Maybe TyThing]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat) ([[Maybe TyThing]] -> [TyThing])
-> m [[Maybe TyThing]] -> m [TyThing]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM`
(String -> m [Maybe TyThing]) -> [String] -> m [[Maybe TyThing]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\w :: String
w -> String -> m [Name]
forall (m :: * -> *). GhcMonad m => String -> m [Name]
GHC.parseName String
w m [Name] -> ([Name] -> m [Maybe TyThing]) -> m [Maybe TyThing]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
(Name -> m (Maybe TyThing)) -> [Name] -> m [Maybe TyThing]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Name -> m (Maybe TyThing)
forall (m :: * -> *). GhcMonad m => Name -> m (Maybe TyThing)
GHC.lookupName)
(String -> [String]
words String
str)
let ids :: [Id]
ids = [Id
id | AnId id :: Id
id <- [TyThing]
tythings]
(subst :: TCvSubst
subst, terms :: [Term]
terms) <- (TCvSubst -> Id -> m (TCvSubst, Term))
-> TCvSubst -> [Id] -> m (TCvSubst, [Term])
forall (m :: * -> *) acc x y.
Monad m =>
(acc -> x -> m (acc, y)) -> acc -> [x] -> m (acc, [y])
mapAccumLM TCvSubst -> Id -> m (TCvSubst, Term)
forall (m :: * -> *).
GhcMonad m =>
TCvSubst -> Id -> m (TCvSubst, Term)
go TCvSubst
emptyTCvSubst [Id]
ids
(HscEnv -> HscEnv) -> m ()
forall (m :: * -> *). GhcMonad m => (HscEnv -> HscEnv) -> m ()
modifySession ((HscEnv -> HscEnv) -> m ()) -> (HscEnv -> HscEnv) -> m ()
forall a b. (a -> b) -> a -> b
$ \hsc_env :: HscEnv
hsc_env ->
HscEnv
hsc_env{hsc_IC :: InteractiveContext
hsc_IC = InteractiveContext -> TCvSubst -> InteractiveContext
substInteractiveContext (HscEnv -> InteractiveContext
hsc_IC HscEnv
hsc_env) TCvSubst
subst}
PrintUnqualified
unqual <- m PrintUnqualified
forall (m :: * -> *). GhcMonad m => m PrintUnqualified
GHC.getPrintUnqual
[SDoc]
docterms <- (Term -> m SDoc) -> [Term] -> m [SDoc]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Term -> m SDoc
forall (m :: * -> *). GhcMonad m => Term -> m SDoc
showTerm [Term]
terms
DynFlags
dflags <- m DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ (DynFlags -> PrintUnqualified -> SDoc -> IO ()
printOutputForUser DynFlags
dflags PrintUnqualified
unqual (SDoc -> IO ()) -> ([SDoc] -> SDoc) -> [SDoc] -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [SDoc] -> SDoc
vcat)
((Id -> SDoc -> SDoc) -> [Id] -> [SDoc] -> [SDoc]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (\id :: Id
id docterm :: SDoc
docterm -> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
id SDoc -> SDoc -> SDoc
<+> Char -> SDoc
char '=' SDoc -> SDoc -> SDoc
<+> SDoc
docterm)
[Id]
ids
[SDoc]
docterms)
where
go :: GhcMonad m => TCvSubst -> Id -> m (TCvSubst, Term)
go :: TCvSubst -> Id -> m (TCvSubst, Term)
go subst :: TCvSubst
subst id :: Id
id = do
let id' :: Id
id' = Id
id Id -> Type -> Id
`setIdType` HasCallStack => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst (Id -> Type
idType Id
id)
Term
term_ <- Int -> Bool -> Id -> m Term
forall (m :: * -> *). GhcMonad m => Int -> Bool -> Id -> m Term
GHC.obtainTermFromId Int
forall a. Bounded a => a
maxBound Bool
force Id
id'
Term
term <- Term -> m Term
forall (m :: * -> *). GhcMonad m => Term -> m Term
tidyTermTyVars Term
term_
Term
term' <- if Bool
bindThings Bool -> Bool -> Bool
&&
(Bool -> Bool
not (HasDebugCallStack => Type -> Bool
Type -> Bool
isUnliftedType (Term -> Type
termType Term
term)))
then Term -> m Term
forall (m :: * -> *). GhcMonad m => Term -> m Term
bindSuspensions Term
term
else Term -> m Term
forall (m :: * -> *) a. Monad m => a -> m a
return Term
term
let reconstructed_type :: Type
reconstructed_type = Term -> Type
termType Term
term
HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
case (HscEnv -> Type -> Type -> Maybe TCvSubst
improveRTTIType HscEnv
hsc_env (Id -> Type
idType Id
id) (Type
reconstructed_type)) of
Nothing -> (TCvSubst, Term) -> m (TCvSubst, Term)
forall (m :: * -> *) a. Monad m => a -> m a
return (TCvSubst
subst, Term
term')
Just subst' :: TCvSubst
subst' -> do { DynFlags
dflags <- m DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
GHC.getSessionDynFlags
; IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$
DynFlags -> DumpFlag -> String -> SDoc -> IO ()
dumpIfSet_dyn DynFlags
dflags DumpFlag
Opt_D_dump_rtti "RTTI"
([SDoc] -> SDoc
fsep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ [String -> SDoc
text "RTTI Improvement for", Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
id,
String -> SDoc
text "is the substitution:" , TCvSubst -> SDoc
forall a. Outputable a => a -> SDoc
ppr TCvSubst
subst'])
; (TCvSubst, Term) -> m (TCvSubst, Term)
forall (m :: * -> *) a. Monad m => a -> m a
return (TCvSubst
subst TCvSubst -> TCvSubst -> TCvSubst
`unionTCvSubst` TCvSubst
subst', Term
term')}
tidyTermTyVars :: GhcMonad m => Term -> m Term
tidyTermTyVars :: Term -> m Term
tidyTermTyVars t :: Term
t =
(HscEnv -> m Term) -> m Term
forall (m :: * -> *) a. GhcMonad m => (HscEnv -> m a) -> m a
withSession ((HscEnv -> m Term) -> m Term) -> (HscEnv -> m Term) -> m Term
forall a b. (a -> b) -> a -> b
$ \hsc_env :: HscEnv
hsc_env -> do
let env_tvs :: TyCoVarSet
env_tvs = [TyThing] -> TyCoVarSet
tyThingsTyCoVars ([TyThing] -> TyCoVarSet) -> [TyThing] -> TyCoVarSet
forall a b. (a -> b) -> a -> b
$ InteractiveContext -> [TyThing]
ic_tythings (InteractiveContext -> [TyThing])
-> InteractiveContext -> [TyThing]
forall a b. (a -> b) -> a -> b
$ HscEnv -> InteractiveContext
hsc_IC HscEnv
hsc_env
my_tvs :: TyCoVarSet
my_tvs = Term -> TyCoVarSet
termTyCoVars Term
t
tvs :: TyCoVarSet
tvs = TyCoVarSet
env_tvs TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`minusVarSet` TyCoVarSet
my_tvs
tyvarOccName :: Id -> OccName
tyvarOccName = Name -> OccName
nameOccName (Name -> OccName) -> (Id -> Name) -> Id -> OccName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> Name
tyVarName
tidyEnv :: (TidyOccEnv, UniqFM Id)
tidyEnv = ([OccName] -> TidyOccEnv
initTidyOccEnv ((Id -> OccName) -> [Id] -> [OccName]
forall a b. (a -> b) -> [a] -> [b]
map Id -> OccName
tyvarOccName (TyCoVarSet -> [Id]
forall elt. UniqSet elt -> [elt]
nonDetEltsUniqSet TyCoVarSet
tvs))
, TyCoVarSet -> UniqFM Id
forall a. UniqSet a -> UniqFM a
getUniqSet (TyCoVarSet -> UniqFM Id) -> TyCoVarSet -> UniqFM Id
forall a b. (a -> b) -> a -> b
$ TyCoVarSet
env_tvs TyCoVarSet -> TyCoVarSet -> TyCoVarSet
`intersectVarSet` TyCoVarSet
my_tvs)
Term -> m Term
forall (m :: * -> *) a. Monad m => a -> m a
return (Term -> m Term) -> Term -> m Term
forall a b. (a -> b) -> a -> b
$ (Type -> Type) -> Term -> Term
mapTermType (((TidyOccEnv, UniqFM Id), Type) -> Type
forall a b. (a, b) -> b
snd (((TidyOccEnv, UniqFM Id), Type) -> Type)
-> (Type -> ((TidyOccEnv, UniqFM Id), Type)) -> Type -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TidyOccEnv, UniqFM Id) -> Type -> ((TidyOccEnv, UniqFM Id), Type)
tidyOpenType (TidyOccEnv, UniqFM Id)
tidyEnv) Term
t
bindSuspensions :: GhcMonad m => Term -> m Term
bindSuspensions :: Term -> m Term
bindSuspensions t :: Term
t = do
HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
[TyThing]
inScope <- m [TyThing]
forall (m :: * -> *). GhcMonad m => m [TyThing]
GHC.getBindings
let ictxt :: InteractiveContext
ictxt = HscEnv -> InteractiveContext
hsc_IC HscEnv
hsc_env
prefix :: String
prefix = "_t"
alreadyUsedNames :: [String]
alreadyUsedNames = (TyThing -> String) -> [TyThing] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (OccName -> String
occNameString (OccName -> String) -> (TyThing -> OccName) -> TyThing -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> OccName
nameOccName (Name -> OccName) -> (TyThing -> Name) -> TyThing -> OccName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TyThing -> Name
forall a. NamedThing a => a -> Name
getName) [TyThing]
inScope
availNames :: [String]
availNames = (Int -> String) -> [Int] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((String
prefixString -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (Int -> String) -> Int -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show) [(1::Int)..] [String] -> [String] -> [String]
forall a. Eq a => [a] -> [a] -> [a]
\\ [String]
alreadyUsedNames
IORef [String]
availNames_var <- IO (IORef [String]) -> m (IORef [String])
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef [String]) -> m (IORef [String]))
-> IO (IORef [String]) -> m (IORef [String])
forall a b. (a -> b) -> a -> b
$ [String] -> IO (IORef [String])
forall a. a -> IO (IORef a)
newIORef [String]
availNames
(t' :: Term
t', stuff :: [(Name, Type, ForeignHValue)]
stuff) <- IO (Term, [(Name, Type, ForeignHValue)])
-> m (Term, [(Name, Type, ForeignHValue)])
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Term, [(Name, Type, ForeignHValue)])
-> m (Term, [(Name, Type, ForeignHValue)]))
-> IO (Term, [(Name, Type, ForeignHValue)])
-> m (Term, [(Name, Type, ForeignHValue)])
forall a b. (a -> b) -> a -> b
$ TermFold (IO (Term, [(Name, Type, ForeignHValue)]))
-> Term -> IO (Term, [(Name, Type, ForeignHValue)])
forall a. TermFold a -> Term -> a
foldTerm (HscEnv
-> IORef [String]
-> TermFold (IO (Term, [(Name, Type, ForeignHValue)]))
nameSuspensionsAndGetInfos HscEnv
hsc_env IORef [String]
availNames_var) Term
t
let (names :: [Name]
names, tys :: [Type]
tys, fhvs :: [ForeignHValue]
fhvs) = [(Name, Type, ForeignHValue)] -> ([Name], [Type], [ForeignHValue])
forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 [(Name, Type, ForeignHValue)]
stuff
let ids :: [Id]
ids = [ Name -> Type -> Id
mkVanillaGlobal Name
name Type
ty
| (name :: Name
name,ty :: Type
ty) <- [Name] -> [Type] -> [(Name, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
names [Type]
tys]
new_ic :: InteractiveContext
new_ic = InteractiveContext -> [Id] -> InteractiveContext
extendInteractiveContextWithIds InteractiveContext
ictxt [Id]
ids
IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ [(Name, ForeignHValue)] -> IO ()
extendLinkEnv ([Name] -> [ForeignHValue] -> [(Name, ForeignHValue)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Name]
names [ForeignHValue]
fhvs)
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env {hsc_IC :: InteractiveContext
hsc_IC = InteractiveContext
new_ic }
Term -> m Term
forall (m :: * -> *) a. Monad m => a -> m a
return Term
t'
where
nameSuspensionsAndGetInfos :: HscEnv -> IORef [String]
-> TermFold (IO (Term, [(Name,Type,ForeignHValue)]))
nameSuspensionsAndGetInfos :: HscEnv
-> IORef [String]
-> TermFold (IO (Term, [(Name, Type, ForeignHValue)]))
nameSuspensionsAndGetInfos hsc_env :: HscEnv
hsc_env freeNames :: IORef [String]
freeNames = TermFold :: forall a.
TermProcessor a a
-> (Type -> [Word] -> a)
-> (ClosureType -> Type -> ForeignHValue -> Maybe Name -> a)
-> (Type -> Either String DataCon -> a -> a)
-> (Type -> a -> a)
-> TermFold a
TermFold
{
fSuspension :: ClosureType
-> Type
-> ForeignHValue
-> Maybe Name
-> IO (Term, [(Name, Type, ForeignHValue)])
fSuspension = HscEnv
-> IORef [String]
-> ClosureType
-> Type
-> ForeignHValue
-> Maybe Name
-> IO (Term, [(Name, Type, ForeignHValue)])
forall p.
HscEnv
-> IORef [String]
-> ClosureType
-> Type
-> ForeignHValue
-> p
-> IO (Term, [(Name, Type, ForeignHValue)])
doSuspension HscEnv
hsc_env IORef [String]
freeNames
, fTerm :: TermProcessor
(IO (Term, [(Name, Type, ForeignHValue)]))
(IO (Term, [(Name, Type, ForeignHValue)]))
fTerm = \ty :: Type
ty dc :: Either String DataCon
dc v :: ForeignHValue
v tt :: [IO (Term, [(Name, Type, ForeignHValue)])]
tt -> do
[(Term, [(Name, Type, ForeignHValue)])]
tt' <- [IO (Term, [(Name, Type, ForeignHValue)])]
-> IO [(Term, [(Name, Type, ForeignHValue)])]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence [IO (Term, [(Name, Type, ForeignHValue)])]
tt
let (terms :: [Term]
terms,names :: [[(Name, Type, ForeignHValue)]]
names) = [(Term, [(Name, Type, ForeignHValue)])]
-> ([Term], [[(Name, Type, ForeignHValue)]])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Term, [(Name, Type, ForeignHValue)])]
tt'
(Term, [(Name, Type, ForeignHValue)])
-> IO (Term, [(Name, Type, ForeignHValue)])
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Either String DataCon -> ForeignHValue -> [Term] -> Term
Term Type
ty Either String DataCon
dc ForeignHValue
v [Term]
terms, [[(Name, Type, ForeignHValue)]] -> [(Name, Type, ForeignHValue)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[(Name, Type, ForeignHValue)]]
names)
, fPrim :: Type -> [Word] -> IO (Term, [(Name, Type, ForeignHValue)])
fPrim = \ty :: Type
ty n :: [Word]
n ->(Term, [(Name, Type, ForeignHValue)])
-> IO (Term, [(Name, Type, ForeignHValue)])
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> [Word] -> Term
Prim Type
ty [Word]
n,[])
, fNewtypeWrap :: Type
-> Either String DataCon
-> IO (Term, [(Name, Type, ForeignHValue)])
-> IO (Term, [(Name, Type, ForeignHValue)])
fNewtypeWrap =
\ty :: Type
ty dc :: Either String DataCon
dc t :: IO (Term, [(Name, Type, ForeignHValue)])
t -> do
(term :: Term
term, names :: [(Name, Type, ForeignHValue)]
names) <- IO (Term, [(Name, Type, ForeignHValue)])
t
(Term, [(Name, Type, ForeignHValue)])
-> IO (Term, [(Name, Type, ForeignHValue)])
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Either String DataCon -> Term -> Term
NewtypeWrap Type
ty Either String DataCon
dc Term
term, [(Name, Type, ForeignHValue)]
names)
, fRefWrap :: Type
-> IO (Term, [(Name, Type, ForeignHValue)])
-> IO (Term, [(Name, Type, ForeignHValue)])
fRefWrap = \ty :: Type
ty t :: IO (Term, [(Name, Type, ForeignHValue)])
t -> do
(term :: Term
term, names :: [(Name, Type, ForeignHValue)]
names) <- IO (Term, [(Name, Type, ForeignHValue)])
t
(Term, [(Name, Type, ForeignHValue)])
-> IO (Term, [(Name, Type, ForeignHValue)])
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Term -> Term
RefWrap Type
ty Term
term, [(Name, Type, ForeignHValue)]
names)
}
doSuspension :: HscEnv
-> IORef [String]
-> ClosureType
-> Type
-> ForeignHValue
-> p
-> IO (Term, [(Name, Type, ForeignHValue)])
doSuspension hsc_env :: HscEnv
hsc_env freeNames :: IORef [String]
freeNames ct :: ClosureType
ct ty :: Type
ty hval :: ForeignHValue
hval _name :: p
_name = do
String
name <- IORef [String] -> ([String] -> ([String], String)) -> IO String
forall a b. IORef a -> (a -> (a, b)) -> IO b
atomicModifyIORef' IORef [String]
freeNames (\x :: [String]
x->([String] -> [String]
forall a. [a] -> [a]
tail [String]
x, [String] -> String
forall a. [a] -> a
head [String]
x))
Name
n <- HscEnv -> String -> IO Name
forall (m :: * -> *). MonadIO m => HscEnv -> String -> m Name
newGrimName HscEnv
hsc_env String
name
(Term, [(Name, Type, ForeignHValue)])
-> IO (Term, [(Name, Type, ForeignHValue)])
forall (m :: * -> *) a. Monad m => a -> m a
return (ClosureType -> Type -> ForeignHValue -> Maybe Name -> Term
Suspension ClosureType
ct Type
ty ForeignHValue
hval (Name -> Maybe Name
forall a. a -> Maybe a
Just Name
n), [(Name
n,Type
ty,ForeignHValue
hval)])
showTerm :: GhcMonad m => Term -> m SDoc
showTerm :: Term -> m SDoc
showTerm term :: Term
term = do
DynFlags
dflags <- m DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
GHC.getSessionDynFlags
if GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_PrintEvldWithShow DynFlags
dflags
then CustomTermPrinter m -> Term -> m SDoc
forall (m :: * -> *).
Monad m =>
CustomTermPrinter m -> Term -> m SDoc
cPprTerm (([Int -> Term -> m (Maybe SDoc)]
-> [Int -> Term -> m (Maybe SDoc)]
-> [Int -> Term -> m (Maybe SDoc)])
-> CustomTermPrinter m
-> CustomTermPrinter m
-> CustomTermPrinter m
forall (m :: * -> *) a1 a2 r.
Monad m =>
(a1 -> a2 -> r) -> m a1 -> m a2 -> m r
liftM2 [Int -> Term -> m (Maybe SDoc)]
-> [Int -> Term -> m (Maybe SDoc)]
-> [Int -> Term -> m (Maybe SDoc)]
forall a. [a] -> [a] -> [a]
(++) (\_y :: Int -> Term -> m SDoc
_y->[Int -> Term -> m (Maybe SDoc)
forall (m :: * -> *) t.
(GhcMonad m, Ord t, Num t) =>
t -> Term -> m (Maybe SDoc)
cPprShowable]) CustomTermPrinter m
forall (m :: * -> *). Monad m => CustomTermPrinter m
cPprTermBase) Term
term
else CustomTermPrinter m -> Term -> m SDoc
forall (m :: * -> *).
Monad m =>
CustomTermPrinter m -> Term -> m SDoc
cPprTerm CustomTermPrinter m
forall (m :: * -> *). Monad m => CustomTermPrinter m
cPprTermBase Term
term
where
cPprShowable :: t -> Term -> m (Maybe SDoc)
cPprShowable prec :: t
prec t :: Term
t@Term{ty :: Term -> Type
ty=Type
ty, val :: Term -> ForeignHValue
val=ForeignHValue
fhv} =
if Bool -> Bool
not (Term -> Bool
isFullyEvaluatedTerm Term
t)
then Maybe SDoc -> m (Maybe SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SDoc
forall a. Maybe a
Nothing
else do
HscEnv
hsc_env <- m HscEnv
forall (m :: * -> *). GhcMonad m => m HscEnv
getSession
DynFlags
dflags <- m DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
GHC.getSessionDynFlags
do
(new_env :: HscEnv
new_env, bname :: Name
bname) <- HscEnv -> Type -> String -> m (HscEnv, Name)
forall (m :: * -> *).
MonadIO m =>
HscEnv -> Type -> String -> m (HscEnv, Name)
bindToFreshName HscEnv
hsc_env Type
ty "showme"
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
new_env
let noop_log :: p -> p -> p -> p -> p -> p -> m ()
noop_log _ _ _ _ _ _ = () -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
expr :: String
expr = "Prelude.return (Prelude.show " String -> String -> String
forall a. [a] -> [a] -> [a]
++
DynFlags -> Name -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags Name
bname String -> String -> String
forall a. [a] -> [a] -> [a]
++
") :: Prelude.IO Prelude.String"
[InstalledUnitId]
_ <- DynFlags -> m [InstalledUnitId]
forall (m :: * -> *). GhcMonad m => DynFlags -> m [InstalledUnitId]
GHC.setSessionDynFlags DynFlags
dflags{log_action :: LogAction
log_action=LogAction
forall (m :: * -> *) p p p p p p.
Monad m =>
p -> p -> p -> p -> p -> p -> m ()
noop_log}
ForeignHValue
txt_ <- [(Name, ForeignHValue)] -> m ForeignHValue -> m ForeignHValue
forall (m :: * -> *) a.
ExceptionMonad m =>
[(Name, ForeignHValue)] -> m a -> m a
withExtendedLinkEnv [(Name
bname, ForeignHValue
fhv)]
(String -> m ForeignHValue
forall (m :: * -> *). GhcMonad m => String -> m ForeignHValue
GHC.compileExprRemote String
expr)
let myprec :: t
myprec = 10
String
txt <- IO String -> m String
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO String -> m String) -> IO String -> m String
forall a b. (a -> b) -> a -> b
$ HscEnv -> ForeignHValue -> IO String
evalString HscEnv
hsc_env ForeignHValue
txt_
if Bool -> Bool
not (String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
txt) then
Maybe SDoc -> m (Maybe SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe SDoc -> m (Maybe SDoc)) -> Maybe SDoc -> m (Maybe SDoc)
forall a b. (a -> b) -> a -> b
$ SDoc -> Maybe SDoc
forall a. a -> Maybe a
Just (SDoc -> Maybe SDoc) -> SDoc -> Maybe SDoc
forall a b. (a -> b) -> a -> b
$ Bool -> SDoc -> SDoc
cparen (t
prec t -> t -> Bool
forall a. Ord a => a -> a -> Bool
>= t
myprec Bool -> Bool -> Bool
&& String -> Bool
needsParens String
txt)
(String -> SDoc
text String
txt)
else Maybe SDoc -> m (Maybe SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SDoc
forall a. Maybe a
Nothing
m (Maybe SDoc) -> m [InstalledUnitId] -> m (Maybe SDoc)
forall (m :: * -> *) a b. ExceptionMonad m => m a -> m b -> m a
`gfinally` do
HscEnv -> m ()
forall (m :: * -> *). GhcMonad m => HscEnv -> m ()
setSession HscEnv
hsc_env
DynFlags -> m [InstalledUnitId]
forall (m :: * -> *). GhcMonad m => DynFlags -> m [InstalledUnitId]
GHC.setSessionDynFlags DynFlags
dflags
cPprShowable prec :: t
prec NewtypeWrap{ty :: Term -> Type
ty=Type
new_ty,wrapped_term :: Term -> Term
wrapped_term=Term
t} =
t -> Term -> m (Maybe SDoc)
cPprShowable t
prec Term
t{ty :: Type
ty=Type
new_ty}
cPprShowable _ _ = Maybe SDoc -> m (Maybe SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe SDoc
forall a. Maybe a
Nothing
needsParens :: String -> Bool
needsParens ('"':_) = Bool
False
needsParens ('(':_) = Bool
False
needsParens txt :: String
txt = ' ' Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
txt
bindToFreshName :: HscEnv -> Type -> String -> m (HscEnv, Name)
bindToFreshName hsc_env :: HscEnv
hsc_env ty :: Type
ty userName :: String
userName = do
Name
name <- HscEnv -> String -> m Name
forall (m :: * -> *). MonadIO m => HscEnv -> String -> m Name
newGrimName HscEnv
hsc_env String
userName
let id :: Id
id = Name -> Type -> Id
mkVanillaGlobal Name
name Type
ty
new_ic :: InteractiveContext
new_ic = InteractiveContext -> [Id] -> InteractiveContext
extendInteractiveContextWithIds (HscEnv -> InteractiveContext
hsc_IC HscEnv
hsc_env) [Id
id]
(HscEnv, Name) -> m (HscEnv, Name)
forall (m :: * -> *) a. Monad m => a -> m a
return (HscEnv
hsc_env {hsc_IC :: InteractiveContext
hsc_IC = InteractiveContext
new_ic }, Name
name)
newGrimName :: MonadIO m => HscEnv -> String -> m Name
newGrimName :: HscEnv -> String -> m Name
newGrimName hsc_env :: HscEnv
hsc_env userName :: String
userName
= IO Name -> m Name
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (HscEnv -> OccName -> SrcSpan -> IO Name
newInteractiveBinder HscEnv
hsc_env OccName
occ SrcSpan
noSrcSpan)
where
occ :: OccName
occ = NameSpace -> String -> OccName
mkOccName NameSpace
varName String
userName
pprTypeAndContents :: GhcMonad m => Id -> m SDoc
pprTypeAndContents :: Id -> m SDoc
pprTypeAndContents id :: Id
id = do
DynFlags
dflags <- m DynFlags
forall (m :: * -> *). GhcMonad m => m DynFlags
GHC.getSessionDynFlags
let pcontents :: Bool
pcontents = GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_PrintBindContents DynFlags
dflags
pprdId :: SDoc
pprdId = (ShowSub -> TyThing -> SDoc
pprTyThing ShowSub
showToHeader (TyThing -> SDoc) -> (Id -> TyThing) -> Id -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> TyThing
AnId) Id
id
if Bool
pcontents
then do
let depthBound :: Int
depthBound = 100
Either SomeException Term
e_term <- m Term -> m (Either SomeException Term)
forall (m :: * -> *) e a.
(ExceptionMonad m, Exception e) =>
m a -> m (Either e a)
gtry (m Term -> m (Either SomeException Term))
-> m Term -> m (Either SomeException Term)
forall a b. (a -> b) -> a -> b
$ Int -> Bool -> Id -> m Term
forall (m :: * -> *). GhcMonad m => Int -> Bool -> Id -> m Term
GHC.obtainTermFromId Int
depthBound Bool
False Id
id
SDoc
docs_term <- case Either SomeException Term
e_term of
Right term :: Term
term -> Term -> m SDoc
forall (m :: * -> *). GhcMonad m => Term -> m SDoc
showTerm Term
term
Left exn :: SomeException
exn -> SDoc -> m SDoc
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> SDoc
text "*** Exception:" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text (SomeException -> String
forall a. Show a => a -> String
show (SomeException
exn :: SomeException)))
SDoc -> m SDoc
forall (m :: * -> *) a. Monad m => a -> m a
return (SDoc -> m SDoc) -> SDoc -> m SDoc
forall a b. (a -> b) -> a -> b
$ SDoc
pprdId SDoc -> SDoc -> SDoc
<+> SDoc
equals SDoc -> SDoc -> SDoc
<+> SDoc
docs_term
else SDoc -> m SDoc
forall (m :: * -> *) a. Monad m => a -> m a
return SDoc
pprdId