-- -- a simple shell for loading plugins and evaluating their functions -- import Plugins import API import Data.Either import Data.Char import Control.Monad ( when ) import System.Console.Readline ( readline ) import System.Exit ( ExitCode(..), exitWith ) source = "Plugin.hs" stub = "Plugin.stub" object = "Plugin.o" sym = "resource" main = do makeWith source stub [] p <- load object ["."] Nothing sym shell p where shell p@(m,v) = do s <- readline "> " cmd <- case s of Nothing -> exitWith ExitSuccess Just ":quit" -> exitWith ExitSuccess Just s -> return (chomp s) -- possibly recompile if the source changed (_,rebuilt,_) <- makeWith source stub [] p' <- if rebuilt then return p -- not remade, don't reload else reload m sym >>= \v' -> return (m,v') p'' <- eval cmd p' shell p'' -- -- shell commands -- eval "" p = return p eval ":clear" p = do let loop i = when (i < 40) (do putStr "\n" ; loop $! i+1) loop 0 return p -- apply the user's code eval cmd@(':':'f':'i':'l':'t':'e':'r':' ':s) (m,v) = putStrLn ((function v) s) >> return (m,v) eval ":?" p = do putStrLn$"\":?\"\n" ++ "\":quit\"\n" ++ "\":clear\"\n" ++ "\":filter foo\"" return p eval _ p = putStrLn "command not found" >> return p -- -- strip trailing whitespace -- chomp :: String -> String chomp [] = [] chomp s | isSpace (last s) = chomp $! init s | otherwise = s