Created
November 5, 2012 01:44
-
-
Save seliopou/4014802 to your computer and use it in GitHub Desktop.
Boilerplate module for dynamically compiling, loading, and evaluating Haskell code.
This file contains 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
-- Boilerplate module for dynamic compilation, loading, and evaluation of | |
-- modules using the GHC API, v. 7.4.1. Note that the GHC API is subject to | |
-- change, so this file may not work for future versions. | |
-- | |
-- Load and play around with this file using: | |
-- | |
-- ghci -package ghc -XCPP GhcAPI.hs | |
-- | |
-- or | |
-- | |
-- ghci -package ghc -package ghc-mtl -XCPP -DWITH_MTL GhcAPI.hs | |
-- | |
-- References: | |
-- | |
-- 1. http://www.haskell.org/haskellwiki/GHC/As_a_library | |
-- 2. http://www.bluishcoder.co.nz/2008/11/dynamic-compilation-and-loading-of.html | |
-- | |
-- Some of the examples in the above references may be out-of-date with respect | |
-- to the 7.4.1 API. | |
-- | |
-- Note the return type of `evalFromModule` is way too general to be useful. | |
-- You need to make sure that you constrain the type variable to the type of | |
-- the identifier you're accessing in the dynamically loaded module. | |
-- | |
module GhcAPI where | |
#ifdef WITH_MTL | |
import Control.Monad.Ghc | |
import GHC hiding ( Ghc, GhcT, runGhc, runGhcT ) | |
#else | |
import GHC | |
#endif | |
import Data.Dynamic | |
import GHC.Paths ( libdir ) | |
import DynFlags | |
evalFromModule file modul ident = | |
defaultErrorHandler defaultLogAction $ do | |
runGhcT (Just libdir) $ do | |
dflags <- getSessionDynFlags | |
setSessionDynFlags dflags | |
target <- guessTarget file Nothing | |
setTargets [target] | |
result <- load LoadAllTargets | |
case result of | |
Succeeded -> do | |
m <- findModule (mkModuleName modul) Nothing | |
setContext [IIModule m] | |
value <- dynCompileExpr $ modul ++ "." ++ ident | |
return $ Just value | |
Failed -> return Nothing | |
evalFromModule' file modul ident witness = do | |
mval <- evalFromModule file modul ident | |
let c = flip (const :: Maybe a -> a -> Maybe a) witness | |
case mval of | |
Just v -> return $ c $ fromDynamic v | |
Nothing -> return Nothing |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment