[project @ 2002-02-04 03:40:31 by chak]
[ghc-hetmet.git] / ghc / compiler / parser / Parser.y
index fc7db9e..e3f305f 100644 (file)
@@ -1,6 +1,6 @@
-{-
+{-                                                             -*-haskell-*-
 -----------------------------------------------------------------------------
-$Id: Parser.y,v 1.61 2001/05/08 14:44:37 simonpj Exp $
+$Id: Parser.y,v 1.83 2002/02/04 03:40:32 chak Exp $
 
 Haskell grammar.
 
@@ -9,7 +9,7 @@ Author(s): Simon Marlow, Sven Panne 1997, 1998, 1999
 -}
 
 {
-module Parser ( parseModule, parseStmt ) where
+module Parser ( parseModule, parseStmt, parseIdentifier ) where
 
 import HsSyn
 import HsTypes         ( mkHsTupCon )
@@ -21,16 +21,21 @@ 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(..), 
+                         CCallConv(..), CCallTarget(..), defaultCCallConv,
+                         DNCallSpec(..) )
 import OccName         ( UserFS, varName, tcName, dataName, tcClsName, tvName )
 import SrcLoc          ( SrcLoc )
 import Module
-import CallConv
 import CmdLineOpts     ( opt_SccProfilingOn )
-import BasicTypes      ( Boxity(..), Fixity(..), FixityDirection(..), NewOrData(..) )
+import BasicTypes      ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
+                         NewOrData(..), StrictnessMark(..), Activation(..) )
 import Panic
 
 import GlaExts
-import FastString      ( tailFS )
+import CStrings                ( CLabelString )
+import FastString
+import Maybes          ( orElse )
 import Outputable
 
 #include "HsVersions.h"
@@ -38,8 +43,7 @@ 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'
        (shift parses as 'if x then y else (z + 1)', as per longest-parse rule)
@@ -61,6 +65,9 @@ Conflicts: 14 shift/reduce
        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.
+
 -----------------------------------------------------------------------------
 -}
 
@@ -97,14 +104,16 @@ Conflicts: 14 shift/reduce
  'export'      { ITexport }
  'label'       { ITlabel } 
  'dynamic'     { ITdynamic }
+ 'safe'                { ITsafe }
  'unsafe'      { ITunsafe }
  'with'        { ITwith }
  'stdcall'      { ITstdcallconv }
  'ccall'        { ITccallconv }
- '_ccall_'     { ITccall (False, False, False) }
- '_ccall_GC_'  { ITccall (False, False, True)  }
- '_casm_'      { ITccall (False, True,  False) }
- '_casm_GC_'   { ITccall (False, True,  True)  }
+ '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 }
@@ -140,7 +149,7 @@ Conflicts: 14 shift/reduce
  '__A'         { ITarity }
  '__P'         { ITspecialise }
  '__C'         { ITnocaf }
- '__U'         { ITunfold $$ }
+ '__U'         { ITunfold }
  '__S'         { ITstrict $$ }
  '__M'         { ITcprinfo $$ }
 -}
@@ -183,7 +192,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   $$ }
@@ -201,6 +211,7 @@ Conflicts: 14 shift/reduce
 %lexer { lexer } { ITeof }
 %name parseModule module
 %name parseStmt   maybe_stmt
+%name parseIdentifier  identifier
 %tokentype { Token }
 %%
 
@@ -279,8 +290,8 @@ importdecls :: { [RdrNameImportDecl] }
        | {- empty -}                           { [] }
 
 importdecl :: { RdrNameImportDecl }
-       : 'import' srcloc maybe_src optqualified CONID maybeas maybeimpspec 
-               { ImportDecl (mkModuleNameFS $5) $3 $4 $6 $7 $2 }
+       : 'import' srcloc maybe_src optqualified modid maybeas maybeimpspec 
+               { ImportDecl $5 $3 $4 $6 $7 $2 }
 
 maybe_src :: { WhereFrom }
        : '{-# SOURCE' '#-}'                    { ImportByUserSource }
@@ -335,18 +346,18 @@ topdecl :: { RdrBinding }
                -- 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) ->
