summaryrefslogtreecommitdiff
path: root/ghc
diff options
context:
space:
mode:
authorRoman Shatsov <roshats@gmail.com>2015-11-21 15:58:34 +0100
committerBen Gamari <ben@smart-cactus.org>2015-11-21 11:15:09 -0500
commitb98ff3ccb14e36145404f075349c8689762a2913 (patch)
tree06eb4336d7637d5ecaa0bc68ae047eb524a3b03d /ghc
parent2325bd4e0fad0e5872556c5a78d1a6a1873e7201 (diff)
downloadhaskell-b98ff3ccb14e36145404f075349c8689762a2913.tar.gz
Function definition in GHCi
This patch allows define and re-define functions in ghci. `let` is not required anymore (but can be used). Idea: If ghci input string can be parsed as statement then run it as statement else run it as declaration. Reviewers: mpickering, bgamari, austin Reviewed By: mpickering, bgamari, austin Subscribers: hvr, mpickering, dterei, thomie Differential Revision: https://phabricator.haskell.org/D1299 GHC Trac Issues: #7253
Diffstat (limited to 'ghc')
-rw-r--r--ghc/GhciMonad.hs19
-rw-r--r--ghc/InteractiveUI.hs25
2 files changed, 23 insertions, 21 deletions
diff --git a/ghc/GhciMonad.hs b/ghc/GhciMonad.hs
index 7dd005b99e..6d068be485 100644
--- a/ghc/GhciMonad.hs
+++ b/ghc/GhciMonad.hs
@@ -19,7 +19,7 @@ module GhciMonad (
TickArray,
getDynFlags,
- runStmt, runDecls, resume, timeIt, recordBreak, revertCAFs,
+ isStmt, runStmt, runDecls, resume, timeIt, recordBreak, revertCAFs,
printForUser, printForUserPartWay, prettyLocations,
initInterpBuffering, turnOffBuffering, flushInterpBuffers,
@@ -50,6 +50,10 @@ import System.IO
import Control.Monad
import GHC.Exts
+import qualified Lexer (ParseResult(..), unP, mkPState)
+import qualified Parser (parseStmt)
+import StringBuffer (stringToStringBuffer)
+
import System.Console.Haskeline (CompletionFunc, InputT)
import qualified System.Console.Haskeline as Haskeline
import Control.Monad.Trans.Class
@@ -262,6 +266,19 @@ printForUserPartWay doc = do
dflags <- getDynFlags
liftIO $ Outputable.printForUserPartWay dflags stdout (pprUserLength dflags) unqual doc
+isStmt :: String -> GHCi Bool
+isStmt stmt = do
+ st <- getGHCiState
+ dflags <- GHC.getInteractiveDynFlags
+
+ let buf = stringToStringBuffer stmt
+ loc = mkRealSrcLoc (fsLit "<interactive>") (line_number st) 1
+ parser = Parser.parseStmt
+
+ case Lexer.unP parser (Lexer.mkPState dflags buf loc) of
+ Lexer.POk _ _ -> return True
+ Lexer.PFailed _ _ -> return False
+
-- | Run a single Haskell expression
runStmt :: String -> GHC.SingleStep -> GHCi (Maybe GHC.ExecResult)
runStmt expr step = do
diff --git a/ghc/InteractiveUI.hs b/ghc/InteractiveUI.hs
index 8f861eecac..e5c4e11dea 100644
--- a/ghc/InteractiveUI.hs
+++ b/ghc/InteractiveUI.hs
@@ -897,22 +897,6 @@ enqueueCommands cmds = do
cmds `deepseq` return ()
modifyGHCiState $ \st -> st{ cmdqueue = cmds ++ cmdqueue st }
--- | If we one of these strings prefixes a command, then we treat it as a decl
--- rather than a stmt. NB that the appropriate decl prefixes depends on the
--- flag settings (Trac #9915)
-declPrefixes :: DynFlags -> [String]
-declPrefixes dflags = keywords ++ concat opt_keywords
- where
- keywords = [ "class ", "instance "
- , "data ", "newtype ", "type "
- , "default ", "default("
- ]
-
- opt_keywords = [ ["foreign " | xopt Opt_ForeignFunctionInterface dflags]
- , ["deriving " | xopt Opt_StandaloneDeriving dflags]
- , ["pattern " | xopt Opt_PatternSynonyms dflags]
- ]
-
-- | Entry point to execute some haskell code from user.
-- The return value True indicates success, as in `runOneCommand`.
runStmt :: String -> SingleStep -> GHCi (Maybe GHC.ExecResult)
@@ -927,10 +911,11 @@ runStmt stmt step
= do addImportToContext stmt; return (Just (GHC.ExecComplete (Right []) 0))
| otherwise
- = do dflags <- getDynFlags
- if any (stmt `looks_like`) (declPrefixes dflags)
- then run_decl
- else run_stmt
+ = do
+ parse_res <- GhciMonad.isStmt stmt
+ if parse_res
+ then run_stmt
+ else run_decl
where
run_decl =
do _ <- liftIO $ tryIO $ hFlushAll stdin