-- ---------------------------------------------------------------------------
{
-module Parser ( parseModule, parseStmt, parseIdentifier, parseIface ) where
+module Parser ( parseModule, parseStmt, parseIdentifier, parseIface, parseType ) where
#define INCLUDE #include
INCLUDE "HsVersions.h"
import OccName ( UserFS, varName, dataName, tcClsName, tvName )
import DataCon ( DataCon, dataConName )
import SrcLoc ( Located(..), unLoc, getLoc, noLoc, combineSrcSpans,
- SrcSpan, combineLocs, mkGeneralSrcSpan, srcLocFile )
+ SrcSpan, combineLocs, srcLocFile,
+ mkSrcLoc, mkSrcSpan )
import Module
import CmdLineOpts ( opt_SccProfilingOn )
import Type ( Kind, mkArrowKind, liftedTypeKind )
import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
- NewOrData(..), Activation(..) )
+ Activation(..) )
+import OrdList
import Bag ( emptyBag )
import Panic
-import GLAEXTS
import CStrings ( CLabelString )
import FastString
import Maybes ( orElse )
import Outputable
+import GLAEXTS
}
{-
1 for ambiguity in 'if x then y else z :: T' [State 136]
(shift parses as 'if x then y else (z :: T)', as per longest-parse rule)
+4 for ambiguity in 'if x then y else z -< e'
+ (shift parses as 'if x then y else (z -< T)', as per longest-parse rule)
+
8 for ambiguity in 'e :: a `b` c'. Does this mean [States 160,246]
(e::a) `b` c, or
(e :: (a `b` c))
%name parseStmt maybe_stmt
%name parseIdentifier identifier
%name parseIface iface
+%name parseType ctype
%tokentype { Located Token }
%%
{ SigD (Sig $1 $3) }
| 'type' syn_hdr '=' ctype
{ let (tc,tvs) = $2 in TyClD (TySynonym tc tvs $4) }
- | 'data' tycl_hdr
- { TyClD (mkTyData DataType (unLoc $2) [] Nothing) }
- | 'newtype' tycl_hdr
+ | 'data' tycl_hdr constrs -- No deriving in hi-boot
+ { TyClD (mkTyData DataType (unLoc $2) (reverse (unLoc $3)) Nothing) }
+ | 'newtype' tycl_hdr -- Constructor is optional
{ TyClD (mkTyData NewType (unLoc $2) [] Nothing) }
+ | 'newtype' tycl_hdr '=' newconstr
+ { TyClD (mkTyData NewType (unLoc $2) [$4] Nothing) }
| 'class' tycl_hdr fds
{ TyClD (mkClassDecl (unLoc $2) (unLoc $3) [] emptyBag) }
-----------------------------------------------------------------------------
-- Top-Level Declarations
-topdecls :: { [RdrBinding] } -- Reversed
- : topdecls ';' topdecl { $3 : $1 }
+topdecls :: { OrdList (LHsDecl RdrName) } -- Reversed
+ : topdecls ';' topdecl { $1 `appOL` $3 }
| topdecls ';' { $1 }
- | topdecl { [$1] }
+ | topdecl { $1 }
-topdecl :: { RdrBinding }
- : tycl_decl { RdrHsDecl (L1 (TyClD (unLoc $1))) }
+topdecl :: { OrdList (LHsDecl RdrName) }
+ : tycl_decl { unitOL (L1 (TyClD (unLoc $1))) }
| 'instance' inst_type where
{ let (binds,sigs) = cvBindsAndSigs (unLoc $3)
- in RdrHsDecl (L (comb3 $1 $2 $3) (InstD (InstDecl $2 binds sigs))) }
- | 'default' '(' comma_types0 ')' { RdrHsDecl (LL $ DefD (DefaultDecl $3)) }
- | 'foreign' fdecl { RdrHsDecl (LL (unLoc $2)) }
- | '{-# DEPRECATED' deprecations '#-}' { RdrBindings (reverse $2) }
- | '{-# RULES' rules '#-}' { RdrBindings (reverse $2) }
- | '$(' exp ')' { RdrHsDecl (LL $ SpliceD (SpliceDecl $2)) }
+ in unitOL (L (comb3 $1 $2 $3) (InstD (InstDecl $2 binds sigs))) }
+ | 'default' '(' comma_types0 ')' { unitOL (LL $ DefD (DefaultDecl $3)) }
+ | 'foreign' fdecl { unitOL (LL (unLoc $2)) }
+ | '{-# DEPRECATED' deprecations '#-}' { $2 }
+ | '{-# RULES' rules '#-}' { $2 }
+ | '$(' exp ')' { unitOL (LL $ SpliceD (SpliceDecl $2)) }
| decl { unLoc $1 }
tycl_decl :: { LTyClDecl RdrName }
-----------------------------------------------------------------------------
-- Nested declarations
-decls :: { Located [RdrBinding] } -- Reversed
- : decls ';' decl { LL (unLoc $3 : unLoc $1) }
+decls :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed
+ : decls ';' decl { LL (unLoc $1 `appOL` unLoc $3) }
| decls ';' { LL (unLoc $1) }
- | decl { L1 [unLoc $1] }
- | {- empty -} { noLoc [] }
+ | decl { $1 }
+ | {- empty -} { noLoc nilOL }
-decllist :: { Located [RdrBinding] } -- Reversed
+decllist :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed
: '{' decls '}' { LL (unLoc $2) }
| vocurly decls close { $2 }
-where :: { Located [RdrBinding] } -- Reversed
+where :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed
-- No implicit parameters
: 'where' decllist { LL (unLoc $2) }
- | {- empty -} { noLoc [] }
+ | {- empty -} { noLoc nilOL }
binds :: { Located [HsBindGroup RdrName] } -- May have implicit parameters
: decllist { L1 [cvBindGroup (unLoc $1)] }
-----------------------------------------------------------------------------
-- Transformation Rules
-rules :: { [RdrBinding] } -- Reversed
- : rules ';' rule { $3 : $1 }
+rules :: { OrdList (LHsDecl RdrName) } -- Reversed
+ : rules ';' rule { $1 `snocOL` $3 }
| rules ';' { $1 }
- | rule { [$1] }
- | {- empty -} { [] }
+ | rule { unitOL $1 }
+ | {- empty -} { nilOL }
-rule :: { RdrBinding }
+rule :: { LHsDecl RdrName }
: STRING activation rule_forall infixexp '=' exp
- { RdrHsDecl (LL $ RuleD (HsRule (getSTRING $1) $2 $3 $4 $6)) }
+ { LL $ RuleD (HsRule (getSTRING $1) $2 $3 $4 $6) }
activation :: { Activation } -- Omitted means AlwaysActive
: {- empty -} { AlwaysActive }
-----------------------------------------------------------------------------
-- Deprecations (c.f. rules)
-deprecations :: { [RdrBinding] } -- Reversed
- : deprecations ';' deprecation { $3 : $1 }
+deprecations :: { OrdList (LHsDecl RdrName) } -- Reversed
+ : deprecations ';' deprecation { $1 `appOL` $3 }
| deprecations ';' { $1 }
- | deprecation { [$1] }
- | {- empty -} { [] }
+ | deprecation { $1 }
+ | {- empty -} { nilOL }
-- SUP: TEMPORARY HACK, not checking for `module Foo'
-deprecation :: { RdrBinding }
+deprecation :: { OrdList (LHsDecl RdrName) }
: depreclist STRING
- { RdrBindings [ RdrHsDecl (LL $ DeprecD (Deprecation n (getSTRING $2))) | n <- unLoc $1 ] }
+ { toOL [ LL $ DeprecD (Deprecation n (getSTRING $2))
+ | n <- unLoc $1 ] }
-----------------------------------------------------------------------------
: {- empty -} { Nothing }
| '::' atype { Just $2 }
-sigtypes :: { [LHsType RdrName] }
+sigtypes1 :: { [LHsType RdrName] }
: sigtype { [ $1 ] }
- | sigtypes ',' sigtype { $3 : $1 }
+ | sigtype ',' sigtypes1 { $1 : $3 }
sigtype :: { LHsType RdrName }
: ctype { L1 (mkImplicitHsForAllTy (noLoc []) $1) }
: btype {% checkContext $1 }
type :: { LHsType RdrName }
- : ipvar '::' gentype { LL (HsPredTy (LL $ HsIParam (unLoc $1) $3)) }
+ : ipvar '::' gentype { LL (HsPredTy (HsIParam (unLoc $1) $3)) }
| gentype { $1 }
gentype :: { LHsType RdrName }
inst_type :: { LHsType RdrName }
: ctype {% checkInstType $1 }
+inst_types1 :: { [LHsType RdrName] }
+ : inst_type { [$1] }
+ | inst_type ',' inst_types1 { $1 : $3 }
+
comma_types0 :: { [LHsType RdrName] }
: comma_types1 { $1 }
| {- empty -} { [] }
: '!' { L1 HsStrict }
| '{-# UNPACK' '#-}' '!' { LL HsUnbox }
-deriving :: { Located (Maybe (LHsContext RdrName)) }
- : {- empty -} { noLoc Nothing }
- | 'deriving' context { LL (Just $2) }
+-- We allow the odd-looking 'inst_type' in a deriving clause, so that
+-- we can do deriving( forall a. C [a] ) in a newtype (GHC extension).
+-- The 'C [a]' part is converted to an HsPredTy by checkInstType
+-- We don't allow a context, but that's sorted out by the type checker.
+deriving :: { Located (Maybe [LHsType RdrName]) }
+ : {- empty -} { noLoc Nothing }
+ | 'deriving' qtycon {% do { let { L loc tv = $2 }
+ ; p <- checkInstType (L loc (HsTyVar tv))
+ ; return (LL (Just [p])) } }
+ | 'deriving' '(' ')' { LL (Just []) }
+ | 'deriving' '(' inst_types1 ')' { LL (Just $3) }
-- Glasgow extension: allow partial
-- applications in derivings
We can't tell whether to reduce var to qvar until after we've read the signatures.
-}
-decl :: { Located RdrBinding }
+decl :: { Located (OrdList (LHsDecl RdrName)) }
: sigdecl { $1 }
| infixexp opt_sig rhs {% do { r <- checkValDef $1 $2 (unLoc $3);
- return (LL $ RdrValBinding (LL r)) } }
+ return (LL $ unitOL (LL $ ValD r)) } }
rhs :: { Located (GRHSs RdrName) }
: '=' exp wherebinds { L (comb3 $1 $2 $3) $ GRHSs (unguardedRHS $2) (unLoc $3) placeHolderType }
: '|' quals '=' exp { LL $ GRHS (reverse (L (getLoc $4) (ResultStmt $4) :
unLoc $2)) }
-sigdecl :: { Located RdrBinding }
+sigdecl :: { Located (OrdList (LHsDecl RdrName)) }
: infixexp '::' sigtype
{% do s <- checkValSig $1 $3;
- return (LL $ RdrHsDecl (LL $ SigD s)) }
+ return (LL $ unitOL (LL $ SigD s)) }
-- See the above notes for why we need infixexp here
| var ',' sig_vars '::' sigtype
- { LL $ mkSigDecls [ LL $ Sig n $5 | n <- $1 : unLoc $3 ] }
- | infix prec ops { LL $ mkSigDecls [ LL $ FixSig (FixitySig n (Fixity $2 (unLoc $1)))
+ { LL $ toOL [ LL $ SigD (Sig n $5) | n <- $1 : unLoc $3 ] }
+ | infix prec ops { LL $ toOL [ LL $ SigD (FixSig (FixitySig n (Fixity $2 (unLoc $1))))
| n <- unLoc $3 ] }
| '{-# INLINE' activation qvar '#-}'
- { LL $ RdrHsDecl (LL $ SigD (InlineSig True $3 $2)) }
+ { LL $ unitOL (LL $ SigD (InlineSig True $3 $2)) }
| '{-# NOINLINE' inverse_activation qvar '#-}'
- { LL $ RdrHsDecl (LL $ SigD (InlineSig False $3 $2)) }
- | '{-# SPECIALISE' qvar '::' sigtypes '#-}'
- { LL $ mkSigDecls [ LL $ SpecSig $2 t | t <- $4] }
+ { LL $ unitOL (LL $ SigD (InlineSig False $3 $2)) }
+ | '{-# SPECIALISE' qvar '::' sigtypes1 '#-}'
+ { LL $ toOL [ LL $ SigD (SpecSig $2 t)
+ | t <- $4] }
| '{-# SPECIALISE' 'instance' inst_type '#-}'
- { LL $ RdrHsDecl (LL $ SigD (SpecInstSig $3)) }
+ { LL $ unitOL (LL $ SigD (SpecInstSig $3)) }
-----------------------------------------------------------------------------
-- Expressions
exp :: { LHsExpr RdrName }
: infixexp '::' sigtype { LL $ ExprWithTySig $1 $3 }
- | fexp '-<' exp { LL $ HsArrApp $1 $3 placeHolderType HsFirstOrderApp True }
- | fexp '>-' exp { LL $ HsArrApp $3 $1 placeHolderType HsFirstOrderApp False }
- | fexp '-<<' exp { LL $ HsArrApp $1 $3 placeHolderType HsHigherOrderApp True }
- | fexp '>>-' exp { LL $ HsArrApp $3 $1 placeHolderType HsHigherOrderApp False}
+ | infixexp '-<' exp { LL $ HsArrApp $1 $3 placeHolderType HsFirstOrderApp True }
+ | infixexp '>-' exp { LL $ HsArrApp $3 $1 placeHolderType HsFirstOrderApp False }
+ | infixexp '-<<' exp { LL $ HsArrApp $1 $3 placeHolderType HsHigherOrderApp True }
+ | infixexp '>>-' exp { LL $ HsArrApp $3 $1 placeHolderType HsHigherOrderApp False}
| infixexp { $1 }
infixexp :: { LHsExpr RdrName }
| '_' { L1 EWildPat }
-- MetaHaskell Extension
- | TH_ID_SPLICE { L1 $ mkHsSplice
+ | TH_ID_SPLICE { L1 $ HsSpliceE (mkHsSplice
(L1 $ HsVar (mkUnqual varName
- (getTH_ID_SPLICE $1))) } -- $x
- | '$(' exp ')' { LL $ mkHsSplice $2 } -- $( exp )
+ (getTH_ID_SPLICE $1)))) } -- $x
+ | '$(' exp ')' { LL $ HsSpliceE (mkHsSplice $2) } -- $( exp )
+
| TH_VAR_QUOTE qvar { LL $ HsBracket (VarBr (unLoc $2)) }
- | TH_VAR_QUOTE qcon { LL $ HsBracket (VarBr (unLoc $2)) }
+ | TH_VAR_QUOTE gcon { LL $ HsBracket (VarBr (unLoc $2)) }
| TH_TY_QUOTE tyvar { LL $ HsBracket (VarBr (unLoc $2)) }
| TH_TY_QUOTE gtycon { LL $ HsBracket (VarBr (unLoc $2)) }
| '[|' exp '|]' { LL $ HsBracket (ExpBr $2) }
: aexp2 { L1 $ HsCmdTop $1 [] placeHolderType undefined }
cvtopbody :: { [LHsDecl RdrName] }
- : '{' cvtopdecls '}' { $2 }
- | vocurly cvtopdecls close { $2 }
+ : '{' cvtopdecls0 '}' { $2 }
+ | vocurly cvtopdecls0 close { $2 }
+
+cvtopdecls0 :: { [LHsDecl RdrName] }
+ : {- empty -} { [] }
+ | cvtopdecls { $1 }
texps :: { [LHsExpr RdrName] }
: texps ',' exp { $3 : $1 }
sL :: SrcSpan -> a -> Located a
sL span a = span `seq` L span a
--- Make a source location that is just the filename. This seems slightly
--- neater than trying to construct the span of the text within the file.
+-- 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
+-- try to find the span of the whole file (ToDo).
fileSrcSpan :: P SrcSpan
-fileSrcSpan = do l <- getSrcLoc; return (mkGeneralSrcSpan (srcLocFile l))
+fileSrcSpan = do
+ l <- getSrcLoc;
+ let loc = mkSrcLoc (srcLocFile l) 1 0;
+ return (mkSrcSpan loc loc)
}