+       | srcloc 'data' ctype constrs deriving
+               {% checkDataHeader "data" $3 `thenP` \(cs,c,ts) ->
                   returnP (RdrHsDecl (TyClD
-                     (mkTyData DataType cs c ts (reverse $5) (length $5) $6 $1))) }
+                     (mkTyData DataType cs c ts (reverse $4) (length $4) $5 $1))) }
 
        | srcloc 'newtype' ctype '=' newconstr deriving
-               {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
+               {% checkDataHeader "newtype" $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) ->
+               {% checkDataHeader "class" $3 `thenP` \(cs,c,ts) ->
                   let 
                        (binds,sigs) = cvMonoBindsAndSigs cvClassOpSig (groupBindings $5) 
                   in
@@ -359,24 +370,125 @@ topdecl :: { RdrBinding }
                                (groupBindings $4)
                  in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $1)) }
 
-       | srcloc 'default' '(' types0 ')'
-               { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
-
-       | srcloc 'foreign' 'import' callconv ext_name 
-         unsafe_flag varid_no_unsafe '::' sigtype
-               { RdrHsDecl (ForD (ForeignDecl $7 (FoImport $6) $9 (mkExtName $5 $7) $4 $1)) }
-
-       | srcloc 'foreign' 'export' callconv ext_name varid '::' sigtype
-               { RdrHsDecl (ForD (ForeignDecl $6 FoExport $8 (mkExtName $5 $6) $4 $1)) }
-
-       | srcloc 'foreign' 'label' ext_name varid '::' sigtype
-               { RdrHsDecl (ForD (ForeignDecl $5 FoLabel $7 (mkExtName $4 $5)
-                                       defaultCallConv $1)) }
-
+       | srcloc 'default' '(' types0 ')'               { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
+       | 'foreign' fdecl                               { RdrHsDecl $2 }
        | '{-# DEPRECATED' deprecations '#-}'           { $2 }
        | '{-# RULES' rules '#-}'                       { $2 }
        | decl                                          { $1 }
 
+-- 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 $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 _NIL_ _NIL_ 
+                                  (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 _NIL_ _NIL_ 
+                                  (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 _NIL_ _NIL_ 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 _NIL_ _NIL_ 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_ 
+                                  (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 _NIL_ _NIL_ 
+                                       (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 _NIL_ _NIL_ 
+                                  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 _NIL_ _NIL_ 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
+
 decls  :: { [RdrBinding] }
        : decls ';' decl                { $3 : $1 }
        | decls ';'                     { $1 }
@@ -386,18 +498,14 @@ decls     :: { [RdrBinding] }
 decl   :: { RdrBinding }
        : fixdecl                       { $1 }
        | valdef                        { $1 }
-       | '{-# INLINE'   srcloc opt_phase qvar '#-}'     { RdrSig (InlineSig $4 $3 $2) }
-       | '{-# NOINLINE' srcloc opt_phase qvar '#-}'     { RdrSig (NoInlineSig $4 $3 $2) }
+       | '{-# 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) }
 
-opt_phase :: { Maybe Int }
-          : INTEGER                     { Just (fromInteger $1) }
-          | {- empty -}                 { Nothing }
-
 wherebinds :: { RdrNameHsBinds }
        : where                 { cvBinds cvValSig (groupBindings $1) }
 
@@ -428,8 +536,20 @@ rules      :: { RdrBinding }
        |  {- empty -}                          { RdrNullBind }
 
 rule   :: { RdrBinding }
-       : STRING rule_forall infixexp '=' srcloc exp
-            { RdrHsDecl (RuleD (HsRule $1 [] $2 $3 $6 $5)) }
+       : STRING activation rule_forall infixexp '=' srcloc exp
+            { RdrHsDecl (RuleD (HsRule $1 $2 $3 $4 $7 $6)) }
+
+activation :: { Activation }           -- Omitted means AlwaysActive
+        : {- empty -}                           { AlwaysActive }
+        | explicit_activation                   { $1 }
+
+inverse_activation :: { Activation }   -- Omitted means NeverActive
+        : {- empty -}                           { NeverActive }
+        | explicit_activation                   { $1 }
+
+explicit_activation :: { Activation }  -- In brackets
+        : '[' INTEGER ']'                       { ActiveAfter  (fromInteger $2) }
+        | '[' '~' INTEGER ']'                   { ActiveBefore (fromInteger $3) }
 
 rule_forall :: { [RdrNameRuleBndr] }
        : 'forall' rule_var_list '.'            { $2 }
@@ -459,21 +579,34 @@ deprecation :: { RdrBinding }
                        [ RdrHsDecl (DeprecD (Deprecation n $3 $1)) | n <- $2 ] }
 
 -----------------------------------------------------------------------------
--- Foreign import/export
-
-callconv :: { Int }
-       : 'stdcall'             { stdCallConv }
-       | 'ccall'               { cCallConv }
-       | {- empty -}           { defaultCallConv }
-
-unsafe_flag :: { Bool }
-       : 'unsafe'              { True }
-       | {- empty -}           { False }
-
-ext_name :: { Maybe ExtName }
-       : 'dynamic'             { Just Dynamic }
-       | STRING                { Just (ExtName $1 Nothing)   }
-       | STRING STRING         { Just (ExtName $2 (Just $1)) }
+-- Foreign declarations
+
+callconv :: { CallConv }
+         : 'stdcall'                   { CCall  StdCallConv }
+         | 'ccall'                     { CCall  CCallConv   }
+         | 'dotnet'                    { DNCall             }
+
+safety :: { Safety }
+       : 'unsafe'                      { PlayRisky }
+       | 'safe'                        { PlaySafe  }
+       | {- empty -}                   { PlaySafe  }
+
+safety1 :: { Safety }
+       : 'unsafe'                      { PlayRisky }
+       | 'safe'                        { PlaySafe  }
+         -- 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) }
+         -- 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
        | {- empty -}           { Nothing }
 
 
@@ -505,7 +638,7 @@ 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 }
+       | context '=>' type             { mkHsForAllTy Nothing   $1 $3 }
        -- A type of form (context => type) is an *implicit* HsForAllTy
        | type                          { $1 }
 
@@ -574,17 +707,21 @@ varids0   :: { [RdrName] }
 -- Datatype declarations
 
 newconstr :: { RdrNameConDecl }
-       : srcloc conid atype    { mkConDecl $2 [] [] (VanillaCon [Unbanged $3]) $1 }
-       | srcloc conid '{' var '::' type '}'
-                               { mkConDecl $2 [] [] (RecCon [([$4], Unbanged $6)]) $1 }
+       : srcloc conid atype    { mkConDecl $2 [] [] (VanillaCon [unbangedType $3]) $1 }
+       | srcloc conid '{' var '::' ctype '}'
+                               { mkConDecl $2 [] [] (RecCon [([$4], unbangedType $6)]) $1 }
 
 constrs :: { [RdrNameConDecl] }
-       : constrs '|' constr            { $3 : $1 }
+        : {- empty; a GHC extension -}  { [] }
+        | '=' constrs1                  { $2 }
+
+constrs1 :: { [RdrNameConDecl] }
+       : constrs1 '|' constr           { $3 : $1 }
        | 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 }
 
@@ -593,22 +730,23 @@ forall :: { [RdrNameHsTyVar] }
        | {- empty -}                   { [] }
 
 context :: { RdrNameContext }
-       : btype '=>'                    {% checkContext $1 }
+       : btype                         {% checkContext $1 }
 
 constr_stuff :: { (RdrName, RdrNameConDetails) }
        : btype                         {% mkVanillaCon $1 []               }
-       | btype '!' atype satypes       {% mkVanillaCon $1 (Banged $3 : $4) }
+       | btype '!' atype satypes       {% mkVanillaCon $1 (BangType MarkedUserStrict $3 : $4) }
+       | gtycon '{' '}'                {% mkRecCon $1 [] }
        | gtycon '{' fielddecls '}'     {% mkRecCon $1 $3 }
        | sbtype conop sbtype           { ($2, InfixCon $1 $3) }
 
 satypes        :: { [RdrNameBangType] }
-       : atype satypes                 { Unbanged $1 : $2 }
-       | '!' atype satypes             { Banged   $2 : $3 }
+       : atype satypes                 { unbangedType $1 : $2 }
+       | '!' atype satypes             { BangType MarkedUserStrict $2 : $3 }
        | {- empty -}                   { [] }
 
 sbtype :: { RdrNameBangType }
-       : btype                         { Unbanged $1 }
-       | '!' atype                     { Banged   $2 }
+       : btype                         { unbangedType $1 }
+       | '!' atype                     { BangType MarkedUserStrict $2 }
 
 fielddecls :: { [([RdrName],RdrNameBangType)] }
        : fielddecl ',' fielddecls      { $1 : $3 }
@@ -618,18 +756,14 @@ fielddecl :: { ([RdrName],RdrNameBangType) }
        : sig_vars '::' stype           { (reverse $1, $3) }
 
 stype :: { RdrNameBangType }
-       : ctype                         { Unbanged $1 } 
-       | '!' atype                     { Banged   $2 }
+       : 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
@@ -663,16 +797,15 @@ valdef :: { RdrBinding }
 
 
 rhs    :: { RdrNameGRHSs }
-       : '=' srcloc exp wherebinds     { (GRHSs (unguardedRHS $3 $2) 
-                                                               $4 Nothing)}
-       | gdrhs wherebinds              { GRHSs (reverse $1) $2 Nothing }
+       : '=' srcloc exp wherebinds     { (GRHSs (unguardedRHS $3 $2) $4 placeHolderType)}
+       | gdrhs wherebinds              { GRHSs (reverse $1) $2 placeHolderType }
 
 gdrhs :: { [RdrNameGRHS] }
        : gdrhs gdrh                    { $2 : $1 }
        | gdrh                          { [$1] }
 
 gdrh :: { RdrNameGRHS }
-       : '|' srcloc quals '=' exp      { GRHS (reverse (ExprStmt $5 $2 : $3)) $2 }
+       : '|' srcloc quals '=' exp      { GRHS (reverse (ResultStmt $5 $2 : $3)) $2 }
 
 -----------------------------------------------------------------------------
 -- Expressions
@@ -690,19 +823,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 Nothing))) }
+                                                  EmptyBinds placeHolderType))) }
        | 'let' declbinds '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                  { HsDo DoExpr $3 $1 }
