Here is a full length example of a Haskell interpreter/compiler in the style of Malcolm Wallace's hi. Rather than compiling the user's code to an executable, we use hs-plugins to instead load an object file and execute that instead, using the eval interface. This cuts out the linking phase from the process, making turnaround at the prompt around twice as fast as hi.
import System.Eval.Haskell import System.Plugins import System.Exit ( ExitCode(..), exitWith ) import System.IO import System.Console.Readline ( readline, addHistory ) symbol = "resource" main = do putStrLn banner putStr "Loading package base" >> hFlush stdout loadPackage "base" putStr " ... linking ... " >> hFlush stdout resolveObjs putStrLn "done" shell [] shell :: [String] -> IO () shell imps = do s <- readline "plugs> " cmd <- case s of Nothing -> exitWith ExitSuccess Just (':':'q':_) -> exitWith ExitSuccess Just s -> addHistory s >> return s imps' <- run cmd imps shell imps' run :: String -> [String] -> IO [String] run "" is = return is run ":?" is = putStrLn help >> return is run ":l" _ = return [] run (':':'l':' ':m) is = return (m:is) run (':':'t':' ':s) is = do ty <- typeOf s is when (not $ null ty) (putStrLn $ s ++ " :: " ++ ty) return is run (':':_) is = putStrLn help >> return is run s is = do s <- unsafeEval ("show $ "++s) is when (isJust s) (putStrLn (fromJust s)) return is banner = "\ \ __ \n\ \ ____ / /_ ______ ______ \n\ \ / __ \\/ / / / / __ `/ ___/ PLugin User's GHCi System, for Haskell 98\n\ \ / /_/ / / /_/ / /_/ (__ ) http://www.cse.unsw.edu.au/~dons/hs-plugins\n\ \ / .___/_/\\__,_/\\__, /____/ Type :? for help \n\ \/_/ /____/ \n" help = "\ \Commands :\n\ \ <expr> evaluate expression\n\ \ :t <expr> show type of expression (monomorphic only)\n\ \ :l module bring module in to scope\n\ \ :l clear module list\n\ \ :quit quit\n\ \ :? display this list of commands"
And a transcript:
$ ./plugs __ ____ / /_ ______ ______ / __ \/ / / / / __ `/ ___/ PLugin User's GHCi System, for Haskell 98 / /_/ / / /_/ / /_/ (__ ) http://www.cse.unsw.edu.au/~dons/hs-plugins / .___/_/\__,_/\__, /____/ Type :? for help /_/ /____/ Loading package base ... linking ... done plugs> 1 1 plugs> let x = 1 + 2 in x 3 plugs> :l Data.List plugs> case [1,3,2] of x -> sort x [1,2,3] plugs> reverse [1,3,2] [2,3,1] plugs> map (\x-> (x,2^x)) [1,2,3,4,5,6,7,8,9,10] [(1,2),(2,4),(3,8),(4,16),(5,32),(6,64),(7,128),(8,256),(9,512),(10,1024)] plugs> :t "haskell" "haskell" :: [Char] plugs> :quit