1 {-# OPTIONS -#include "Linker.h" #-}
2 -----------------------------------------------------------------------------
4 -- GHC Interactive User Interface
6 -- (c) The GHC Team 2005
8 -----------------------------------------------------------------------------
14 #include "HsVersions.h"
18 import GHC ( Session, verbosity, dopt, DynFlag(..),
19 mkModule, pprModule, Type, Module, SuccessFlag(..),
20 TyThing(..), Name, LoadHowMuch(..), Phase,
21 GhcException(..), showGhcException,
25 -- for createtags (should these come via GHC?)
26 import Module( moduleUserString )
27 import Name( nameSrcLoc, nameModule, nameOccName )
28 import OccName( pprOccName )
29 import SrcLoc( isGoodSrcLoc, srcLocFile, srcLocLine, srcLocCol )
31 -- following all needed for :info... ToDo: remove
32 import IfaceSyn ( IfaceDecl(..), IfaceClassOp(..), IfaceConDecls(..),
33 IfaceConDecl(..), IfaceType,
34 pprIfaceDeclHead, pprParendIfaceType,
35 pprIfaceForAllPart, pprIfaceType )
36 import FunDeps ( pprFundeps )
37 import SrcLoc ( SrcLoc, pprDefnLoc )
38 import OccName ( OccName, parenSymOcc, occNameUserString )
39 import BasicTypes ( StrictnessMark(..), defaultFixity, failed, successIf )
41 -- Other random utilities
42 import Panic ( panic, installSignalHandlers )
44 import StaticFlags ( opt_IgnoreDotGhci )
45 import Linker ( showLinkerState )
46 import Util ( removeSpaces, handle, global, toArgs,
47 looksLikeModuleName, prefixMatch, sortLe )
48 import ErrUtils ( printErrorsAndWarnings )
50 #ifndef mingw32_HOST_OS
52 #if __GLASGOW_HASKELL__ > 504
56 import GHC.ConsoleHandler ( flushConsole )
60 import Control.Concurrent ( yield ) -- Used in readline loop
61 import System.Console.Readline as Readline
66 import Control.Exception as Exception
68 -- import Control.Concurrent
72 import Data.Int ( Int64 )
73 import Data.Maybe ( isJust )
76 import System.Environment
77 import System.Exit ( exitWith, ExitCode(..) )
78 import System.Directory
80 import System.IO.Error as IO
82 import Control.Monad as Monad
83 import Foreign.StablePtr ( newStablePtr )
85 import GHC.Exts ( unsafeCoerce# )
86 import GHC.IOBase ( IOErrorType(InvalidArgument) )
88 import Data.IORef ( IORef, newIORef, readIORef, writeIORef )
90 import System.Posix.Internals ( setNonBlockingFD )
92 -----------------------------------------------------------------------------
96 " / _ \\ /\\ /\\/ __(_)\n"++
97 " / /_\\// /_/ / / | | GHC Interactive, version " ++ cProjectVersion ++ ", for Haskell 98.\n"++
98 "/ /_\\\\/ __ / /___| | http://www.haskell.org/ghc/\n"++
99 "\\____/\\/ /_/\\____/|_| Type :? for help.\n"
101 GLOBAL_VAR(commands, builtin_commands, [(String, String -> GHCi Bool)])
103 builtin_commands :: [(String, String -> GHCi Bool)]
105 ("add", keepGoingPaths addModule),
106 ("browse", keepGoing browseCmd),
107 ("cd", keepGoing changeDirectory),
108 ("def", keepGoing defineMacro),
109 ("help", keepGoing help),
110 ("?", keepGoing help),
111 ("info", keepGoing info),
112 ("load", keepGoingPaths loadModule_),
113 ("module", keepGoing setContext),
114 ("reload", keepGoing reloadModule),
115 ("check", keepGoing checkModule),
116 ("set", keepGoing setCmd),
117 ("show", keepGoing showCmd),
118 ("tags", keepGoing createTagsFileCmd),
119 ("type", keepGoing typeOfExpr),
120 ("kind", keepGoing kindOfType),
121 ("unset", keepGoing unsetOptions),
122 ("undef", keepGoing undefineMacro),
126 keepGoing :: (String -> GHCi ()) -> (String -> GHCi Bool)
127 keepGoing a str = a str >> return False
129 keepGoingPaths :: ([FilePath] -> GHCi ()) -> (String -> GHCi Bool)
130 keepGoingPaths a str = a (toArgs str) >> return False
132 shortHelpText = "use :? for help.\n"
134 -- NOTE: spaces at the end of each line to workaround CPP/string gap bug.
136 " Commands available from the prompt:\n" ++
138 " <stmt> evaluate/run <stmt>\n" ++
139 " :add <filename> ... add module(s) to the current target set\n" ++
140 " :browse [*]<module> display the names defined by <module>\n" ++
141 " :cd <dir> change directory to <dir>\n" ++
142 " :def <cmd> <expr> define a command :<cmd>\n" ++
143 " :help, :? display this list of commands\n" ++
144 " :info [<name> ...] display information about the given names\n" ++
145 " :load <filename> ... load module(s) and their dependents\n" ++
146 " :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
147 " :reload reload the current module set\n" ++
149 " :set <option> ... set options\n" ++
150 " :set args <arg> ... set the arguments returned by System.getArgs\n" ++
151 " :set prog <progname> set the value returned by System.getProgName\n" ++
153 " :show modules show the currently loaded modules\n" ++
154 " :show bindings show the current bindings made at the prompt\n" ++
156 " :tags -e|-c create tags file for Vi (-c) or Emacs (-e)\n" ++
157 " :type <expr> show the type of <expr>\n" ++
158 " :kind <type> show the kind of <type>\n" ++
159 " :undef <cmd> undefine user-defined command :<cmd>\n" ++
160 " :unset <option> ... unset options\n" ++
161 " :quit exit GHCi\n" ++
162 " :!<command> run the shell command <command>\n" ++
164 " Options for ':set' and ':unset':\n" ++
166 " +r revert top-level expressions after each evaluation\n" ++
167 " +s print timing/memory stats after each evaluation\n" ++
168 " +t print type after evaluation\n" ++
169 " -<flags> most GHC command line flags can also be set here\n" ++
170 " (eg. -v2, -fglasgow-exts, etc.)\n"
173 interactiveUI :: Session -> [(FilePath, Maybe Phase)] -> Maybe String -> IO ()
174 interactiveUI session srcs maybe_expr = do
176 -- HACK! If we happen to get into an infinite loop (eg the user
177 -- types 'let x=x in x' at the prompt), then the thread will block
178 -- on a blackhole, and become unreachable during GC. The GC will
179 -- detect that it is unreachable and send it the NonTermination
180 -- exception. However, since the thread is unreachable, everything
181 -- it refers to might be finalized, including the standard Handles.
182 -- This sounds like a bug, but we don't have a good solution right
189 hSetBuffering stdout NoBuffering
191 -- Initialise buffering for the *interpreted* I/O system
192 initInterpBuffering session
194 -- We don't want the cmd line to buffer any input that might be
195 -- intended for the program, so unbuffer stdin.
196 hSetBuffering stdin NoBuffering
198 -- initial context is just the Prelude
199 GHC.setContext session [] [prelude_mod]
205 #if defined(mingw32_HOST_OS)
206 -- The win32 Console API mutates the first character of
207 -- type-ahead when reading from it in a non-buffered manner. Work
208 -- around this by flushing the input buffer of type-ahead characters.
210 GHC.ConsoleHandler.flushConsole stdin
212 startGHCi (runGHCi srcs maybe_expr)
213 GHCiState{ progname = "<interactive>",
219 Readline.resetTerminal Nothing
224 runGHCi :: [(FilePath, Maybe Phase)] -> Maybe String -> GHCi ()
225 runGHCi paths maybe_expr = do
226 let read_dot_files = not opt_IgnoreDotGhci
228 when (read_dot_files) $ do
231 exists <- io (doesFileExist file)
233 dir_ok <- io (checkPerms ".")
234 file_ok <- io (checkPerms file)
235 when (dir_ok && file_ok) $ do
236 either_hdl <- io (IO.try (openFile "./.ghci" ReadMode))
239 Right hdl -> fileLoop hdl False
241 when (read_dot_files) $ do
242 -- Read in $HOME/.ghci
243 either_dir <- io (IO.try (getEnv "HOME"))
247 cwd <- io (getCurrentDirectory)
248 when (dir /= cwd) $ do
249 let file = dir ++ "/.ghci"
250 ok <- io (checkPerms file)
252 either_hdl <- io (IO.try (openFile file ReadMode))
255 Right hdl -> fileLoop hdl False
257 -- Perform a :load for files given on the GHCi command line
258 -- When in -e mode, if the load fails then we want to stop
259 -- immediately rather than going on to evaluate the expression.
260 when (not (null paths)) $ do
261 ok <- ghciHandle (\e -> do showException e; return Failed) $
263 when (isJust maybe_expr && failed ok) $
264 io (exitWith (ExitFailure 1))
266 -- if verbosity is greater than 0, or we are connected to a
267 -- terminal, display the prompt in the interactive loop.
268 is_tty <- io (hIsTerminalDevice stdin)
269 dflags <- getDynFlags
270 let show_prompt = verbosity dflags > 0 || is_tty
274 -- enter the interactive loop
275 interactiveLoop is_tty show_prompt
277 -- just evaluate the expression we were given
282 io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi."
285 interactiveLoop is_tty show_prompt = do
286 -- Ignore ^C exceptions caught here
287 ghciHandleDyn (\e -> case e of
288 Interrupted -> ghciUnblock (
289 #if defined(mingw32_HOST_OS)
292 interactiveLoop is_tty show_prompt)
293 _other -> return ()) $ do
295 -- read commands from stdin
299 else fileLoop stdin show_prompt
301 fileLoop stdin show_prompt
305 -- NOTE: We only read .ghci files if they are owned by the current user,
306 -- and aren't world writable. Otherwise, we could be accidentally
307 -- running code planted by a malicious third party.
309 -- Furthermore, We only read ./.ghci if . is owned by the current user
310 -- and isn't writable by anyone else. I think this is sufficient: we
311 -- don't need to check .. and ../.. etc. because "." always refers to
312 -- the same directory while a process is running.
314 checkPerms :: String -> IO Bool
316 #ifdef mingw32_HOST_OS
319 Util.handle (\_ -> return False) $ do
320 st <- getFileStatus name
322 if fileOwner st /= me then do
323 putStrLn $ "WARNING: " ++ name ++ " is owned by someone else, IGNORING!"
326 let mode = fileMode st
327 if (groupWriteMode == (mode `intersectFileModes` groupWriteMode))
328 || (otherWriteMode == (mode `intersectFileModes` otherWriteMode))
330 putStrLn $ "*** WARNING: " ++ name ++
331 " is writable by someone else, IGNORING!"
336 fileLoop :: Handle -> Bool -> GHCi ()
337 fileLoop hdl prompt = do
338 session <- getSession
339 (mod,imports) <- io (GHC.getContext session)
340 when prompt (io (putStr (mkPrompt mod imports)))
341 l <- io (IO.try (hGetLine hdl))
343 Left e | isEOFError e -> return ()
344 | InvalidArgument <- etype -> return ()
345 | otherwise -> io (ioError e)
346 where etype = ioeGetErrorType e
347 -- treat InvalidArgument in the same way as EOF:
348 -- this can happen if the user closed stdin, or
349 -- perhaps did getContents which closes stdin at
352 case removeSpaces l of
353 "" -> fileLoop hdl prompt
354 l -> do quit <- runCommand l
355 if quit then return () else fileLoop hdl prompt
357 stringLoop :: [String] -> GHCi ()
358 stringLoop [] = return ()
359 stringLoop (s:ss) = do
360 case removeSpaces s of
362 l -> do quit <- runCommand l
363 if quit then return () else stringLoop ss
365 mkPrompt toplevs exports
366 = showSDoc (hsep (map (\m -> char '*' <> pprModule m) toplevs)
367 <+> hsep (map pprModule exports)
371 readlineLoop :: GHCi ()
373 session <- getSession
374 (mod,imports) <- io (GHC.getContext session)
376 l <- io (readline (mkPrompt mod imports)
377 `finally` setNonBlockingFD 0)
378 -- readline sometimes puts stdin into blocking mode,
379 -- so we need to put it back for the IO library
383 case removeSpaces l of
388 if quit then return () else readlineLoop
391 runCommand :: String -> GHCi Bool
392 runCommand c = ghciHandle handler (doCommand c)
394 -- This version is for the GHC command-line option -e. The only difference
395 -- from runCommand is that it catches the ExitException exception and
396 -- exits, rather than printing out the exception.
397 runCommandEval c = ghciHandle handleEval (doCommand c)
399 handleEval (ExitException code) = io (exitWith code)
400 handleEval e = do showException e
401 io (exitWith (ExitFailure 1))
403 -- This is the exception handler for exceptions generated by the
404 -- user's code; it normally just prints out the exception. The
405 -- handler must be recursive, in case showing the exception causes
406 -- more exceptions to be raised.
408 -- Bugfix: if the user closed stdout or stderr, the flushing will fail,
409 -- raising another exception. We therefore don't put the recursive
410 -- handler arond the flushing operation, so if stderr is closed
411 -- GHCi will just die gracefully rather than going into an infinite loop.
412 handler :: Exception -> GHCi Bool
413 handler exception = do
415 io installSignalHandlers
416 ghciHandle handler (showException exception >> return False)
418 showException (DynException dyn) =
419 case fromDynamic dyn of
420 Nothing -> io (putStrLn ("*** Exception: (unknown)"))
421 Just Interrupted -> io (putStrLn "Interrupted.")
422 Just (CmdLineError s) -> io (putStrLn s) -- omit the location for CmdLineError
423 Just ph@PhaseFailed{} -> io (putStrLn (showGhcException ph "")) -- ditto
424 Just other_ghc_ex -> io (print other_ghc_ex)
426 showException other_exception
427 = io (putStrLn ("*** Exception: " ++ show other_exception))
429 doCommand (':' : command) = specialCommand command
431 = do timeIt (do nms <- runStmt stmt; finishEvalExpr nms)
434 runStmt :: String -> GHCi [Name]
436 | null (filter (not.isSpace) stmt) = return []
438 = do st <- getGHCiState
439 session <- getSession
440 result <- io $ withProgName (progname st) $ withArgs (args st) $
441 GHC.runStmt session stmt
443 GHC.RunFailed -> return []
444 GHC.RunException e -> throw e -- this is caught by runCommand(Eval)
445 GHC.RunOk names -> return names
447 -- possibly print the type and revert CAFs after evaluating an expression
449 = do b <- isOptionSet ShowType
450 session <- getSession
451 when b (mapM_ (showTypeOfName session) names)
454 io installSignalHandlers
455 b <- isOptionSet RevertCAFs
456 io (when b revertCAFs)
459 showTypeOfName :: Session -> Name -> GHCi ()
460 showTypeOfName session n
461 = do maybe_tything <- io (GHC.lookupName session n)
462 case maybe_tything of
464 Just thing -> showTyThing thing
466 showForUser :: SDoc -> GHCi String
468 session <- getSession
469 unqual <- io (GHC.getPrintUnqual session)
470 return $! showSDocForUser unqual doc
472 specialCommand :: String -> GHCi Bool
473 specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
474 specialCommand str = do
475 let (cmd,rest) = break isSpace str
476 cmds <- io (readIORef commands)
477 case [ (s,f) | (s,f) <- cmds, prefixMatch cmd s ] of
478 [] -> io (hPutStr stdout ("unknown command ':" ++ cmd ++ "'\n"
479 ++ shortHelpText) >> return False)
480 [(_,f)] -> f (dropWhile isSpace rest)
481 cs -> io (hPutStrLn stdout ("prefix " ++ cmd ++
482 " matches multiple commands (" ++
483 foldr1 (\a b -> a ++ ',':b) (map fst cs)
484 ++ ")") >> return False)
486 -----------------------------------------------------------------------------
487 -- To flush buffers for the *interpreted* computation we need
488 -- to refer to *its* stdout/stderr handles
490 GLOBAL_VAR(flush_interp, error "no flush_interp", IO ())
491 GLOBAL_VAR(turn_off_buffering, error "no flush_stdout", IO ())
493 no_buf_cmd = "System.IO.hSetBuffering System.IO.stdout System.IO.NoBuffering" ++
494 " Prelude.>> System.IO.hSetBuffering System.IO.stderr System.IO.NoBuffering"
495 flush_cmd = "System.IO.hFlush System.IO.stdout Prelude.>> System.IO.hFlush IO.stderr"
497 initInterpBuffering :: Session -> IO ()
498 initInterpBuffering session
499 = do maybe_hval <- GHC.compileExpr session no_buf_cmd
502 Just hval -> writeIORef turn_off_buffering (unsafeCoerce# hval :: IO ())
503 other -> panic "interactiveUI:setBuffering"
505 maybe_hval <- GHC.compileExpr session flush_cmd
507 Just hval -> writeIORef flush_interp (unsafeCoerce# hval :: IO ())
508 _ -> panic "interactiveUI:flush"
510 turnOffBuffering -- Turn it off right now
515 flushInterpBuffers :: GHCi ()
517 = io $ do Monad.join (readIORef flush_interp)
520 turnOffBuffering :: IO ()
522 = do Monad.join (readIORef turn_off_buffering)
525 -----------------------------------------------------------------------------
528 help :: String -> GHCi ()
529 help _ = io (putStr helpText)
531 info :: String -> GHCi ()
532 info "" = throwDyn (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
533 info s = do { let names = words s
534 ; session <- getSession
535 ; dflags <- getDynFlags
536 ; let exts = dopt Opt_GlasgowExts dflags
537 ; mapM_ (infoThing exts session) names }
539 infoThing exts session name
540 = do { stuff <- io (GHC.getInfo session name)
541 ; unqual <- io (GHC.getPrintUnqual session)
542 ; io (putStrLn (showSDocForUser unqual $
543 vcat (intersperse (text "") (map (showThing exts) stuff)))) }
545 showThing :: Bool -> GHC.GetInfoResult -> SDoc
546 showThing exts (wanted_str, thing, fixity, src_loc, insts)
547 = vcat [ showWithLoc src_loc (showDecl exts want_name thing),
549 vcat (map show_inst insts)]
551 want_name occ = wanted_str == occNameUserString occ
554 | fix == defaultFixity = empty
555 | otherwise = ppr fix <+> text wanted_str
557 show_inst (inst_ty, loc)
558 = showWithLoc loc (ptext SLIT("instance") <+> ppr inst_ty)
560 showWithLoc :: SrcLoc -> SDoc -> SDoc
562 = hang doc 2 (char '\t' <> comment <+> pprDefnLoc loc)
563 -- The tab tries to make them line up a bit
565 comment = ptext SLIT("--")
568 -- Now there is rather a lot of goop just to print declarations in a
569 -- civilised way with "..." for the parts we are less interested in.
571 showDecl :: Bool -> (OccName -> Bool) -> IfaceDecl -> SDoc
572 showDecl exts want_name (IfaceForeign {ifName = tc})
573 = ppr tc <+> ptext SLIT("is a foreign type")
575 showDecl exts want_name (IfaceId {ifName = var, ifType = ty})
576 = ppr var <+> dcolon <+> showIfaceType exts ty
578 showDecl exts want_name (IfaceSyn {ifName = tycon, ifTyVars = tyvars, ifSynRhs = mono_ty})
579 = hang (ptext SLIT("type") <+> pprIfaceDeclHead [] tycon tyvars)
580 2 (equals <+> ppr mono_ty)
582 showDecl exts want_name (IfaceData {ifName = tycon,
583 ifTyVars = tyvars, ifCons = condecls, ifCtxt = context})
584 = hang (pp_nd <+> pprIfaceDeclHead context tycon tyvars)
585 2 (add_bars (ppr_trim show_con cs))
587 show_con (IfVanillaCon { ifConOcc = con_name, ifConInfix = is_infix, ifConArgTys = tys,
588 ifConStricts = strs, ifConFields = flds})
589 | want_name tycon || want_name con_name || any want_name flds
590 = Just (show_guts con_name is_infix tys_w_strs flds)
591 | otherwise = Nothing
593 tys_w_strs = tys `zip` (strs ++ repeat NotMarkedStrict)
594 show_con (IfGadtCon { ifConOcc = con_name, ifConTyVars = tvs, ifConCtxt = theta,
595 ifConArgTys = arg_tys, ifConResTys = res_tys, ifConStricts = strs })
596 | want_name tycon || want_name con_name
597 = Just (ppr_bndr con_name <+> colon <+> pprIfaceForAllPart tvs theta pp_tau)
598 | otherwise = Nothing
600 tys_w_strs = arg_tys `zip` (strs ++ repeat NotMarkedStrict)
601 pp_tau = foldr add pp_res_ty tys_w_strs
602 pp_res_ty = ppr_bndr tycon <+> hsep (map pprParendIfaceType res_tys)
603 add bty pp_ty = ppr_bangty bty <+> arrow <+> pp_ty
605 show_guts con True [ty1, ty2] flds = sep [ppr_bangty ty1, ppr con, ppr_bangty ty2]
606 show_guts con _ tys [] = ppr_bndr con <+> sep (map ppr_bangty tys)
607 show_guts con _ tys flds
608 = ppr_bndr con <+> braces (sep (punctuate comma (ppr_trim show_fld (tys `zip` flds))))
610 show_fld (bty, fld) | want_name tycon || want_name con || want_name fld
611 = Just (ppr_bndr fld <+> dcolon <+> ppr_bangty bty)
612 | otherwise = Nothing
614 (pp_nd, cs) = case condecls of
615 IfAbstractTyCon -> (ptext SLIT("data"), [])
616 IfDataTyCon cs -> (ptext SLIT("data"), cs)
617 IfNewTyCon c -> (ptext SLIT("newtype"),[c])
620 add_bars [c] = equals <+> c
621 add_bars (c:cs) = equals <+> sep (c : map (char '|' <+>) cs)
623 ppr_bangty (ty, str) = ppr_str str <> pprParendIfaceType ty
624 ppr_str MarkedStrict = char '!'
625 ppr_str MarkedUnboxed = ptext SLIT("!!")
626 ppr_str NotMarkedStrict = empty
628 showDecl exts want_name (IfaceClass {ifCtxt = context, ifName = clas, ifTyVars = tyvars,
629 ifFDs = fds, ifSigs = sigs})
630 = hang (ptext SLIT("class") <+> pprIfaceDeclHead context clas tyvars
631 <+> pprFundeps fds <+> opt_where)
632 2 (vcat (ppr_trim show_op sigs))
634 opt_where | null sigs = empty
635 | otherwise = ptext SLIT("where")
636 show_op (IfaceClassOp op dm ty)
637 | want_name clas || want_name op
638 = Just (ppr_bndr op <+> dcolon <+> showIfaceType exts ty)
642 showIfaceType :: Bool -> IfaceType -> SDoc
643 showIfaceType True ty = pprIfaceType ty -- -fglasgow-exts: print with the foralls
644 showIfaceType False ty = ppr ty -- otherwise, print without the foralls
646 ppr_trim :: (a -> Maybe SDoc) -> [a] -> [SDoc]
648 = snd (foldr go (False, []) xs)
650 go x (eliding, so_far)
651 | Just doc <- show x = (False, doc : so_far)
652 | otherwise = if eliding then (True, so_far)
653 else (True, ptext SLIT("...") : so_far)
655 ppr_bndr :: OccName -> SDoc
656 -- Wrap operators in ()
657 ppr_bndr occ = parenSymOcc occ (ppr occ)
660 -----------------------------------------------------------------------------
663 addModule :: [FilePath] -> GHCi ()
665 io (revertCAFs) -- always revert CAFs on load/add.
666 files <- mapM expandPath files
667 targets <- mapM (\m -> io (GHC.guessTarget m Nothing)) files
668 session <- getSession
669 io (mapM_ (GHC.addTarget session) targets)
670 ok <- io (GHC.load session LoadAllTargets)
673 changeDirectory :: String -> GHCi ()
674 changeDirectory dir = do
675 session <- getSession
676 graph <- io (GHC.getModuleGraph session)
677 when (not (null graph)) $
678 io $ putStr "Warning: changing directory causes all loaded modules to be unloaded,\nbecause the search path has changed.\n"
679 io (GHC.setTargets session [])
680 io (GHC.load session LoadAllTargets)
681 setContextAfterLoad []
682 io (GHC.workingDirectoryChanged session)
683 dir <- expandPath dir
684 io (setCurrentDirectory dir)
686 defineMacro :: String -> GHCi ()
688 let (macro_name, definition) = break isSpace s
689 cmds <- io (readIORef commands)
691 then throwDyn (CmdLineError "invalid macro name")
693 if (macro_name `elem` map fst cmds)
694 then throwDyn (CmdLineError
695 ("command '" ++ macro_name ++ "' is already defined"))
698 -- give the expression a type signature, so we can be sure we're getting
699 -- something of the right type.
700 let new_expr = '(' : definition ++ ") :: String -> IO String"
702 -- compile the expression
704 maybe_hv <- io (GHC.compileExpr cms new_expr)
707 Just hv -> io (writeIORef commands --
708 ((macro_name, keepGoing (runMacro hv)) : cmds))
710 runMacro :: GHC.HValue{-String -> IO String-} -> String -> GHCi ()
712 str <- io ((unsafeCoerce# fun :: String -> IO String) s)
713 stringLoop (lines str)
715 undefineMacro :: String -> GHCi ()
716 undefineMacro macro_name = do
717 cmds <- io (readIORef commands)
718 if (macro_name `elem` map fst builtin_commands)
719 then throwDyn (CmdLineError
720 ("command '" ++ macro_name ++ "' cannot be undefined"))
722 if (macro_name `notElem` map fst cmds)
723 then throwDyn (CmdLineError
724 ("command '" ++ macro_name ++ "' not defined"))
726 io (writeIORef commands (filter ((/= macro_name) . fst) cmds))
729 loadModule :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
730 loadModule fs = timeIt (loadModule' fs)
732 loadModule_ :: [FilePath] -> GHCi ()
733 loadModule_ fs = do loadModule (zip fs (repeat Nothing)); return ()
735 loadModule' :: [(FilePath, Maybe Phase)] -> GHCi SuccessFlag
736 loadModule' files = do
737 session <- getSession
740 io (GHC.setTargets session [])
741 io (GHC.load session LoadAllTargets)
744 let (filenames, phases) = unzip files
745 exp_filenames <- mapM expandPath filenames
746 let files' = zip exp_filenames phases
747 targets <- io (mapM (uncurry GHC.guessTarget) files')
749 -- NOTE: we used to do the dependency anal first, so that if it
750 -- fails we didn't throw away the current set of modules. This would
751 -- require some re-working of the GHC interface, so we'll leave it
752 -- as a ToDo for now.
754 io (GHC.setTargets session targets)
755 ok <- io (GHC.load session LoadAllTargets)
759 checkModule :: String -> GHCi ()
761 let modl = mkModule m
762 session <- getSession
763 result <- io (GHC.checkModule session modl printErrorsAndWarnings)
765 Nothing -> io $ putStrLn "Nothing"
766 Just r -> io $ putStrLn (showSDoc (
767 case checkedModuleInfo r of
768 Just cm | Just scope <- GHC.modInfoTopLevelScope cm ->
770 (local,global) = partition ((== modl) . GHC.nameModule) scope
772 (text "global names: " <+> ppr global) $$
773 (text "local names: " <+> ppr local)
775 afterLoad (successIf (isJust result)) session
777 reloadModule :: String -> GHCi ()
779 io (revertCAFs) -- always revert CAFs on reload.
780 session <- getSession
781 ok <- io (GHC.load session LoadAllTargets)
784 io (revertCAFs) -- always revert CAFs on reload.
785 session <- getSession
786 ok <- io (GHC.load session (LoadUpTo (mkModule m)))
789 afterLoad ok session = do
790 io (revertCAFs) -- always revert CAFs on load.
791 graph <- io (GHC.getModuleGraph session)
792 let mods = map GHC.ms_mod graph
793 mods' <- filterM (io . GHC.isLoaded session) mods
794 setContextAfterLoad mods'
795 modulesLoadedMsg ok mods'
797 setContextAfterLoad [] = do
798 session <- getSession
799 io (GHC.setContext session [] [prelude_mod])
800 setContextAfterLoad (m:_) = do
801 session <- getSession
802 b <- io (GHC.moduleIsInterpreted session m)
803 if b then io (GHC.setContext session [m] [])
804 else io (GHC.setContext session [] [m])
806 modulesLoadedMsg :: SuccessFlag -> [Module] -> GHCi ()
807 modulesLoadedMsg ok mods = do
808 dflags <- getDynFlags
809 when (verbosity dflags > 0) $ do
811 | null mods = text "none."
813 punctuate comma (map pprModule mods)) <> text "."
816 io (putStrLn (showSDoc (text "Failed, modules loaded: " <> mod_commas)))
818 io (putStrLn (showSDoc (text "Ok, modules loaded: " <> mod_commas)))
821 typeOfExpr :: String -> GHCi ()
823 = do cms <- getSession
824 maybe_ty <- io (GHC.exprType cms str)
827 Just ty -> do ty' <- cleanType ty
828 tystr <- showForUser (ppr ty')
829 io (putStrLn (str ++ " :: " ++ tystr))
831 kindOfType :: String -> GHCi ()
833 = do cms <- getSession
834 maybe_ty <- io (GHC.typeKind cms str)
837 Just ty -> do tystr <- showForUser (ppr ty)
838 io (putStrLn (str ++ " :: " ++ tystr))
840 quit :: String -> GHCi Bool
843 shellEscape :: String -> GHCi Bool
844 shellEscape str = io (system str >> return False)
846 -----------------------------------------------------------------------------
847 -- create tags file for currently loaded modules.
849 createTagsFileCmd :: String -> GHCi ()
850 createTagsFileCmd "-c" = ghciCreateTagsFile CTags "tags"
851 createTagsFileCmd "-e" = ghciCreateTagsFile ETags "TAGS"
852 createTagsFileCmd _ = throwDyn (CmdLineError "syntax: :tags -c|-e")
854 data TagsKind = ETags | CTags
856 ghciCreateTagsFile :: TagsKind -> FilePath -> GHCi ()
857 ghciCreateTagsFile kind file = do
858 session <- getSession
859 io $ createTagsFile session kind file
862 -- - remove restriction that all modules must be interpreted
863 -- (problem: we don't know source locations for entities unless
864 -- we compiled the module.
866 -- - extract createTagsFile so it can be used from the command-line
867 -- (probably need to fix first problem before this is useful).
869 createTagsFile :: Session -> TagsKind -> FilePath -> IO ()
870 createTagsFile session tagskind tagFile = do
871 graph <- GHC.getModuleGraph session
872 let ms = map GHC.ms_mod graph
874 is_interpreted <- GHC.moduleIsInterpreted session m
875 -- should we just skip these?
876 when (not is_interpreted) $
877 throwDyn (CmdLineError ("module '" ++ moduleUserString m ++ "' is not interpreted"))
879 mbModInfo <- GHC.getModuleInfo session m
881 | Just modinfo <- mbModInfo,
882 Just unqual <- GHC.modInfoPrintUnqualified modinfo = unqual
883 | otherwise = GHC.alwaysQualify
886 Just modInfo -> return $! listTags unqual modInfo
889 mtags <- mapM tagModule ms
890 either_res <- collateAndWriteTags tagskind tagFile $ concat mtags
892 Left e -> hPutStrLn stderr $ ioeGetErrorString e
895 listTags :: PrintUnqualified -> GHC.ModuleInfo -> [TagInfo]
896 listTags unqual modInfo =
897 [ tagInfo unqual name loc
898 | name <- GHC.modInfoExports modInfo
899 , let loc = nameSrcLoc name
903 type TagInfo = (String -- tag name
906 ,Int -- column number
909 -- get tag info, for later translation into Vim or Emacs style
910 tagInfo :: PrintUnqualified -> Name -> SrcLoc -> TagInfo
911 tagInfo unqual name loc
912 = ( showSDocForUser unqual $ pprOccName (nameOccName name)
913 , showSDocForUser unqual $ ftext (srcLocFile loc)
918 collateAndWriteTags :: TagsKind -> FilePath -> [TagInfo] -> IO (Either IOError ())
919 collateAndWriteTags CTags file tagInfos = do -- ctags style, Vim et al
920 let tags = unlines $ sortLe (<=) $ nub $ map showTag tagInfos
921 IO.try (writeFile file tags)
922 collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
923 let byFile op (_,f1,_,_) (_,f2,_,_) = f1 `op` f2
924 groups = groupBy (byFile (==)) $ sortLe (byFile (<=)) tagInfos
925 tagGroups <- mapM tagFileGroup groups
926 IO.try (writeFile file $ concat tagGroups)
928 tagFileGroup group@[] = throwDyn (CmdLineError "empty tag file group??")
929 tagFileGroup group@((_,fileName,_,_):_) = do
930 file <- readFile fileName -- need to get additional info from sources..
931 let byLine (_,_,l1,_) (_,_,l2,_) = l1 <= l2
932 sortedGroup = sortLe byLine group
933 tags = unlines $ perFile sortedGroup 1 0 $ lines file
934 return $ "\x0c\n" ++ fileName ++ "," ++ show (length tags) ++ "\n" ++ tags
935 perFile (tagInfo@(tag,file,lNo,colNo):tags) count pos (line:lines) | lNo>count =
936 perFile (tagInfo:tags) (count+1) (pos+length line) lines
937 perFile (tagInfo@(tag,file,lNo,colNo):tags) count pos lines@(line:_) | lNo==count =
938 showETag tagInfo line pos : perFile tags count pos lines
939 perFile tags count pos lines = []
941 -- simple ctags format, for Vim et al
942 showTag :: TagInfo -> String
943 showTag (tag,file,lineNo,colNo)
944 = tag ++ "\t" ++ file ++ "\t" ++ show lineNo
946 -- etags format, for Emacs/XEmacs
947 showETag :: TagInfo -> String -> Int -> String
948 showETag (tag,file,lineNo,colNo) line charPos
949 = take colNo line ++ tag
951 ++ "\x01" ++ show lineNo
952 ++ "," ++ show charPos
954 -----------------------------------------------------------------------------
955 -- Browsing a module's contents
957 browseCmd :: String -> GHCi ()
960 ['*':m] | looksLikeModuleName m -> browseModule m False
961 [m] | looksLikeModuleName m -> browseModule m True
962 _ -> throwDyn (CmdLineError "syntax: :browse <module>")
964 browseModule m exports_only = do
967 let modl = mkModule m
968 is_interpreted <- io (GHC.moduleIsInterpreted s modl)
969 when (not is_interpreted && not exports_only) $
970 throwDyn (CmdLineError ("module '" ++ m ++ "' is not interpreted"))
972 -- Temporarily set the context to the module we're interested in,
973 -- just so we can get an appropriate PrintUnqualified
974 (as,bs) <- io (GHC.getContext s)
975 io (if exports_only then GHC.setContext s [] [prelude_mod,modl]
976 else GHC.setContext s [modl] [])
977 io (GHC.setContext s as bs)
979 things <- io (GHC.browseModule s modl exports_only)
980 unqual <- io (GHC.getPrintUnqual s)
982 dflags <- getDynFlags
983 let exts = dopt Opt_GlasgowExts dflags
984 io (putStrLn (showSDocForUser unqual (
985 vcat (map (showDecl exts (const True)) things)
988 -----------------------------------------------------------------------------
989 -- Setting the module context
992 | all sensible mods = fn mods
993 | otherwise = throwDyn (CmdLineError "syntax: :module [+/-] [*]M1 ... [*]Mn")
995 (fn, mods) = case str of
996 '+':stuff -> (addToContext, words stuff)
997 '-':stuff -> (removeFromContext, words stuff)
998 stuff -> (newContext, words stuff)
1000 sensible ('*':m) = looksLikeModuleName m
1001 sensible m = looksLikeModuleName m
1003 newContext mods = do
1004 session <- getSession
1005 (as,bs) <- separate session mods [] []
1006 let bs' = if null as && prelude_mod `notElem` bs then prelude_mod:bs else bs
1007 io (GHC.setContext session as bs')
1009 separate :: Session -> [String] -> [Module] -> [Module]
1010 -> GHCi ([Module],[Module])
1011 separate session [] as bs = return (as,bs)
1012 separate session (('*':m):ms) as bs = do
1013 let modl = mkModule m
1014 b <- io (GHC.moduleIsInterpreted session modl)
1015 if b then separate session ms (modl:as) bs
1016 else throwDyn (CmdLineError ("module '" ++ m ++ "' is not interpreted"))
1017 separate session (m:ms) as bs = separate session ms as (mkModule m:bs)
1019 prelude_mod = mkModule "Prelude"
1022 addToContext mods = do
1024 (as,bs) <- io (GHC.getContext cms)
1026 (as',bs') <- separate cms mods [] []
1028 let as_to_add = as' \\ (as ++ bs)
1029 bs_to_add = bs' \\ (as ++ bs)
1031 io (GHC.setContext cms (as ++ as_to_add) (bs ++ bs_to_add))
1034 removeFromContext mods = do
1036 (as,bs) <- io (GHC.getContext cms)
1038 (as_to_remove,bs_to_remove) <- separate cms mods [] []
1040 let as' = as \\ (as_to_remove ++ bs_to_remove)
1041 bs' = bs \\ (as_to_remove ++ bs_to_remove)
1043 io (GHC.setContext cms as' bs')
1045 ----------------------------------------------------------------------------
1048 -- set options in the interpreter. Syntax is exactly the same as the
1049 -- ghc command line, except that certain options aren't available (-C,
1052 -- This is pretty fragile: most options won't work as expected. ToDo:
1053 -- figure out which ones & disallow them.
1055 setCmd :: String -> GHCi ()
1057 = do st <- getGHCiState
1058 let opts = options st
1059 io $ putStrLn (showSDoc (
1060 text "options currently set: " <>
1063 else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
1067 ("args":args) -> setArgs args
1068 ("prog":prog) -> setProg prog
1069 wds -> setOptions wds
1073 setGHCiState st{ args = args }
1077 setGHCiState st{ progname = prog }
1079 io (hPutStrLn stderr "syntax: :set prog <progname>")
1082 do -- first, deal with the GHCi opts (+s, +t, etc.)
1083 let (plus_opts, minus_opts) = partition isPlus wds
1084 mapM_ setOpt plus_opts
1086 -- then, dynamic flags
1087 dflags <- getDynFlags
1088 (dflags',leftovers) <- io $ GHC.parseDynamicFlags dflags minus_opts
1091 -- update things if the users wants more packages
1093 let new_packages = pkgs_after \\ pkgs_before
1094 when (not (null new_packages)) $
1095 newPackages new_packages
1098 if (not (null leftovers))
1099 then throwDyn (CmdLineError ("unrecognised flags: " ++
1104 unsetOptions :: String -> GHCi ()
1106 = do -- first, deal with the GHCi opts (+s, +t, etc.)
1107 let opts = words str
1108 (minus_opts, rest1) = partition isMinus opts
1109 (plus_opts, rest2) = partition isPlus rest1
1111 if (not (null rest2))
1112 then io (putStrLn ("unknown option: '" ++ head rest2 ++ "'"))
1115 mapM_ unsetOpt plus_opts
1117 -- can't do GHC flags for now
1118 if (not (null minus_opts))
1119 then throwDyn (CmdLineError "can't unset GHC command-line flags")
1122 isMinus ('-':s) = True
1125 isPlus ('+':s) = True
1129 = case strToGHCiOpt str of
1130 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1131 Just o -> setOption o
1134 = case strToGHCiOpt str of
1135 Nothing -> io (putStrLn ("unknown option: '" ++ str ++ "'"))
1136 Just o -> unsetOption o
1138 strToGHCiOpt :: String -> (Maybe GHCiOption)
1139 strToGHCiOpt "s" = Just ShowTiming
1140 strToGHCiOpt "t" = Just ShowType
1141 strToGHCiOpt "r" = Just RevertCAFs
1142 strToGHCiOpt _ = Nothing
1144 optToStr :: GHCiOption -> String
1145 optToStr ShowTiming = "s"
1146 optToStr ShowType = "t"
1147 optToStr RevertCAFs = "r"
1150 newPackages new_pkgs = do -- The new packages are already in v_Packages
1151 session <- getSession
1152 io (GHC.setTargets session [])
1153 io (GHC.load session Nothing)
1154 dflags <- getDynFlags
1155 io (linkPackages dflags new_pkgs)
1156 setContextAfterLoad []
1159 -- ---------------------------------------------------------------------------
1164 ["modules" ] -> showModules
1165 ["bindings"] -> showBindings
1166 ["linker"] -> io showLinkerState
1167 _ -> throwDyn (CmdLineError "syntax: :show [modules|bindings]")
1170 session <- getSession
1171 let show_one ms = do m <- io (GHC.showModule session ms)
1173 graph <- io (GHC.getModuleGraph session)
1174 mapM_ show_one graph
1178 unqual <- io (GHC.getPrintUnqual s)
1179 bindings <- io (GHC.getBindings s)
1180 mapM_ showTyThing bindings
1183 showTyThing (AnId id) = do
1184 ty' <- cleanType (GHC.idType id)
1185 str <- showForUser (ppr id <> text " :: " <> ppr ty')
1187 showTyThing _ = return ()
1189 -- if -fglasgow-exts is on we show the foralls, otherwise we don't.
1190 cleanType :: Type -> GHCi Type
1192 dflags <- getDynFlags
1193 if dopt Opt_GlasgowExts dflags
1195 else return $! GHC.dropForAlls ty
1197 -----------------------------------------------------------------------------
1200 data GHCiState = GHCiState
1204 session :: GHC.Session,
1205 options :: [GHCiOption]
1209 = ShowTiming -- show time/allocs after evaluation
1210 | ShowType -- show the type of expressions
1211 | RevertCAFs -- revert CAFs after every evaluation
1214 newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> IO a }
1216 startGHCi :: GHCi a -> GHCiState -> IO a
1217 startGHCi g state = do ref <- newIORef state; unGHCi g ref
1219 instance Monad GHCi where
1220 (GHCi m) >>= k = GHCi $ \s -> m s >>= \a -> unGHCi (k a) s
1221 return a = GHCi $ \s -> return a
1223 ghciHandleDyn :: Typeable t => (t -> GHCi a) -> GHCi a -> GHCi a
1224 ghciHandleDyn h (GHCi m) = GHCi $ \s ->
1225 Exception.catchDyn (m s) (\e -> unGHCi (h e) s)
1227 getGHCiState = GHCi $ \r -> readIORef r
1228 setGHCiState s = GHCi $ \r -> writeIORef r s
1230 -- for convenience...
1231 getSession = getGHCiState >>= return . session
1235 io (GHC.getSessionDynFlags s)
1236 setDynFlags dflags = do
1238 io (GHC.setSessionDynFlags s dflags)
1240 isOptionSet :: GHCiOption -> GHCi Bool
1242 = do st <- getGHCiState
1243 return (opt `elem` options st)
1245 setOption :: GHCiOption -> GHCi ()
1247 = do st <- getGHCiState
1248 setGHCiState (st{ options = opt : filter (/= opt) (options st) })
1250 unsetOption :: GHCiOption -> GHCi ()
1252 = do st <- getGHCiState
1253 setGHCiState (st{ options = filter (/= opt) (options st) })
1255 io :: IO a -> GHCi a
1256 io m = GHCi { unGHCi = \s -> m >>= return }
1258 -----------------------------------------------------------------------------
1259 -- recursive exception handlers
1261 -- Don't forget to unblock async exceptions in the handler, or if we're
1262 -- in an exception loop (eg. let a = error a in a) the ^C exception
1263 -- may never be delivered. Thanks to Marcin for pointing out the bug.
1265 ghciHandle :: (Exception -> GHCi a) -> GHCi a -> GHCi a
1266 ghciHandle h (GHCi m) = GHCi $ \s ->
1267 Exception.catch (m s)
1268 (\e -> unGHCi (ghciUnblock (h e)) s)
1270 ghciUnblock :: GHCi a -> GHCi a
1271 ghciUnblock (GHCi a) = GHCi $ \s -> Exception.unblock (a s)
1273 -----------------------------------------------------------------------------
1274 -- timing & statistics
1276 timeIt :: GHCi a -> GHCi a
1278 = do b <- isOptionSet ShowTiming
1281 else do allocs1 <- io $ getAllocations
1282 time1 <- io $ getCPUTime
1284 allocs2 <- io $ getAllocations
1285 time2 <- io $ getCPUTime
1286 io $ printTimes (fromIntegral (allocs2 - allocs1))
1290 foreign import ccall unsafe "getAllocations" getAllocations :: IO Int64
1291 -- defined in ghc/rts/Stats.c
1293 printTimes :: Integer -> Integer -> IO ()
1294 printTimes allocs psecs
1295 = do let secs = (fromIntegral psecs / (10^12)) :: Float
1296 secs_str = showFFloat (Just 2) secs
1297 putStrLn (showSDoc (
1298 parens (text (secs_str "") <+> text "secs" <> comma <+>
1299 text (show allocs) <+> text "bytes")))
1301 -----------------------------------------------------------------------------
1308 -- Have to turn off buffering again, because we just
1309 -- reverted stdout, stderr & stdin to their defaults.
1311 foreign import ccall "revertCAFs" rts_revertCAFs :: IO ()
1312 -- Make it "safe", just in case
1314 -- -----------------------------------------------------------------------------
1317 expandPath :: String -> GHCi String
1319 case dropWhile isSpace path of
1321 tilde <- io (getEnv "HOME") -- will fail if HOME not defined
1322 return (tilde ++ '/':d)