> {-# OPTIONS_GHC -fglasgow-exts #-} > -- | > -- Module : Ivor.Plugin > -- Copyright : Edwin Brady > -- Licence : BSD-style (see LICENSE in the distribution) > -- > -- Maintainer : eb@dcs.st-and.ac.uk > -- Stability : experimental > -- Portability : portable > -- > -- Plugin loader > module Ivor.Plugin(Ivor.Plugin.load) where > import Ivor.TT > import Ivor.ShellState > -- import System.Plugins as Plugins > import Text.ParserCombinators.Parsec > -- | Load the given plugin file (which should be a full path to a .o or > -- .hs file) and update the Context. If it is a .hs file, it will be > -- compiled if necessary. > -- Plugins must contain the symbol > -- @plugin_context :: Monad m => Context -> m Context@ > -- which updates the context. It may optionally contain symbols > -- @plugin_parser :: Parser ViewTerm@ > -- which adds new parsing rules, > -- @plugin_shell :: ShellState -> IO ShellState@ > -- which updates the shell > -- @plugin_commands :: IO [(String, String -> COntext -> IO (String, Context))]@ > -- which adds new user defined commands (which may need to do some setting up themselves, hence the IO) > -- Returns the new context and the extra parsing rules and commands, if any. > load :: FilePath -> Context -> IO (Context, > Maybe (Parser ViewTerm), > Maybe (ShellState -> IO ShellState), > Maybe (IO [(String, String -> Context -> IO (String, Context))])) > load fn ctxt = fail "Currently disabled" -- > load fn ctxt = do -- > objIn <- compilePlugin fn -- > obj <- case objIn of -- > Left errs -> fail errs -- > Right ok -> return ok -- > contextMod <- Plugins.load_ obj [] "plugin_context" -- > -- mv <- Plugins.load fn [] ["/Users/edwin/.ghc/i386-darwin-6.6.1/package.conf"] "initialise" -- > (mod, contextFn) <- case contextMod of -- > LoadFailure msg -> fail $ "Plugin loading failed: " ++ -- > show msg -- > LoadSuccess mod v -> return (mod, v) -- > parserMod <- Plugins.reload mod "plugin_parser" -- > parserules <- case parserMod of -- > LoadFailure msg -> return Nothing -- > LoadSuccess _ v -> return $ Just v -- > cmdMod <- Plugins.reload mod "plugin_commands" -- > cmds <- case cmdMod of -- > LoadFailure msg -> return Nothing -- > LoadSuccess _ v -> return $ Just v -- > shellMod <- Plugins.reload mod "plugin_shell" -- > shellfn <- case shellMod of -- > LoadFailure msg -> return Nothing -- > LoadSuccess _ v -> return $ Just v -- > ctxt' <- case contextFn ctxt of -- > Just x -> return x -- > Nothing -> fail "Error in running plugin_context" -- > return $ (ctxt', parserules, shellfn, cmds) -- Make a .o from a .hs, so that we can load Haskell source as well as object -- files -- > compilePlugin :: FilePath -> IO (Either String FilePath) -- > compilePlugin hs -- > | isExt ".hs" hs || isExt ".lhs" hs = -- > do status <- makeAll hs [] -- > case status of -- > MakeSuccess c out -> return $ Right out -- > MakeFailure errs -> return $ Left (concat (map (++"\n") errs)) -- > | isExt ".o" hs = return $ Right hs -- > | elem '.' hs = return (Left $ "unrecognised file type " ++ hs) -- > | otherwise = compilePlugin (hs++".o") -- > where isExt ext fn = case span (/='.') fn of -- > (file, e) -> ext == e