+       | srcloc 'do' stmtlist                  {% checkDo $3  `thenP` \ stmts ->
+                                                  returnP (HsDo DoExpr stmts $1) }
 
-       | '_ccall_'    ccallid aexps0           { HsCCall $2 $3 False False cbot }
-       | '_ccall_GC_' ccallid aexps0           { HsCCall $2 $3 True  False cbot }
-       | '_casm_'     CLITLIT aexps0           { HsCCall $2 $3 False True  cbot }
-       | '_casm_GC_'  CLITLIT aexps0           { HsCCall $2 $3 True  True  cbot }
+       | '_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 }
 
         | scc_annot exp                                { if opt_SccProfilingOn
                                                        then HsSCC $1 $2
@@ -743,8 +877,8 @@ aexp1       :: { RdrNameHsExpr }
        : ipvar                         { HsIPVar $1 }
        | var_or_con                    { $1 }
        | literal                       { HsLit $1 }
-       | INTEGER                       { HsOverLit (HsIntegral   $1) }
-       | RATIONAL                      { HsOverLit (HsFractional $1) }
+       | INTEGER                       { HsOverLit (mkHsIntegral   $1) }
+       | RATIONAL                      { HsOverLit (mkHsFractional $1) }
        | '(' exp ')'                   { HsPar $2 }
        | '(' exp ',' texps ')'         { ExplicitTuple ($2 : reverse $4) Boxed}
        | '(#' texps '#)'               { ExplicitTuple (reverse $2)      Unboxed }
@@ -767,8 +901,8 @@ texps :: { [RdrNameHsExpr] }
 -- avoiding another shift/reduce-conflict.
 
 list :: { RdrNameHsExpr }
-       : exp                           { ExplicitList [$1] }
-       | lexps                         { ExplicitList (reverse $1) }
+       : exp                           { ExplicitList placeHolderType [$1] }
+       | lexps                         { ExplicitList placeHolderType (reverse $1) }
        | exp '..'                      { ArithSeqIn (From $1) }
        | exp ',' exp '..'              { ArithSeqIn (FromThen $1 $3) }
        | exp '..' exp                  { ArithSeqIn (FromTo $1 $3) }
@@ -816,8 +950,8 @@ alts1       :: { [RdrNameMatch] }
 alt    :: { RdrNameMatch }
        : srcloc infixexp opt_sig ralt wherebinds
                                        {% (checkPattern $1 $2 `thenP` \p ->
-                                          returnP (Match [] [p] $3
-                                                    (GRHSs $4 $5 Nothing))  )}
+                                          returnP (Match [p] $3
+                                                    (GRHSs $4 $5 placeHolderType))  )}
 
 ralt :: { [RdrNameGRHS] }
        : '->' srcloc exp               { [GRHS [ResultStmt $3 $2] $2] }
