-----------------------------------------------------------------------------
--- $Id: InteractiveUI.hs,v 1.52 2001/02/26 15:06:58 simonmar Exp $
+-- $Id: InteractiveUI.hs,v 1.58 2001/03/27 16:55:03 simonmar Exp $
--
-- GHC Interactive User Interface
--
import Util
import Name ( Name )
import Outputable
+import CmdLineOpts ( DynFlag(..), dopt_unset )
import Panic ( GhcException(..) )
import Config
builtin_commands = [
("add", keepGoing addModule),
("cd", keepGoing changeDirectory),
--- ("def", keepGoing defineMacro),
+ ("def", keepGoing defineMacro),
("help", keepGoing help),
("?", keepGoing help),
("load", keepGoing loadModule),
\ Commands available from the prompt:\n\
\\
\ <stmt> evaluate/run <stmt>\n\
-\ :add <filename> add a module to the current set\n\
\ :cd <dir> change directory to <dir>\n\
+\ :def <cmd> <expr> define a command :<cmd>\n\
\ :help, :? display this list of commands\n\
\ :load <filename> load a module (and it dependents)\n\
\ :module <mod> set the context for expression evaluation to <mod>\n\
\ :reload reload the current module set\n\
\ :set <option> ... set options\n\
-\ :unset <option> ... unset options\n\
+\ :undef <name> undefine user-defined command :<name>\n\
\ :type <expr> show the type of <expr>\n\
+\ :unset <option> ... unset options\n\
\ :quit exit GHCi\n\
\ :!<command> run the shell command <command>\n\
\\
\ Options for `:set' and `:unset':\n\
\\
+\ +r revert top-level expressions after each evaluation\n\
\ +s print timing/memory stats after each evaluation\n\
\ +t print type after evaluation\n\
-\ +r revert top-level expressions after each evaluation\n\
\ -<flags> most GHC command line flags can also be set here\n\
\ (eg. -v2, -fglasgow-exts, etc.)\n\
\"
+ --ToDo :add <filename> add a module to the current set\n\
interactiveUI :: CmState -> Maybe FilePath -> [LibrarySpec] -> IO ()
interactiveUI cmstate mod cmdline_libs = do
dflags <- getDynFlags
-{-
- (cmstate, _) <- cmRunStmt cmstate dflags False prel
- "PrelHandle.hFlush PrelHandle.stdout"
- case maybe_stuff of
- Nothing -> return ()
- Just (hv,_,_) -> writeIORef flush_stdout hv
-
- (cmstate, _) <- cmGetExpr cmstate dflags False prel
- "PrelHandle.hFlush PrelHandle.stdout"
- case maybe_stuff of
- Nothing -> return ()
- Just (hv,_,_) -> writeIORef flush_stderr hv
--}
-
+ (cmstate, maybe_hval)
+ <- cmCompileExpr cmstate dflags "IO.hFlush PrelHandle.stderr"
+ case maybe_hval of
+ Just hval -> writeIORef flush_stderr (unsafeCoerce# hval :: IO ())
+ _ -> panic "interactiveUI:stderr"
+
+ (cmstate, maybe_hval)
+ <- cmCompileExpr cmstate dflags "IO.hFlush PrelHandle.stdout"
+ case maybe_hval of
+ Just hval -> writeIORef flush_stdout (unsafeCoerce# hval :: IO ())
+ _ -> panic "interactiveUI:stdout"
+
(unGHCi runGHCi) GHCiState{ target = mod,
cmstate = cmstate,
options = [ShowTiming] }
case home of
Left e -> return ()
Right dir -> do
- dot_ghci <- io (IO.try (openFile (dir ++ "/.ghci") ReadMode))
- case dot_ghci of
- Left e -> return ()
- Right hdl -> fileLoop hdl False
+ cwd <- io (getCurrentDirectory)
+ when (dir /= cwd) $ do
+ dot_ghci <- io (IO.try (openFile (dir ++ "/.ghci") ReadMode))
+ case dot_ghci of
+ Left e -> return ()
+ Right hdl -> fileLoop hdl False
-- read commands from stdin
#ifndef NO_READLINE
doCommand c
doCommand (':' : command) = specialCommand command
-doCommand ('-':'-':_) = return False -- comments, useful in scripts
doCommand stmt
= do timeIt (do stuff <- runStmt stmt; finishEvalExpr stuff)
return False
| otherwise
= do st <- getGHCiState
dflags <- io (getDynFlags)
- (new_cmstate, names) <- io (cmRunStmt (cmstate st) dflags stmt)
+ let dflags' = dopt_unset dflags Opt_WarnUnusedBinds
+ (new_cmstate, names) <- io (cmRunStmt (cmstate st) dflags' stmt)
setGHCiState st{cmstate = new_cmstate}
return (Just names)
flushEverything :: GHCi ()
flushEverything
- = io $ {-do flush_so <- readIORef flush_stdout
- cmRunExpr flush_so
+ = io $ do flush_so <- readIORef flush_stdout
+ flush_so
flush_se <- readIORef flush_stdout
- cmRunExpr flush_se
- -} (return ())
+ flush_se
+ return ()
specialCommand :: String -> GHCi Bool
specialCommand ('!':str) = shellEscape (dropWhile isSpace str)
foldr1 (\a b -> a ++ ',':b) (map fst cs)
++ ")") >> return False)
-noArgs c = io (hPutStrLn stdout ("command `:" ++ c ++ "' takes no arguments"))
+noArgs c = throwDyn (OtherError ("command `" ++ c ++ "' takes no arguments"))
-----------------------------------------------------------------------------
-- Commands
setGHCiState st{cmstate=new_cmstate}
changeDirectory :: String -> GHCi ()
+changeDirectory ('~':d) = do
+ tilde <- io (getEnv "HOME") -- will fail if HOME not defined
+ io (setCurrentDirectory (tilde ++ '/':d))
changeDirectory d = io (setCurrentDirectory d)
-{-
defineMacro :: String -> GHCi ()
defineMacro s = do
let (macro_name, definition) = break isSpace s
else do
if (macro_name `elem` map fst cmds)
then throwDyn (OtherError
- ("command `" ++ macro_name ++ "' already defined"))
+ ("command `" ++ macro_name ++ "' is already defined"))
else do
-- give the expression a type signature, so we can be sure we're getting
-- compile the expression
st <- getGHCiState
dflags <- io (getDynFlags)
- (new_cmstate, maybe_stuff) <-
- io (cmGetExpr (cmstate st) dflags new_expr)
+ (new_cmstate, maybe_hv) <- io (cmCompileExpr (cmstate st) dflags new_expr)
setGHCiState st{cmstate = new_cmstate}
- case maybe_stuff of
+ case maybe_hv of
Nothing -> return ()
- Just (hv, unqual, ty)
- -> io (writeIORef commands
- ((macro_name, keepGoing (runMacro hv)) : cmds))
--}
+ Just hv -> io (writeIORef commands --
+ ((macro_name, keepGoing (runMacro hv)) : cmds))
runMacro :: HValue{-String -> IO String-} -> String -> GHCi ()
runMacro fun s = do
typeOfExpr str
= do st <- getGHCiState
dflags <- io (getDynFlags)
- (new_cmstate, names)
- <- io (cmRunStmt (cmstate st) dflags ("let it=" ++ str))
+ (new_cmstate, maybe_tystr) <- io (cmTypeOfExpr (cmstate st) dflags str)
setGHCiState st{cmstate = new_cmstate}
- case names of
- [name] -> do maybe_tystr <- io (cmTypeOfName new_cmstate name)
- case maybe_tystr of
- Nothing -> return ()
- Just tystr -> io (putStrLn (":: " ++ tystr))
- _other -> pprPanic "typeOfExpr" (ppr names)
+ case maybe_tystr of
+ Nothing -> return ()
+ Just tystr -> io (putStrLn tystr)
quit :: String -> GHCi Bool
quit _ = return True
| RevertCAFs -- revert CAFs after every evaluation
deriving Eq
-GLOBAL_VAR(flush_stdout, error "no flush_stdout", HValue)
-GLOBAL_VAR(flush_stderr, error "no flush_stdout", HValue)
+GLOBAL_VAR(flush_stdout, error "no flush_stdout", IO ())
+GLOBAL_VAR(flush_stderr, error "no flush_stdout", IO ())
newtype GHCi a = GHCi { unGHCi :: GHCiState -> IO (GHCiState, a) }
showLS (Left nm) = "(static) " ++ nm
showLS (Right nm) = "(dynamic) " ++ nm
-linkPackages :: [LibrarySpec] -> [Package] -> IO ()
+linkPackages :: [LibrarySpec] -> [PackageConfig] -> IO ()
linkPackages cmdline_lib_specs pkgs
= do mapM_ linkPackage pkgs
mapM_ preloadLib cmdline_lib_specs
croak = throwDyn (OtherError "user specified .o/.so/.DLL could not be loaded.")
-linkPackage :: Package -> IO ()
+linkPackage :: PackageConfig -> IO ()
-- ignore rts and gmp for now (ToDo; better?)
linkPackage pkg
| name pkg `elem` ["rts", "gmp"]