module Parser ( parseModule, parseStmt, parseIdentifier, parseType,
parseHeader ) where
-#define INCLUDE #include
-INCLUDE "HsVersions.h"
-
import HsSyn
import RdrHsSyn
import HscTypes ( IsBootInterface, DeprecTxt )
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,
PRIMCHAR { L _ (ITprimchar _) }
PRIMSTRING { L _ (ITprimstring _) }
PRIMINTEGER { L _ (ITprimint _) }
+ PRIMWORD { L _ (ITprimword _) }
PRIMFLOAT { L _ (ITprimfloat _) }
PRIMDOUBLE { L _ (ITprimdouble _) }
'$(' { 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 }
Nothing)) }
maybedocheader :: { (HaddockModInfo RdrName, Maybe (HsDoc RdrName)) }
- : moduleheader { (fst $1, snd $1) }
+ : moduleheader { $1 }
| {- empty -} { (emptyHaddockModInfo, Nothing) }
missing_module_keyword :: { () }
| 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 }
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] }
scc_annot :: { Located FastString }
: '_scc_' STRING {% (addWarning Opt_WarnDeprecations (getLoc $1) (text "_scc_ is deprecated; use an SCC pragma instead")) >>= \_ ->
- (return $ LL $ getSTRING $2) }
- | '{-# SCC' STRING '#-}' { LL $ getSTRING $2 }
+ ( 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 '#-}'
(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)) }
| 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] }
-----------------------------------------------------------------------------
-- 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 }
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 }
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
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") }
+ | '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") }
+ | '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
: 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 }
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 {
MyLeft err -> parseError (getLoc $1) err;
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
getDOCNAMED (L _ (ITdocCommentNamed x)) = x
getDOCSECTION (L _ (ITdocSection n x)) = (n, 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