Commit 5e05865d authored by simonpj@microsoft.com's avatar simonpj@microsoft.com

Use -X for language extensions

We've often talked about having a separate flag for language extensions,
and now we have one. You can say

	-XImplicitParams
	-X=ImplicitParams
	-Ximplicit-params

as you like.  These replace the "-f" flags with similar names (though
the -f prefix will serve as a synonym for -X for a while).  

There's an optional "=", and the flag is normalised by removing hyphens
and lower-casing, so all the above variants mean the same thing.

The nomenclature is intended to match the LANGUAGE pramgas, which are
defined by Cabal.  So you can also say

	{-# LANGUAGE ImplicitParams #-}

But Cabal doesn't have as many language options as GHC does, so the -X
things are a superset of the LANGUAGE things.

The optional "=" applies to all flags that take an argument, so you can,
for example, say
	
	-pgmL=/etc/foo

I hope that's ok.  (It's an unforced change; just fitted in.)

I hope we'll add more -X flags, to replace the portmanteau -fglasgow-exts 
which does everything!  

I have updated the manual, but doubtless missed something.

parent 2a2c4275
......@@ -62,10 +62,11 @@ processOneArg :: OptKind m -> String -> String -> [String]
-> Either String (m (), [String])
processOneArg action rest arg args
= let dash_arg = '-' : arg
rest_no_eq = dropEq rest
in case action of
NoArg a -> ASSERT(null rest) Right (a, args)
HasArg f | notNull rest -> Right (f rest, args)
HasArg f | notNull rest_no_eq -> Right (f rest_no_eq, args)
| otherwise -> case args of
[] -> missingArgErr dash_arg
(arg1:args1) -> Right (f arg1, args1)
......@@ -74,23 +75,23 @@ processOneArg action rest arg args
[] -> unknownFlagErr dash_arg
(arg1:args1) -> Right (f arg1, args1)
Prefix f | notNull rest -> Right (f rest, args)
Prefix f | notNull rest_no_eq -> Right (f rest_no_eq, args)
| otherwise -> unknownFlagErr dash_arg
PrefixPred p f | notNull rest -> Right (f rest, args)
| otherwise -> unknownFlagErr dash_arg
PrefixPred p f | notNull rest_no_eq -> Right (f rest_no_eq, args)
| otherwise -> unknownFlagErr dash_arg
PassFlag f | notNull rest -> unknownFlagErr dash_arg
| otherwise -> Right (f dash_arg, args)
OptIntSuffix f | null rest -> Right (f Nothing, args)
| Just n <- parseInt rest -> Right (f (Just n), args)
OptIntSuffix f | null rest -> Right (f Nothing, args)
| Just n <- parseInt rest_no_eq -> Right (f (Just n), args)
| otherwise -> Left ("malformed integer argument in " ++ dash_arg)
IntSuffix f | Just n <- parseInt rest -> Right (f n, args)
IntSuffix f | Just n <- parseInt rest_no_eq -> Right (f n, args)
| otherwise -> Left ("malformed integer argument in " ++ dash_arg)
OptPrefix f -> Right (f rest, args)
OptPrefix f -> Right (f rest_no_eq, args)
AnySuffix f -> Right (f dash_arg, args)
AnySuffixPred p f -> Right (f dash_arg, args)
......@@ -109,7 +110,7 @@ arg_ok (NoArg _) rest arg = null rest
arg_ok (HasArg _) rest arg = True
arg_ok (SepArg _) rest arg = null rest
arg_ok (Prefix _) rest arg = notNull rest
arg_ok (PrefixPred p _) rest arg = notNull rest && p rest
arg_ok (PrefixPred p _) rest arg = notNull rest && p (dropEq rest)
arg_ok (OptIntSuffix _) rest arg = True
arg_ok (IntSuffix _) rest arg = True
arg_ok (OptPrefix _) rest arg = True
......@@ -121,7 +122,7 @@ parseInt :: String -> Maybe Int
-- Looks for "433" or "=342", with no trailing gubbins
-- n or =n => Just n
-- gibberish => Nothing
parseInt s = case reads (dropEq s) of
parseInt s = case reads s of
((n,""):_) -> Just n
other -> Nothing
......
......@@ -68,7 +68,7 @@ import Constants ( mAX_CONTEXT_REDUCTION_DEPTH )
import Panic ( panic, GhcException(..) )
import UniqFM ( UniqFM )
import Util ( notNull, splitLongestPrefix, normalisePath )
import Maybes ( fromJust, orElse )
import Maybes ( orElse, fromJust )
import SrcLoc ( SrcSpan )
import Outputable
import {-# SOURCE #-} ErrUtils ( Severity(..), Message, mkLocMessage )
......@@ -82,7 +82,7 @@ import Data.List ( isPrefixOf )
import Util ( split )
#endif
import Data.Char ( isUpper )
import Data.Char ( isUpper, toLower )
import System.IO ( hPutStrLn, stderr )
-- -----------------------------------------------------------------------------
......@@ -177,6 +177,8 @@ data DynFlag
| Opt_BangPatterns
| Opt_TypeFamilies
| Opt_OverloadedStrings
| Opt_GADTs
| Opt_RelaxedPolyRec -- -X=RelaxedPolyRec
-- optimisation opts
| Opt_Strictness
......@@ -1018,10 +1020,16 @@ dynamic_flags = [
, ( "fglasgow-exts", NoArg (mapM_ setDynFlag glasgowExtsFlags) )
, ( "fno-glasgow-exts", NoArg (mapM_ unSetDynFlag glasgowExtsFlags) )
-- the rest of the -f* and -fno-* flags
, ( "fno-", PrefixPred (\f -> isFFlag f) (\f -> unSetDynFlag (getFFlag f)) )
, ( "f", PrefixPred (\f -> isFFlag f) (\f -> setDynFlag (getFFlag f)) )
, ( "f", PrefixPred (isFlag fFlags) (\f -> setDynFlag (getFlag fFlags f)) )
, ( "f", PrefixPred (isNoFlag fFlags) (\f -> unSetDynFlag (getNoFlag fFlags f)) )
-- For now, allow -X flags with -f; ToDo: report this as deprecated
, ( "f", PrefixPred (isFlag xFlags) (\f -> setDynFlag (getFlag fFlags f)) )
-- the rest of the -X* and -Xno-* flags
, ( "X", PrefixPred (isFlag xFlags) (\f -> setDynFlag (getFlag xFlags f)) )
, ( "X", PrefixPred (isNoFlag xFlags) (\f -> unSetDynFlag (getNoFlag xFlags f)) )
]
-- these -f<blah> flags can all be reversed with -fno-<blah>
......@@ -1046,24 +1054,6 @@ fFlags = [
( "warn-deprecations", Opt_WarnDeprecations ),
( "warn-orphans", Opt_WarnOrphans ),
( "warn-tabs", Opt_WarnTabs ),
( "fi", Opt_FFI ), -- support `-ffi'...
( "ffi", Opt_FFI ), -- ...and also `-fffi'
( "arrows", Opt_Arrows ), -- arrow syntax
( "parr", Opt_PArr ),
( "th", Opt_TH ),
( "implicit-prelude", Opt_ImplicitPrelude ),
( "scoped-type-variables", Opt_ScopedTypeVariables ),
( "bang-patterns", Opt_BangPatterns ),
( "overloaded-strings", Opt_OverloadedStrings ),
( "type-families", Opt_TypeFamilies ),
( "monomorphism-restriction", Opt_MonomorphismRestriction ),
( "mono-pat-binds", Opt_MonoPatBinds ),
( "extended-default-rules", Opt_ExtendedDefaultRules ),
( "implicit-params", Opt_ImplicitParams ),
( "allow-overlapping-instances", Opt_AllowOverlappingInstances ),
( "allow-undecidable-instances", Opt_AllowUndecidableInstances ),
( "allow-incoherent-instances", Opt_AllowIncoherentInstances ),
( "generics", Opt_Generics ),
( "strictness", Opt_Strictness ),
( "full-laziness", Opt_FullLaziness ),
( "liberate-case", Opt_LiberateCase ),
......@@ -1088,15 +1078,85 @@ fFlags = [
]
glasgowExtsFlags = [
Opt_GlasgowExts,
Opt_FFI,
Opt_ImplicitParams,
Opt_ScopedTypeVariables,
Opt_TypeFamilies ]
-- These -X<blah> flags can all be reversed with -Xno-<blah>
xFlags :: [(String, DynFlag)]
xFlags = [
( "FI", Opt_FFI ), -- support `-ffi'...
( "FFI", Opt_FFI ), -- ...and also `-fffi'
( "ForeignFunctionInterface", Opt_FFI ), -- ...and also `-fffi'
( "Arrows", Opt_Arrows ), -- arrow syntax
( "Parr", Opt_PArr ),
( "TH", Opt_TH ),
( "TemplateHaskelll", Opt_TH ),
( "Generics", Opt_Generics ),
( "ImplicitPrelude", Opt_ImplicitPrelude ), -- On by default
( "OverloadedStrings", Opt_OverloadedStrings ),
( "GADTs", Opt_GADTs ),
( "TypeFamilies", Opt_TypeFamilies ),
( "BangPatterns", Opt_BangPatterns ),
( "MonomorphismRestriction", Opt_MonomorphismRestriction ), -- On by default
( "MonoPatBinds", Opt_MonoPatBinds ), -- On by default (which is not strictly H98)
( "RelaxedPolyRec", Opt_RelaxedPolyRec),
( "ExtendedDefaultRules", Opt_ExtendedDefaultRules ),
( "ImplicitParams", Opt_ImplicitParams ),
( "ScopedTypeVariables", Opt_ScopedTypeVariables ),
( "AllowOverlappingInstances", Opt_AllowOverlappingInstances ),
( "AllowUndecidableInstances", Opt_AllowUndecidableInstances ),
( "AllowIncoherentInstances", Opt_AllowIncoherentInstances )
]
impliedFlags :: [(DynFlag, [DynFlag])]
impliedFlags = [
( Opt_GADTs, [Opt_RelaxedPolyRec] ) -- We want type-sig variables to be completely rigid for GADTs
]
glasgowExtsFlags = [ Opt_GlasgowExts
, Opt_FFI
, Opt_ImplicitParams
, Opt_ScopedTypeVariables
, Opt_TypeFamilies ]
------------------
isNoFlag, isFlag :: [(String,a)] -> String -> Bool
isFlag flags f = is_flag flags (normaliseFlag f)
isFFlag f = f `elem` (map fst fFlags)
getFFlag f = fromJust (lookup f fFlags)
isNoFlag flags no_f
| Just f <- noFlag_maybe (normaliseFlag no_f) = is_flag flags f
| otherwise = False
is_flag flags nf = any (\(ff,_) -> normaliseFlag ff == nf) flags
-- nf is normalised alreadly
------------------
getFlag, getNoFlag :: [(String,a)] -> String -> a
getFlag flags f = get_flag flags (normaliseFlag f)
getNoFlag flags f = getFlag flags (fromJust (noFlag_maybe (normaliseFlag f)))
-- The flag should be a no-flag already
get_flag flags nf = head [ opt | (ff, opt) <- flags, normaliseFlag ff == nf]
------------------
noFlag_maybe :: String -> Maybe String
-- The input is normalised already
noFlag_maybe ('n' : 'o' : f) = Just f
noFlag_maybe other = Nothing
normaliseFlag :: String -> String
-- Normalise a option flag by
-- * map to lower case
-- * removing hyphens
-- Thus: -X=overloaded-strings or -XOverloadedStrings
normaliseFlag [] = []
normaliseFlag ('-':s) = normaliseFlag s
normaliseFlag (c:s) = toLower c : normaliseFlag s
-- -----------------------------------------------------------------------------
-- Parsing the dynamic flags.
......@@ -1117,10 +1177,18 @@ upd f = do
dfs <- getCmdLineState
putCmdLineState $! (f dfs)
--------------------------
setDynFlag, unSetDynFlag :: DynFlag -> DynP ()
setDynFlag f = upd (\dfs -> dopt_set dfs f)
setDynFlag f = upd (\dfs -> foldl dopt_set (dopt_set dfs f) deps)
where
deps = [ d | (f', ds) <- impliedFlags, f' == f, d <- ds ]
-- When you set f, set the ones it implies
-- When you un-set f, however, we don't un-set the things it implies
-- (except for -fno-glasgow-exts, which is treated specially)
unSetDynFlag f = upd (\dfs -> dopt_unset dfs f)
--------------------------
setDumpFlag :: DynFlag -> OptKind DynP
setDumpFlag dump_flag
= NoArg (setDynFlag Opt_ForceRecomp >> setDynFlag dump_flag)
......
......@@ -596,23 +596,29 @@
</thead>
<tbody>
<row>
<entry><option>-fallow-overlapping-instances</option></entry>
<entry><option>-fglasgow-exts</option></entry>
<entry>Enable most language extensions</entry>
<entry>dynamic</entry>
<entry><option>-fno-glasgow-exts</option></entry>
</row>
<row>
<entry><option>-X=AllowOverlappingInstances</option></entry>
<entry>Enable <link linkend="instance-overlap">overlapping instances</link></entry>
<entry>dynamic</entry>
<entry><option>-fno-allow-overlapping-instances</option></entry>
<entry><option>-X=NoAllowOverlappingInstances</option></entry>
</row>
<row>
<entry><option>-fallow-incoherent-instances</option></entry>
<entry><option>-X=AllowIncoherentInstances</option></entry>
<entry>Enable <link linkend="instance-overlap">incoherent instances</link>.
Implies <option>-fallow-overlapping-instances</option> </entry>
Implies <option>-X=AllowOverlappingInstances</option> </entry>
<entry>dynamic</entry>
<entry><option>-fno-allow-incoherent-instances</option></entry>
<entry><option>-X=NoAllowIncoherentInstances</option></entry>
</row>
<row>
<entry><option>-fallow-undecidable-instances</option></entry>
<entry><option>-X=AllowUndecidableInstances</option></entry>
<entry>Enable <link linkend="undecidable-instances">undecidable instances</link></entry>
<entry>dynamic</entry>
<entry><option>-fno-allow-undecidable-instances</option></entry>
<entry><option>-X=NoAllowUndecidableInstances</option></entry>
</row>
<row>
<entry><option>-fcontext-stack=N</option><replaceable>n</replaceable></entry>
......@@ -621,37 +627,31 @@
<entry><option>20</option></entry>
</row>
<row>
<entry><option>-farrows</option></entry>
<entry><option>-X=Arrows</option></entry>
<entry>Enable <link linkend="arrow-notation">arrow
notation</link> extension</entry>
<entry>dynamic</entry>
<entry><option>-fno-arrows</option></entry>
<entry><option>-X=NoArrows</option></entry>
</row>
<row>
<entry><option>-ffi</option> or <option>-fffi</option></entry>
<entry><option>-X=FFI</option> or <option>-X=ForeignFunctionInterface</option></entry>
<entry>Enable <link linkend="ffi">foreign function interface</link> (implied by
<option>-fglasgow-exts</option>)</entry>
<entry>dynamic</entry>
<entry><option>-fno-ffi</option></entry>
<entry><option>-X=NoFFI</option></entry>
</row>
<row>
<entry><option>-fgenerics</option></entry>
<entry><option>-X=Generics</option></entry>
<entry>Enable <link linkend="generic-classes">generic classes</link></entry>
<entry>dynamic</entry>
<entry><option>-fno-fgenerics</option></entry>
</row>
<row>
<entry><option>-fglasgow-exts</option></entry>
<entry>Enable most language extensions</entry>
<entry>dynamic</entry>
<entry><option>-fno-glasgow-exts</option></entry>
<entry><option>-X=NoGenerics</option></entry>
</row>
<row>
<entry><option>-fimplicit-params</option></entry>
<entry><option>-X=ImplicitParams</option></entry>
<entry>Enable <link linkend="implicit-parameters">Implicit Parameters</link>.
Implied by <option>-fglasgow-exts</option>.</entry>
<entry>dynamic</entry>
<entry><option>-fno-implicit-params</option></entry>
<entry><option>-X=NoImplicitParams</option></entry>
</row>
<row>
<entry><option>-firrefutable-tuples</option></entry>
......@@ -660,61 +660,61 @@
<entry><option>-fno-irrefutable-tuples</option></entry>
</row>
<row>
<entry><option>-fno-implicit-prelude</option></entry>
<entry><option>-X=NoImplicitPrelude</option></entry>
<entry>Don't implicitly <literal>import Prelude</literal></entry>
<entry>dynamic</entry>
<entry><option>-fimplicit-prelude</option></entry>
<entry><option>-X=ImplicitPrelude</option></entry>
</row>
<row>
<entry><option>-fno-monomorphism-restriction</option></entry>
<entry><option>-X=NoMonomorphismRestriction</option></entry>
<entry>Disable the <link linkend="monomorphism">monomorphism restriction</link></entry>
<entry>dynamic</entry>
<entry><option>-fmonomorphism-restriction</option></entry>
<entry><option>-X=MonomorphismRrestriction</option></entry>
</row>
<row>
<entry><option>-fno-mono-pat-binds</option></entry>
<entry><option>-X=NoMonoPatBinds</option></entry>
<entry>Make <link linkend="monomorphism">pattern bindings polymorphic</link></entry>
<entry>dynamic</entry>
<entry><option>-fmono-pat-binds</option></entry>
<entry><option>-X=MonoPatBinds</option></entry>
</row>
<row>
<entry><option>-fextended-default-rules</option></entry>
<entry><option>-X=ExtendedDefaultRules</option></entry>
<entry>Use GHCi's <link linkend="extended-default-rules">extended default rules</link> in a normal module</entry>
<entry>dynamic</entry>
<entry><option>-fno-extended-default-rules</option></entry>
<entry><option>-X=NoExtendedDefaultRules</option></entry>
</row>
<row>
<entry><option>-foverloaded-strings</option></entry>
<entry><option>-X=OverloadedStrings</option></entry>
<entry>Enable <link linkend="overloaded-strings">overloaded string literals</link>.
</entry>
<entry>dynamic</entry>
<entry><option>-fno-overloaded-strings</option></entry>
<entry><option>-X=OverloadedStrings</option></entry>
</row>
<row>
<entry><option>-fscoped-type-variables</option></entry>
<entry><option>-X=ScopedTypeVariables</option></entry>
<entry>Enable <link linkend="scoped-type-variables">lexically-scoped type variables</link>.
Implied by <option>-fglasgow-exts</option>.</entry>
<entry>dynamic</entry>
<entry><option>-fno-scoped-type-variables</option></entry>
<entry><option>-X=NoScopedTypeVariables</option></entry>
</row>
<row>
<entry><option>-fth</option></entry>
<entry><option>-X=TH</option> or <option>-X=TemplateHaskell</option></entry>
<entry>Enable <link linkend="template-haskell">Template Haskell</link>.
No longer implied by <option>-fglasgow-exts</option>.</entry>
<entry>dynamic</entry>
<entry><option>-fno-th</option></entry>
<entry><option>-X=NoTH</option></entry>
</row>
<row>
<entry><option>-ftype-families</option></entry>
<entry><option>-X=TypeFamilies</option></entry>
<entry>Enable <link linkend="type-families">type families</link>.</entry>
<entry>dynamic</entry>
<entry><option>-fno-type-families</option></entry>
<entry><option>-X=NoTypeFamilies</option></entry>
</row>
<row>
<entry><option>-fbang-patterns</option></entry>
<entry><option>-X=BangPtterns</option></entry>
<entry>Enable <link linkend="bang-patterns">bang patterns</link>.</entry>
<entry>dynamic</entry>
<entry><option>-fno-bang-patterns</option></entry>
<entry><option>-X=NoBangPatterns</option></entry>
</row>
</tbody>
</tgroup>
......
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment