-- ---------------------------------------------------------------------------
{
+{-# OPTIONS -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
+-- for details
+
+{-# OPTIONS_GHC -O0 -fno-ignore-interface-pragmas #-}
+{-
+Careful optimisation of the parser: we don't want to throw everything
+at it, because that takes too long and doesn't buy much, but we do want
+to inline certain key external functions, so we instruct GHC not to
+throw away inlinings as it would normally do in -O0 mode.
+-}
+
module Parser ( parseModule, parseStmt, parseIdentifier, parseType,
parseHeader ) where
-#define INCLUDE #include
-INCLUDE "HsVersions.h"
-
import HsSyn
import RdrHsSyn
-import HscTypes ( IsBootInterface, DeprecTxt )
+import HscTypes ( IsBootInterface, WarningTxt(..) )
import Lexer
import RdrName
import TysWiredIn ( unitTyCon, unitDataCon, tupleTyCon, tupleCon, nilDataCon,
+ unboxedSingletonTyCon, unboxedSingletonDataCon,
listTyCon_RDR, parrTyCon_RDR, consDataCon_RDR )
import Type ( funTyCon )
import ForeignCall ( Safety(..), CExportSpec(..), CLabelString,
import StaticFlags ( opt_SccProfilingOn, opt_Hpc )
import Type ( Kind, mkArrowKind, liftedTypeKind, unliftedTypeKind )
import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
- Activation(..), defaultInlineSpec )
+ Activation(..), RuleMatchInfo(..), defaultInlineSpec )
+import DynFlags
import OrdList
import HaddockParse
import {-# SOURCE #-} HaddockLex hiding ( Token )
'dotnet' { L _ ITdotnet }
'proc' { L _ ITproc } -- for arrow notation extension
'rec' { L _ ITrec } -- for arrow notation extension
+ 'group' { L _ ITgroup } -- for list transform extension
+ 'by' { L _ ITby } -- for list transform extension
+ 'using' { L _ ITusing } -- for list transform extension
'{-# INLINE' { L _ (ITinline_prag _) }
+ '{-# INLINE_CONLIKE' { L _ (ITinline_conlike_prag _) }
'{-# SPECIALISE' { L _ ITspec_prag }
'{-# SPECIALISE_INLINE' { L _ (ITspec_inline_prag _) }
'{-# SOURCE' { L _ ITsource_prag }
'{-# SCC' { L _ ITscc_prag }
'{-# GENERATED' { L _ ITgenerated_prag }
'{-# DEPRECATED' { L _ ITdeprecated_prag }
+ '{-# WARNING' { L _ ITwarning_prag }
'{-# UNPACK' { L _ ITunpack_prag }
+ '{-# ANN' { L _ ITann_prag }
'#-}' { L _ ITclose_prag }
'..' { L _ ITdotdot } -- reserved symbols
QCONID { L _ (ITqconid _) }
QVARSYM { L _ (ITqvarsym _) }
QCONSYM { L _ (ITqconsym _) }
+ PREFIXQVARSYM { L _ (ITprefixqvarsym _) }
+ PREFIXQCONSYM { L _ (ITprefixqconsym _) }
IPDUPVARID { L _ (ITdupipvarid _) } -- GHC extension
PRIMCHAR { L _ (ITprimchar _) }
PRIMSTRING { L _ (ITprimstring _) }
PRIMINTEGER { L _ (ITprimint _) }
+ PRIMWORD { L _ (ITprimword _) }
PRIMFLOAT { L _ (ITprimfloat _) }
PRIMDOUBLE { L _ (ITprimdouble _) }
DOCPREV { L _ (ITdocCommentPrev _) }
DOCNAMED { L _ (ITdocCommentNamed _) }
DOCSECTION { L _ (ITdocSection _ _) }
- DOCOPTIONS { L _ (ITdocOptions _) }
-- Template Haskell
'[|' { L _ ITopenExpQuote }
'$(' { L _ ITparenEscape } -- $( exp )
TH_VAR_QUOTE { L _ ITvarQuote } -- 'x
TH_TY_QUOTE { L _ ITtyQuote } -- ''T
+TH_QUASIQUOTE { L _ (ITquasiQuote _) }
%monad { P } { >>= } { return }
%lexer { lexer } { L _ ITeof }
| qcon { $1 }
| qvarop { $1 }
| qconop { $1 }
+ | '(' '->' ')' { LL $ getRdrName funTyCon }
-----------------------------------------------------------------------------
-- Module Header
-- know what they are doing. :-)
module :: { Located (HsModule RdrName) }
- : optdoc 'module' modid maybemoddeprec maybeexports 'where' body
- {% fileSrcSpan >>= \ loc -> case $1 of { (opt, info, doc) ->
- return (L loc (HsModule (Just $3) $5 (fst $7) (snd $7) $4
- opt info doc) )}}
+ : maybedocheader 'module' modid maybemodwarning maybeexports 'where' body
+ {% fileSrcSpan >>= \ loc -> case $1 of { (info, doc) ->
+ return (L loc (HsModule (Just $3) $5 (fst $7) (snd $7) $4
+ info doc) )}}
| body2
{% fileSrcSpan >>= \ loc ->
- return (L loc (HsModule Nothing Nothing
- (fst $1) (snd $1) Nothing Nothing emptyHaddockModInfo
+ return (L loc (HsModule Nothing Nothing
+ (fst $1) (snd $1) Nothing emptyHaddockModInfo
Nothing)) }
-optdoc :: { (Maybe String, HaddockModInfo RdrName, Maybe (HsDoc RdrName)) }
- : moduleheader { (Nothing, fst $1, snd $1) }
- | docoptions { (Just $1, emptyHaddockModInfo, Nothing)}
- | docoptions moduleheader { (Just $1, fst $2, snd $2) }
- | moduleheader docoptions { (Just $2, fst $1, snd $1) }
- | {- empty -} { (Nothing, emptyHaddockModInfo, Nothing) }
+maybedocheader :: { (HaddockModInfo RdrName, Maybe (HsDoc RdrName)) }
+ : moduleheader { $1 }
+ | {- empty -} { (emptyHaddockModInfo, Nothing) }
missing_module_keyword :: { () }
: {- empty -} {% pushCurrentContext }
-maybemoddeprec :: { Maybe DeprecTxt }
- : '{-# DEPRECATED' STRING '#-}' { Just (getSTRING $2) }
- | {- empty -} { Nothing }
+maybemodwarning :: { Maybe WarningTxt }
+ : '{-# DEPRECATED' STRING '#-}' { Just (DeprecatedTxt (getSTRING $2)) }
+ | '{-# WARNING' STRING '#-}' { Just (WarningTxt (getSTRING $2)) }
+ | {- empty -} { Nothing }
body :: { ([LImportDecl RdrName], [LHsDecl RdrName]) }
: '{' top '}' { $2 }
-- Module declaration & imports only
header :: { Located (HsModule RdrName) }
- : optdoc 'module' modid maybemoddeprec maybeexports 'where' header_body
- {% fileSrcSpan >>= \ loc -> case $1 of { (opt, info, doc) ->
- return (L loc (HsModule (Just $3) $5 $7 [] $4
- opt info doc))}}
+ : maybedocheader 'module' modid maybemodwarning maybeexports 'where' header_body
+ {% fileSrcSpan >>= \ loc -> case $1 of { (info, doc) ->
+ return (L loc (HsModule (Just $3) $5 $7 [] $4
+ info doc))}}
| missing_module_keyword importdecls
{% fileSrcSpan >>= \ loc ->
- return (L loc (HsModule Nothing Nothing $2 [] Nothing
- Nothing emptyHaddockModInfo Nothing)) }
+ return (L loc (HsModule Nothing Nothing $2 [] Nothing
+ emptyHaddockModInfo Nothing)) }
header_body :: { [LImportDecl RdrName] }
: '{' importdecls { $2 }
| {- empty -} { [] }
importdecl :: { LImportDecl RdrName }
- : 'import' maybe_src optqualified modid maybeas maybeimpspec
- { L (comb4 $1 $4 $5 $6) (ImportDecl $4 $2 $3 (unLoc $5) (unLoc $6)) }
+ : 'import' maybe_src optqualified maybe_pkg modid maybeas maybeimpspec
+ { L (comb4 $1 $5 $6 $7) (ImportDecl $5 $4 $2 $3 (unLoc $6) (unLoc $7)) }
maybe_src :: { IsBootInterface }
: '{-# SOURCE' '#-}' { True }
| {- empty -} { False }
+maybe_pkg :: { Maybe FastString }
+ : STRING { Just (getSTRING $1) }
+ | {- empty -} { Nothing }
+
optqualified :: { Bool }
: 'qualified' { True }
| {- empty -} { False }
| stand_alone_deriving { unitOL (LL (DerivD (unLoc $1))) }
| 'default' '(' comma_types0 ')' { unitOL (LL $ DefD (DefaultDecl $3)) }
| 'foreign' fdecl { unitOL (LL (unLoc $2)) }
- | '{-# DEPRECATED' deprecations '#-}' { $2 }
+ | '{-# DEPRECATED' deprecations '#-}' { $2 }
+ | '{-# WARNING' warnings '#-}' { $2 }
| '{-# RULES' rules '#-}' { $2 }
+ | annotation { unitOL $1 }
| decl { unLoc $1 }
-- Template Haskell Extension
| data_or_newtype tycl_hdr constrs deriving
{% do { let {(ctxt, tc, tvs, tparms) = unLoc $2}
; checkTyVars tparms -- no type pattern
- ; return $
- L (comb4 $1 $2 $3 $4)
+ ; return $!
+ sL (comb4 $1 $2 $3 $4)
-- We need the location on tycl_hdr in case
-- constrs and deriving are both empty
(mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing)
deriving
{% do { let {(ctxt, tc, tvs, tparms) = unLoc $2}
; checkTyVars tparms -- can have type pats
- ; return $
- L (comb4 $1 $2 $4 $5)
+ ; return $!
+ sL (comb4 $1 $2 $4 $5)
(mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing)
(unLoc $3) (reverse (unLoc $5)) (unLoc $6)) } }
-- Declarations in binding groups other than classes and instances
--
decls :: { Located (OrdList (LHsDecl RdrName)) }
- : decls ';' decl { LL (unLoc $1 `appOL` unLoc $3) }
+ : decls ';' decl { let { this = unLoc $3;
+ rest = unLoc $1;
+ these = rest `appOL` this }
+ in rest `seq` this `seq` these `seq`
+ LL these }
| decls ';' { LL (unLoc $1) }
| decl { $1 }
| {- empty -} { noLoc nilOL }
| '(' varid '::' ctype ')' { RuleBndrSig $2 $4 }
-----------------------------------------------------------------------------
--- Deprecations (c.f. rules)
+-- Warnings and deprecations (c.f. rules)
+
+warnings :: { OrdList (LHsDecl RdrName) }
+ : warnings ';' warning { $1 `appOL` $3 }
+ | warnings ';' { $1 }
+ | warning { $1 }
+ | {- empty -} { nilOL }
+
+-- SUP: TEMPORARY HACK, not checking for `module Foo'
+warning :: { OrdList (LHsDecl RdrName) }
+ : namelist STRING
+ { toOL [ LL $ WarningD (Warning n (WarningTxt (getSTRING $2)))
+ | n <- unLoc $1 ] }
deprecations :: { OrdList (LHsDecl RdrName) }
: deprecations ';' deprecation { $1 `appOL` $3 }
-- SUP: TEMPORARY HACK, not checking for `module Foo'
deprecation :: { OrdList (LHsDecl RdrName) }
- : depreclist STRING
- { toOL [ LL $ DeprecD (Deprecation n (getSTRING $2))
+ : namelist STRING
+ { toOL [ LL $ WarningD (Warning n (DeprecatedTxt (getSTRING $2)))
| n <- unLoc $1 ] }
+-----------------------------------------------------------------------------
+-- Annotations
+annotation :: { LHsDecl RdrName }
+ : '{-# ANN' name_var aexp '#-}' { LL (AnnD $ HsAnnotation (ValueAnnProvenance (unLoc $2)) $3) }
+ | '{-# ANN' 'type' tycon aexp '#-}' { LL (AnnD $ HsAnnotation (TypeAnnProvenance (unLoc $3)) $4) }
+ | '{-# ANN' 'module' aexp '#-}' { LL (AnnD $ HsAnnotation ModuleAnnProvenance $3) }
+
-----------------------------------------------------------------------------
-- Foreign import and export declarations
ctypedoc :: { LHsType RdrName }
: 'forall' tv_bndrs '.' ctypedoc { LL $ mkExplicitHsForAllTy $2 (noLoc []) $4 }
- | context '=>' gentypedoc { LL $ mkImplicitHsForAllTy $1 $3 }
+ | context '=>' ctypedoc { LL $ mkImplicitHsForAllTy $1 $3 }
-- A type of form (context => type) is an *implicit* HsForAllTy
| gentypedoc { $1 }
return (LL $ unitOL $ LL $ ValD (
PatBind (LL $ BangPat pat) (unLoc $3)
placeHolderType placeHolderNames)) } }
- | infixexp opt_sig rhs {% do { r <- checkValDef $1 $2 $3;
- return (LL $ unitOL (LL $ ValD r)) } }
+ | infixexp opt_sig rhs {% do { r <- checkValDef $1 $2 $3;
+ let { l = comb2 $1 $> };
+ return $! (sL l (unitOL $! (sL l $ ValD r))) } }
| docdecl { LL $ unitOL $1 }
rhs :: { Located (GRHSs RdrName) }
- : '=' exp wherebinds { L (comb3 $1 $2 $3) $ GRHSs (unguardedRHS $2) (unLoc $3) }
+ : '=' exp wherebinds { sL (comb3 $1 $2 $3) $ GRHSs (unguardedRHS $2) (unLoc $3) }
| gdrhs wherebinds { LL $ GRHSs (reverse (unLoc $1)) (unLoc $2) }
gdrhs :: { Located [LGRHS RdrName] }
| gdrh { L1 [$1] }
gdrh :: { LGRHS RdrName }
- : '|' quals '=' exp { sL (comb2 $1 $>) $ GRHS (reverse (unLoc $2)) $4 }
+ : '|' guardquals '=' exp { sL (comb2 $1 $>) $ GRHS (unLoc $2) $4 }
sigdecl :: { Located (OrdList (LHsDecl RdrName)) }
: infixexp '::' sigtypedoc
| infix prec ops { LL $ toOL [ LL $ SigD (FixSig (FixitySig n (Fixity $2 (unLoc $1))))
| n <- unLoc $3 ] }
| '{-# INLINE' activation qvar '#-}'
- { LL $ unitOL (LL $ SigD (InlineSig $3 (mkInlineSpec $2 (getINLINE $1)))) }
+ { LL $ unitOL (LL $ SigD (InlineSig $3 (mkInlineSpec $2 FunLike (getINLINE $1)))) }
+ | '{-# INLINE_CONLIKE' activation qvar '#-}'
+ { LL $ unitOL (LL $ SigD (InlineSig $3 (mkInlineSpec $2 ConLike (getINLINE_CONLIKE $1)))) }
| '{-# SPECIALISE' qvar '::' sigtypes1 '#-}'
{ LL $ toOL [ LL $ SigD (SpecSig $2 t defaultInlineSpec)
| t <- $4] }
| '{-# SPECIALISE_INLINE' activation qvar '::' sigtypes1 '#-}'
- { LL $ toOL [ LL $ SigD (SpecSig $3 t (mkInlineSpec $2 (getSPEC_INLINE $1)))
+ { LL $ toOL [ LL $ SigD (SpecSig $3 t (mkInlineSpec $2 FunLike (getSPEC_INLINE $1)))
| t <- $5] }
| '{-# SPECIALISE' 'instance' inst_type '#-}'
{ LL $ unitOL (LL $ SigD (SpecInstSig $3)) }
| fexp { $1 }
scc_annot :: { Located FastString }
- : '_scc_' STRING { LL $ getSTRING $2 }
- | '{-# SCC' STRING '#-}' { LL $ getSTRING $2 }
+ : '_scc_' STRING {% (addWarning Opt_WarnWarningsDeprecations (getLoc $1) (text "_scc_ is deprecated; use an SCC pragma instead")) >>= \_ ->
+ ( do scc <- getSCC $2; return $ LL scc ) }
+ | '{-# SCC' STRING '#-}' {% do scc <- getSCC $2; return $ LL scc }
hpc_annot :: { Located (FastString,(Int,Int),(Int,Int)) }
: '{-# GENERATED' STRING INTEGER ':' INTEGER '-' INTEGER ':' INTEGER '#-}'
aexp :: { LHsExpr RdrName }
: qvar '@' aexp { LL $ EAsPat $1 $3 }
| '~' aexp { LL $ ELazyPat $2 }
- | aexp1 { $1 }
+ | aexp1 { $1 }
aexp1 :: { LHsExpr RdrName }
: aexp1 '{' fbinds '}' {% do { r <- mkRecConstrOrUpdate $1 (comb2 $2 $4) $3
| literal { L1 (HsLit $! unLoc $1) }
-- This will enable overloaded strings permanently. Normally the renamer turns HsString
-- into HsOverLit when -foverloaded-strings is on.
--- | STRING { L1 (HsOverLit $! mkHsIsString (getSTRING $1)) }
- | INTEGER { L1 (HsOverLit $! mkHsIntegral (getINTEGER $1)) }
- | RATIONAL { L1 (HsOverLit $! mkHsFractional (getRATIONAL $1)) }
- | '(' exp ')' { LL (HsPar $2) }
+-- | STRING { sL (getLoc $1) (HsOverLit $! mkHsIsString (getSTRING $1) placeHolderType) }
+ | INTEGER { sL (getLoc $1) (HsOverLit $! mkHsIntegral (getINTEGER $1) placeHolderType) }
+ | RATIONAL { sL (getLoc $1) (HsOverLit $! mkHsFractional (getRATIONAL $1) placeHolderType) }
+ -- N.B.: sections get parsed by these next two productions.
+ -- This allows you to write, e.g., '(+ 3, 4 -)', which isn't correct Haskell98
+ -- (you'd have to write '((+ 3), (4 -))')
+ -- but the less cluttered version fell out of having texps.
+ | '(' texp ')' { LL (HsPar $2) }
| '(' texp ',' texps ')' { LL $ ExplicitTuple ($2 : reverse $4) Boxed }
| '(#' texps '#)' { LL $ ExplicitTuple (reverse $2) Unboxed }
| '[' list ']' { LL (unLoc $2) }
| '[:' parr ':]' { LL (unLoc $2) }
- | '(' infixexp qop ')' { LL $ SectionL $2 $3 }
- | '(' qopm infixexp ')' { LL $ SectionR $2 $3 }
| '_' { L1 EWildPat }
-- Template Haskell Extension
(getTH_ID_SPLICE $1)))) } -- $x
| '$(' exp ')' { LL $ HsSpliceE (mkHsSplice $2) } -- $( exp )
+ | TH_QUASIQUOTE { let { loc = getLoc $1
+ ; ITquasiQuote (quoter, quote, quoteSpan) = unLoc $1
+ ; quoterId = mkUnqual varName quoter
+ }
+ in sL loc $ HsQuasiQuoteE (mkHsQuasiQuote quoterId quoteSpan quote) }
| TH_VAR_QUOTE qvar { LL $ HsBracket (VarBr (unLoc $2)) }
| TH_VAR_QUOTE qcon { LL $ HsBracket (VarBr (unLoc $2)) }
| TH_TY_QUOTE tyvar { LL $ HsBracket (VarBr (unLoc $2)) }
: {- empty -} { [] }
| cvtopdecls { $1 }
+-- "texp" is short for tuple expressions:
+-- things that can appear unparenthesized as long as they're
+-- inside parens or delimitted by commas
texp :: { LHsExpr RdrName }
: exp { $1 }
- | qopm infixexp { LL $ SectionR $1 $2 }
- -- The second production is really here only for bang patterns
- -- but
+
+ -- Note [Parsing sections]
+ -- ~~~~~~~~~~~~~~~~~~~~~~~
+ -- We include left and right sections here, which isn't
+ -- technically right according to Haskell 98. For example
+ -- (3 +, True) isn't legal
+ -- However, we want to parse bang patterns like
+ -- (!x, !y)
+ -- and it's convenient to do so here as a section
+ -- Then when converting expr to pattern we unravel it again
+ -- Meanwhile, the renamer checks that real sections appear
+ -- inside parens.
+ | infixexp qop { LL $ SectionL $1 $2 }
+ | qopm infixexp { LL $ SectionR $1 $2 }
+
+ -- View patterns get parenthesized above
+ | exp '->' exp { LL $ EViewPat $1 $3 }
texps :: { [LHsExpr RdrName] }
: texps ',' texp { $3 : $1 }
| texp ',' exp '..' { LL $ ArithSeq noPostTcExpr (FromThen $1 $3) }
| texp '..' exp { LL $ ArithSeq noPostTcExpr (FromTo $1 $3) }
| texp ',' exp '..' exp { LL $ ArithSeq noPostTcExpr (FromThenTo $1 $3 $5) }
- | texp pquals { sL (comb2 $1 $>) $ mkHsDo ListComp (reverse (unLoc $2)) $1 }
+ | texp '|' flattenedpquals { sL (comb2 $1 $>) $ mkHsDo ListComp (unLoc $3) $1 }
lexps :: { Located [LHsExpr RdrName] }
- : lexps ',' texp { LL ($3 : unLoc $1) }
+ : lexps ',' texp { LL (((:) $! $3) $! unLoc $1) }
| texp ',' texp { LL [$3,$1] }
-----------------------------------------------------------------------------
-- List Comprehensions
-pquals :: { Located [LStmt RdrName] } -- Either a singleton ParStmt,
- -- or a reversed list of Stmts
- : pquals1 { case unLoc $1 of
- [qs] -> L1 qs
- qss -> L1 [L1 (ParStmt stmtss)]
- where
- stmtss = [ (reverse qs, undefined)
- | qs <- qss ]
- }
-
+flattenedpquals :: { Located [LStmt RdrName] }
+ : pquals { case (unLoc $1) of
+ ParStmt [(qs, _)] -> L1 qs
+ -- We just had one thing in our "parallel" list so
+ -- we simply return that thing directly
+
+ _ -> L1 [$1]
+ -- We actually found some actual parallel lists so
+ -- we leave them into as a ParStmt
+ }
+
+pquals :: { LStmt RdrName }
+ : pquals1 { L1 (ParStmt [(qs, undefined) | qs <- (reverse (unLoc $1))]) }
+
pquals1 :: { Located [[LStmt RdrName]] }
- : pquals1 '|' quals { LL (unLoc $3 : unLoc $1) }
- | '|' quals { L (getLoc $2) [unLoc $2] }
+ : pquals1 '|' squals { LL (unLoc $3 : unLoc $1) }
+ | squals { L (getLoc $1) [unLoc $1] }
+
+squals :: { Located [LStmt RdrName] }
+ : squals1 { L (getLoc $1) (reverse (unLoc $1)) }
+
+squals1 :: { Located [LStmt RdrName] }
+ : transformquals1 { LL (unLoc $1) }
+
+transformquals1 :: { Located [LStmt RdrName] }
+ : transformquals1 ',' transformqual { LL $ [LL ((unLoc $3) (unLoc $1))] }
+ | transformquals1 ',' qual { LL ($3 : unLoc $1) }
+-- | transformquals1 ',' '{|' pquals '|}' { LL ($4 : unLoc $1) }
+ | transformqual { LL $ [LL ((unLoc $1) [])] }
+ | qual { L1 [$1] }
+-- | '{|' pquals '|}' { L1 [$2] }
+
+
+-- It is possible to enable bracketing (associating) qualifier lists by uncommenting the lines with {| |}
+-- above. Due to a lack of consensus on the syntax, this feature is not being used until we get user
+-- demand. Note that the {| |} symbols are reused from -XGenerics and hence if you want to compile
+-- a program that makes use of this temporary syntax you must supply that flag to GHC
-quals :: { Located [LStmt RdrName] }
- : quals ',' qual { LL ($3 : unLoc $1) }
- | qual { L1 [$1] }
+transformqual :: { Located ([LStmt RdrName] -> Stmt RdrName) }
+ : 'then' exp { LL $ \leftStmts -> (mkTransformStmt (reverse leftStmts) $2) }
+ | 'then' exp 'by' exp { LL $ \leftStmts -> (mkTransformByStmt (reverse leftStmts) $2 $4) }
+ | 'then' 'group' 'by' exp { LL $ \leftStmts -> (mkGroupByStmt (reverse leftStmts) $4) }
+ | 'then' 'group' 'using' exp { LL $ \leftStmts -> (mkGroupUsingStmt (reverse leftStmts) $4) }
+ | 'then' 'group' 'by' exp 'using' exp { LL $ \leftStmts -> (mkGroupByUsingStmt (reverse leftStmts) $4 $6) }
-----------------------------------------------------------------------------
-- Parallel array expressions
(reverse (unLoc $1)) }
| texp '..' exp { LL $ PArrSeq noPostTcExpr (FromTo $1 $3) }
| texp ',' exp '..' exp { LL $ PArrSeq noPostTcExpr (FromThenTo $1 $3 $5) }
- | texp pquals { sL (comb2 $1 $>) $ mkHsDo PArrComp (reverse (unLoc $2)) $1 }
+ | texp '|' flattenedpquals { LL $ mkHsDo PArrComp (unLoc $3) $1 }
--- We are reusing `lexps' and `pquals' from the list case.
+-- We are reusing `lexps' and `flattenedpquals' from the list case.
+
+-----------------------------------------------------------------------------
+-- Guards
+
+guardquals :: { Located [LStmt RdrName] }
+ : guardquals1 { L (getLoc $1) (reverse (unLoc $1)) }
+
+guardquals1 :: { Located [LStmt RdrName] }
+ : guardquals1 ',' qual { LL ($3 : unLoc $1) }
+ | qual { L1 [$1] }
-----------------------------------------------------------------------------
-- Case alternatives
| gdpat { L1 [$1] }
gdpat :: { LGRHS RdrName }
- : '|' quals '->' exp { sL (comb2 $1 $>) $ GRHS (reverse (unLoc $2)) $4 }
+ : '|' guardquals '->' exp { sL (comb2 $1 $>) $ GRHS (unLoc $2) $4 }
-- 'pat' recognises a pattern, including one with a bang at the top
-- e.g. "!x" or "!(x,y)" or "C a b" etc
| {- nothing -} { Nothing }
stmt :: { LStmt RdrName }
- : qual { $1 }
+ : qual { $1 }
| 'rec' stmtlist { LL $ mkRecStmt (unLoc $2) }
qual :: { LStmt RdrName }
- : pat '<-' exp { LL $ mkBindStmt $1 $3 }
- | exp { L1 $ mkExprStmt $1 }
- | 'let' binds { LL $ LetStmt (unLoc $2) }
+ : pat '<-' exp { LL $ mkBindStmt $1 $3 }
+ | exp { L1 $ mkExprStmt $1 }
+ | 'let' binds { LL $ LetStmt (unLoc $2) }
-----------------------------------------------------------------------------
-- Record Field Update/Construction
-- Implicit Parameter Bindings
dbinds :: { Located [LIPBind RdrName] }
- : dbinds ';' dbind { LL ($3 : unLoc $1) }
+ : dbinds ';' dbind { let { this = $3; rest = unLoc $1 }
+ in rest `seq` this `seq` LL (this : rest) }
| dbinds ';' { LL (unLoc $1) }
- | dbind { L1 [$1] }
+ | dbind { let this = $1 in this `seq` L1 [this] }
-- | {- empty -} { [] }
dbind :: { LIPBind RdrName }
: IPDUPVARID { L1 (IPName (mkUnqual varName (getIPDUPVARID $1))) }
-----------------------------------------------------------------------------
--- Deprecations
+-- Warnings and deprecations
-depreclist :: { Located [RdrName] }
-depreclist : deprec_var { L1 [unLoc $1] }
- | deprec_var ',' depreclist { LL (unLoc $1 : unLoc $3) }
+namelist :: { Located [RdrName] }
+namelist : name_var { L1 [unLoc $1] }
+ | name_var ',' namelist { LL (unLoc $1 : unLoc $3) }
-deprec_var :: { Located RdrName }
-deprec_var : var { $1 }
- | con { $1 }
+name_var :: { Located RdrName }
+name_var : var { $1 }
+ | con { $1 }
-----------------------------------------
-- Data constructors
sysdcon :: { Located DataCon } -- Wired in data constructors
: '(' ')' { LL unitDataCon }
| '(' commas ')' { LL $ tupleCon Boxed $2 }
+ | '(#' '#)' { LL $ unboxedSingletonDataCon }
+ | '(#' commas '#)' { LL $ tupleCon Unboxed $2 }
| '[' ']' { LL nilDataCon }
conop :: { Located RdrName }
: oqtycon { $1 }
| '(' ')' { LL $ getRdrName unitTyCon }
| '(' commas ')' { LL $ getRdrName (tupleTyCon Boxed $2) }
+ | '(#' '#)' { LL $ getRdrName unboxedSingletonTyCon }
+ | '(#' commas '#)' { LL $ getRdrName (tupleTyCon Unboxed $2) }
| '(' '->' ')' { LL $ getRdrName funTyCon }
| '[' ']' { LL $ listTyCon_RDR }
| '[:' ':]' { LL $ parrTyCon_RDR }
qtycon :: { Located RdrName } -- Qualified or unqualified
: QCONID { L1 $! mkQual tcClsName (getQCONID $1) }
+ | PREFIXQCONSYM { L1 $! mkQual tcClsName (getPREFIXQCONSYM $1) }
| tycon { $1 }
tycon :: { Located RdrName } -- Unqualified
tyvarid :: { Located RdrName }
: VARID { L1 $! mkUnqual tvName (getVARID $1) }
| special_id { L1 $! mkUnqual tvName (unLoc $1) }
- | 'unsafe' { L1 $! mkUnqual tvName FSLIT("unsafe") }
- | 'safe' { L1 $! mkUnqual tvName FSLIT("safe") }
- | 'threadsafe' { L1 $! mkUnqual tvName FSLIT("threadsafe") }
+ | 'unsafe' { L1 $! mkUnqual tvName (fsLit "unsafe") }
+ | 'safe' { L1 $! mkUnqual tvName (fsLit "safe") }
+ | 'threadsafe' { L1 $! mkUnqual tvName (fsLit "threadsafe") }
tyvarsym :: { Located RdrName }
-- Does not include "!", because that is used for strictness marks
qvarid :: { Located RdrName }
: varid { $1 }
- | QVARID { L1 $ mkQual varName (getQVARID $1) }
+ | QVARID { L1 $! mkQual varName (getQVARID $1) }
+ | PREFIXQVARSYM { L1 $! mkQual varName (getPREFIXQVARSYM $1) }
varid :: { Located RdrName }
- : varid_no_unsafe { $1 }
- | 'unsafe' { L1 $! mkUnqual varName FSLIT("unsafe") }
- | 'safe' { L1 $! mkUnqual varName FSLIT("safe") }
- | 'threadsafe' { L1 $! mkUnqual varName FSLIT("threadsafe") }
-
-varid_no_unsafe :: { Located RdrName }
: VARID { L1 $! mkUnqual varName (getVARID $1) }
| special_id { L1 $! mkUnqual varName (unLoc $1) }
- | 'forall' { L1 $! mkUnqual varName FSLIT("forall") }
- | 'family' { L1 $! mkUnqual varName FSLIT("family") }
+ | 'unsafe' { L1 $! mkUnqual varName (fsLit "unsafe") }
+ | 'safe' { L1 $! mkUnqual varName (fsLit "safe") }
+ | 'threadsafe' { L1 $! mkUnqual varName (fsLit "threadsafe") }
+ | 'forall' { L1 $! mkUnqual varName (fsLit "forall") }
+ | 'family' { L1 $! mkUnqual varName (fsLit "family") }
qvarsym :: { Located RdrName }
: varsym { $1 }
varsym :: { Located RdrName }
: varsym_no_minus { $1 }
- | '-' { L1 $ mkUnqual varName FSLIT("-") }
+ | '-' { L1 $ mkUnqual varName (fsLit "-") }
varsym_no_minus :: { Located RdrName } -- varsym not including '-'
: VARSYM { L1 $ mkUnqual varName (getVARSYM $1) }
-- depending on context
special_id :: { Located FastString }
special_id
- : 'as' { L1 FSLIT("as") }
- | 'qualified' { L1 FSLIT("qualified") }
- | 'hiding' { L1 FSLIT("hiding") }
- | 'export' { L1 FSLIT("export") }
- | 'label' { L1 FSLIT("label") }
- | 'dynamic' { L1 FSLIT("dynamic") }
- | 'stdcall' { L1 FSLIT("stdcall") }
- | 'ccall' { L1 FSLIT("ccall") }
+ : 'as' { L1 (fsLit "as") }
+ | 'qualified' { L1 (fsLit "qualified") }
+ | 'hiding' { L1 (fsLit "hiding") }
+ | 'export' { L1 (fsLit "export") }
+ | 'label' { L1 (fsLit "label") }
+ | 'dynamic' { L1 (fsLit "dynamic") }
+ | 'stdcall' { L1 (fsLit "stdcall") }
+ | 'ccall' { L1 (fsLit "ccall") }
special_sym :: { Located FastString }
-special_sym : '!' { L1 FSLIT("!") }
- | '.' { L1 FSLIT(".") }
- | '*' { L1 FSLIT("*") }
+special_sym : '!' { L1 (fsLit "!") }
+ | '.' { L1 (fsLit ".") }
+ | '*' { L1 (fsLit "*") }
-----------------------------------------------------------------------------
-- Data constructors
qconid :: { Located RdrName } -- Qualified or unqualified
: conid { $1 }
- | QCONID { L1 $ mkQual dataName (getQCONID $1) }
+ | QCONID { L1 $! mkQual dataName (getQCONID $1) }
+ | PREFIXQCONSYM { L1 $! mkQual dataName (getPREFIXQCONSYM $1) }
conid :: { Located RdrName }
: CONID { L1 $ mkUnqual dataName (getCONID $1) }
: CHAR { L1 $ HsChar $ getCHAR $1 }
| STRING { L1 $ HsString $ getSTRING $1 }
| PRIMINTEGER { L1 $ HsIntPrim $ getPRIMINTEGER $1 }
+ | PRIMWORD { L1 $ HsWordPrim $ getPRIMWORD $1 }
| PRIMCHAR { L1 $ HsCharPrim $ getPRIMCHAR $1 }
| PRIMSTRING { L1 $ HsStringPrim $ getPRIMSTRING $1 }
| PRIMFLOAT { L1 $ HsFloatPrim $ getPRIMFLOAT $1 }
docnext :: { LHsDoc RdrName }
: DOCNEXT {% case parseHaddockParagraphs (tokenise (getDOCNEXT $1)) of {
- Left err -> parseError (getLoc $1) err;
- Right doc -> return (L1 doc) } }
+ MyLeft err -> parseError (getLoc $1) err;
+ MyRight doc -> return (L1 doc) } }
docprev :: { LHsDoc RdrName }
: DOCPREV {% case parseHaddockParagraphs (tokenise (getDOCPREV $1)) of {
- Left err -> parseError (getLoc $1) err;
- Right doc -> return (L1 doc) } }
+ MyLeft err -> parseError (getLoc $1) err;
+ MyRight doc -> return (L1 doc) } }
docnamed :: { Located (String, (HsDoc RdrName)) }
: DOCNAMED {%
let string = getDOCNAMED $1
(name, rest) = break isSpace string
in case parseHaddockParagraphs (tokenise rest) of {
- Left err -> parseError (getLoc $1) err;
- Right doc -> return (L1 (name, doc)) } }
+ MyLeft err -> parseError (getLoc $1) err;
+ MyRight doc -> return (L1 (name, doc)) } }
-docsection :: { Located (n, HsDoc RdrName) }
+docsection :: { Located (Int, HsDoc RdrName) }
: DOCSECTION {% let (n, doc) = getDOCSECTION $1 in
case parseHaddockString (tokenise doc) of {
- Left err -> parseError (getLoc $1) err;
- Right doc -> return (L1 (n, doc)) } }
-
-docoptions :: { String }
- : DOCOPTIONS { getDOCOPTIONS $1 }
+ MyLeft err -> parseError (getLoc $1) err;
+ MyRight doc -> return (L1 (n, doc)) } }
moduleheader :: { (HaddockModInfo RdrName, Maybe (HsDoc RdrName)) }
: DOCNEXT {% let string = getDOCNEXT $1 in
case parseModuleHeader string of {
Right (str, info) ->
case parseHaddockParagraphs (tokenise str) of {
- Left err -> parseError (getLoc $1) err;
- Right doc -> return (info, Just doc);
+ MyLeft err -> parseError (getLoc $1) err;
+ MyRight doc -> return (info, Just doc);
};
Left err -> parseError (getLoc $1) err
} }
getQCONID (L _ (ITqconid x)) = x
getQVARSYM (L _ (ITqvarsym x)) = x
getQCONSYM (L _ (ITqconsym x)) = x
+getPREFIXQVARSYM (L _ (ITprefixqvarsym x)) = x
+getPREFIXQCONSYM (L _ (ITprefixqconsym x)) = x
getIPDUPVARID (L _ (ITdupipvarid x)) = x
getCHAR (L _ (ITchar x)) = x
getSTRING (L _ (ITstring x)) = x
getPRIMCHAR (L _ (ITprimchar x)) = x
getPRIMSTRING (L _ (ITprimstring x)) = x
getPRIMINTEGER (L _ (ITprimint x)) = x
+getPRIMWORD (L _ (ITprimword x)) = x
getPRIMFLOAT (L _ (ITprimfloat x)) = x
getPRIMDOUBLE (L _ (ITprimdouble x)) = x
getTH_ID_SPLICE (L _ (ITidEscape x)) = x
getINLINE (L _ (ITinline_prag b)) = b
+getINLINE_CONLIKE (L _ (ITinline_conlike_prag b)) = b
getSPEC_INLINE (L _ (ITspec_inline_prag b)) = b
getDOCNEXT (L _ (ITdocCommentNext x)) = x
getDOCPREV (L _ (ITdocCommentPrev x)) = x
getDOCNAMED (L _ (ITdocCommentNamed x)) = x
getDOCSECTION (L _ (ITdocSection n x)) = (n, x)
-getDOCOPTIONS (L _ (ITdocOptions x)) = x
+
+getSCC :: Located Token -> P FastString
+getSCC lt = do let s = getSTRING lt
+ err = "Spaces are not allowed in SCCs"
+ -- We probably actually want to be more restrictive than this
+ if ' ' `elem` unpackFS s
+ then failSpanMsgP (getLoc lt) (text err)
+ else return s
-- Utilities for combining source spans
comb2 :: Located a -> Located b -> SrcSpan
-comb2 = combineLocs
+comb2 a b = a `seq` b `seq` combineLocs a b
comb3 :: Located a -> Located b -> Located c -> SrcSpan
-comb3 a b c = combineSrcSpans (getLoc a) (combineSrcSpans (getLoc b) (getLoc c))
+comb3 a b c = a `seq` b `seq` c `seq`
+ combineSrcSpans (getLoc a) (combineSrcSpans (getLoc b) (getLoc c))
comb4 :: Located a -> Located b -> Located c -> Located d -> SrcSpan
-comb4 a b c d = combineSrcSpans (getLoc a) $ combineSrcSpans (getLoc b) $
- combineSrcSpans (getLoc c) (getLoc d)
+comb4 a b c d = a `seq` b `seq` c `seq` d `seq`
+ (combineSrcSpans (getLoc a) $ combineSrcSpans (getLoc b) $
+ combineSrcSpans (getLoc c) (getLoc d))
-- strict constructor version:
{-# INLINE sL #-}
sL :: SrcSpan -> a -> Located a
-sL span a = span `seq` L span a
+sL span a = span `seq` a `seq` L span a
-- Make a source location for the file. We're a bit lazy here and just
-- make a point SrcSpan at line 1, column 0. Strictly speaking we should