From: simonmar Date: Thu, 4 Sep 2003 11:08:48 +0000 (+0000) Subject: [project @ 2003-09-04 11:08:46 by simonmar] X-Git-Tag: Approx_11550_changesets_converted~496 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=e98cf284e1181d6cd67ec90b8d1c4f06eca7bc81;p=ghc-hetmet.git [project @ 2003-09-04 11:08:46 by simonmar] Add a new command-line flag -e EXPR, which runs ghc in interactive mode and evaluates EXPR only before exiting. Also, the lexer now ignores lines beginning with "#!". This is so that we can use ghc as a scripting language with Unix-style scripts beginning with #! /usr/local/bin/ghc -e main (well, it's not quite that simple, but I'll leave the details for the more enterprising hackers). --- diff --git a/ghc/compiler/ghci/InteractiveUI.hs b/ghc/compiler/ghci/InteractiveUI.hs index 257c219..fceb192 100644 --- a/ghc/compiler/ghci/InteractiveUI.hs +++ b/ghc/compiler/ghci/InteractiveUI.hs @@ -1,6 +1,6 @@ {-# OPTIONS -#include "Linker.h" #-} ----------------------------------------------------------------------------- --- $Id: InteractiveUI.hs,v 1.158 2003/08/27 12:29:21 simonmar Exp $ +-- $Id: InteractiveUI.hs,v 1.159 2003/09/04 11:08:46 simonmar Exp $ -- -- GHC Interactive User Interface -- @@ -155,8 +155,8 @@ helpText = "\ \ (eg. -v2, -fglasgow-exts, etc.)\n\ \" -interactiveUI :: [FilePath] -> IO () -interactiveUI srcs = do +interactiveUI :: [FilePath] -> Maybe String -> IO () +interactiveUI srcs maybe_expr = do dflags <- getDynFlags cmstate <- cmInit Interactive; @@ -178,7 +178,7 @@ interactiveUI srcs = do Readline.initialize #endif - startGHCi (runGHCi srcs dflags) + startGHCi (runGHCi srcs dflags maybe_expr) GHCiState{ progname = "", args = [], targets = srcs, @@ -191,8 +191,8 @@ interactiveUI srcs = do return () -runGHCi :: [FilePath] -> DynFlags -> GHCi () -runGHCi paths dflags = do +runGHCi :: [FilePath] -> DynFlags -> Maybe String -> GHCi () +runGHCi paths dflags maybe_expr = do read_dot_files <- io (readIORef v_Read_DotGHCi) when (read_dot_files) $ do @@ -234,8 +234,14 @@ runGHCi paths dflags = do is_tty <- io (hIsTerminalDevice stdin) let show_prompt = verbosity dflags > 0 || is_tty - -- enter the interactive loop - interactiveLoop is_tty show_prompt + case maybe_expr of + Nothing -> + -- enter the interactive loop + interactiveLoop is_tty show_prompt + Just expr -> do + -- just evaluate the expression we were given + runCommand expr + return () -- and finally, exit io $ do when (verbosity dflags > 0) $ putStrLn "Leaving GHCi." diff --git a/ghc/compiler/main/DriverFlags.hs b/ghc/compiler/main/DriverFlags.hs index 38210a7..1189f10 100644 --- a/ghc/compiler/main/DriverFlags.hs +++ b/ghc/compiler/main/DriverFlags.hs @@ -1,5 +1,5 @@ ----------------------------------------------------------------------------- --- $Id: DriverFlags.hs,v 1.122 2003/08/29 16:00:25 simonmar Exp $ +-- $Id: DriverFlags.hs,v 1.123 2003/09/04 11:08:47 simonmar Exp $ -- -- Driver flags -- @@ -178,6 +178,7 @@ static_flags = , ( "-make" , PassFlag (setMode DoMake)) , ( "-interactive" , PassFlag (setMode DoInteractive)) , ( "-mk-dll" , PassFlag (setMode DoMkDLL)) + , ( "e" , HasArg (\s -> setMode (DoEval s) "-e")) -- -fno-code says to stop after Hsc but don't generate any code. , ( "fno-code" , PassFlag (\f -> do setMode (StopBefore HCc) f diff --git a/ghc/compiler/main/DriverState.hs b/ghc/compiler/main/DriverState.hs index 7c01e32..e8f83a2 100644 --- a/ghc/compiler/main/DriverState.hs +++ b/ghc/compiler/main/DriverState.hs @@ -1,5 +1,5 @@ ----------------------------------------------------------------------------- --- $Id: DriverState.hs,v 1.95 2003/08/20 18:48:20 sof Exp $ +-- $Id: DriverState.hs,v 1.96 2003/09/04 11:08:47 simonmar Exp $ -- -- Settings for the driver -- @@ -47,6 +47,7 @@ data GhcMode | DoMake -- ghc --make | DoInteractive -- ghc --interactive | DoLink -- [ the default ] + | DoEval String -- ghc -e deriving (Eq,Show) GLOBAL_VAR(v_GhcMode, DoLink, GhcMode) diff --git a/ghc/compiler/main/Main.hs b/ghc/compiler/main/Main.hs index 7da0074..5c66a92 100644 --- a/ghc/compiler/main/Main.hs +++ b/ghc/compiler/main/Main.hs @@ -1,7 +1,7 @@ {-# OPTIONS -fno-warn-incomplete-patterns -optc-DNON_POSIX_SOURCE #-} ----------------------------------------------------------------------------- --- $Id: Main.hs,v 1.131 2003/07/21 15:14:18 ross Exp $ +-- $Id: Main.hs,v 1.132 2003/09/04 11:08:47 simonmar Exp $ -- -- GHC Driver program -- @@ -142,11 +142,11 @@ main = -- -O and --interactive are not a good combination -- ditto with any kind of way selection orig_opt_level <- readIORef v_OptLevel - when (orig_opt_level > 0 && mode == DoInteractive) $ + when (orig_opt_level > 0 && isInteractive mode) $ do putStr "warning: -O conflicts with --interactive; -O turned off.\n" writeIORef v_OptLevel 0 orig_ways <- readIORef v_Ways - when (notNull orig_ways && mode == DoInteractive) $ + when (notNull orig_ways && isInteractive mode) $ do throwDyn (UsageError "--interactive can't be used with -prof, -ticky, -unreg or -smp.") @@ -177,6 +177,7 @@ main = build_tag <- readIORef v_Build_tag let lang = case mode of DoInteractive -> HscInterpreted + DoEval _ -> HscInterpreted _other | build_tag /= "" -> HscC | otherwise -> hscLang dyn_flags -- for ways other that the normal way, we must @@ -187,7 +188,9 @@ main = hscLang = lang, -- leave out hscOutName for now hscOutName = panic "Main.main:hscOutName not set", - verbosity = 1 + verbosity = case mode of + DoEval _ -> 0 + _other -> 1 }) -- The rest of the arguments are "dynamic" @@ -255,9 +258,13 @@ main = (staticLink o_files def_hs_pkgs) } #ifndef GHCI - DoInteractive -> throwDyn (CmdLineError "not built for interactive use") + DoInteractive -> noInteractiveError + DoEval _ -> noInteractiveError + where + noInteractiveError = throwDyn (CmdLineError "not built for interactive use") #else - DoInteractive -> interactiveUI srcs + DoInteractive -> interactiveUI srcs Nothing + DoEval expr -> interactiveUI srcs (Just expr) #endif -- ----------------------------------------------------------------------------- @@ -273,7 +280,7 @@ checkOptions mode srcs objs = do -- -ohi sanity check ohi <- readIORef v_Output_hi if (isJust ohi && - (mode == DoMake || mode == DoInteractive || srcs `lengthExceeds` 1)) + (mode == DoMake || isInteractive mode || srcs `lengthExceeds` 1)) then throwDyn (UsageError "-ohi can only be used when compiling a single source file") else do @@ -285,13 +292,16 @@ checkOptions mode srcs objs = do -- Check that there are some input files (except in the interactive -- case) - if null srcs && null objs && mode /= DoInteractive + if null srcs && null objs && not (isInteractive mode) then throwDyn (UsageError "no input files") else do -- Verify that output files point somewhere sensible. verifyOutputFiles +isInteractive DoInteractive = True +isInteractive (DoEval _) = True +isInteractive _ = False -- ----------------------------------------------------------------------------- -- Compile files in one-shot mode. diff --git a/ghc/compiler/parser/Lex.lhs b/ghc/compiler/parser/Lex.lhs index d559150..5be189c 100644 --- a/ghc/compiler/parser/Lex.lhs +++ b/ghc/compiler/parser/Lex.lhs @@ -441,6 +441,13 @@ lexer cont buf s@(PState{ -- special GHC extension: we grok cpp-style #line pragmas '#'# | lexemeIndex buf ==# bol -> -- the '#' must be in column 0 + -- SPECIAL CASE: if we see "#!" at the beginning of the line, + -- we ignore the rest of the line. This is for script-files + -- on Unix which begin with the special syntax "#! /bin/sh", + -- for example. + if lookAhead# buf 1# `eqChar#` '!'# + then next_line (stepOnBy# buf 2#) s' + else let buf1 | lookAhead# buf 1# `eqChar#` 'l'# && lookAhead# buf 2# `eqChar#` 'i'# && lookAhead# buf 3# `eqChar#` 'n'# &&