Skip to content

Instantly share code, notes, and snippets.

@jhartikainen
Created August 20, 2011 11:31

Revisions

  1. jhartikainen created this gist Aug 20, 2011.
    45 changes: 45 additions & 0 deletions DynLoad.hs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    {-# LANGUAGE ScopedTypeVariables #-}
    module DynLoad (
    loadSourceGhc,
    execFnGhc
    ) where

    import Control.Exception (throw)
    import GHC hiding (loadModule)
    import GHC.Paths (libdir)
    import HscTypes (SourceError, srcErrorMessages)
    import DynFlags
    import Unsafe.Coerce
    import Bag (bagToList)

    execFnGhc :: String -> String -> Ghc a
    execFnGhc modname fn = do
    mod <- findModule (mkModuleName modname) Nothing
    setContext [] [mod]
    value <- compileExpr (modname ++ "." ++ fn)

    let value' = (unsafeCoerce value) :: a
    return value'

    loadSourceGhc :: String -> Ghc (Maybe String)
    loadSourceGhc path = let
    throwingLogger (Just e) = throw e
    throwingLogger _ = return ()
    in do
    dflags <- getSessionDynFlags
    setSessionDynFlags (dflags{
    ghcLink = LinkInMemory,
    hscTarget = HscInterpreted,
    packageFlags = [ExposePackage "ghc"]
    })
    target <- guessTarget path Nothing
    addTarget target
    r <- loadWithLogger throwingLogger LoadAllTargets
    case r of
    Failed -> return $ Just "Generic module load error"
    Succeeded -> return Nothing

    `gcatch` \(e :: SourceError) -> let
    errors e = concat $ map show (bagToList $ srcErrorMessages e)
    in
    return $ Just (errors e)