X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Fparser%2FParser.y;h=ea8f6f51d28e54212120a1b812832a25d037cf32;hb=2205f0ceeb65d8acb7db953bf4fd2ad673dc55ee;hp=e57973e14ed982ffb1cd634cc41dbddc05f256d4;hpb=e0f44735eb8fd4d078ffe11f396c3ab47e0b276e;p=ghc-hetmet.git diff --git a/ghc/compiler/parser/Parser.y b/ghc/compiler/parser/Parser.y index e57973e..ea8f6f5 100644 --- a/ghc/compiler/parser/Parser.y +++ b/ghc/compiler/parser/Parser.y @@ -1,6 +1,6 @@ -{- +{- -*-haskell-*- ----------------------------------------------------------------------------- -$Id: Parser.y,v 1.75 2001/10/22 09:37:24 simonpj Exp $ +$Id: Parser.y,v 1.100 2002/06/07 07:16:05 chak Exp $ Haskell grammar. @@ -9,26 +9,29 @@ Author(s): Simon Marlow, Sven Panne 1997, 1998, 1999 -} { -module Parser ( parseModule, parseStmt, parseIdentifier ) where +module Parser ( parseModule, parseStmt, parseIdentifier, parseIface ) where import HsSyn import HsTypes ( mkHsTupCon ) import RdrHsSyn +import RnMonad ( ParsedIface(..) ) import Lex import ParseUtil import RdrName -import PrelNames ( mAIN_Name, unitTyCon_RDR, funTyCon_RDR, listTyCon_RDR, - tupleTyCon_RDR, unitCon_RDR, nilCon_RDR, tupleCon_RDR - ) -import ForeignCall ( Safety(..), CExportSpec(..), CCallSpec(..), +import PrelNames ( mAIN_Name, unitTyCon_RDR, funTyCon_RDR, + listTyCon_RDR, parrTyCon_RDR, tupleTyCon_RDR, + unitCon_RDR, nilCon_RDR, tupleCon_RDR ) +import ForeignCall ( Safety(..), CExportSpec(..), CCallConv(..), CCallTarget(..), defaultCCallConv, - DNCallSpec(..) ) + ) import OccName ( UserFS, varName, tcName, dataName, tcClsName, tvName ) +import TyCon ( DataConDetails(..) ) import SrcLoc ( SrcLoc ) import Module -import CmdLineOpts ( opt_SccProfilingOn ) -import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), +import CmdLineOpts ( opt_SccProfilingOn, opt_InPackage ) +import Type ( Kind, mkArrowKind, liftedTypeKind ) +import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..), NewOrData(..), StrictnessMark(..), Activation(..) ) import Panic @@ -43,18 +46,18 @@ import Outputable {- ----------------------------------------------------------------------------- -Conflicts: 14 shift/reduce - (note: it's currently 21 -- JRL, 31/1/2000) +Conflicts: 21 shift/reduce, -=chak[4Feb2] -8 for abiguity in 'if x then y else z + 1' +11 for abiguity in 'if x then y else z + 1' [State 128] (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' - (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) + 8 because op might be: - ! * . `x` VARSYM CONSYM QVARSYM QCONSYM + +1 for ambiguity in '{-# RULES "name" [ ... #-} [State 210] + 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 = ... #-}' +1 for ambiguity in '{-# RULES "name" forall = ... #-}' [State 412] 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 @@ -62,9 +65,28 @@ Conflicts: 14 shift/reduce 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. +1 for ambiguity in 'let ?x ...' [State 278] + 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. + + +8 for ambiguity in 'e :: a `b` c'. Does this mean [States 238,267] + (e::a) `b` c, or + (e :: (a `b` c)) + +6 for conflicts between `fdecl' and `fdeclDEPRECATED', [States 402,403] + which are resolved correctly, and moreover, + should go away when `fdeclDEPRECATED' is removed. + +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' + (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) + ----------------------------------------------------------------------------- -} @@ -102,15 +124,17 @@ Conflicts: 14 shift/reduce 'export' { ITexport } 'label' { ITlabel } 'dynamic' { ITdynamic } + 'safe' { ITsafe } + 'threadsafe' { ITthreadsafe } 'unsafe' { ITunsafe } 'with' { ITwith } '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 } @@ -163,6 +187,7 @@ Conflicts: 14 shift/reduce '=>' { ITdarrow } '-' { ITminus } '!' { ITbang } + '*' { ITstar } '.' { ITdot } '{' { ITocurly } -- special symbols @@ -172,6 +197,8 @@ Conflicts: 14 shift/reduce vccurly { ITvccurly } -- virtual close curly (from layout) '[' { ITobrack } ']' { ITcbrack } + '[:' { ITopabrack } + ':]' { ITcpabrack } '(' { IToparen } ')' { ITcparen } '(#' { IToubxparen } @@ -189,7 +216,8 @@ Conflicts: 14 shift/reduce QVARSYM { ITqvarsym $$ } QCONSYM { ITqconsym $$ } - IPVARID { ITipvarid $$ } -- GHC extension + IPDUPVARID { ITdupipvarid $$ } -- GHC extension + IPSPLITVARID { ITsplitipvarid $$ } -- GHC extension CHAR { ITchar $$ } STRING { ITstring $$ } @@ -208,6 +236,7 @@ Conflicts: 14 shift/reduce %name parseModule module %name parseStmt maybe_stmt %name parseIdentifier identifier +%name parseIface iface %tokentype { Token } %% @@ -244,6 +273,56 @@ cvtopdecls :: { [RdrNameHsDecl] } : topdecls { cvTopDecls (groupBindings $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_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 } + : srcloc 'data' tycl_hdr constrs + { mkTyData DataType $3 (DataCons (reverse $4)) Nothing $1 } + + | srcloc 'newtype' tycl_hdr '=' newconstr + { mkTyData NewType $3 (DataCons [$5]) Nothing $1 } + + | srcloc 'class' tycl_hdr fds where + { let + (binds,sigs) = cvMonoBindsAndSigs cvClassOpSig + (groupBindings $5) + in + mkClassDecl $3 $4 sigs (Just binds) $1 } + + | srcloc 'type' tycon tv_bndrs '=' ctype + { TySynonym $3 $4 $6 $1 } + + | srcloc var '::' sigtype + { IfaceSig $2 $4 [] $1 } + +----------------------------------------------------------------------------- -- The Export List maybeexports :: { Maybe [RdrNameIE] } @@ -335,30 +414,29 @@ topdecls :: { [RdrBinding] } | topdecl { [$1] } topdecl :: { RdrBinding } - : srcloc 'type' simpletype '=' ctype + : 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)) } + { let (tc,tvs) = $3 + in RdrHsDecl (TyClD (TySynonym tc tvs $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 'data' tycl_hdr constrs deriving + {% returnP (RdrHsDecl (TyClD + (mkTyData DataType $3 (DataCons (reverse $4)) $5 $1))) } - | srcloc 'class' ctype fds where - {% checkDataHeader $3 `thenP` \(cs,c,ts) -> - let + | srcloc 'newtype' tycl_hdr '=' newconstr deriving + {% returnP (RdrHsDecl (TyClD + (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 cs c ts $4 sigs (Just binds) $1))) } + (mkClassDecl $3 $4 sigs (Just binds) $1))) } | srcloc 'instance' inst_type where { let (binds,sigs) @@ -366,45 +444,66 @@ topdecl :: { RdrBinding } (groupBindings $4) in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $1)) } - | srcloc 'default' '(' types0 ')' { RdrHsDecl (DefD (DefaultDecl $4 $1)) } - | 'foreign' fordecl { RdrHsDecl $2 } + | srcloc 'default' '(' comma_types0 ')' { RdrHsDecl (DefD (DefaultDecl $4 $1)) } + | 'foreign' fdecl { 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) } - - - ----------- 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) - } +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 $3 `thenP` \ (tc,tvs) -> + returnP ($1, tc, tvs) } + | type {% checkTyClHdr $1 `thenP` \ (tc,tvs) -> + returnP ([], tc, tvs) } - | srcloc 'import' ccallconv 'dynamic' unsafe_flag varid_no_unsafe '::' sigtype - { let - call_spec = CCallSpec DynamicTarget $3 $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) } +{- + : '(' comma_types1 ')' '=>' gtycon tv_bndrs + {% mapP checkPred $2 `thenP` \ cxt -> + returnP (cxt, $5, $6) } + + | '(' ')' '=>' gtycon tv_bndrs + { ([], $4, $5) } + + -- 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 + +atypes0 :: { [RdrNameHsType] } + : atypes1 { $1 } + | {- empty -} { [] } - | srcloc 'import' 'dotnet' 'type' ext_name tycon - { TyClD (ForeignType $6 $5 DNType $1) } +atypes1 :: { [RdrNameHsType] } + : atype { [$1] } + | atype atypes1 { $1 : $2 } +-} decls :: { [RdrBinding] } : decls ';' decl { $3 : $1 } @@ -437,6 +536,11 @@ decllist :: { [RdrBinding] } : '{' decls '}' { $2 } | layout_on decls close { $2 } +letbinds :: { RdrNameHsExpr -> RdrNameHsExpr } + : decllist { HsLet (cvBinds cvValSig (groupBindings $1)) } + | '{' dbinds '}' { \e -> HsWith e $2 False{-not with-} } + | layout_on dbinds close { \e -> HsWith e $2 False{-not with-} } + fixdecl :: { RdrBinding } : srcloc infix prec ops { foldr1 RdrAndBindings [ RdrSig (FixSig (FixitySig n @@ -454,15 +558,19 @@ rules :: { RdrBinding } rule :: { RdrBinding } : STRING activation rule_forall infixexp '=' srcloc exp - { RdrHsDecl (RuleD (HsRule $1 $2 [] $3 $4 $7 $6)) } + { RdrHsDecl (RuleD (HsRule $1 $2 $3 $4 $7 $6)) } 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 } @@ -491,18 +599,149 @@ deprecation :: { RdrBinding } { foldr RdrAndBindings RdrNullBind [ 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 -> returnP $ + 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 -> returnP $ + 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 -> returnP $ + 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 -> returnP $ + 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 -> returnP $ + 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 varid '::' sigtype { ($1 , $2, $4) } + | varid '::' 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 @@ -525,7 +764,7 @@ sigtypes :: { [RdrNameHsType] } | sigtypes ',' sigtype { $3 : $1 } sigtype :: { RdrNameHsType } - : ctype { (mkHsForAllTy Nothing [] $1) } + : ctype { mkHsForAllTy Nothing [] $1 } sig_vars :: { [RdrName] } : sig_vars ',' var { $3 : $1 } @@ -536,32 +775,40 @@ sig_vars :: { [RdrName] } -- 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 { mkHsForAllTy (Just $2) [] $4 } + | context '=>' type { mkHsForAllTy Nothing $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 (HsTyOp $2) $3 } + | btype '->' gentype { HsOpTy $1 HsArrow $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 (mkHsTupCon tcName Boxed ($2:$4)) ($2:$4) } + | '(#' comma_types1 '#)' { HsTupleTy (mkHsTupCon tcName Unboxed $2) $2 } + | '[' type ']' { HsListTy $2 } + | '[:' type ':]' { HsPArrTy $2 } + | '(' ctype ')' { HsParTy $2 } + | '(' ctype '::' kind ')' { HsKindSig $2 $4 } -- Generics | INTEGER { HsNumTy $1 } @@ -572,20 +819,21 @@ atype :: { RdrNameHsType } 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 ')' { IfaceTyVar $2 $4 } fds :: { [([RdrName], [RdrName])] } : {- empty -} { [] } @@ -603,6 +851,18 @@ varids0 :: { [RdrName] } | varids0 tyvar { $2 : $1 } ----------------------------------------------------------------------------- +-- Kinds + +kind :: { Kind } + : akind { $1 } + | akind '->' kind { mkArrowKind $1 $3 } + +akind :: { Kind } + : '*' { liftedTypeKind } + | '(' kind ')' { $2 } + + +----------------------------------------------------------------------------- -- Datatype declarations newconstr :: { RdrNameConDecl } @@ -619,21 +879,19 @@ constrs1 :: { [RdrNameConDecl] } | constr { [$1] } constr :: { RdrNameConDecl } - : srcloc forall context constr_stuff - { mkConDecl (fst $4) $2 $3 (snd $4) $1 } + : srcloc forall context '=>' constr_stuff + { mkConDecl (fst $5) $2 $3 (snd $5) $1 } | srcloc forall constr_stuff { mkConDecl (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 '{' '}' {% mkRecCon $1 [] } | gtycon '{' fielddecls '}' {% mkRecCon $1 $3 } | sbtype conop sbtype { ($2, InfixCon $1 $3) } @@ -657,15 +915,11 @@ stype :: { RdrNameBangType } : ctype { unbangedType $1 } | '!' atype { BangType MarkedUserStrict $2 } -deriving :: { Maybe [RdrName] } +deriving :: { Maybe RdrNameContext } : {- empty -} { Nothing } - | 'deriving' qtycls { Just [$2] } - | 'deriving' '(' ')' { Just [] } - | 'deriving' '(' dclasses ')' { Just (reverse $3) } - -dclasses :: { [RdrName] } - : dclasses ',' qtycls { $3 : $1 } - | qtycls { [$1] } + | 'deriving' context { Just $2 } + -- Glasgow extension: allow partial + -- applications in derivings ----------------------------------------------------------------------------- -- Value definitions @@ -714,7 +968,7 @@ gdrh :: { RdrNameGRHS } exp :: { RdrNameHsExpr } : infixexp '::' sigtype { (ExprWithTySig $1 $3) } - | infixexp 'with' dbinding { HsWith $1 $3 } + | infixexp 'with' dbinding { HsWith $1 $3 True{-not a let-} } | infixexp { $1 } infixexp :: { RdrNameHsExpr } @@ -725,20 +979,20 @@ infixexp :: { RdrNameHsExpr } exp10 :: { RdrNameHsExpr } : '\\' srcloc aexp aexps opt_asig '->' srcloc exp {% checkPatterns $2 ($3 : reverse $4) `thenP` \ ps -> - returnP (HsLam (Match [] ps $5 + returnP (HsLam (Match ps $5 (GRHSs (unguardedRHS $8 $7) EmptyBinds placeHolderType))) } - | 'let' declbinds 'in' exp { HsLet $2 $4 } + | 'let' letbinds 'in' exp { $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) } | '_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 @@ -746,11 +1000,11 @@ exp10 :: { RdrNameHsExpr } | fexp { $1 } -scc_annot :: { FAST_STRING } +scc_annot :: { FastString } : '_scc_' STRING { $2 } | '{-# SCC' STRING '#-}' { $2 } -ccallid :: { FAST_STRING } +ccallid :: { FastString } : VARID { $1 } | CONID { $1 } @@ -759,23 +1013,29 @@ fexp :: { RdrNameHsExpr } | aexp { $1 } aexps0 :: { [RdrNameHsExpr] } - : aexps { (reverse $1) } + : aexps { reverse $1 } aexps :: { [RdrNameHsExpr] } : aexps aexp { $2 : $1 } | {- empty -} { [] } aexp :: { RdrNameHsExpr } - : var_or_con '{|' gentype '|}' { (HsApp $1 (HsType $3)) } - | aexp '{' fbinds '}' {% (mkRecConstrOrUpdate $1 + : qvar '@' aexp { EAsPat $1 $3 } + | '~' aexp { ELazyPat $2 } + | aexp1 { $1 } + +aexp1 :: { RdrNameHsExpr } + : aexp1 '{' fbinds '}' {% (mkRecConstrOrUpdate $1 (reverse $3)) } - | aexp1 { $1 } + | aexp2 { $1 } + | var_or_con '{|' gentype '|}' { HsApp $1 (HsType $3) } + var_or_con :: { RdrNameHsExpr } : qvar { HsVar $1 } | gcon { HsVar $1 } -aexp1 :: { RdrNameHsExpr } +aexp2 :: { RdrNameHsExpr } : ipvar { HsIPVar $1 } | var_or_con { $1 } | literal { HsLit $1 } @@ -785,11 +1045,10 @@ aexp1 :: { RdrNameHsExpr } | '(' 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 } texps :: { [RdrNameHsExpr] } : texps ',' exp { $3 : $1 } @@ -812,9 +1071,9 @@ list :: { RdrNameHsExpr } | 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 ) } @@ -834,6 +1093,35 @@ quals :: { [RdrNameStmt] } | stmt { [$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 {% let { + body [qs] = qs; + body qss = [ParStmt + (map reverse qss)]} + in + returnP $ + mkHsDo PArrComp + (reverse (ResultStmt $1 $2 + : body $3)) + $2 + } + +-- We are reusing `lexps' and `pquals' from the list case. + +----------------------------------------------------------------------------- -- Case alternatives altslist :: { [RdrNameMatch] } @@ -852,12 +1140,12 @@ alts1 :: { [RdrNameMatch] } alt :: { RdrNameMatch } : srcloc infixexp opt_sig ralt wherebinds {% (checkPattern $1 $2 `thenP` \p -> - returnP (Match [] [p] $3 + returnP (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 } @@ -914,17 +1202,17 @@ fbind :: { (RdrName, RdrNameHsExpr, Bool) } ----------------------------------------------------------------------------- -- Implicit Parameter Bindings -dbinding :: { [(RdrName, RdrNameHsExpr)] } +dbinding :: { [(IPName RdrName, RdrNameHsExpr)] } : '{' dbinds '}' { $2 } | layout_on dbinds close { $2 } -dbinds :: { [(RdrName, RdrNameHsExpr)] } +dbinds :: { [(IPName RdrName, RdrNameHsExpr)] } : dbinds ';' dbind { $3 : $1 } | dbinds ';' { $1 } | dbind { [$1] } - | {- empty -} { [] } +-- | {- empty -} { [] } -dbind :: { (RdrName, RdrNameHsExpr) } +dbind :: { (IPName RdrName, RdrNameHsExpr) } dbind : ipvar '=' exp { ($1, $3) } ----------------------------------------------------------------------------- @@ -949,13 +1237,15 @@ gtycon :: { RdrName } | '(' ')' { unitTyCon_RDR } | '(' '->' ')' { funTyCon_RDR } | '[' ']' { listTyCon_RDR } + | '[:' ':]' { parrTyCon_RDR } | '(' commas ')' { tupleTyCon_RDR $2 } -gcon :: { RdrName } +gcon :: { RdrName } -- Data constructor namespace : '(' ')' { unitCon_RDR } | '[' ']' { nilCon_RDR } | '(' commas ')' { tupleCon_RDR $2 } | qcon { $1 } +-- the case of '[:' ':]' is part of the production `parr' var :: { RdrName } : varid { $1 } @@ -969,8 +1259,9 @@ qvar :: { RdrName } -- whether it's a qvar or a var can be postponed until -- *after* we see the close paren. -ipvar :: { RdrName } - : IPVARID { (mkUnqual varName (tailFS $1)) } +ipvar :: { IPName RdrName } + : IPDUPVARID { Dupable (mkUnqual varName $1) } + | IPSPLITVARID { Linear (mkUnqual varName $1) } qcon :: { RdrName } : qconid { $1 } @@ -997,6 +1288,26 @@ qconop :: { RdrName } | '`' qconid '`' { $2 } ----------------------------------------------------------------------------- +-- Type constructors + +tycon :: { RdrName } -- Unqualified + : CONID { mkUnqual tcClsName $1 } + +tyconop :: { RdrName } -- Unqualified + : CONSYM { mkUnqual tcClsName $1 } + | '`' tyvar '`' { $2 } + | '`' tycon '`' { $2 } + +qtycon :: { RdrName } -- Qualified or unqualified + : QCONID { mkQual tcClsName $1 } + | tycon { $1 } + +qtyconop :: { RdrName } -- Qualified or unqualified + : QCONSYM { mkQual tcClsName $1 } + | '`' QCONID '`' { mkQual tcClsName $2 } + | tyconop { $1 } + +----------------------------------------------------------------------------- -- Any operator op :: { RdrName } -- used in infix decls @@ -1020,54 +1331,38 @@ qvarid :: { RdrName } 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 } - : 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 } + : '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 } @@ -1082,7 +1377,7 @@ qvarsym1 : QVARSYM { mkQual varName $1 } varsym :: { RdrName } : varsym_no_minus { $1 } - | '-' { mkUnqual varName SLIT("-") } + | '-' { mkUnqual varName FSLIT("-") } varsym_no_minus :: { RdrName } -- varsym not including '-' : VARSYM { mkUnqual varName $1 } @@ -1091,8 +1386,27 @@ varsym_no_minus :: { RdrName } -- varsym not including '-' -- 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 } + ----------------------------------------------------------------------------- -- Literals @@ -1130,23 +1444,6 @@ modid :: { ModuleName } '.':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 }