@@ -837,13 +971,22 @@ stmtlist :: { [RdrNameStmt] }
        : '{'                   stmts '}'       { $2 }
        |     layout_on_for_do  stmts close     { $2 }
 
+--     do { ;; s ; s ; ; s ;; }
+-- The last Stmt should be a ResultStmt, but that's hard to enforce
+-- here, because we need too much lookahead if we see do { e ; }
+-- So we use ExprStmts throughout, and switch the last one over
+-- in ParseUtils.checkDo instead
 stmts :: { [RdrNameStmt] }
+       : stmt stmts_help               { $1 : $2 }
+       | ';' stmts                     { $2 }
+       | {- empty -}                   { [] }
+
+stmts_help :: { [RdrNameStmt] }
        : ';' stmts                     { $2 }
-       | stmt ';' stmts                { $1 : $3 }
-       | srcloc exp                    { [ResultStmt $2 $1] }
+       | {- empty -}                   { [] }
 
--- for typing stmts at the GHCi prompt, where the input may consist of
--- just comments.
+-- For typing stmts at the GHCi prompt, where 
+-- the input may consist of just comments.
 maybe_stmt :: { Maybe RdrNameStmt }
        : stmt                          { Just $1 }
        | {- nothing -}                 { Nothing }
@@ -851,7 +994,7 @@ maybe_stmt :: { Maybe RdrNameStmt }
 stmt  :: { RdrNameStmt }
        : srcloc infixexp '<-' exp      {% checkPattern $1 $2 `thenP` \p ->
                                           returnP (BindStmt p $4 $1) }
