summaryrefslogtreecommitdiff
path: root/ghc
diff options
context:
space:
mode:
authorRoland Senn <rsx@bluewin.ch>2019-04-14 14:21:40 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-05-10 16:32:38 -0400
commitc7913f71bc8ed8910c829a84b78d2f56b05f0473 (patch)
tree9132f648948d7e2423fdd1fb9c7fe203c1786b6b /ghc
parent5eb9445444c4099fc9ee0803ba45db390900a80f (diff)
downloadhaskell-c7913f71bc8ed8910c829a84b78d2f56b05f0473.tar.gz
Fix bugs and documentation for #13456
Diffstat (limited to 'ghc')
-rw-r--r--ghc/GHCi/UI.hs66
1 files changed, 37 insertions, 29 deletions
diff --git a/ghc/GHCi/UI.hs b/ghc/GHCi/UI.hs
index aeb8067bcc..da288c5e1e 100644
--- a/ghc/GHCi/UI.hs
+++ b/ghc/GHCi/UI.hs
@@ -1618,8 +1618,11 @@ chooseEditFile =
-- :def
defineMacro :: GhciMonad m => Bool{-overwrite-} -> String -> m ()
-defineMacro _ (':':_) =
- liftIO $ putStrLn "macro name cannot start with a colon"
+defineMacro _ (':':_) = liftIO $ putStrLn
+ "macro name cannot start with a colon"
+defineMacro _ ('!':_) = liftIO $ putStrLn
+ "macro name cannot start with an exclamation mark"
+ -- little code duplication allows to grep error msg
defineMacro overwrite s = do
let (macro_name, definition) = break isSpace s
macros <- ghci_macros <$> getGHCiState
@@ -1629,33 +1632,38 @@ defineMacro overwrite s = do
then liftIO $ putStrLn "no macros defined"
else liftIO $ putStr ("the following macros are defined:\n" ++
unlines defined)
- else do
- if (not overwrite && macro_name `elem` defined)
- then throwGhcException (CmdLineError
- ("macro '" ++ macro_name ++ "' is already defined"))
- else do
-
- -- compile the expression
- handleSourceError GHC.printException $ do
- step <- getGhciStepIO
- expr <- GHC.parseExpr definition
- -- > ghciStepIO . definition :: String -> IO String
- let stringTy = nlHsTyVar stringTy_RDR
- ioM = nlHsTyVar (getRdrName ioTyConName) `nlHsAppTy` stringTy
- body = nlHsVar compose_RDR `mkHsApp` (nlHsPar step)
- `mkHsApp` (nlHsPar expr)
- tySig = mkLHsSigWcType (stringTy `nlHsFunTy` ioM)
- new_expr = L (getLoc expr) $ ExprWithTySig noExt body tySig
- hv <- GHC.compileParsedExprRemote new_expr
-
- let newCmd = Command { cmdName = macro_name
- , cmdAction = lift . runMacro hv
- , cmdHidden = False
- , cmdCompletionFunc = noCompletion
- }
-
- -- later defined macros have precedence
- modifyGHCiState $ \s ->
+ else do
+ isCommand <- isJust <$> lookupCommand' macro_name
+ let check_newname
+ | macro_name `elem` defined = throwGhcException (CmdLineError
+ ("macro '" ++ macro_name ++ "' is already defined. " ++ hint))
+ | isCommand = throwGhcException (CmdLineError
+ ("macro '" ++ macro_name ++ "' overwrites builtin command. " ++ hint))
+ | otherwise = return ()
+ hint = " Use ':def!' to overwrite."
+
+ unless overwrite check_newname
+ -- compile the expression
+ handleSourceError GHC.printException $ do
+ step <- getGhciStepIO
+ expr <- GHC.parseExpr definition
+ -- > ghciStepIO . definition :: String -> IO String
+ let stringTy = nlHsTyVar stringTy_RDR
+ ioM = nlHsTyVar (getRdrName ioTyConName) `nlHsAppTy` stringTy
+ body = nlHsVar compose_RDR `mkHsApp` (nlHsPar step)
+ `mkHsApp` (nlHsPar expr)
+ tySig = mkLHsSigWcType (stringTy `nlHsFunTy` ioM)
+ new_expr = L (getLoc expr) $ ExprWithTySig noExt body tySig
+ hv <- GHC.compileParsedExprRemote new_expr
+
+ let newCmd = Command { cmdName = macro_name
+ , cmdAction = lift . runMacro hv
+ , cmdHidden = False
+ , cmdCompletionFunc = noCompletion
+ }
+
+ -- later defined macros have precedence
+ modifyGHCiState $ \s ->
let filtered = [ cmd | cmd <- macros, cmdName cmd /= macro_name ]
in s { ghci_macros = newCmd : filtered }