diff options
author | Roland Senn <rsx@bluewin.ch> | 2019-04-14 14:21:40 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2019-05-10 16:32:38 -0400 |
commit | c7913f71bc8ed8910c829a84b78d2f56b05f0473 (patch) | |
tree | 9132f648948d7e2423fdd1fb9c7fe203c1786b6b /ghc | |
parent | 5eb9445444c4099fc9ee0803ba45db390900a80f (diff) | |
download | haskell-c7913f71bc8ed8910c829a84b78d2f56b05f0473.tar.gz |
Fix bugs and documentation for #13456
Diffstat (limited to 'ghc')
-rw-r--r-- | ghc/GHCi/UI.hs | 66 |
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 } |