-{-
+{- -*-haskell-*-
-----------------------------------------------------------------------------
-$Id: Parser.y,v 1.77 2001/11/26 09:20:26 simonpj Exp $
+$Id: Parser.y,v 1.131 2003/11/27 13:26:39 simonmar Exp $
Haskell grammar.
-}
{
-module Parser ( parseModule, parseStmt, parseIdentifier ) where
+module Parser ( parseModule, parseStmt, parseIdentifier, parseIface ) where
-import HsSyn
-import HsTypes ( mkHsTupCon )
-import TypeRep ( IPName(..) )
+#include "HsVersions.h"
+import HsSyn
import RdrHsSyn
-import Lex
-import ParseUtil
+import HscTypes ( ModIface, IsBootInterface, DeprecTxt )
+import Lexer
import RdrName
-import PrelNames ( mAIN_Name, unitTyCon_RDR, funTyCon_RDR, listTyCon_RDR,
- tupleTyCon_RDR, unitCon_RDR, nilCon_RDR, tupleCon_RDR
+import TysWiredIn ( unitTyCon, unitDataCon, tupleTyCon, tupleCon, nilDataCon,
+ listTyCon_RDR, parrTyCon_RDR, consDataCon_RDR )
+import Type ( funTyCon )
+import ForeignCall ( Safety(..), CExportSpec(..),
+ CCallConv(..), CCallTarget(..), defaultCCallConv
)
-import ForeignCall ( Safety(..), CExportSpec(..), CCallSpec(..),
- CCallConv(..), CCallTarget(..), defaultCCallConv,
- DNCallSpec(..) )
-import OccName ( UserFS, varName, tcName, dataName, tcClsName, tvName )
-import SrcLoc ( SrcLoc )
+import OccName ( UserFS, varName, dataName, tcClsName, tvName )
+import DataCon ( DataCon, dataConName )
+import SrcLoc ( SrcLoc, noSrcLoc )
import Module
import CmdLineOpts ( opt_SccProfilingOn )
-import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..),
- NewOrData(..), StrictnessMark(..), Activation(..) )
+import Type ( Kind, mkArrowKind, liftedTypeKind )
+import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
+ NewOrData(..), Activation(..) )
import Panic
-import GlaExts
+import GLAEXTS
import CStrings ( CLabelString )
import FastString
import Maybes ( orElse )
import Outputable
+import Char ( ord )
-#include "HsVersions.h"
}
{-
-----------------------------------------------------------------------------
-Conflicts: 14 shift/reduce
- (note: it's currently 21 -- JRL, 31/1/2000)
+Conflicts: 29 shift/reduce, [SDM 19/9/2002]
-8 for abiguity in 'if x then y else z + 1'
+10 for abiguity in 'if x then y else z + 1' [State 136]
(shift parses as 'if x then y else (z + 1)', as per longest-parse rule)
-1 for ambiguity in 'if x then y else z :: T'
+ 10 because op might be: : - ! * . `x` VARSYM CONSYM QVARSYM QCONSYM
+
+1 for ambiguity in 'if x then y else z with ?x=3' [State 136]
+ (shift parses as 'if x then y else (z with ?x=3)'
+
+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)
-3 for ambiguity in 'case x of y :: a -> b'
- (don't know whether to reduce 'a' as a btype or shift the '->'.
- conclusion: bogus expression anyway, doesn't matter)
-1 for ambiguity in '{-# RULES "name" forall = ... #-}'
+8 for ambiguity in 'e :: a `b` c'. Does this mean [States 160,246]
+ (e::a) `b` c, or
+ (e :: (a `b` c))
+
+1 for ambiguity in 'let ?x ...' [State 268]
+ the parser can't tell whether the ?x is the lhs of a normal binding or
+ an implicit binding. Fortunately resolving as shift gives it the only
+ sensible meaning, namely the lhs of an implicit binding.
+
+1 for ambiguity in '{-# RULES "name" [ ... #-} [State 332]
+ we don't know whether the '[' starts the activation or not: it
+ might be the start of the declaration with the activation being
+ empty. --SDM 1/4/2002
+
+1 for ambiguity in '{-# RULES "name" forall = ... #-}' [State 394]
since 'forall' is a valid variable name, we don't know whether
to treat a forall on the input as the beginning of a quantifier
or the beginning of the rule itself. Resolving to shift means
This saves explicitly defining a grammar for the rule lhs that
doesn't include 'forall'.
-1 for ambiguity in 'x @ Rec{..}'.
- Only sensible parse is 'x @ (Rec{..})', which is what resolving
- to shift gives us.
+6 for conflicts between `fdecl' and `fdeclDEPRECATED', [States 384,385]
+ which are resolved correctly, and moreover,
+ should go away when `fdeclDEPRECATED' is removed.
-----------------------------------------------------------------------------
-}
%token
- '_' { ITunderscore } -- Haskell keywords
- 'as' { ITas }
- 'case' { ITcase }
- 'class' { ITclass }
- 'data' { ITdata }
- 'default' { ITdefault }
- 'deriving' { ITderiving }
- 'do' { ITdo }
- 'else' { ITelse }
- 'hiding' { IThiding }
- 'if' { ITif }
- 'import' { ITimport }
- 'in' { ITin }
- 'infix' { ITinfix }
- 'infixl' { ITinfixl }
- 'infixr' { ITinfixr }
- 'instance' { ITinstance }
- 'let' { ITlet }
- 'module' { ITmodule }
- 'newtype' { ITnewtype }
- 'of' { ITof }
- 'qualified' { ITqualified }
- 'then' { ITthen }
- 'type' { ITtype }
- 'where' { ITwhere }
- '_scc_' { ITscc } -- ToDo: remove
-
- 'forall' { ITforall } -- GHC extension keywords
- 'foreign' { ITforeign }
- 'export' { ITexport }
- 'label' { ITlabel }
- 'dynamic' { ITdynamic }
- 'unsafe' { ITunsafe }
- 'with' { ITwith }
- 'stdcall' { ITstdcallconv }
- 'ccall' { ITccallconv }
- 'dotnet' { ITdotnet }
- '_ccall_' { ITccall (False, False, PlayRisky) }
- '_ccall_GC_' { ITccall (False, False, PlaySafe) }
- '_casm_' { ITccall (False, True, PlayRisky) }
- '_casm_GC_' { ITccall (False, True, PlaySafe) }
-
- '{-# SPECIALISE' { ITspecialise_prag }
- '{-# SOURCE' { ITsource_prag }
- '{-# INLINE' { ITinline_prag }
- '{-# NOINLINE' { ITnoinline_prag }
- '{-# RULES' { ITrules_prag }
- '{-# SCC' { ITscc_prag }
- '{-# DEPRECATED' { ITdeprecated_prag }
- '#-}' { ITclose_prag }
-
-{-
- '__interface' { ITinterface } -- interface keywords
- '__export' { IT__export }
- '__instimport' { ITinstimport }
- '__forall' { IT__forall }
- '__letrec' { ITletrec }
- '__coerce' { ITcoerce }
- '__depends' { ITdepends }
- '__inline' { ITinline }
- '__DEFAULT' { ITdefaultbranch }
- '__bot' { ITbottom }
- '__integer' { ITinteger_lit }
- '__float' { ITfloat_lit }
- '__rational' { ITrational_lit }
- '__addr' { ITaddr_lit }
- '__label' { ITlabel_lit }
- '__litlit' { ITlit_lit }
- '__string' { ITstring_lit }
- '__ccall' { ITccall $$ }
- '__scc' { IT__scc }
- '__sccC' { ITsccAllCafs }
-
- '__A' { ITarity }
- '__P' { ITspecialise }
- '__C' { ITnocaf }
- '__U' { ITunfold }
- '__S' { ITstrict $$ }
- '__M' { ITcprinfo $$ }
--}
-
- '..' { ITdotdot } -- reserved symbols
- '::' { ITdcolon }
- '=' { ITequal }
- '\\' { ITlam }
- '|' { ITvbar }
- '<-' { ITlarrow }
- '->' { ITrarrow }
- '@' { ITat }
- '~' { ITtilde }
- '=>' { ITdarrow }
- '-' { ITminus }
- '!' { ITbang }
- '.' { ITdot }
-
- '{' { ITocurly } -- special symbols
- '}' { ITccurly }
- '{|' { ITocurlybar }
- '|}' { ITccurlybar }
- vccurly { ITvccurly } -- virtual close curly (from layout)
- '[' { ITobrack }
- ']' { ITcbrack }
- '(' { IToparen }
- ')' { ITcparen }
- '(#' { IToubxparen }
- '#)' { ITcubxparen }
- ';' { ITsemi }
- ',' { ITcomma }
- '`' { ITbackquote }
-
- VARID { ITvarid $$ } -- identifiers
- CONID { ITconid $$ }
- VARSYM { ITvarsym $$ }
- CONSYM { ITconsym $$ }
- QVARID { ITqvarid $$ }
- QCONID { ITqconid $$ }
- QVARSYM { ITqvarsym $$ }
- QCONSYM { ITqconsym $$ }
-
- IPDUPVARID { ITdupipvarid $$ } -- GHC extension
- IPSPLITVARID { ITsplitipvarid $$ } -- GHC extension
-
- CHAR { ITchar $$ }
- STRING { ITstring $$ }
- INTEGER { ITinteger $$ }
- RATIONAL { ITrational $$ }
-
- PRIMCHAR { ITprimchar $$ }
- PRIMSTRING { ITprimstring $$ }
- PRIMINTEGER { ITprimint $$ }
- PRIMFLOAT { ITprimfloat $$ }
- PRIMDOUBLE { ITprimdouble $$ }
- CLITLIT { ITlitlit $$ }
-
-%monad { P } { thenP } { returnP }
-%lexer { lexer } { ITeof }
+ '_' { T _ _ ITunderscore } -- Haskell keywords
+ 'as' { T _ _ ITas }
+ 'case' { T _ _ ITcase }
+ 'class' { T _ _ ITclass }
+ 'data' { T _ _ ITdata }
+ 'default' { T _ _ ITdefault }
+ 'deriving' { T _ _ ITderiving }
+ 'do' { T _ _ ITdo }
+ 'else' { T _ _ ITelse }
+ 'hiding' { T _ _ IThiding }
+ 'if' { T _ _ ITif }
+ 'import' { T _ _ ITimport }
+ 'in' { T _ _ ITin }
+ 'infix' { T _ _ ITinfix }
+ 'infixl' { T _ _ ITinfixl }
+ 'infixr' { T _ _ ITinfixr }
+ 'instance' { T _ _ ITinstance }
+ 'let' { T _ _ ITlet }
+ 'module' { T _ _ ITmodule }
+ 'newtype' { T _ _ ITnewtype }
+ 'of' { T _ _ ITof }
+ 'qualified' { T _ _ ITqualified }
+ 'then' { T _ _ ITthen }
+ 'type' { T _ _ ITtype }
+ 'where' { T _ _ ITwhere }
+ '_scc_' { T _ _ ITscc } -- ToDo: remove
+
+ 'forall' { T _ _ ITforall } -- GHC extension keywords
+ 'foreign' { T _ _ ITforeign }
+ 'export' { T _ _ ITexport }
+ 'label' { T _ _ ITlabel }
+ 'dynamic' { T _ _ ITdynamic }
+ 'safe' { T _ _ ITsafe }
+ 'threadsafe' { T _ _ ITthreadsafe }
+ 'unsafe' { T _ _ ITunsafe }
+ 'mdo' { T _ _ ITmdo }
+ 'stdcall' { T _ _ ITstdcallconv }
+ 'ccall' { T _ _ ITccallconv }
+ 'dotnet' { T _ _ ITdotnet }
+ 'proc' { T _ _ ITproc } -- for arrow notation extension
+ 'rec' { T _ _ ITrec } -- for arrow notation extension
+
+ '{-# SPECIALISE' { T _ _ ITspecialise_prag }
+ '{-# SOURCE' { T _ _ ITsource_prag }
+ '{-# INLINE' { T _ _ ITinline_prag }
+ '{-# NOINLINE' { T _ _ ITnoinline_prag }
+ '{-# RULES' { T _ _ ITrules_prag }
+ '{-# CORE' { T _ _ ITcore_prag } -- hdaume: annotated core
+ '{-# SCC' { T _ _ ITscc_prag }
+ '{-# DEPRECATED' { T _ _ ITdeprecated_prag }
+ '{-# UNPACK' { T _ _ ITunpack_prag }
+ '#-}' { T _ _ ITclose_prag }
+
+ '..' { T _ _ ITdotdot } -- reserved symbols
+ ':' { T _ _ ITcolon }
+ '::' { T _ _ ITdcolon }
+ '=' { T _ _ ITequal }
+ '\\' { T _ _ ITlam }
+ '|' { T _ _ ITvbar }
+ '<-' { T _ _ ITlarrow }
+ '->' { T _ _ ITrarrow }
+ '@' { T _ _ ITat }
+ '~' { T _ _ ITtilde }
+ '=>' { T _ _ ITdarrow }
+ '-' { T _ _ ITminus }
+ '!' { T _ _ ITbang }
+ '*' { T _ _ ITstar }
+ '-<' { T _ _ ITlarrowtail } -- for arrow notation
+ '>-' { T _ _ ITrarrowtail } -- for arrow notation
+ '-<<' { T _ _ ITLarrowtail } -- for arrow notation
+ '>>-' { T _ _ ITRarrowtail } -- for arrow notation
+ '.' { T _ _ ITdot }
+
+ '{' { T _ _ ITocurly } -- special symbols
+ '}' { T _ _ ITccurly }
+ '{|' { T _ _ ITocurlybar }
+ '|}' { T _ _ ITccurlybar }
+ vocurly { T _ _ ITvocurly } -- virtual open curly (from layout)
+ vccurly { T _ _ ITvccurly } -- virtual close curly (from layout)
+ '[' { T _ _ ITobrack }
+ ']' { T _ _ ITcbrack }
+ '[:' { T _ _ ITopabrack }
+ ':]' { T _ _ ITcpabrack }
+ '(' { T _ _ IToparen }
+ ')' { T _ _ ITcparen }
+ '(#' { T _ _ IToubxparen }
+ '#)' { T _ _ ITcubxparen }
+ '(|' { T _ _ IToparenbar }
+ '|)' { T _ _ ITcparenbar }
+ ';' { T _ _ ITsemi }
+ ',' { T _ _ ITcomma }
+ '`' { T _ _ ITbackquote }
+
+ VARID { T _ _ (ITvarid $$) } -- identifiers
+ CONID { T _ _ (ITconid $$) }
+ VARSYM { T _ _ (ITvarsym $$) }
+ CONSYM { T _ _ (ITconsym $$) }
+ QVARID { T _ _ (ITqvarid $$) }
+ QCONID { T _ _ (ITqconid $$) }
+ QVARSYM { T _ _ (ITqvarsym $$) }
+ QCONSYM { T _ _ (ITqconsym $$) }
+
+ IPDUPVARID { T _ _ (ITdupipvarid $$) } -- GHC extension
+ IPSPLITVARID { T _ _ (ITsplitipvarid $$) } -- GHC extension
+
+ CHAR { T _ _ (ITchar $$) }
+ STRING { T _ _ (ITstring $$) }
+ INTEGER { T _ _ (ITinteger $$) }
+ RATIONAL { T _ _ (ITrational $$) }
+
+ PRIMCHAR { T _ _ (ITprimchar $$) }
+ PRIMSTRING { T _ _ (ITprimstring $$) }
+ PRIMINTEGER { T _ _ (ITprimint $$) }
+ PRIMFLOAT { T _ _ (ITprimfloat $$) }
+ PRIMDOUBLE { T _ _ (ITprimdouble $$) }
+
+-- Template Haskell
+'[|' { T _ _ ITopenExpQuote }
+'[p|' { T _ _ ITopenPatQuote }
+'[t|' { T _ _ ITopenTypQuote }
+'[d|' { T _ _ ITopenDecQuote }
+'|]' { T _ _ ITcloseQuote }
+TH_ID_SPLICE { T _ _ (ITidEscape $$) } -- $x
+'$(' { T _ _ ITparenEscape } -- $( exp )
+TH_VAR_QUOTE { T _ _ ITvarQuote } -- 'x
+TH_TY_QUOTE { T _ _ ITtyQuote } -- ''T
+
+%monad { P } { >>= } { return }
+%lexer { lexer } { T _ _ ITeof }
%name parseModule module
%name parseStmt maybe_stmt
%name parseIdentifier identifier
+%name parseIface iface
%tokentype { Token }
%%
module :: { RdrNameHsModule }
: srcloc 'module' modid maybemoddeprec maybeexports 'where' body
- { HsModule $3 Nothing $5 (fst $7) (snd $7) $4 $1 }
- | srcloc body
- { HsModule mAIN_Name Nothing Nothing (fst $2) (snd $2) Nothing $1 }
+ { HsModule (Just (mkHomeModule $3)) $5 (fst $7) (snd $7) $4 $1 }
+ | srcloc missing_module_keyword top close
+ { HsModule Nothing Nothing (fst $3) (snd $3) Nothing $1 }
+
+missing_module_keyword :: { () }
+ : {- empty -} {% pushCurrentContext }
maybemoddeprec :: { Maybe DeprecTxt }
: '{-# DEPRECATED' STRING '#-}' { Just $2 }
body :: { ([RdrNameImportDecl], [RdrNameHsDecl]) }
: '{' top '}' { $2 }
- | layout_on top close { $2 }
+ | vocurly top close { $2 }
top :: { ([RdrNameImportDecl], [RdrNameHsDecl]) }
: importdecls { (reverse $1,[]) }
| cvtopdecls { ([],$1) }
cvtopdecls :: { [RdrNameHsDecl] }
- : topdecls { cvTopDecls (groupBindings $1)}
+ : topdecls { cvTopDecls $1 }
+
+-----------------------------------------------------------------------------
+-- Interfaces (.hi-boot files)
+
+iface :: { ModIface }
+ : 'module' modid 'where' ifacebody { mkBootIface $2 $4 }
+
+ifacebody :: { [HsDecl RdrName] }
+ : '{' ifacedecls '}' { $2 }
+ | vocurly ifacedecls close { $2 }
+
+ifacedecls :: { [HsDecl RdrName] }
+ : ifacedecl ';' ifacedecls { $1 : $3 }
+ | ';' ifacedecls { $2 }
+ | ifacedecl { [$1] }
+ | {- empty -} { [] }
+
+ifacedecl :: { HsDecl RdrName }
+ : var '::' sigtype
+ { SigD (Sig $1 $3 noSrcLoc) }
+ | 'type' syn_hdr '=' ctype
+ { let (tc,tvs) = $2 in TyClD (TySynonym tc tvs $4 noSrcLoc) }
+ | new_or_data tycl_hdr
+ { TyClD (mkTyData $1 $2 [] Nothing noSrcLoc) }
+ | 'class' tycl_hdr fds
+ { TyClD (mkClassDecl $2 $3 [] EmptyMonoBinds noSrcLoc) }
+
+new_or_data :: { NewOrData }
+ : 'data' { DataType }
+ | 'newtype' { NewType }
-----------------------------------------------------------------------------
-- The Export List
| export { [$1] }
| {- empty -} { [] }
- -- GHC extension: we allow things like [] and (,,,) to be exported
+ -- No longer allow things like [] and (,,,) to be exported
+ -- They are built in syntax, always available
export :: { RdrNameIE }
: qvar { IEVar $1 }
- | gtycon { IEThingAbs $1 }
- | gtycon '(' '..' ')' { IEThingAll $1 }
- | gtycon '(' ')' { IEThingWith $1 [] }
- | gtycon '(' qcnames ')' { IEThingWith $1 (reverse $3) }
+ | oqtycon { IEThingAbs $1 }
+ | oqtycon '(' '..' ')' { IEThingAll $1 }
+ | oqtycon '(' ')' { IEThingWith $1 [] }
+ | oqtycon '(' qcnames ')' { IEThingWith $1 (reverse $3) }
| 'module' modid { IEModuleContents $2 }
qcnames :: { [RdrName] }
: qcnames ',' qcname { $3 : $1 }
| qcname { [$1] }
-qcname :: { RdrName }
+qcname :: { RdrName } -- Variable or data constructor
: qvar { $1 }
| gcon { $1 }
: 'import' srcloc maybe_src optqualified modid maybeas maybeimpspec
{ ImportDecl $5 $3 $4 $6 $7 $2 }
-maybe_src :: { WhereFrom }
- : '{-# SOURCE' '#-}' { ImportByUserSource }
- | {- empty -} { ImportByUser }
+maybe_src :: { IsBootInterface }
+ : '{-# SOURCE' '#-}' { True }
+ | {- empty -} { False }
optqualified :: { Bool }
: 'qualified' { True }
prec :: { Int }
: {- empty -} { 9 }
- | INTEGER {% checkPrec $1 `thenP_`
- returnP (fromInteger $1) }
+ | INTEGER {% checkPrecP (fromInteger $1) }
infix :: { FixityDirection }
: 'infix' { InfixN }
-----------------------------------------------------------------------------
-- Top-Level Declarations
-topdecls :: { [RdrBinding] }
- : topdecls ';' topdecl { ($3 : $1) }
+topdecls :: { [RdrBinding] } -- Reversed
+ : topdecls ';' topdecl { $3 : $1 }
| topdecls ';' { $1 }
| topdecl { [$1] }
topdecl :: { RdrBinding }
- : srcloc 'type' simpletype '=' ctype
+ : tycl_decl { RdrHsDecl (TyClD $1) }
+ | srcloc 'instance' inst_type where
+ { let (binds,sigs) = cvMonoBindsAndSigs $4
+ in RdrHsDecl (InstD (InstDecl $3 binds sigs $1)) }
+ | srcloc 'default' '(' comma_types0 ')' { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
+ | 'foreign' fdecl { RdrHsDecl $2 }
+ | '{-# DEPRECATED' deprecations '#-}' { RdrBindings (reverse $2) }
+ | '{-# RULES' rules '#-}' { RdrBindings (reverse $2) }
+ | srcloc '$(' exp ')' { RdrHsDecl (SpliceD (SpliceDecl $3 $1)) }
+ | decl { $1 }
+
+tycl_decl :: { RdrNameTyClDecl }
+ : srcloc 'type' syn_hdr '=' ctype
-- Note ctype, not sigtype.
-- We allow an explicit for-all but we don't insert one
-- in type Foo a = (b,b)
-- Instead we just say b is out of scope
- { RdrHsDecl (TyClD (TySynonym (fst $3) (snd $3) $5 $1)) }
-
- | srcloc 'data' ctype constrs deriving
- {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
- returnP (RdrHsDecl (TyClD
- (mkTyData DataType cs c ts (reverse $4) (length $4) $5 $1))) }
-
- | srcloc 'newtype' ctype '=' newconstr deriving
- {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
- returnP (RdrHsDecl (TyClD
- (mkTyData NewType cs c ts [$5] 1 $6 $1))) }
-
- | srcloc 'class' ctype fds where
- {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
- let
- (binds,sigs) = cvMonoBindsAndSigs cvClassOpSig (groupBindings $5)
- in
- returnP (RdrHsDecl (TyClD
- (mkClassDecl cs c ts $4 sigs (Just binds) $1))) }
+ { let (tc,tvs) = $3 in TySynonym tc tvs $5 $1 }
- | srcloc 'instance' inst_type where
- { let (binds,sigs)
- = cvMonoBindsAndSigs cvInstDeclSig
- (groupBindings $4)
- in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $1)) }
-
- | srcloc 'default' '(' types0 ')' { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
- | 'foreign' fordecl { RdrHsDecl $2 }
- | '{-# DEPRECATED' deprecations '#-}' { $2 }
- | '{-# RULES' rules '#-}' { $2 }
- | decl { $1 }
-
-fordecl :: { RdrNameHsDecl }
-fordecl : srcloc 'label' ext_name varid '::' sigtype
- { ForD (ForeignImport $4 $6 (LblImport ($3 `orElse` mkExtName $4)) $1) }
+ | srcloc 'data' tycl_hdr constrs deriving
+ { mkTyData DataType $3 (reverse $4) $5 $1 }
+ | srcloc 'newtype' tycl_hdr '=' newconstr deriving
+ { mkTyData NewType $3 [$5] $6 $1 }
- ----------- ccall/stdcall decls ------------
- | srcloc 'import' ccallconv ext_name unsafe_flag varid_no_unsafe '::' sigtype
- { let
- call_spec = CCallSpec (StaticTarget ($4 `orElse` mkExtName $6)) $3 $5
- in
- ForD (ForeignImport $6 $8 (CImport call_spec) $1)
- }
-
- | srcloc 'import' ccallconv 'dynamic' unsafe_flag varid_no_unsafe '::' sigtype
- { let
- call_spec = CCallSpec DynamicTarget $3 $5
+ | srcloc 'class' tycl_hdr fds where
+ { let
+ (binds,sigs) = cvMonoBindsAndSigs $5
in
- ForD (ForeignImport $6 $8 (CImport call_spec) $1)
- }
-
- | srcloc 'export' ccallconv ext_name varid '::' sigtype
- { ForD (ForeignExport $5 $7 (CExport (CExportStatic ($4 `orElse` mkExtName $5) $3)) $1) }
-
- | srcloc 'export' ccallconv 'dynamic' varid '::' sigtype
- { ForD (ForeignImport $5 $7 (CDynImport $3) $1) }
-
-
- ----------- .NET decls ------------
- | srcloc 'import' 'dotnet' ext_name varid '::' sigtype
- { ForD (ForeignImport $5 $7 (DNImport (DNCallSpec ($4 `orElse` mkExtName $5))) $1) }
+ mkClassDecl $3 $4 sigs binds $1 }
+
+syn_hdr :: { (RdrName, [RdrNameHsTyVar]) } -- We don't retain the syntax of an infix
+ -- type synonym declaration. Oh well.
+ : tycon tv_bndrs { ($1, $2) }
+ | tv_bndr tyconop tv_bndr { ($2, [$1,$3]) }
+
+-- tycl_hdr parses the header of a type or class decl,
+-- which takes the form
+-- T a b
+-- Eq a => T a
+-- (Eq a, Ord b) => T a b
+-- Rather a lot of inlining here, else we get reduce/reduce errors
+tycl_hdr :: { (RdrNameContext, RdrName, [RdrNameHsTyVar]) }
+ : context '=>' type {% checkTyClHdr $1 $3 }
+ | type {% checkTyClHdr [] $1 }
- | srcloc 'import' 'dotnet' 'type' ext_name tycon
- { TyClD (ForeignType $6 $5 DNType $1) }
+-----------------------------------------------------------------------------
+-- Nested declarations
-decls :: { [RdrBinding] }
+decls :: { [RdrBinding] } -- Reversed
: decls ';' decl { $3 : $1 }
| decls ';' { $1 }
| decl { [$1] }
| {- empty -} { [] }
-decl :: { RdrBinding }
- : fixdecl { $1 }
- | valdef { $1 }
- | '{-# INLINE' srcloc activation qvar '#-}' { RdrSig (InlineSig True $4 $3 $2) }
- | '{-# NOINLINE' srcloc inverse_activation qvar '#-}' { RdrSig (InlineSig False $4 $3 $2) }
- | '{-# SPECIALISE' srcloc qvar '::' sigtypes '#-}'
- { foldr1 RdrAndBindings
- (map (\t -> RdrSig (SpecSig $3 t $2)) $5) }
- | '{-# SPECIALISE' srcloc 'instance' inst_type '#-}'
- { RdrSig (SpecInstSig $4 $2) }
-wherebinds :: { RdrNameHsBinds }
- : where { cvBinds cvValSig (groupBindings $1) }
+decllist :: { [RdrBinding] } -- Reversed
+ : '{' decls '}' { $2 }
+ | vocurly decls close { $2 }
-where :: { [RdrBinding] }
+where :: { [RdrBinding] } -- Reversed
+ -- No implicit parameters
: 'where' decllist { $2 }
| {- empty -} { [] }
-declbinds :: { RdrNameHsBinds }
- : decllist { cvBinds cvValSig (groupBindings $1) }
+binds :: { RdrNameHsBinds } -- May have implicit parameters
+ : decllist { cvBinds $1 }
+ | '{' dbinds '}' { IPBinds $2 }
+ | vocurly dbinds close { IPBinds $2 }
+
+wherebinds :: { RdrNameHsBinds } -- May have implicit parameters
+ : 'where' binds { $2 }
+ | {- empty -} { EmptyBinds }
-decllist :: { [RdrBinding] }
- : '{' decls '}' { $2 }
- | layout_on decls close { $2 }
-fixdecl :: { RdrBinding }
- : srcloc infix prec ops { foldr1 RdrAndBindings
- [ RdrSig (FixSig (FixitySig n
- (Fixity $3 $2) $1))
- | n <- $4 ] }
-----------------------------------------------------------------------------
-- Transformation Rules
-rules :: { RdrBinding }
- : rules ';' rule { $1 `RdrAndBindings` $3 }
+rules :: { [RdrBinding] } -- Reversed
+ : rules ';' rule { $3 : $1 }
| rules ';' { $1 }
- | rule { $1 }
- | {- empty -} { RdrNullBind }
+ | rule { [$1] }
+ | {- empty -} { [] }
rule :: { RdrBinding }
: STRING activation rule_forall infixexp '=' srcloc exp
activation :: { Activation } -- Omitted means AlwaysActive
: {- empty -} { AlwaysActive }
- | '[' INTEGER ']' { ActiveAfter (fromInteger $2) }
+ | explicit_activation { $1 }
inverse_activation :: { Activation } -- Omitted means NeverActive
: {- empty -} { NeverActive }
- | '[' INTEGER ']' { ActiveAfter (fromInteger $2) }
+ | explicit_activation { $1 }
+
+explicit_activation :: { Activation } -- In brackets
+ : '[' INTEGER ']' { ActiveAfter (fromInteger $2) }
+ | '[' '~' INTEGER ']' { ActiveBefore (fromInteger $3) }
rule_forall :: { [RdrNameRuleBndr] }
: 'forall' rule_var_list '.' { $2 }
| '(' varid '::' ctype ')' { RuleBndrSig $2 $4 }
-----------------------------------------------------------------------------
--- Deprecations
+-- Deprecations (c.f. rules)
-deprecations :: { RdrBinding }
- : deprecations ';' deprecation { $1 `RdrAndBindings` $3 }
- | deprecations ';' { $1 }
- | deprecation { $1 }
- | {- empty -} { RdrNullBind }
+deprecations :: { [RdrBinding] } -- Reversed
+ : deprecations ';' deprecation { $3 : $1 }
+ | deprecations ';' { $1 }
+ | deprecation { [$1] }
+ | {- empty -} { [] }
-- SUP: TEMPORARY HACK, not checking for `module Foo'
deprecation :: { RdrBinding }
: srcloc depreclist STRING
- { foldr RdrAndBindings RdrNullBind
+ { RdrBindings
[ RdrHsDecl (DeprecD (Deprecation n $3 $1)) | n <- $2 ] }
------------------------------------------------------------------------------
--- Foreign import/export
-
-ccallconv :: { CCallConv }
- : 'stdcall' { StdCallConv }
- | 'ccall' { CCallConv }
- | {- empty -} { defaultCCallConv }
-
-unsafe_flag :: { Safety }
- : 'unsafe' { PlayRisky }
- | {- empty -} { PlaySafe }
+-----------------------------------------------------------------------------
+-- Foreign import and export declarations
+
+-- for the time being, the following accepts foreign declarations conforming
+-- to the FFI Addendum, Version 1.0 as well as pre-standard declarations
+--
+-- * a flag indicates whether pre-standard declarations have been used and
+-- triggers a deprecation warning further down the road
+--
+-- NB: The first two rules could be combined into one by replacing `safety1'
+-- with `safety'. However, the combined rule conflicts with the
+-- DEPRECATED rules.
+--
+fdecl :: { RdrNameHsDecl }
+fdecl : srcloc 'import' callconv safety1 fspec {% mkImport $3 $4 $5 $1 }
+ | srcloc 'import' callconv fspec {% mkImport $3 (PlaySafe False) $4 $1 }
+ | srcloc 'export' callconv fspec {% mkExport $3 $4 $1 }
+ -- the following syntax is DEPRECATED
+ | srcloc fdecl1DEPRECATED { ForD ($2 True $1) }
+ | srcloc fdecl2DEPRECATED { $2 $1 }
+
+fdecl1DEPRECATED :: { Bool -> SrcLoc -> ForeignDecl RdrName }
+fdecl1DEPRECATED
+ ----------- DEPRECATED label decls ------------
+ : 'label' ext_name varid '::' sigtype
+ { ForeignImport $3 $5 (CImport defaultCCallConv (PlaySafe False) nilFS nilFS
+ (CLabel ($2 `orElse` mkExtName $3))) }
+
+ ----------- DEPRECATED ccall/stdcall decls ------------
+ --
+ -- NB: This business with the case expression below may seem overly
+ -- complicated, but it is necessary to avoid some conflicts.
+
+ -- DEPRECATED variant #1: lack of a calling convention specification
+ -- (import)
+ | 'import' {-no callconv-} ext_name safety varid_no_unsafe '::' sigtype
+ { let
+ target = StaticTarget ($2 `orElse` mkExtName $4)
+ in
+ ForeignImport $4 $6 (CImport defaultCCallConv $3 nilFS nilFS
+ (CFunction target)) }
+
+ -- DEPRECATED variant #2: external name consists of two separate strings
+ -- (module name and function name) (import)
+ | 'import' callconv STRING STRING safety varid_no_unsafe '::' sigtype
+ {% case $2 of
+ DNCall -> parseError "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ let
+ imp = CFunction (StaticTarget $4)
+ in
+ ForeignImport $6 $8 (CImport cconv $5 nilFS nilFS imp) }
+
+ -- DEPRECATED variant #3: `unsafe' after entity
+ | 'import' callconv STRING 'unsafe' varid_no_unsafe '::' sigtype
+ {% case $2 of
+ DNCall -> parseError "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ let
+ imp = CFunction (StaticTarget $3)
+ in
+ ForeignImport $5 $7 (CImport cconv PlayRisky nilFS nilFS imp) }
+
+ -- DEPRECATED variant #4: use of the special identifier `dynamic' without
+ -- an explicit calling convention (import)
+ | 'import' {-no callconv-} 'dynamic' safety varid_no_unsafe '::' sigtype
+ { ForeignImport $4 $6 (CImport defaultCCallConv $3 nilFS nilFS
+ (CFunction DynamicTarget)) }
+
+ -- DEPRECATED variant #5: use of the special identifier `dynamic' (import)
+ | 'import' callconv 'dynamic' safety varid_no_unsafe '::' sigtype
+ {% case $2 of
+ DNCall -> parseError "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ ForeignImport $5 $7 (CImport cconv $4 nilFS nilFS
+ (CFunction DynamicTarget)) }
+
+ -- DEPRECATED variant #6: lack of a calling convention specification
+ -- (export)
+ | 'export' {-no callconv-} ext_name varid '::' sigtype
+ { ForeignExport $3 $5 (CExport (CExportStatic ($2 `orElse` mkExtName $3)
+ defaultCCallConv)) }
+
+ -- DEPRECATED variant #7: external name consists of two separate strings
+ -- (module name and function name) (export)
+ | 'export' callconv STRING STRING varid '::' sigtype
+ {% case $2 of
+ DNCall -> parseError "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ ForeignExport $5 $7
+ (CExport (CExportStatic $4 cconv)) }
+
+ -- DEPRECATED variant #8: use of the special identifier `dynamic' without
+ -- an explicit calling convention (export)
+ | 'export' {-no callconv-} 'dynamic' varid '::' sigtype
+ { ForeignImport $3 $5 (CImport defaultCCallConv (PlaySafe False) nilFS nilFS
+ CWrapper) }
+
+ -- DEPRECATED variant #9: use of the special identifier `dynamic' (export)
+ | 'export' callconv 'dynamic' varid '::' sigtype
+ {% case $2 of
+ DNCall -> parseError "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ ForeignImport $4 $6 (CImport cconv (PlaySafe False) nilFS nilFS CWrapper) }
+
+ ----------- DEPRECATED .NET decls ------------
+ -- NB: removed the .NET call declaration, as it is entirely subsumed
+ -- by the new standard FFI declarations
+
+fdecl2DEPRECATED :: { SrcLoc -> RdrNameHsDecl }
+fdecl2DEPRECATED
+ : 'import' 'dotnet' 'type' ext_name tycon
+ { \loc -> TyClD (ForeignType $5 $4 DNType loc) }
+ -- left this one unchanged for the moment as type imports are not
+ -- covered currently by the FFI standard -=chak
+
+
+callconv :: { CallConv }
+ : 'stdcall' { CCall StdCallConv }
+ | 'ccall' { CCall CCallConv }
+ | 'dotnet' { DNCall }
+
+safety :: { Safety }
+ : 'unsafe' { PlayRisky }
+ | 'safe' { PlaySafe False }
+ | 'threadsafe' { PlaySafe True }
+ | {- empty -} { PlaySafe False }
+
+safety1 :: { Safety }
+ : 'unsafe' { PlayRisky }
+ | 'safe' { PlaySafe False }
+ | 'threadsafe' { PlaySafe True }
+ -- only needed to avoid conflicts with the DEPRECATED rules
+
+fspec :: { (FastString, RdrName, RdrNameHsType) }
+ : STRING var '::' sigtype { ($1 , $2, $4) }
+ | var '::' sigtype { (nilFS, $1, $3) }
+ -- if the entity string is missing, it defaults to the empty string;
+ -- the meaning of an empty entity string depends on the calling
+ -- convention
+
+-- DEPRECATED syntax
ext_name :: { Maybe CLabelString }
: STRING { Just $1 }
| STRING STRING { Just $2 } -- Ignore "module name" for now
| sigtypes ',' sigtype { $3 : $1 }
sigtype :: { RdrNameHsType }
- : ctype { (mkHsForAllTy Nothing [] $1) }
+ : ctype { mkImplicitHsForAllTy [] $1 }
+ -- Wrap an Implicit forall if there isn't one there already
sig_vars :: { [RdrName] }
: sig_vars ',' var { $3 : $1 }
-- A ctype is a for-all type
ctype :: { RdrNameHsType }
- : 'forall' tyvars '.' ctype { mkHsForAllTy (Just $2) [] $4 }
- | context type { mkHsForAllTy Nothing $1 $2 }
+ : 'forall' tv_bndrs '.' ctype { mkExplicitHsForAllTy $2 [] $4 }
+ | context '=>' type { mkImplicitHsForAllTy $1 $3 }
-- A type of form (context => type) is an *implicit* HsForAllTy
| type { $1 }
+-- We parse a context as a btype so that we don't get reduce/reduce
+-- errors in ctype. The basic problem is that
+-- (Eq a, Ord a)
+-- looks so much like a tuple type. We can't tell until we find the =>
+context :: { RdrNameContext }
+ : btype {% checkContext $1 }
+
type :: { RdrNameHsType }
- : gentype '->' type { HsFunTy $1 $3 }
- | ipvar '::' type { mkHsIParamTy $1 $3 }
+ : ipvar '::' gentype { mkHsIParamTy $1 $3 }
| gentype { $1 }
gentype :: { RdrNameHsType }
: btype { $1 }
--- Generics
- | atype tyconop atype { HsOpTy $1 $2 $3 }
+ | btype qtyconop gentype { HsOpTy $1 $2 $3 }
+ | btype '`' tyvar '`' gentype { HsOpTy $1 $3 $5 }
+ | btype '->' gentype { HsFunTy $1 $3 }
btype :: { RdrNameHsType }
- : btype atype { (HsAppTy $1 $2) }
+ : btype atype { HsAppTy $1 $2 }
| atype { $1 }
atype :: { RdrNameHsType }
: gtycon { HsTyVar $1 }
| tyvar { HsTyVar $1 }
- | '(' type ',' types ')' { HsTupleTy (mkHsTupCon tcName Boxed ($2:$4)) ($2 : reverse $4) }
- | '(#' types '#)' { HsTupleTy (mkHsTupCon tcName Unboxed $2) (reverse $2) }
- | '[' type ']' { HsListTy $2 }
- | '(' ctype ')' { $2 }
+ | '(' type ',' comma_types1 ')' { HsTupleTy Boxed ($2:$4) }
+ | '(#' comma_types1 '#)' { HsTupleTy Unboxed $2 }
+ | '[' type ']' { HsListTy $2 }
+ | '[:' type ':]' { HsPArrTy $2 }
+ | '(' ctype ')' { HsParTy $2 }
+ | '(' ctype '::' kind ')' { HsKindSig $2 $4 }
-- Generics
| INTEGER { HsNumTy $1 }
inst_type :: { RdrNameHsType }
: ctype {% checkInstType $1 }
-types0 :: { [RdrNameHsType] }
- : types { reverse $1 }
+comma_types0 :: { [RdrNameHsType] }
+ : comma_types1 { $1 }
| {- empty -} { [] }
-types :: { [RdrNameHsType] }
+comma_types1 :: { [RdrNameHsType] }
: type { [$1] }
- | types ',' type { $3 : $1 }
+ | type ',' comma_types1 { $1 : $3 }
-simpletype :: { (RdrName, [RdrNameHsTyVar]) }
- : tycon tyvars { ($1, reverse $2) }
+tv_bndrs :: { [RdrNameHsTyVar] }
+ : tv_bndr tv_bndrs { $1 : $2 }
+ | {- empty -} { [] }
-tyvars :: { [RdrNameHsTyVar] }
- : tyvars tyvar { UserTyVar $2 : $1 }
- | {- empty -} { [] }
+tv_bndr :: { RdrNameHsTyVar }
+ : tyvar { UserTyVar $1 }
+ | '(' tyvar '::' kind ')' { KindedTyVar $2 $4 }
fds :: { [([RdrName], [RdrName])] }
: {- empty -} { [] }
| varids0 tyvar { $2 : $1 }
-----------------------------------------------------------------------------
+-- Kinds
+
+kind :: { Kind }
+ : akind { $1 }
+ | akind '->' kind { mkArrowKind $1 $3 }
+
+akind :: { Kind }
+ : '*' { liftedTypeKind }
+ | '(' kind ')' { $2 }
+
+
+-----------------------------------------------------------------------------
-- Datatype declarations
newconstr :: { RdrNameConDecl }
- : srcloc conid atype { mkConDecl $2 [] [] (VanillaCon [unbangedType $3]) $1 }
+ : srcloc conid atype { ConDecl $2 [] [] (PrefixCon [unbangedType $3]) $1 }
| srcloc conid '{' var '::' ctype '}'
- { mkConDecl $2 [] [] (RecCon [([$4], unbangedType $6)]) $1 }
+ { ConDecl $2 [] [] (RecCon [($4, unbangedType $6)]) $1 }
constrs :: { [RdrNameConDecl] }
: {- empty; a GHC extension -} { [] }
| constr { [$1] }
constr :: { RdrNameConDecl }
- : srcloc forall context constr_stuff
- { mkConDecl (fst $4) $2 $3 (snd $4) $1 }
+ : srcloc forall context '=>' constr_stuff
+ { ConDecl (fst $5) $2 $3 (snd $5) $1 }
| srcloc forall constr_stuff
- { mkConDecl (fst $3) $2 [] (snd $3) $1 }
+ { ConDecl (fst $3) $2 [] (snd $3) $1 }
forall :: { [RdrNameHsTyVar] }
- : 'forall' tyvars '.' { $2 }
+ : 'forall' tv_bndrs '.' { $2 }
| {- empty -} { [] }
-context :: { RdrNameContext }
- : btype '=>' {% checkContext $1 }
-
constr_stuff :: { (RdrName, RdrNameConDetails) }
- : btype {% mkVanillaCon $1 [] }
- | btype '!' atype satypes {% mkVanillaCon $1 (BangType MarkedUserStrict $3 : $4) }
- | gtycon '{' fielddecls '}' {% mkRecCon $1 $3 }
+ : btype {% mkPrefixCon $1 [] }
+ | btype strict_mark atype satypes {% mkPrefixCon $1 (BangType $2 $3 : $4) }
+ | oqtycon '{' '}' {% mkRecCon $1 [] }
+ | oqtycon '{' fielddecls '}' {% mkRecCon $1 $3 }
| sbtype conop sbtype { ($2, InfixCon $1 $3) }
satypes :: { [RdrNameBangType] }
: atype satypes { unbangedType $1 : $2 }
- | '!' atype satypes { BangType MarkedUserStrict $2 : $3 }
+ | strict_mark atype satypes { BangType $1 $2 : $3 }
| {- empty -} { [] }
sbtype :: { RdrNameBangType }
: btype { unbangedType $1 }
- | '!' atype { BangType MarkedUserStrict $2 }
+ | strict_mark atype { BangType $1 $2 }
fielddecls :: { [([RdrName],RdrNameBangType)] }
: fielddecl ',' fielddecls { $1 : $3 }
stype :: { RdrNameBangType }
: ctype { unbangedType $1 }
- | '!' atype { BangType MarkedUserStrict $2 }
+ | strict_mark atype { BangType $1 $2 }
-deriving :: { Maybe [RdrName] }
- : {- empty -} { Nothing }
- | 'deriving' qtycls { Just [$2] }
- | 'deriving' '(' ')' { Just [] }
- | 'deriving' '(' dclasses ')' { Just (reverse $3) }
+strict_mark :: { HsBang }
+ : '!' { HsStrict }
+ | '{-# UNPACK' '#-}' '!' { HsUnbox }
-dclasses :: { [RdrName] }
- : dclasses ',' qtycls { $3 : $1 }
- | qtycls { [$1] }
+deriving :: { Maybe RdrNameContext }
+ : {- empty -} { Nothing }
+ | 'deriving' context { Just $2 }
+ -- Glasgow extension: allow partial
+ -- applications in derivings
-----------------------------------------------------------------------------
-- Value definitions
We can't tell whether to reduce var to qvar until after we've read the signatures.
-}
-valdef :: { RdrBinding }
- : infixexp srcloc opt_sig rhs {% (checkValDef $1 $3 $4 $2) }
- | infixexp srcloc '::' sigtype {% (checkValSig $1 $4 $2) }
- | var ',' sig_vars srcloc '::' sigtype { foldr1 RdrAndBindings
- [ RdrSig (Sig n $6 $4) | n <- $1:$3 ]
- }
-
+decl :: { RdrBinding }
+ : sigdecl { $1 }
+ | infixexp srcloc opt_sig rhs {% checkValDef $1 $3 $4 $2 }
rhs :: { RdrNameGRHSs }
- : '=' srcloc exp wherebinds { (GRHSs (unguardedRHS $3 $2) $4 placeHolderType)}
- | gdrhs wherebinds { GRHSs (reverse $1) $2 placeHolderType }
+ : '=' srcloc exp wherebinds { GRHSs (unguardedRHS $3 $2) $4 placeHolderType }
+ | gdrhs wherebinds { GRHSs (reverse $1) $2 placeHolderType }
gdrhs :: { [RdrNameGRHS] }
: gdrhs gdrh { $2 : $1 }
gdrh :: { RdrNameGRHS }
: '|' srcloc quals '=' exp { GRHS (reverse (ResultStmt $5 $2 : $3)) $2 }
+sigdecl :: { RdrBinding }
+ : infixexp srcloc '::' sigtype
+ {% checkValSig $1 $4 $2 }
+ -- See the above notes for why we need infixexp here
+ | var ',' sig_vars srcloc '::' sigtype
+ { mkSigDecls [ Sig n $6 $4 | n <- $1:$3 ] }
+ | srcloc infix prec ops { mkSigDecls [ FixSig (FixitySig n (Fixity $3 $2) $1)
+ | n <- $4 ] }
+ | '{-# INLINE' srcloc activation qvar '#-}'
+ { RdrHsDecl (SigD (InlineSig True $4 $3 $2)) }
+ | '{-# NOINLINE' srcloc inverse_activation qvar '#-}'
+ { RdrHsDecl (SigD (InlineSig False $4 $3 $2)) }
+ | '{-# SPECIALISE' srcloc qvar '::' sigtypes '#-}'
+ { mkSigDecls [ SpecSig $3 t $2 | t <- $5] }
+ | '{-# SPECIALISE' srcloc 'instance' inst_type '#-}'
+ { RdrHsDecl (SigD (SpecInstSig $4 $2)) }
+
-----------------------------------------------------------------------------
-- Expressions
exp :: { RdrNameHsExpr }
- : infixexp '::' sigtype { (ExprWithTySig $1 $3) }
- | infixexp 'with' dbinding { HsWith $1 $3 }
+ : infixexp '::' sigtype { ExprWithTySig $1 $3 }
+ | fexp srcloc '-<' exp { HsArrApp $1 $4 placeHolderType HsFirstOrderApp True $2 }
+ | fexp srcloc '>-' exp { HsArrApp $4 $1 placeHolderType HsFirstOrderApp False $2 }
+ | fexp srcloc '-<<' exp { HsArrApp $1 $4 placeHolderType HsHigherOrderApp True $2 }
+ | fexp srcloc '>>-' exp { HsArrApp $4 $1 placeHolderType HsHigherOrderApp False $2 }
| infixexp { $1 }
infixexp :: { RdrNameHsExpr }
exp10 :: { RdrNameHsExpr }
: '\\' srcloc aexp aexps opt_asig '->' srcloc exp
- {% checkPatterns $2 ($3 : reverse $4) `thenP` \ ps ->
- returnP (HsLam (Match ps $5
+ {% checkPatterns $2 ($3 : reverse $4) >>= \ ps ->
+ return (HsLam (Match ps $5
(GRHSs (unguardedRHS $8 $7)
EmptyBinds placeHolderType))) }
- | 'let' declbinds 'in' exp { HsLet $2 $4 }
+ | 'let' binds 'in' exp { HsLet $2 $4 }
| 'if' srcloc exp 'then' exp 'else' exp { HsIf $3 $5 $7 $2 }
| 'case' srcloc exp 'of' altslist { HsCase $3 $5 $2 }
| '-' fexp { mkHsNegApp $2 }
- | srcloc 'do' stmtlist {% checkDo $3 `thenP` \ stmts ->
- returnP (HsDo DoExpr stmts $1) }
-
- | '_ccall_' ccallid aexps0 { HsCCall $2 $3 PlayRisky False placeHolderType }
- | '_ccall_GC_' ccallid aexps0 { HsCCall $2 $3 PlaySafe False placeHolderType }
- | '_casm_' CLITLIT aexps0 { HsCCall $2 $3 PlayRisky True placeHolderType }
- | '_casm_GC_' CLITLIT aexps0 { HsCCall $2 $3 PlaySafe True placeHolderType }
+ | srcloc 'do' stmtlist {% checkDo $3 >>= \ stmts ->
+ return (mkHsDo DoExpr stmts $1) }
+ | srcloc 'mdo' stmtlist {% checkMDo $3 >>= \ stmts ->
+ return (mkHsDo MDoExpr stmts $1) }
| scc_annot exp { if opt_SccProfilingOn
then HsSCC $1 $2
else HsPar $2 }
+ | 'proc' srcloc aexp '->' srcloc exp
+ {% checkPattern $2 $3 >>= \ p ->
+ return (HsProc p (HsCmdTop $6 [] placeHolderType undefined) $5) }
+
+ | '{-# CORE' STRING '#-}' exp { HsCoreAnn $2 $4 } -- hdaume: core annotation
+
| fexp { $1 }
-scc_annot :: { FAST_STRING }
+scc_annot :: { FastString }
: '_scc_' STRING { $2 }
| '{-# SCC' STRING '#-}' { $2 }
-ccallid :: { FAST_STRING }
- : VARID { $1 }
- | CONID { $1 }
-
fexp :: { RdrNameHsExpr }
- : fexp aexp { (HsApp $1 $2) }
+ : fexp aexp { HsApp $1 $2 }
| aexp { $1 }
-aexps0 :: { [RdrNameHsExpr] }
- : aexps { (reverse $1) }
-
aexps :: { [RdrNameHsExpr] }
: aexps aexp { $2 : $1 }
| {- empty -} { [] }
aexp :: { RdrNameHsExpr }
- : var_or_con '{|' gentype '|}' { (HsApp $1 (HsType $3)) }
- | aexp '{' fbinds '}' {% (mkRecConstrOrUpdate $1
- (reverse $3)) }
- | aexp1 { $1 }
-
-var_or_con :: { RdrNameHsExpr }
- : qvar { HsVar $1 }
- | gcon { HsVar $1 }
+ : qvar '@' aexp { EAsPat $1 $3 }
+ | '~' aexp { ELazyPat $2 }
+ | aexp1 { $1 }
aexp1 :: { RdrNameHsExpr }
+ : aexp1 '{' fbinds '}' {% (mkRecConstrOrUpdate $1 (reverse $3)) }
+ | aexp2 { $1 }
+
+-- Here was the syntax for type applications that I was planning
+-- but there are difficulties (e.g. what order for type args)
+-- so it's not enabled yet.
+-- But this case *is* used for the left hand side of a generic definition,
+-- which is parsed as an expression before being munged into a pattern
+ | qcname '{|' gentype '|}' { (HsApp (HsVar $1) (HsType $3)) }
+
+aexp2 :: { RdrNameHsExpr }
: ipvar { HsIPVar $1 }
- | var_or_con { $1 }
+ | qcname { HsVar $1 }
| literal { HsLit $1 }
- | INTEGER { HsOverLit (mkHsIntegral $1) }
- | RATIONAL { HsOverLit (mkHsFractional $1) }
+ | INTEGER { HsOverLit $! mkHsIntegral $1 }
+ | RATIONAL { HsOverLit $! mkHsFractional $1 }
| '(' exp ')' { HsPar $2 }
| '(' exp ',' texps ')' { ExplicitTuple ($2 : reverse $4) Boxed}
| '(#' texps '#)' { ExplicitTuple (reverse $2) Unboxed }
| '[' list ']' { $2 }
+ | '[:' parr ':]' { $2 }
| '(' infixexp qop ')' { (SectionL $2 (HsVar $3)) }
| '(' qopm infixexp ')' { (SectionR $2 $3) }
- | qvar '@' aexp { EAsPat $1 $3 }
| '_' { EWildPat }
- | '~' aexp1 { ELazyPat $2 }
+
+ -- MetaHaskell Extension
+ | srcloc TH_ID_SPLICE { mkHsSplice (HsVar (mkUnqual varName $2)) $1 } -- $x
+ | srcloc '$(' exp ')' { mkHsSplice $3 $1 } -- $( exp )
+ | srcloc TH_VAR_QUOTE qvar { HsBracket (VarBr $3) $1 }
+ | srcloc TH_VAR_QUOTE qcon { HsBracket (VarBr $3) $1 }
+ | srcloc TH_TY_QUOTE tyvar { HsBracket (VarBr $3) $1 }
+ | srcloc TH_TY_QUOTE gtycon { HsBracket (VarBr $3) $1 }
+ | srcloc '[|' exp '|]' { HsBracket (ExpBr $3) $1 }
+ | srcloc '[t|' ctype '|]' { HsBracket (TypBr $3) $1 }
+ | srcloc '[p|' infixexp '|]' {% checkPattern $1 $3 >>= \p ->
+ return (HsBracket (PatBr p) $1) }
+ | srcloc '[d|' cvtopbody '|]' { HsBracket (DecBr (mkGroup $3)) $1 }
+
+ -- arrow notation extension
+ | srcloc '(|' aexp2 cmdargs '|)'
+ { HsArrForm $3 Nothing (reverse $4) $1 }
+
+cmdargs :: { [RdrNameHsCmdTop] }
+ : cmdargs acmd { $2 : $1 }
+ | {- empty -} { [] }
+
+acmd :: { RdrNameHsCmdTop }
+ : aexp2 { HsCmdTop $1 [] placeHolderType undefined }
+
+cvtopbody :: { [RdrNameHsDecl] }
+ : '{' cvtopdecls '}' { $2 }
+ | vocurly cvtopdecls close { $2 }
texps :: { [RdrNameHsExpr] }
: texps ',' exp { $3 : $1 }
| exp ',' exp '..' { ArithSeqIn (FromThen $1 $3) }
| exp '..' exp { ArithSeqIn (FromTo $1 $3) }
| exp ',' exp '..' exp { ArithSeqIn (FromThenTo $1 $3 $5) }
- | exp srcloc pquals {% let { body [qs] = qs;
- body qss = [ParStmt (map reverse qss)] }
- in
- returnP ( HsDo ListComp
- (reverse (ResultStmt $1 $2 : body $3))
- $2
- )
+ | exp srcloc pquals { mkHsDo ListComp
+ (reverse (ResultStmt $1 $2 : $3))
+ $2
}
lexps :: { [RdrNameHsExpr] }
-----------------------------------------------------------------------------
-- List Comprehensions
-pquals :: { [[RdrNameStmt]] }
- : pquals '|' quals { $3 : $1 }
+pquals :: { [RdrNameStmt] } -- Either a singleton ParStmt, or a reversed list of Stmts
+ : pquals1 { case $1 of
+ [qs] -> qs
+ qss -> [ParStmt stmtss]
+ where
+ stmtss = [ (reverse qs, undefined)
+ | qs <- qss ]
+ }
+
+pquals1 :: { [[RdrNameStmt]] }
+ : pquals1 '|' quals { $3 : $1 }
| '|' quals { [$2] }
quals :: { [RdrNameStmt] }
- : quals ',' stmt { $3 : $1 }
- | stmt { [$1] }
+ : quals ',' qual { $3 : $1 }
+ | qual { [$1] }
+
+-----------------------------------------------------------------------------
+-- Parallel array expressions
+
+-- The rules below are little bit contorted; see the list case for details.
+-- Note that, in contrast to lists, we only have finite arithmetic sequences.
+-- Moreover, we allow explicit arrays with no element (represented by the nil
+-- constructor in the list case).
+
+parr :: { RdrNameHsExpr }
+ : { ExplicitPArr placeHolderType [] }
+ | exp { ExplicitPArr placeHolderType [$1] }
+ | lexps { ExplicitPArr placeHolderType
+ (reverse $1) }
+ | exp '..' exp { PArrSeqIn (FromTo $1 $3) }
+ | exp ',' exp '..' exp { PArrSeqIn (FromThenTo $1 $3 $5) }
+ | exp srcloc pquals { mkHsDo PArrComp
+ (reverse (ResultStmt $1 $2 : $3))
+ $2
+ }
+
+-- We are reusing `lexps' and `pquals' from the list case.
-----------------------------------------------------------------------------
-- Case alternatives
altslist :: { [RdrNameMatch] }
: '{' alts '}' { reverse $2 }
- | layout_on alts close { reverse $2 }
+ | vocurly alts close { reverse $2 }
alts :: { [RdrNameMatch] }
: alts1 { $1 }
alt :: { RdrNameMatch }
: srcloc infixexp opt_sig ralt wherebinds
- {% (checkPattern $1 $2 `thenP` \p ->
- returnP (Match [p] $3
+ {% (checkPattern $1 $2 >>= \p ->
+ return (Match [p] $3
(GRHSs $4 $5 placeHolderType)) )}
ralt :: { [RdrNameGRHS] }
: '->' srcloc exp { [GRHS [ResultStmt $3 $2] $2] }
- | gdpats { (reverse $1) }
+ | gdpats { reverse $1 }
gdpats :: { [RdrNameGRHS] }
: gdpats gdpat { $2 : $1 }
-- Statement sequences
stmtlist :: { [RdrNameStmt] }
- : '{' stmts '}' { $2 }
- | layout_on_for_do stmts close { $2 }
+ : '{' stmts '}' { $2 }
+ | vocurly stmts close { $2 }
-- do { ;; s ; s ; ; s ;; }
-- The last Stmt should be a ResultStmt, but that's hard to enforce
| {- nothing -} { Nothing }
stmt :: { RdrNameStmt }
- : srcloc infixexp '<-' exp {% checkPattern $1 $2 `thenP` \p ->
- returnP (BindStmt p $4 $1) }
+ : qual { $1 }
+ | srcloc infixexp '->' exp {% checkPattern $1 $4 >>= \p ->
+ return (BindStmt p $2 $1) }
+ | srcloc 'rec' stmtlist { RecStmt $3 undefined undefined undefined }
+
+qual :: { RdrNameStmt }
+ : srcloc infixexp '<-' exp {% checkPattern $1 $2 >>= \p ->
+ return (BindStmt p $4 $1) }
| srcloc exp { ExprStmt $2 placeHolderType $1 }
- | srcloc 'let' declbinds { LetStmt $3 }
+ | srcloc 'let' binds { LetStmt $3 }
-----------------------------------------------------------------------------
-- Record Field Update/Construction
-fbinds :: { RdrNameHsRecordBinds }
- : fbinds ',' fbind { $3 : $1 }
- | fbinds ',' { $1 }
- | fbind { [$1] }
+fbinds :: { RdrNameHsRecordBinds }
+ : fbinds1 { $1 }
| {- empty -} { [] }
-fbind :: { (RdrName, RdrNameHsExpr, Bool) }
- : qvar '=' exp { ($1,$3,False) }
+fbinds1 :: { RdrNameHsRecordBinds }
+ : fbinds1 ',' fbind { $3 : $1 }
+ | fbind { [$1] }
+
+fbind :: { (RdrName, RdrNameHsExpr) }
+ : qvar '=' exp { ($1,$3) }
-----------------------------------------------------------------------------
-- Implicit Parameter Bindings
-dbinding :: { [(IPName RdrName, RdrNameHsExpr)] }
- : '{' dbinds '}' { $2 }
- | layout_on dbinds close { $2 }
-
dbinds :: { [(IPName RdrName, RdrNameHsExpr)] }
: dbinds ';' dbind { $3 : $1 }
| dbinds ';' { $1 }
| dbind { [$1] }
- | {- empty -} { [] }
+-- | {- empty -} { [] }
dbind :: { (IPName RdrName, RdrNameHsExpr) }
dbind : ipvar '=' exp { ($1, $3) }
deprec_var : var { $1 }
| tycon { $1 }
-gtycon :: { RdrName }
- : qtycon { $1 }
- | '(' qtyconop ')' { $2 }
- | '(' ')' { unitTyCon_RDR }
- | '(' '->' ')' { funTyCon_RDR }
- | '[' ']' { listTyCon_RDR }
- | '(' commas ')' { tupleTyCon_RDR $2 }
-
-gcon :: { RdrName }
- : '(' ')' { unitCon_RDR }
- | '[' ']' { nilCon_RDR }
- | '(' commas ')' { tupleCon_RDR $2 }
+gcon :: { RdrName } -- Data constructor namespace
+ : sysdcon { nameRdrName (dataConName $1) }
| qcon { $1 }
+-- the case of '[:' ':]' is part of the production `parr'
+
+sysdcon :: { DataCon } -- Wired in data constructors
+ : '(' ')' { unitDataCon }
+ | '(' commas ')' { tupleCon Boxed $2 }
+ | '[' ']' { nilDataCon }
var :: { RdrName }
: varid { $1 }
-- *after* we see the close paren.
ipvar :: { IPName RdrName }
- : IPDUPVARID { Dupable (mkUnqual varName $1) }
- | IPSPLITVARID { MustSplit (mkUnqual varName $1) }
+ : IPDUPVARID { Dupable (mkUnqual varName $1) }
+ | IPSPLITVARID { Linear (mkUnqual varName $1) }
qcon :: { RdrName }
: qconid { $1 }
| '`' qconid '`' { $2 }
-----------------------------------------------------------------------------
+-- Type constructors
+
+gtycon :: { RdrName } -- A "general" qualified tycon
+ : oqtycon { $1 }
+ | '(' ')' { getRdrName unitTyCon }
+ | '(' commas ')' { getRdrName (tupleTyCon Boxed $2) }
+ | '(' '->' ')' { getRdrName funTyCon }
+ | '[' ']' { listTyCon_RDR }
+ | '[:' ':]' { parrTyCon_RDR }
+
+oqtycon :: { RdrName } -- An "ordinary" qualified tycon
+ : qtycon { $1 }
+ | '(' qtyconsym ')' { $2 }
+
+qtyconop :: { RdrName } -- Qualified or unqualified
+ : qtyconsym { $1 }
+ | '`' qtycon '`' { $2 }
+
+tyconop :: { RdrName } -- Unqualified
+ : tyconsym { $1 }
+ | '`' tycon '`' { $2 }
+
+qtycon :: { RdrName } -- Qualified or unqualified
+ : QCONID { mkQual tcClsName $1 }
+ | tycon { $1 }
+
+tycon :: { RdrName } -- Unqualified
+ : CONID { mkUnqual tcClsName $1 }
+
+qtyconsym :: { RdrName }
+ : QCONSYM { mkQual tcClsName $1 }
+ | tyconsym { $1 }
+
+tyconsym :: { RdrName }
+ : CONSYM { mkUnqual tcClsName $1 }
+
+-----------------------------------------------------------------------------
-- Any operator
op :: { RdrName } -- used in infix decls
varid :: { RdrName }
: varid_no_unsafe { $1 }
- | 'unsafe' { mkUnqual varName SLIT("unsafe") }
+ | 'unsafe' { mkUnqual varName FSLIT("unsafe") }
+ | 'safe' { mkUnqual varName FSLIT("safe") }
+ | 'threadsafe' { mkUnqual varName FSLIT("threadsafe") }
varid_no_unsafe :: { RdrName }
: VARID { mkUnqual varName $1 }
| special_id { mkUnqual varName $1 }
- | 'forall' { mkUnqual varName SLIT("forall") }
+ | 'forall' { mkUnqual varName FSLIT("forall") }
tyvar :: { RdrName }
: VARID { mkUnqual tvName $1 }
| special_id { mkUnqual tvName $1 }
- | 'unsafe' { mkUnqual tvName SLIT("unsafe") }
+ | 'unsafe' { mkUnqual tvName FSLIT("unsafe") }
+ | 'safe' { mkUnqual tvName FSLIT("safe") }
+ | 'threadsafe' { mkUnqual tvName FSLIT("threadsafe") }
-- These special_ids are treated as keywords in various places,
--- but as ordinary ids elsewhere. A special_id collects all thsee
+-- but as ordinary ids elsewhere. 'special_id' collects all these
-- except 'unsafe' and 'forall' whose treatment differs depending on context
special_id :: { UserFS }
special_id
- : 'as' { SLIT("as") }
- | 'qualified' { SLIT("qualified") }
- | 'hiding' { SLIT("hiding") }
- | 'export' { SLIT("export") }
- | 'label' { SLIT("label") }
- | 'dynamic' { SLIT("dynamic") }
- | 'stdcall' { SLIT("stdcall") }
- | 'ccall' { SLIT("ccall") }
+ : 'as' { FSLIT("as") }
+ | 'qualified' { FSLIT("qualified") }
+ | 'hiding' { FSLIT("hiding") }
+ | 'export' { FSLIT("export") }
+ | 'label' { FSLIT("label") }
+ | 'dynamic' { FSLIT("dynamic") }
+ | 'stdcall' { FSLIT("stdcall") }
+ | 'ccall' { FSLIT("ccall") }
-----------------------------------------------------------------------------
--- ConIds
-
-qconid :: { RdrName }
- : conid { $1 }
- | QCONID { mkQual dataName $1 }
-
-conid :: { RdrName }
- : CONID { mkUnqual dataName $1 }
-
------------------------------------------------------------------------------
--- ConSyms
-
-qconsym :: { RdrName }
- : consym { $1 }
- | QCONSYM { mkQual dataName $1 }
-
-consym :: { RdrName }
- : CONSYM { mkUnqual dataName $1 }
-
------------------------------------------------------------------------------
--- VarSyms
+-- Variables
qvarsym :: { RdrName }
: varsym { $1 }
varsym :: { RdrName }
: varsym_no_minus { $1 }
- | '-' { mkUnqual varName SLIT("-") }
+ | '-' { mkUnqual varName FSLIT("-") }
varsym_no_minus :: { RdrName } -- varsym not including '-'
: VARSYM { mkUnqual varName $1 }
-- See comments with special_id
special_sym :: { UserFS }
-special_sym : '!' { SLIT("!") }
- | '.' { SLIT(".") }
+special_sym : '!' { FSLIT("!") }
+ | '.' { FSLIT(".") }
+ | '*' { FSLIT("*") }
+
+-----------------------------------------------------------------------------
+-- Data constructors
+
+qconid :: { RdrName } -- Qualified or unqualifiedb
+ : conid { $1 }
+ | QCONID { mkQual dataName $1 }
+
+conid :: { RdrName }
+ : CONID { mkUnqual dataName $1 }
+
+qconsym :: { RdrName } -- Qualified or unqualified
+ : consym { $1 }
+ | QCONSYM { mkQual dataName $1 }
+
+consym :: { RdrName }
+ : CONSYM { mkUnqual dataName $1 }
+
+ -- ':' means only list cons
+ | ':' { consDataCon_RDR }
+
-----------------------------------------------------------------------------
-- Literals
literal :: { HsLit }
- : CHAR { HsChar $1 }
+ : CHAR { HsChar (ord $1) } --TODO remove ord
| STRING { HsString $1 }
| PRIMINTEGER { HsIntPrim $1 }
- | PRIMCHAR { HsCharPrim $1 }
+ | PRIMCHAR { HsCharPrim (ord $1) } --TODO remove ord
| PRIMSTRING { HsStringPrim $1 }
| PRIMFLOAT { HsFloatPrim $1 }
| PRIMDOUBLE { HsDoublePrim $1 }
- | CLITLIT { HsLitLit $1 placeHolderType }
-srcloc :: { SrcLoc } : {% getSrcLocP }
-
+srcloc :: { SrcLoc } : {% getSrcLoc }
+
-----------------------------------------------------------------------------
-- Layout
: vccurly { () } -- context popped in lexer.
| error {% popContext }
-layout_on :: { () } : {% layoutOn True{-strict-} }
-layout_on_for_do :: { () } : {% layoutOn False }
-
-----------------------------------------------------------------------------
-- Miscellaneous (mostly renamings)
'.':unpackFS (snd $1)))
}
-tycon :: { RdrName }
- : CONID { mkUnqual tcClsName $1 }
-
-tyconop :: { RdrName }
- : CONSYM { mkUnqual tcClsName $1 }
-
-qtycon :: { RdrName }
- : tycon { $1 }
- | QCONID { mkQual tcClsName $1 }
-
-qtyconop :: { RdrName }
- : tyconop { $1 }
- | QCONSYM { mkQual tcClsName $1 }
-
-qtycls :: { RdrName }
- : qtycon { $1 }
-
commas :: { Int }
: commas ',' { $1 + 1 }
| ',' { 2 }
{
happyError :: P a
-happyError buf PState{ loc = loc } = PFailed (srcParseErr buf loc)
+happyError = srcParseFail
}