summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/users_guide/using.rst14
-rw-r--r--ghc/Main.hs25
-rw-r--r--testsuite/tests/driver/RunMode.hs4
-rw-r--r--testsuite/tests/driver/RunMode.stdout1
-rw-r--r--testsuite/tests/driver/RunMode/Test.hs7
-rw-r--r--testsuite/tests/driver/all.T1
6 files changed, 49 insertions, 3 deletions
diff --git a/docs/users_guide/using.rst b/docs/users_guide/using.rst
index dee39d4d94..086ad30e5e 100644
--- a/docs/users_guide/using.rst
+++ b/docs/users_guide/using.rst
@@ -265,6 +265,20 @@ The available mode flags are:
Interactive mode, which is also available as :program:`ghci`. Interactive
mode is described in more detail in :ref:`ghci`.
+.. ghc-flag:: --run ⟨file⟩
+ :shortdesc: Run a Haskell program.
+ :type: mode
+ :category: modes
+
+ .. index::
+ single: run mode
+ single: GHCi
+
+ Run a script's ``main`` entry-point. Similar to ``runghc`` this will by
+ default use the bytecode interpreter. If the command-line contains a ``--``
+ argument then all arguments that follow will be passed to the script. All
+ arguments that precede ``--`` are interpreted as GHC arguments.
+
.. ghc-flag:: --make
:shortdesc: Build a multi-module Haskell program, automatically figuring out
dependencies. Likely to be much easier, and faster, than using
diff --git a/ghc/Main.hs b/ghc/Main.hs
index 9c4c012247..2db9a99005 100644
--- a/ghc/Main.hs
+++ b/ghc/Main.hs
@@ -155,6 +155,9 @@ main = do
main' :: PostLoadMode -> DynFlags -> [Located String] -> [Warn]
-> Ghc ()
main' postLoadMode dflags0 args flagWarnings = do
+ let args' = case postLoadMode of
+ DoRun -> takeWhile (\arg -> unLoc arg /= "--") args
+ _ -> args
-- set the default GhcMode, backend and GhcLink. The backend
-- can be further adjusted on a module by module basis, using only
@@ -165,6 +168,7 @@ main' postLoadMode dflags0 args flagWarnings = do
= case postLoadMode of
DoInteractive -> (CompManager, Interpreter, LinkInMemory)
DoEval _ -> (CompManager, Interpreter, LinkInMemory)
+ DoRun -> (CompManager, Interpreter, LinkInMemory)
DoMake -> (CompManager, dflt_backend, LinkBinary)
DoBackpack -> (CompManager, dflt_backend, LinkBinary)
DoMkDependHS -> (MkDepend, dflt_backend, LinkBinary)
@@ -176,6 +180,7 @@ main' postLoadMode dflags0 args flagWarnings = do
ghcLink = link,
verbosity = case postLoadMode of
DoEval _ -> 0
+ DoRun -> 0
_other -> 1
}
@@ -189,6 +194,7 @@ main' postLoadMode dflags0 args flagWarnings = do
-- a great story for the moment.
dflags2 | DoInteractive <- postLoadMode = def_ghci_flags
| DoEval _ <- postLoadMode = def_ghci_flags
+ | DoRun <- postLoadMode = def_ghci_flags
| otherwise = dflags1
where def_ghci_flags = dflags1 `gopt_set` Opt_ImplicitImportQualified
`gopt_set` Opt_IgnoreOptimChanges
@@ -200,7 +206,7 @@ main' postLoadMode dflags0 args flagWarnings = do
-- The rest of the arguments are "dynamic"
-- Leftover ones are presumably files
(dflags3, fileish_args, dynamicFlagWarnings) <-
- GHC.parseDynamicFlags logger2 dflags2 args
+ GHC.parseDynamicFlags logger2 dflags2 args'
let dflags4 = case bcknd of
Interpreter | not (gopt Opt_ExternalInterpreter dflags3) ->
@@ -262,6 +268,7 @@ main' postLoadMode dflags0 args flagWarnings = do
StopBefore p -> liftIO (oneShot hsc_env p srcs)
DoInteractive -> ghciUI srcs Nothing
DoEval exprs -> ghciUI srcs $ Just $ reverse exprs
+ DoRun -> doRun srcs args
DoAbiHash -> abiHash (map fst srcs)
ShowPackages -> liftIO $ showUnits hsc_env
DoFrontend f -> doFrontend f srcs
@@ -269,6 +276,14 @@ main' postLoadMode dflags0 args flagWarnings = do
liftIO $ dumpFinalStats logger
+doRun :: [(FilePath, Maybe Phase)] -> [Located String] -> Ghc ()
+doRun srcs args = do
+ dflags <- getDynFlags
+ let mainFun = fromMaybe "main" (mainFunIs dflags)
+ ghciUI srcs (Just ["System.Environment.withArgs " ++ show args' ++ " (Control.Monad.void " ++ mainFun ++ ")"])
+ where
+ args' = drop 1 $ dropWhile (/= "--") $ map unLoc args
+
ghciUI :: [(FilePath, Maybe Phase)] -> Maybe [String] -> Ghc ()
#if !defined(HAVE_INTERNAL_INTERPRETER)
ghciUI _ _ =
@@ -430,16 +445,17 @@ data PostLoadMode
| DoBackpack -- ghc --backpack foo.bkp
| DoInteractive -- ghc --interactive
| DoEval [String] -- ghc -e foo -e bar => DoEval ["bar", "foo"]
+ | DoRun -- ghc --run
| DoAbiHash -- ghc --abi-hash
| ShowPackages -- ghc --show-packages
| DoFrontend ModuleName -- ghc --frontend Plugin.Module
-
-doMkDependHSMode, doMakeMode, doInteractiveMode,
+doMkDependHSMode, doMakeMode, doInteractiveMode, doRunMode,
doAbiHashMode, showUnitsMode :: Mode
doMkDependHSMode = mkPostLoadMode DoMkDependHS
doMakeMode = mkPostLoadMode DoMake
doInteractiveMode = mkPostLoadMode DoInteractive
+doRunMode = mkPostLoadMode DoRun
doAbiHashMode = mkPostLoadMode DoAbiHash
showUnitsMode = mkPostLoadMode ShowPackages
@@ -500,11 +516,13 @@ needsInputsMode _ = False
isLinkMode :: PostLoadMode -> Bool
isLinkMode (StopBefore NoStop) = True
isLinkMode DoMake = True
+isLinkMode DoRun = True
isLinkMode DoInteractive = True
isLinkMode (DoEval _) = True
isLinkMode _ = False
isCompManagerMode :: PostLoadMode -> Bool
+isCompManagerMode DoRun = True
isCompManagerMode DoMake = True
isCompManagerMode DoInteractive = True
isCompManagerMode (DoEval _) = True
@@ -586,6 +604,7 @@ mode_flags =
, defFlag "E" (PassFlag (setMode (stopBeforeMode StopPreprocess )))
, defFlag "C" (PassFlag (setMode (stopBeforeMode StopC)))
, defFlag "S" (PassFlag (setMode (stopBeforeMode StopAs)))
+ , defFlag "-run" (PassFlag (setMode doRunMode))
, defFlag "-make" (PassFlag (setMode doMakeMode))
, defFlag "-backpack" (PassFlag (setMode doBackpackMode))
, defFlag "-interactive" (PassFlag (setMode doInteractiveMode))
diff --git a/testsuite/tests/driver/RunMode.hs b/testsuite/tests/driver/RunMode.hs
new file mode 100644
index 0000000000..bad01fef39
--- /dev/null
+++ b/testsuite/tests/driver/RunMode.hs
@@ -0,0 +1,4 @@
+import Test
+
+main :: IO ()
+main = test
diff --git a/testsuite/tests/driver/RunMode.stdout b/testsuite/tests/driver/RunMode.stdout
new file mode 100644
index 0000000000..4b7e5d76b5
--- /dev/null
+++ b/testsuite/tests/driver/RunMode.stdout
@@ -0,0 +1 @@
+["hello"]
diff --git a/testsuite/tests/driver/RunMode/Test.hs b/testsuite/tests/driver/RunMode/Test.hs
new file mode 100644
index 0000000000..125535e437
--- /dev/null
+++ b/testsuite/tests/driver/RunMode/Test.hs
@@ -0,0 +1,7 @@
+module Test (test) where
+
+import System.Environment
+
+test :: IO ()
+test = do
+ print =<< getArgs
diff --git a/testsuite/tests/driver/all.T b/testsuite/tests/driver/all.T
index 6f45e1ec21..0e6eb594b1 100644
--- a/testsuite/tests/driver/all.T
+++ b/testsuite/tests/driver/all.T
@@ -293,3 +293,4 @@ test('FullGHCVersion', normal, compile_and_run, ['-package ghc-boot'])
test('OneShotTH', normal, makefile_test, [])
test('T17481', normal, makefile_test, [])
test('T20084', normal, makefile_test, [])
+test('RunMode', extra_files(['RunMode/Test.hs']), run_command, ['{compiler} --run -iRunMode/ -ignore-dot-ghci RunMode.hs -- hello'])