semdoc-0.1.0: src/Text/Semdoc/EvalExpr.hs
{-# LANGUAGE NamedFieldPuns #-}
module Text.Semdoc.EvalExpr where
import Control.Applicative ((<$>))
import Control.Monad (join)
import Debugger (showTerm)
import DynFlags (ExtensionFlag (..), PkgConfRef (..),
xopt_set)
import GHC
import GHC.Paths (libdir)
import MonadUtils
import Outputable (neverQualify, showSDocForUser)
import Packages (initPackages)
import System.FilePath.Glob (glob)
data EvalInput a = EvalInput
{ inputModule :: String
, inputStmts :: String
}
deriving (Show)
addPkgDbs :: GhcMonad m => [FilePath] -> m ()
addPkgDbs fps = do
dfs <- getSessionDynFlags
let pkgs = map PkgConfFile fps
let dfs' = dfs { extraPkgConfs = (pkgs ++) . extraPkgConfs dfs }
_ <- setSessionDynFlags dfs'
_ <- liftIO $ initPackages dfs'
return ()
evalExpr :: Read a => [EvalInput a] -> IO [a]
evalExpr exprs = do
pkgDbs <- join <$> mapM glob
[ "dist/package.conf.inplace"
, ".cabal-sandbox/*-packages.conf.d"
, "../.cabal-sandbox/*-packages.conf.d"
]
GHC.runGhc (Just libdir) $ do
addPkgDbs pkgDbs
dflags <- getSessionDynFlags
_ <- setSessionDynFlags $ foldl xopt_set dflags
{ hscTarget = HscInterpreted
, ghcLink = LinkInMemory
, ghcMode = CompManager
} [Opt_ImplicitPrelude]
_ <- load LoadAllTargets
mapM evalOne exprs
evalOne :: (Read a, GhcMonad m) => EvalInput a -> m a
evalOne EvalInput { inputModule, inputStmts } = do
setContext $ map mkImportDecl
[ ("Data.Char" , Just "Char")
, ("Data.List" , Just "List")
, ("Prelude" , Nothing)
, ("Text.Pandoc" , Nothing)
, ("Text.Printf" , Nothing)
, ("Text.Semdoc.Util", Nothing)
, (inputModule , Nothing)
]
ns <- reverse <$> runDecls inputStmts
case ns of
n:_ -> getResult n
_ -> fail "no declarations found"
where
mkImportDecl (m, n) =
IIDecl (simpleImportDecl $ mkModuleName m)
{ ideclAs = fmap mkModuleName n
, ideclQualified = n /= Nothing
}
getResult :: (Read a, GhcMonad m) => Name -> m a
getResult n = do
df <- getSessionDynFlags
Just (AnId aid) <- lookupName n
result <- fmap (pp df) $ showTerm =<< obtainTermFromId maxBound True aid
--liftIO $ putStrLn result
return $ read result
where
pp df = showSDocForUser df neverQualify