- let
- (ghc_args, rest) = break notArg args
- --
- case rest of
- [] -> dieProg "syntax: runghc [-f GHCPATH] [GHC-ARGS] FILE ARG..."
- filename : prog_args -> do
- res <- rawSystem ghc (
- "-ignore-dot-ghci" : ghc_args ++
- [ "-e","System.Environment.withProgName "++show filename++" (System.Environment.withArgs ["
- ++ concat (intersperse "," (map show prog_args))
- ++ "] Main.main)", filename])
- exitWith res
+ let (ghc_args, rest) = getGhcArgs args
+ case rest of
+ [] -> dieProg usage
+ filename : prog_args -> do
+ let expr = "System.Environment.withProgName " ++ show filename ++
+ " (System.Environment.withArgs " ++ show prog_args ++
+ " (GHC.TopHandler.runIOFastExit" ++
+ " (Main.main Prelude.>> Prelude.return ())))"
+ res <- rawSystem ghc (["-ignore-dot-ghci"] ++ ghc_args ++
+ [ "-e", expr, filename])
+ -- runIOFastExit: makes exceptions raised by Main.main
+ -- behave in the same way as for a compiled program.
+ -- The "fast exit" part just calls exit() directly
+ -- instead of doing an orderly runtime shutdown,
+ -- otherwise the main GHCi thread will complain about
+ -- being interrupted.
+ --
+ -- Why (main >> return ()) rather than just main? Because
+ -- otherwise GHCi by default tries to evaluate the result
+ -- of the IO in order to show it (see #1200).
+ exitWith res