-       | srcloc exp                    { ExprStmt $2 $1 }
+       | srcloc exp                    { ExprStmt $2 placeHolderType $1 }
        | srcloc 'let' declbinds        { LetStmt $3 }
 
 -----------------------------------------------------------------------------
@@ -869,22 +1012,27 @@ 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 -}                   { [] }
 
-dbind  :: { (RdrName, RdrNameHsExpr) }
+dbind  :: { (IPName RdrName, RdrNameHsExpr) }
 dbind  : ipvar '=' exp                 { ($1, $3) }
 
 -----------------------------------------------------------------------------
 -- Variables, Constructors and Operators.
 
+identifier :: { RdrName }
+       : qvar                          { $1 }
+       | gcon                          { $1 }
+       | qop                           { $1 }
+
 depreclist :: { [RdrName] }
 depreclist : deprec_var                        { [$1] }
           | deprec_var ',' depreclist  { $1 : $3 }
@@ -919,8 +1067,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 }
@@ -1055,7 +1204,7 @@ literal :: { HsLit }
        | PRIMSTRING            { HsStringPrim $1 }
        | PRIMFLOAT             { HsFloatPrim  $1 }
        | PRIMDOUBLE            { HsDoublePrim $1 }
-       | CLITLIT               { HsLitLit     $1 (error "Parser.y: CLITLIT") }
+       | CLITLIT               { HsLitLit     $1 placeHolderType }
 
 srcloc :: { SrcLoc }   :       {% getSrcLocP }
  
@@ -1074,6 +1223,11 @@ layout_on_for_do  :: { () }      : {% layoutOn False }
 
 modid  :: { ModuleName }
        : CONID                 { mkModuleNameFS $1 }
+        | QCONID               { mkModuleNameFS
+                                  (mkFastString
+                                    (unpackFS (fst $1) ++ 
+                                       '.':unpackFS (snd $1)))
+                               }
 
 tycon  :: { RdrName }
        : CONID                 { mkUnqual tcClsName $1 }
@@ -1089,9 +1243,6 @@ qtyconop :: { RdrName }
          : tyconop             { $1 }
          | QCONSYM             { mkQual tcClsName $1 }
 
-qtycls         :: { RdrName }
-       : qtycon                { $1 }
-
 commas :: { Int }
        : commas ','                    { $1 + 1 }
        | ','                           { 2 }