{- -*-haskell-*-
-----------------------------------------------------------------------------
-$Id: Parser.y,v 1.89 2002/02/13 15:19:19 simonpj Exp $
+$Id: Parser.y,v 1.114 2002/12/10 16:28:48 igloo Exp $
Haskell grammar.
-}
{
-module Parser ( parseModule, parseStmt, parseIdentifier ) where
+module Parser ( parseModule, parseStmt, parseIdentifier, parseIface ) where
+
+#include "HsVersions.h"
import HsSyn
import HsTypes ( mkHsTupCon )
import RdrHsSyn
+import HscTypes ( ParsedIface(..), IsBootInterface, noDependencies )
import Lex
-import ParseUtil
import RdrName
-import PrelNames ( mAIN_Name, unitTyCon_RDR, funTyCon_RDR,
- listTyCon_RDR, parrTyCon_RDR, tupleTyCon_RDR,
- unitCon_RDR, nilCon_RDR, tupleCon_RDR )
+import PrelNames ( mAIN_Name, funTyConName, listTyConName,
+ parrTyConName, consDataConName, nilDataConName )
+import TysWiredIn ( unitTyCon, unitDataCon, tupleTyCon, tupleCon )
import ForeignCall ( Safety(..), CExportSpec(..),
CCallConv(..), CCallTarget(..), defaultCCallConv,
)
import TyCon ( DataConDetails(..) )
import SrcLoc ( SrcLoc )
import Module
-import CmdLineOpts ( opt_SccProfilingOn )
+import CmdLineOpts ( opt_SccProfilingOn, opt_InPackage )
import Type ( Kind, mkArrowKind, liftedTypeKind )
import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
- NewOrData(..), StrictnessMark(..), Activation(..) )
+ NewOrData(..), StrictnessMark(..), Activation(..),
+ FixitySig(..) )
import Panic
-import GlaExts
+import GLAEXTS
import CStrings ( CLabelString )
import FastString
import Maybes ( orElse )
import Outputable
-#include "HsVersions.h"
}
{-
-----------------------------------------------------------------------------
-Conflicts: 21 shift/reduce, -=chak[4Feb2]
+Conflicts: 29 shift/reduce, [SDM 19/9/2002]
-9 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)
- 8 because op might be: - ! * . `x` VARSYM CONSYM QVARSYM QCONSYM
-1 for ambiguity in 'if x then y else z :: T'
- (shift parses as 'if x then y else (z :: T)', as per longest-parse rule)
-1 for ambiguity in 'if x then y else z with ?x=3'
+ 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)'
-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 'if x then y else z :: T' [State 136]
+ (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))
-1 for ambiguity in '{-# RULES "name" forall = ... #-}'
+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', which are resolved
- correctly, and moreover, should go away when `fdeclDEPRECATED' is removed.
+6 for conflicts between `fdecl' and `fdeclDEPRECATED', [States 384,385]
+ which are resolved correctly, and moreover,
+ should go away when `fdeclDEPRECATED' is removed.
-----------------------------------------------------------------------------
-}
'label' { ITlabel }
'dynamic' { ITdynamic }
'safe' { ITsafe }
+ 'threadsafe' { ITthreadsafe }
'unsafe' { ITunsafe }
'with' { ITwith }
+ 'mdo' { ITmdo }
'stdcall' { ITstdcallconv }
'ccall' { ITccallconv }
'dotnet' { ITdotnet }
'_ccall_' { ITccall (False, False, PlayRisky) }
- '_ccall_GC_' { ITccall (False, False, PlaySafe) }
+ '_ccall_GC_' { ITccall (False, False, PlaySafe False) }
'_casm_' { ITccall (False, True, PlayRisky) }
- '_casm_GC_' { ITccall (False, True, PlaySafe) }
+ '_casm_GC_' { ITccall (False, True, PlaySafe False) }
'{-# SPECIALISE' { ITspecialise_prag }
'{-# SOURCE' { ITsource_prag }
-}
'..' { ITdotdot } -- reserved symbols
+ ':' { ITcolon }
'::' { ITdcolon }
'=' { ITequal }
'\\' { ITlam }
PRIMFLOAT { ITprimfloat $$ }
PRIMDOUBLE { ITprimdouble $$ }
CLITLIT { ITlitlit $$ }
+
+-- Template Haskell
+'[|' { ITopenExpQuote }
+'[p|' { ITopenPatQuote }
+'[t|' { ITopenTypQuote }
+'[d|' { ITopenDecQuote }
+'|]' { ITcloseQuote }
+ID_SPLICE { ITidEscape $$ } -- $x
+'$(' { ITparenEscape } -- $( exp )
+REIFY_TYPE { ITreifyType }
+REIFY_DECL { ITreifyDecl }
+REIFY_FIXITY { ITreifyFixity }
%monad { P } { thenP } { returnP }
%lexer { lexer } { 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 }
+ { HsModule (mkHomeModule $3) Nothing $5 (fst $7) (snd $7) $4 $1 }
| srcloc body
- { HsModule mAIN_Name Nothing Nothing (fst $2) (snd $2) Nothing $1 }
+ { HsModule (mkHomeModule mAIN_Name) Nothing Nothing
+ (fst $2) (snd $2) Nothing $1 }
maybemoddeprec :: { Maybe DeprecTxt }
: '{-# DEPRECATED' STRING '#-}' { Just $2 }
| cvtopdecls { ([],$1) }
cvtopdecls :: { [RdrNameHsDecl] }
- : topdecls { cvTopDecls (groupBindings $1)}
+ : topdecls { cvTopDecls $1 }
+
+-----------------------------------------------------------------------------
+-- Interfaces (.hi-boot files)
+
+iface :: { ParsedIface }
+ : 'module' modid 'where' ifacebody
+ { ParsedIface {
+ pi_mod = $2,
+ pi_pkg = opt_InPackage,
+ pi_vers = 1, -- Module version
+ pi_orphan = False,
+ pi_exports = (1,[($2,mkIfaceExports $4)]),
+ pi_deps = noDependencies,
+ pi_usages = [],
+ pi_fixity = [],
+ pi_insts = [],
+ pi_decls = map (\x -> (1,x)) $4,
+ pi_rules = (1,[]),
+ pi_deprecs = Nothing
+ }
+ }
+
+ifacebody :: { [RdrNameTyClDecl] }
+ : '{' ifacedecls '}' { $2 }
+ | layout_on ifacedecls close { $2 }
+
+ifacedecls :: { [RdrNameTyClDecl] }
+ : ifacedecl ';' ifacedecls { $1 : $3 }
+ | ';' ifacedecls { $2 }
+ | ifacedecl { [$1] }
+ | {- empty -} { [] }
+
+ifacedecl :: { RdrNameTyClDecl }
+ : tycl_decl { $1 }
+ | srcloc var '::' sigtype { IfaceSig $2 $4 [] $1 }
-----------------------------------------------------------------------------
-- 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' tycon tv_bndrs '=' ctype
+ : tycl_decl { RdrHsDecl (TyClD $1) }
+ | srcloc 'instance' inst_type where
+ { let (binds,sigs) = cvMonoBindsAndSigs $4
+ in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $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 $3 $4 $6 $1)) }
+ { let (tc,tvs) = $3 in TySynonym tc tvs $5 $1 }
| srcloc 'data' tycl_hdr constrs deriving
- {% returnP (RdrHsDecl (TyClD
- (mkTyData DataType $3 (DataCons (reverse $4)) $5 $1))) }
+ { mkTyData DataType $3 (DataCons (reverse $4)) $5 $1 }
| srcloc 'newtype' tycl_hdr '=' newconstr deriving
- {% returnP (RdrHsDecl (TyClD
- (mkTyData NewType $3 (DataCons [$5]) $6 $1))) }
+ { mkTyData NewType $3 (DataCons [$5]) $6 $1 }
| srcloc 'class' tycl_hdr fds where
- {% let
- (binds,sigs) = cvMonoBindsAndSigs cvClassOpSig (groupBindings $5)
- in
- returnP (RdrHsDecl (TyClD
- (mkClassDecl $3 $4 sigs (Just binds) $1))) }
+ { let
+ (binds,sigs) = cvMonoBindsAndSigs $5
+ in
+ mkClassDecl $3 $4 (map cvClassOpSig sigs) (Just binds) $1 }
- | srcloc 'instance' inst_type where
- { let (binds,sigs)
- = cvMonoBindsAndSigs cvInstDeclSig
- (groupBindings $4)
- in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $1)) }
-
- | srcloc 'default' '(' comma_types0 ')' { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
- | 'foreign' fdecl { RdrHsDecl $2 }
- | '{-# DEPRECATED' deprecations '#-}' { $2 }
- | '{-# RULES' rules '#-}' { $2 }
- | decl { $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
-- (Eq a, Ord b) => T a b
-- Rather a lot of inlining here, else we get reduce/reduce errors
tycl_hdr :: { (RdrNameContext, RdrName, [RdrNameHsTyVar]) }
- : '(' comma_types1 ')' '=>' gtycon tv_bndrs {% mapP checkPred $2 `thenP` \ cxt ->
- returnP (cxt, $5, $6) }
- -- qtycon for the class below name would lead to many s/r conflicts
- -- FIXME: does the renamer pick up all wrong forms and raise an
- -- error
- | gtycon atypes1 '=>' gtycon atypes0 {% checkTyVars $5 `thenP` \ tvs ->
- returnP ([HsClassP $1 $2], $4, tvs) }
- | gtycon atypes0 {% checkTyVars $2 `thenP` \ tvs ->
- returnP ([], $1, tvs) }
- -- We have to have qtycon in this production to avoid s/r
- -- conflicts with the previous one. The renamer will complain
- -- if we use a qualified tycon.
- --
- -- Using a `gtycon' throughout. This enables special syntax,
- -- such as "[]" for tycons as well as tycon ops in
- -- parentheses. This is beyond H98, but used repeatedly in
- -- the Prelude modules. (So, it would be a good idea to raise
- -- an error in the renamer if some non-H98 form is used and
- -- -fglasgow-exts is not given.) -=chak
-
-decls :: { [RdrBinding] }
+ : context '=>' type {% checkTyClHdr $3 `thenP` \ (tc,tvs) ->
+ returnP ($1, tc, tvs) }
+ | type {% checkTyClHdr $1 `thenP` \ (tc,tvs) ->
+ returnP ([], tc, tvs) }
+
+-----------------------------------------------------------------------------
+-- Nested declarations
+
+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 }
+ | layout_on 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 False{-not with-} }
+ | layout_on dbinds close { IPBinds $2 False{-not with-} }
+
+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
| '(' 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 ] }
--
fdecl :: { RdrNameHsDecl }
fdecl : srcloc 'import' callconv safety1 fspec {% mkImport $3 $4 $5 $1 }
- | srcloc 'import' callconv fspec {% mkImport $3 PlaySafe $4 $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) }
fdecl1DEPRECATED
----------- DEPRECATED label decls ------------
: 'label' ext_name varid '::' sigtype
- { ForeignImport $3 $5 (CImport defaultCCallConv PlaySafe _NIL_ _NIL_
+ { ForeignImport $3 $5 (CImport defaultCCallConv (PlaySafe False) nilFS nilFS
(CLabel ($2 `orElse` mkExtName $3))) }
----------- DEPRECATED ccall/stdcall decls ------------
{ let
target = StaticTarget ($2 `orElse` mkExtName $4)
in
- ForeignImport $4 $6 (CImport defaultCCallConv $3 _NIL_ _NIL_
+ ForeignImport $4 $6 (CImport defaultCCallConv $3 nilFS nilFS
(CFunction target)) }
-- DEPRECATED variant #2: external name consists of two separate strings
let
imp = CFunction (StaticTarget $4)
in
- ForeignImport $6 $8 (CImport cconv $5 _NIL_ _NIL_ imp) }
+ ForeignImport $6 $8 (CImport cconv $5 nilFS nilFS imp) }
-- DEPRECATED variant #3: `unsafe' after entity
| 'import' callconv STRING 'unsafe' varid_no_unsafe '::' sigtype
let
imp = CFunction (StaticTarget $3)
in
- ForeignImport $5 $7 (CImport cconv PlayRisky _NIL_ _NIL_ imp) }
+ 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 _NIL_ _NIL_
+ { ForeignImport $4 $6 (CImport defaultCCallConv $3 nilFS nilFS
(CFunction DynamicTarget)) }
-- DEPRECATED variant #5: use of the special identifier `dynamic' (import)
{% case $2 of
DNCall -> parseError "Illegal format of .NET foreign import"
CCall cconv -> returnP $
- ForeignImport $5 $7 (CImport cconv $4 _NIL_ _NIL_
+ ForeignImport $5 $7 (CImport cconv $4 nilFS nilFS
(CFunction DynamicTarget)) }
-- DEPRECATED variant #6: lack of a calling convention specification
-- 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 _NIL_ _NIL_
+ { ForeignImport $3 $5 (CImport defaultCCallConv (PlaySafe False) nilFS nilFS
CWrapper) }
-- DEPRECATED variant #9: use of the special identifier `dynamic' (export)
{% case $2 of
DNCall -> parseError "Illegal format of .NET foreign import"
CCall cconv -> returnP $
- ForeignImport $4 $6 (CImport cconv PlaySafe _NIL_ _NIL_ CWrapper) }
+ ForeignImport $4 $6 (CImport cconv (PlaySafe False) nilFS nilFS CWrapper) }
----------- DEPRECATED .NET decls ------------
-- NB: removed the .NET call declaration, as it is entirely subsumed
safety :: { Safety }
: 'unsafe' { PlayRisky }
- | 'safe' { PlaySafe }
- | {- empty -} { PlaySafe }
+ | 'safe' { PlaySafe False }
+ | 'threadsafe' { PlaySafe True }
+ | {- empty -} { PlaySafe False }
safety1 :: { Safety }
: 'unsafe' { PlayRisky }
- | 'safe' { PlaySafe }
+ | 'safe' { PlaySafe False }
+ | 'threadsafe' { PlaySafe True }
-- only needed to avoid conflicts with the DEPRECATED rules
-fspec :: { (FAST_STRING, RdrName, RdrNameHsType) }
- : STRING varid '::' sigtype { ($1 , $2, $4) }
- | varid '::' sigtype { (SLIT(""), $1, $3) }
+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
: 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 (HsTyOp $2) $3 }
+ | btype '`' tyvar '`' gentype { HsOpTy $1 (HsTyOp $3) $5 }
+ | btype '->' gentype { HsOpTy $1 HsArrow $3 }
btype :: { RdrNameHsType }
: btype atype { HsAppTy $1 $2 }
| tyvar { HsTyVar $1 }
| '(' type ',' comma_types1 ')' { HsTupleTy (mkHsTupCon tcName Boxed ($2:$4)) ($2:$4) }
| '(#' comma_types1 '#)' { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 }
- | '[' type ']' { HsListTy $2 }
- | '[:' type ':]' { HsPArrTy $2 }
- | '(' ctype ')' { $2 }
+ | '[' type ']' { HsListTy $2 }
+ | '[:' type ':]' { HsPArrTy $2 }
+ | '(' ctype ')' { HsParTy $2 }
| '(' ctype '::' kind ')' { HsKindSig $2 $4 }
-- Generics
| INTEGER { HsNumTy $1 }
: type { [$1] }
| type ',' comma_types1 { $1 : $3 }
-atypes0 :: { [RdrNameHsType] }
- : atypes1 { $1 }
- | {- empty -} { [] }
-
-atypes1 :: { [RdrNameHsType] }
- : atype { [$1] }
- | atype atypes1 { $1 : $2 }
-
tv_bndrs :: { [RdrNameHsTyVar] }
: tv_bndr tv_bndrs { $1 : $2 }
| {- empty -} { [] }
-- 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 :: { RdrNameConDecl }
: srcloc forall context '=>' constr_stuff
- { mkConDecl (fst $5) $2 $3 (snd $5) $1 }
+ { 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' tv_bndrs '.' { $2 }
| {- empty -} { [] }
constr_stuff :: { (RdrName, RdrNameConDetails) }
- : btype {% mkVanillaCon $1 [] }
- | btype '!' atype satypes {% mkVanillaCon $1 (BangType MarkedUserStrict $3 : $4) }
- | gtycon '{' '}' {% mkRecCon $1 [] }
- | gtycon '{' fielddecls '}' {% mkRecCon $1 $3 }
+ : btype {% mkPrefixCon $1 [] }
+ | btype '!' atype satypes {% mkPrefixCon $1 (BangType MarkedUserStrict $3 : $4) }
+ | oqtycon '{' '}' {% mkRecCon $1 [] }
+ | oqtycon '{' fielddecls '}' {% mkRecCon $1 $3 }
| sbtype conop sbtype { ($2, InfixCon $1 $3) }
satypes :: { [RdrNameBangType] }
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 }
+ | infixexp 'with' dbinding { HsLet (IPBinds $3 True{-not a let-}) $1 }
| infixexp { $1 }
infixexp :: { RdrNameHsExpr }
returnP (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) }
+ returnP (mkHsDo DoExpr stmts $1) }
+ | srcloc 'mdo' stmtlist {% checkMDo $3 `thenP` \ stmts ->
+ returnP (mkHsDo MDoExpr stmts $1) }
| '_ccall_' ccallid aexps0 { HsCCall $2 $3 PlayRisky False placeHolderType }
- | '_ccall_GC_' ccallid aexps0 { HsCCall $2 $3 PlaySafe False placeHolderType }
+ | '_ccall_GC_' ccallid aexps0 { HsCCall $2 $3 (PlaySafe False) False placeHolderType }
| '_casm_' CLITLIT aexps0 { HsCCall $2 $3 PlayRisky True placeHolderType }
- | '_casm_GC_' CLITLIT aexps0 { HsCCall $2 $3 PlaySafe True placeHolderType }
+ | '_casm_GC_' CLITLIT aexps0 { HsCCall $2 $3 (PlaySafe False) True placeHolderType }
| scc_annot exp { if opt_SccProfilingOn
then HsSCC $1 $2
else HsPar $2 }
+ | reifyexp { HsReify $1 }
| fexp { $1 }
-scc_annot :: { FAST_STRING }
+scc_annot :: { FastString }
: '_scc_' STRING { $2 }
| '{-# SCC' STRING '#-}' { $2 }
-ccallid :: { FAST_STRING }
+ccallid :: { FastString }
: VARID { $1 }
| CONID { $1 }
: fexp aexp { (HsApp $1 $2) }
| aexp { $1 }
+reifyexp :: { HsReify RdrName }
+ : REIFY_DECL gtycon { Reify ReifyDecl $2 }
+ | REIFY_DECL qvar { Reify ReifyDecl $2 }
+ | REIFY_TYPE qcname { Reify ReifyType $2 }
+ | REIFY_FIXITY qcname { Reify ReifyFixity $2 }
+
aexps0 :: { [RdrNameHsExpr] }
: aexps { reverse $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.
+ | 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) }
| '[:' 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 ID_SPLICE { mkHsSplice (HsVar (mkUnqual varName $2)) $1 } -- $x
+ | srcloc '$(' exp ')' { mkHsSplice $3 $1 } -- $( exp )
+ | srcloc '[|' exp '|]' { HsBracket (ExpBr $3) $1 }
+ | srcloc '[t|' ctype '|]' { HsBracket (TypBr $3) $1 }
+ | srcloc '[p|' infixexp '|]' {% checkPattern $1 $3 `thenP` \p ->
+ returnP (HsBracket (PatBr p) $1) }
+ | srcloc '[d|' cvtopbody '|]' { HsBracket (DecBr (mkGroup $3)) $1 }
+
+cvtopbody :: { [RdrNameHsDecl] }
+ : '{' cvtopdecls '}' { $2 }
+ | layout_on cvtopdecls close { $2 }
texps :: { [RdrNameHsExpr] }
: texps ',' exp { $3 : $1 }
| exp srcloc pquals {% let { body [qs] = qs;
body qss = [ParStmt (map reverse qss)] }
in
- returnP ( HsDo ListComp
- (reverse (ResultStmt $1 $2 : body $3))
- $2
+ returnP ( mkHsDo ListComp
+ (reverse (ResultStmt $1 $2 : body $3))
+ $2
)
}
(map reverse qss)]}
in
returnP $
- HsDo PArrComp
- (reverse (ResultStmt $1 $2
- : body $3))
- $2
+ mkHsDo PArrComp
+ (reverse (ResultStmt $1 $2
+ : body $3))
+ $2
}
-- We are reusing `lexps' and `pquals' from the list case.
: srcloc infixexp '<-' exp {% checkPattern $1 $2 `thenP` \p ->
returnP (BindStmt p $4 $1) }
| srcloc exp { ExprStmt $2 placeHolderType $1 }
- | srcloc 'let' declbinds { LetStmt $3 }
+ | srcloc 'let' binds { LetStmt $3 }
-----------------------------------------------------------------------------
-- Record Field Update/Construction
| fbind { [$1] }
| {- empty -} { [] }
-fbind :: { (RdrName, RdrNameHsExpr, Bool) }
- : qvar '=' exp { ($1,$3,False) }
+fbind :: { (RdrName, RdrNameHsExpr) }
+ : qvar '=' exp { ($1,$3) }
-----------------------------------------------------------------------------
-- Implicit Parameter Bindings
: 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 }
- | '[:' ':]' { parrTyCon_RDR }
- | '(' commas ')' { tupleTyCon_RDR $2 }
-
gcon :: { RdrName } -- Data constructor namespace
- : '(' ')' { unitCon_RDR }
- | '[' ']' { nilCon_RDR }
- | '(' commas ')' { tupleCon_RDR $2 }
+ : sysdcon { $1 }
| qcon { $1 }
-- the case of '[:' ':]' is part of the production `parr'
+sysdcon :: { RdrName } -- Data constructor namespace
+ : '(' ')' { getRdrName unitDataCon }
+ | '(' commas ')' { getRdrName (tupleCon Boxed $2) }
+ | '[' ']' { nameRdrName nilDataConName }
+
var :: { RdrName }
: varid { $1 }
| '(' varsym ')' { $2 }
| '`' qconid '`' { $2 }
-----------------------------------------------------------------------------
+-- Type constructors
+
+gtycon :: { RdrName } -- A "general" qualified tycon
+ : oqtycon { $1 }
+ | '(' ')' { getRdrName unitTyCon }
+ | '(' commas ')' { getRdrName (tupleTyCon Boxed $2) }
+ | '(' '->' ')' { nameRdrName funTyConName }
+ | '[' ']' { nameRdrName listTyConName }
+ | '[:' ':]' { nameRdrName parrTyConName }
+
+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") }
-
------------------------------------------------------------------------------
--- ConIds
-
-qconid :: { RdrName } -- Qualified or unqualifiedb
- : conid { $1 }
- | QCONID { mkQual dataName $1 }
-
-conid :: { RdrName }
- : CONID { mkUnqual dataName $1 }
-
------------------------------------------------------------------------------
--- ConSyms
-
-qconsym :: { RdrName } -- Qualified or unqualifiedb
- : consym { $1 }
- | QCONSYM { mkQual dataName $1 }
-
-consym :: { RdrName }
- : CONSYM { mkUnqual dataName $1 }
+ : 'as' { FSLIT("as") }
+ | 'qualified' { FSLIT("qualified") }
+ | 'hiding' { FSLIT("hiding") }
+ | 'export' { FSLIT("export") }
+ | 'label' { FSLIT("label") }
+ | 'dynamic' { FSLIT("dynamic") }
+ | 'stdcall' { FSLIT("stdcall") }
+ | 'ccall' { FSLIT("ccall") }
-----------------------------------------------------------------------------
--- 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(".") }
- | '*' { 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 }
+ | ':' { nameRdrName consDataConName }
+ -- ':' means only list cons
+
-----------------------------------------------------------------------------
-- Literals
'.':unpackFS (snd $1)))
}
-tycon :: { RdrName }
- : CONID { mkUnqual tcClsName $1 }
-
-tyconop :: { RdrName }
- : CONSYM { mkUnqual tcClsName $1 }
-
-qtycon :: { RdrName } -- Qualified or unqualified
- : QCONID { mkQual tcClsName $1 }
- | tycon { $1 }
-
-qtyconop :: { RdrName } -- Qualified or unqualified
- : QCONSYM { mkQual tcClsName $1 }
- | tyconop { $1 }
-
commas :: { Int }
: commas ',' { $1 + 1 }
| ',' { 2 }