-
-
Save worldsayshi/8853946 to your computer and use it in GitHub Desktop.
Example for loading Haskell source code dynamically using the GHC api
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
----------------------------------------------------------------------------- | |
-- | Example for loading Haskell source code dynamically using the GHC api | |
-- Tested on ghc 7.4.2 | |
-- | |
-- Useful links: | |
-- GHC api: | |
-- http://www.haskell.org/ghc/docs/latest/html/libraries/ghc/GHC.html | |
-- Wiki: | |
-- http://www.haskell.org/haskellwiki/GHC/As_a_library | |
----------------------------------------------------------------------------- | |
module DynLoad where | |
import GHC | |
import GhcMonad (liftIO) | |
import GHC.Paths (libdir) | |
import Name (getOccString) | |
import Data.Dynamic (fromDyn) | |
-- | List all exports of this module | |
-- and evaluate a symbol from a module DynTest | |
main = | |
runGhc (Just libdir) $ do | |
putString ":::Display exports of modules:::" | |
modSums <- initSession ["DynLoad","DynTest"] | |
let thisModSum = head modSums | |
exports <- listExports thisModSum | |
mapM_ putString exports | |
putString ":::Evaluate a name from module DynTest:::" | |
importDecl_RdrName <- parseImportDecl "import DynTest as D" | |
setContext [IIDecl importDecl_RdrName] | |
dynVal <- dynCompileExpr "D.aString" | |
liftIO $ print $ (fromDyn dynVal "nope-nothing") | |
-- | Init interactive session and load modules | |
initSession modStrNames = do | |
dflags <- getSessionDynFlags | |
setSessionDynFlags $ dflags { | |
hscTarget = HscInterpreted | |
, ghcLink = LinkInMemory | |
} | |
targets <- mapM | |
(\modStrName -> do | |
putString modStrName | |
target <- guessTarget ("*"++modStrName++".hs") Nothing | |
return target | |
) modStrNames | |
setTargets targets | |
load LoadAllTargets | |
modSums <- mapM | |
(\modStrName -> do | |
putString modStrName | |
modSum <- getModSummary $ mkModuleName modStrName | |
return $ ms_mod modSum | |
) modStrNames | |
return modSums | |
-- | List exported names of this or a sibling module | |
listExports mod = do | |
maybeModInfo <- getModuleInfo mod | |
case maybeModInfo of | |
(Just modInfo) -> do | |
let expNames = modInfoExports modInfo | |
expStrNames = map getOccString expNames | |
return expStrNames | |
_ -> return [] | |
-- | Util for printing | |
putString = liftIO . putStrLn |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module DynTest where | |
aString = "Hello" |
Here's one way of doing it: replace guessTarget ("*"++modStrName++".hs")
above with guessTarget ("/full/path/to/my/source/Foobar.hs")
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also, look at the filepath argument to runGhc. Here I use libdir from the ghc-paths package.