[project @ 2002-02-04 03:40:31 by chak]
[ghc-hetmet.git] / ghc / compiler / parser / Parser.y
index f97ff96..e3f305f 100644 (file)
@@ -1,6 +1,6 @@
-{-
+{-                                                             -*-haskell-*-
 -----------------------------------------------------------------------------
-$Id: Parser.y,v 1.8 1999/06/28 15:42:33 simonmar Exp $
+$Id: Parser.y,v 1.83 2002/02/04 03:40:32 chak Exp $
 
 Haskell grammar.
 
@@ -9,32 +9,41 @@ Author(s): Simon Marlow, Sven Panne 1997, 1998, 1999
 -}
 
 {
-module Parser ( parse ) where
+module Parser ( parseModule, parseStmt, parseIdentifier ) where
 
 import HsSyn
-import HsPragmas
+import HsTypes         ( mkHsTupCon )
 
 import RdrHsSyn
 import Lex
 import ParseUtil
 import RdrName
-import PrelMods                ( mAIN_Name )
-import OccName         ( varName, dataName, tcClsName, tvName )
+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      ( Fixity(..), FixityDirection(..), NewOrData(..) )
+import BasicTypes      ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
+                         NewOrData(..), StrictnessMark(..), Activation(..) )
 import Panic
 
 import GlaExts
+import CStrings                ( CLabelString )
+import FastString
+import Maybes          ( orElse )
+import Outputable
 
 #include "HsVersions.h"
 }
 
 {-
 -----------------------------------------------------------------------------
-Conflicts: 14 shift/reduce
+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)
@@ -56,11 +65,15 @@ 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.
+
 -----------------------------------------------------------------------------
 -}
 
 %token
  '_'            { ITunderscore }               -- Haskell keywords
+ 'as'          { ITas }
  'case'        { ITcase }      
  'class'       { ITclass } 
  'data'        { ITdata } 
@@ -68,6 +81,7 @@ Conflicts: 14 shift/reduce
  'deriving'    { ITderiving }
  'do'          { ITdo }
  'else'        { ITelse }
+ 'hiding'      { IThiding }
  'if'          { ITif }
  'import'      { ITimport }
  'in'          { ITin }
@@ -79,27 +93,35 @@ Conflicts: 14 shift/reduce
  'module'      { ITmodule }
  'newtype'     { ITnewtype }
  'of'          { ITof }
+ 'qualified'   { ITqualified }
  'then'        { ITthen }
  'type'        { ITtype }
  'where'       { ITwhere }
- '_scc_'       { ITscc }
+ '_scc_'       { ITscc }             -- ToDo: remove
 
  'forall'      { ITforall }                    -- GHC extension keywords
  'foreign'     { ITforeign }
  'export'      { ITexport }
  'label'       { ITlabel } 
  'dynamic'     { ITdynamic }
+ 'safe'                { ITsafe }
  'unsafe'      { ITunsafe }
- '_ccall_'     { ITccall (False, False, False) }
- '_ccall_GC_'  { ITccall (False, False, True)  }
- '_casm_'      { ITccall (False, True,  False) }
- '_casm_GC_'   { ITccall (False, True,  True)  }
+ 'with'        { ITwith }
+ 'stdcall'      { ITstdcallconv }
+ 'ccall'        { ITccallconv }
+ 'dotnet'       { ITdotnet }
+ '_ccall_'     { ITccall (False, False, PlayRisky) }
+ '_ccall_GC_'  { ITccall (False, False, PlaySafe)  }
+ '_casm_'      { ITccall (False, True,  PlayRisky) }
+ '_casm_GC_'   { ITccall (False, True,  PlaySafe)  }
 
  '{-# SPECIALISE'  { ITspecialise_prag }
  '{-# SOURCE'     { ITsource_prag }
  '{-# INLINE'      { ITinline_prag }
  '{-# NOINLINE'    { ITnoinline_prag }
  '{-# RULES'      { ITrules_prag }
+ '{-# SCC'        { ITscc_prag }
+ '{-# DEPRECATED'  { ITdeprecated_prag }
  '#-}'            { ITclose_prag }
 
 {-
@@ -117,6 +139,7 @@ Conflicts: 14 shift/reduce
  '__float'     { ITfloat_lit }
  '__rational'  { ITrational_lit }
  '__addr'      { ITaddr_lit }
+ '__label'     { ITlabel_lit }
  '__litlit'    { ITlit_lit }
  '__string'    { ITstring_lit }
  '__ccall'     { ITccall $$ }
@@ -126,7 +149,7 @@ Conflicts: 14 shift/reduce
  '__A'         { ITarity }
  '__P'         { ITspecialise }
  '__C'         { ITnocaf }
- '__U'         { ITunfold $$ }
+ '__U'         { ITunfold }
  '__S'         { ITstrict $$ }
  '__M'         { ITcprinfo $$ }
 -}
@@ -145,10 +168,10 @@ Conflicts: 14 shift/reduce
  '!'           { ITbang }
  '.'           { ITdot }
 
- '/\\'         { ITbiglam }                    -- GHC-extension symbols
-
  '{'           { ITocurly }                    -- special symbols
  '}'           { ITccurly }
+ '{|'           { ITocurlybar }
+ '|}'           { ITccurlybar }
  vccurly       { ITvccurly } -- virtual close curly (from layout)
  '['           { ITobrack }
  ']'           { ITcbrack }
@@ -169,7 +192,8 @@ Conflicts: 14 shift/reduce
  QVARSYM       { ITqvarsym  $$ }
  QCONSYM       { ITqconsym  $$ }
 
- PRAGMA                { ITpragma   $$ }
+ IPDUPVARID    { ITdupipvarid   $$ }           -- GHC extension
+ IPSPLITVARID          { ITsplitipvarid $$ }           -- GHC extension
 
  CHAR          { ITchar     $$ }
  STRING                { ITstring   $$ }
@@ -180,33 +204,44 @@ Conflicts: 14 shift/reduce
  PRIMSTRING    { ITprimstring $$ }
  PRIMINTEGER   { ITprimint    $$ }
  PRIMFLOAT     { ITprimfloat  $$ }
- PRIMDOUBLE    { ITprimdouble  $$ }
+ PRIMDOUBLE    { ITprimdouble $$ }
  CLITLIT       { ITlitlit     $$ }
 
- UNKNOWN       { ITunknown  $$ }
-
 %monad { P } { thenP } { returnP }
 %lexer { lexer } { ITeof }
-%name parse
+%name parseModule module
+%name parseStmt   maybe_stmt
+%name parseIdentifier  identifier
 %tokentype { Token }
 %%
 
 -----------------------------------------------------------------------------
 -- Module Header
 
+-- The place for module deprecation is really too restrictive, but if it
+-- was allowed at its natural place just before 'module', we get an ugly
+-- s/r conflict with the second alternative. Another solution would be the
+-- introduction of a new pragma DEPRECATED_MODULE, but this is not very nice,
+-- either, and DEPRECATED is only expected to be used by people who really
+-- know what they are doing. :-)
+
 module         :: { RdrNameHsModule }
-       : srcloc 'module' modid maybeexports 'where' body 
-               { HsModule $3 Nothing $4 (fst $6) (snd $6) $1 }
-       | srcloc body   
-               { HsModule mAIN_Name Nothing Nothing (fst $2) (snd $2) $1 }
+       : srcloc 'module' modid maybemoddeprec maybeexports 'where' body 
+               { HsModule $3 Nothing $5 (fst $7) (snd $7) $4 $1 }
+       | srcloc body
+               { HsModule mAIN_Name Nothing Nothing (fst $2) (snd $2) Nothing $1 }
+
+maybemoddeprec :: { Maybe DeprecTxt }
+       : '{-# DEPRECATED' STRING '#-}'         { Just $2 }
+       |  {- empty -}                          { Nothing }
 
 body   :: { ([RdrNameImportDecl], [RdrNameHsDecl]) }
        :  '{'            top '}'               { $2 }
        |      layout_on  top close             { $2 }
 
 top    :: { ([RdrNameImportDecl], [RdrNameHsDecl]) }
-       : importdecls ';' cvtopdecls            { (reverse $1,$3) }
-       | importdecls                           { (reverse $1,[]) }
+       : importdecls                           { (reverse $1,[]) }
+       | importdecls ';' cvtopdecls            { (reverse $1,$3) }
        | cvtopdecls                            { ([],$1) }
 
 cvtopdecls :: { [RdrNameHsDecl] }
@@ -255,8 +290,8 @@ importdecls :: { [RdrNameImportDecl] }
        | {- empty -}                           { [] }
 
 importdecl :: { RdrNameImportDecl }
-       : 'import' srcloc maybe_src optqualified CONID maybeas maybeimpspec 
-               { ImportDecl (mkSrcModuleFS $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 }
@@ -304,53 +339,155 @@ topdecls :: { [RdrBinding] }
        | topdecl                       { [$1] }
 
 topdecl :: { RdrBinding }
-       : srcloc 'type' simpletype '=' type     
+       : srcloc 'type' simpletype '=' ctype    
+               -- Note ctype, not sigtype.
+               -- We allow an explicit for-all but we don't insert one
+               -- in   type Foo a = (b,b)
+               -- Instead we just say b is out of scope
                { RdrHsDecl (TyClD (TySynonym (fst $3) (snd $3) $5 $1)) }
 
-       | srcloc 'data' ctype '=' constrs deriving
-               {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
+       | srcloc 'data' ctype constrs deriving
+               {% checkDataHeader "data" $3 `thenP` \(cs,c,ts) ->
                   returnP (RdrHsDecl (TyClD
-                     (TyData DataType cs c ts (reverse $5) $6
-                       NoDataPragmas $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
-                     (TyData NewType cs c ts [$5] $6
-                       NoDataPragmas $1))) }
-
-       | srcloc 'class' ctype where
-               {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
-                  let (binds,sigs) 
-                          = cvMonoBindsAndSigs cvClassOpSig 
-                               (groupBindings $4) 
+                     (mkTyData NewType cs c ts [$5] 1 $6 $1))) }
+
+       | srcloc 'class' ctype fds where
+               {% checkDataHeader "class" $3 `thenP` \(cs,c,ts) ->
+                  let 
+                       (binds,sigs) = cvMonoBindsAndSigs cvClassOpSig (groupBindings $5) 
                   in
                   returnP (RdrHsDecl (TyClD
-                     (mkClassDecl cs c ts sigs binds 
-                       NoClassPragmas $1))) }
+                     (mkClassDecl cs c ts $4 sigs (Just binds) $1))) }
 
        | srcloc 'instance' inst_type where
                { let (binds,sigs) 
                        = cvMonoBindsAndSigs cvInstDeclSig 
                                (groupBindings $4)
-                 in RdrHsDecl (InstD
-                               (InstDecl $3 binds sigs dummyRdrVarName $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 $5 $4 $1)) }
-
-       | srcloc 'foreign' 'export' callconv ext_name varid '::' sigtype
-               { RdrHsDecl (ForD (ForeignDecl $6 FoExport $8 $5 $4 $1)) }
-
-       | srcloc 'foreign' 'label' ext_name varid '::' sigtype
-               { RdrHsDecl (ForD (ForeignDecl $5 FoLabel $7 $4 
-                                       defaultCallConv $1)) }
-
-       | decl          { $1 }
+                 in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $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 }
@@ -359,21 +496,15 @@ decls     :: { [RdrBinding] }
        | {- empty -}                   { [] }
 
 decl   :: { RdrBinding }
-       : signdecl                      { $1 }
-       | fixdecl                       { $1 }
-       | valdef                        { RdrValBinding $1 }
-       | '{-# INLINE'   srcloc qvar '#-}'      { RdrSig (InlineSig $3 $2) }
-       | '{-# NOINLINE' srcloc qvar '#-}'      { RdrSig (NoInlineSig $3 $2) }
+       : 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) }
-       | '{-# RULES' rules '#-}'       { $2 }
-
-sigtypes :: { [RdrNameHsType] }
-       : sigtype                       { [ $1 ] }
-       | sigtypes ',' sigtype          { $3 : $1 }
 
 wherebinds :: { RdrNameHsBinds }
        : where                 { cvBinds cvValSig (groupBindings $1) }
@@ -395,32 +526,6 @@ fixdecl :: { RdrBinding }
                                                            (Fixity $3 $2) $1))
                                            | n <- $4 ] }
 
-signdecl :: { RdrBinding }
-       : vars srcloc '::' sigtype      { foldr1 RdrAndBindings 
-                                             [ RdrSig (Sig n $4 $2) | n <- $1 ] }
-
-sigtype :: { RdrNameHsType }
-       : ctype                 { case $1 of
-                                   HsForAllTy _ _ _ -> $1
-                                   other            -> HsForAllTy Nothing [] $1 }
-
-{-
-  ATTENTION: Dirty Hackery Ahead! If the second alternative of vars is var
-  instead of qvar, we get another shift/reduce-conflict. Consider the
-  following programs:
-  
-     { (+) :: ... }          only var
-     { (+) x y  = ... }      could (incorrectly) be qvar
-  
-  We re-use expressions for patterns, so a qvar would be allowed in patterns
-  instead of a var only (which would be correct). But deciding what the + is,
-  would require more lookahead. So let's check for ourselves...
--}
-
-vars   :: { [RdrName] }
-       : vars ',' var                  { $3 : $1 }
-       | qvar                          { [ $1 ] }
-
 -----------------------------------------------------------------------------
 -- Transformation Rules
 
@@ -431,8 +536,20 @@ rules      :: { RdrBinding }
        |  {- empty -}                          { RdrNullBind }
 
 rule   :: { RdrBinding }
-       : STRING rule_forall fexp '=' srcloc exp
-            { RdrHsDecl (RuleD (RuleDecl $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 }
@@ -440,55 +557,114 @@ rule_forall :: { [RdrNameRuleBndr] }
 
 rule_var_list :: { [RdrNameRuleBndr] }
         : rule_var                             { [$1] }
-        | rule_var ',' rule_var_list           { $1 : $3 }
+        | rule_var rule_var_list               { $1 : $2 }
 
 rule_var :: { RdrNameRuleBndr }
        : varid                                 { RuleBndr $1 }
-               | varid '::' ctype                      { RuleBndrSig $1 $3 }
+               | '(' varid '::' ctype ')'              { RuleBndrSig $2 $4 }
+
+-----------------------------------------------------------------------------
+-- Deprecations
+
+deprecations :: { RdrBinding }
+       : deprecations ';' deprecation          { $1 `RdrAndBindings` $3 }
+       | deprecations ';'                      { $1 }
+       | deprecation                           { $1 }
+       | {- empty -}                           { RdrNullBind }
+
+-- SUP: TEMPORARY HACK, not checking for `module Foo'
+deprecation :: { RdrBinding }
+       : srcloc depreclist STRING
+               { foldr RdrAndBindings RdrNullBind 
+                       [ RdrHsDecl (DeprecD (Deprecation n $3 $1)) | n <- $2 ] }
+
+-----------------------------------------------------------------------------
+-- 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 }
+
 
 -----------------------------------------------------------------------------
--- Foreign import/export
+-- Type signatures
 
-callconv :: { Int }
-       : VARID                 {% checkCallConv $1 }
-       | {- empty -}           { defaultCallConv }
+opt_sig :: { Maybe RdrNameHsType }
+       : {- empty -}                   { Nothing }
+       | '::' sigtype                  { Just $2 }
 
-unsafe_flag :: { Bool }
-       : 'unsafe'              { True }
-       | {- empty -}           { False }
+opt_asig :: { Maybe RdrNameHsType }
+       : {- empty -}                   { Nothing }
+       | '::' atype                    { Just $2 }
 
-ext_name :: { ExtName }
-       : 'dynamic'             { Dynamic }
-       | STRING                { ExtName $1 Nothing }
-       | STRING STRING         { ExtName $2 (Just $1) }
+sigtypes :: { [RdrNameHsType] }
+       : sigtype                       { [ $1 ] }
+       | sigtypes ',' sigtype          { $3 : $1 }
+
+sigtype :: { RdrNameHsType }
+       : ctype                         { (mkHsForAllTy Nothing [] $1) }
+
+sig_vars :: { [RdrName] }
+        : sig_vars ',' var             { $3 : $1 }
+        | var                          { [ $1 ] }
 
 -----------------------------------------------------------------------------
 -- Types
 
-{- ToDo: forall stuff -}
+-- A ctype is a for-all type
+ctype  :: { RdrNameHsType }
+       : 'forall' tyvars '.' ctype     { mkHsForAllTy (Just $2) [] $4 }
+       | context '=>' type             { mkHsForAllTy Nothing   $1 $3 }
+       -- A type of form (context => type) is an *implicit* HsForAllTy
+       | type                          { $1 }
 
 type :: { RdrNameHsType }
-       : btype '->' type               { MonoFunTy $1 $3 }
-       | btype                         { $1 }
+       : gentype '->' type             { HsFunTy $1 $3 }
+       | ipvar '::' type               { mkHsIParamTy $1 $3 }
+       | gentype                       { $1 }
+
+gentype :: { RdrNameHsType }
+        : btype                         { $1 }
+-- Generics
+        | atype tyconop atype           { HsOpTy $1 $2 $3 }
 
 btype :: { RdrNameHsType }
-       : btype atype                   { MonoTyApp $1 $2 }
+       : btype atype                   { (HsAppTy $1 $2) }
        | atype                         { $1 }
 
 atype :: { RdrNameHsType }
-       : gtycon                        { MonoTyVar $1 }
-       | tyvar                         { MonoTyVar $1 }
-       | '(' type ',' types ')'        { MonoTupleTy ($2 : reverse $4) True }
-       | '(#' types '#)'               { MonoTupleTy (reverse $2) False }
-       | '[' type ']'                  { MonoListTy $2 }
-       | '(' ctype ')'                 { $2 }
-
-gtycon         :: { RdrName }
-       : qtycon                        { $1 }
-       | '(' ')'                       { unitTyCon_RDR }
-       | '(' '->' ')'                  { funTyCon_RDR }
-       | '[' ']'                       { listTyCon_RDR }
-       | '(' commas ')'                { tupleTyCon_RDR $2 }
+       : 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 }
+-- Generics
+        | INTEGER                       { HsNumTy $1 }
 
 -- An inst_type is what occurs in the head of an instance decl
 --     e.g.  (Foo a, Gaz b) => Wibble a b
@@ -497,15 +673,8 @@ gtycon     :: { RdrName }
 inst_type :: { RdrNameHsType }
        : ctype                         {% checkInstType $1 }
 
-ctype  :: { RdrNameHsType }
-       : 'forall' tyvars '.' context type
-                                       { HsForAllTy (Just $2) $4 $5 }
-       | 'forall' tyvars '.' type      { HsForAllTy (Just $2) [] $4 }
-       | context type                  { HsForAllTy Nothing   $1 $2 }
-       | type                          { $1 }
-
 types0  :: { [RdrNameHsType] }
-       : types                         { $1 }
+       : types                         { reverse $1 }
        | {- empty -}                   { [] }
 
 types  :: { [RdrNameHsType] }
@@ -519,168 +688,212 @@ tyvars :: { [RdrNameHsTyVar] }
        : tyvars tyvar                  { UserTyVar $2 : $1 }
        | {- empty -}                   { [] }
 
+fds :: { [([RdrName], [RdrName])] }
+       : {- empty -}                   { [] }
+       | '|' fds1                      { reverse $2 }
+
+fds1 :: { [([RdrName], [RdrName])] }
+       : fds1 ',' fd                   { $3 : $1 }
+       | fd                            { [$1] }
+
+fd :: { ([RdrName], [RdrName]) }
+       : varids0 '->' varids0          { (reverse $1, reverse $3) }
+
+varids0        :: { [RdrName] }
+       : {- empty -}                   { [] }
+       | varids0 tyvar                 { $2 : $1 }
+
 -----------------------------------------------------------------------------
 -- Datatype declarations
 
+newconstr :: { RdrNameConDecl }
+       : 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
-               { ConDecl (fst $4) $2 $3 (snd $4) $1 }
+       : srcloc forall context '=>' constr_stuff
+               { mkConDecl (fst $5) $2 $3 (snd $5) $1 }
        | srcloc forall constr_stuff
-               { ConDecl (fst $3) $2 [] (snd $3) $1 }
+               { mkConDecl (fst $3) $2 [] (snd $3) $1 }
 
 forall :: { [RdrNameHsTyVar] }
        : 'forall' tyvars '.'           { $2 }
        | {- empty -}                   { [] }
 
 context :: { RdrNameContext }
-       : btype '=>'                    {% checkContext $1 }
+       : btype                         {% checkContext $1 }
 
 constr_stuff :: { (RdrName, RdrNameConDetails) }
-       : scontype                      { (fst $1, VanillaCon (snd $1)) }
+       : 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) }
-       | con '{' fielddecls '}'        { ($1, RecCon (reverse $3)) }
-
-newconstr :: { RdrNameConDecl }
-       : srcloc conid atype    { ConDecl $2 [] [] (NewCon $3 Nothing) $1 }
-       | srcloc conid '{' var '::' type '}'
-                               { ConDecl $2 [] [] (NewCon $6 (Just $4)) $1 }
-
-scontype :: { (RdrName, [RdrNameBangType]) }
-       : btype                         {% splitForConApp $1 [] }
-       | scontype1                     { $1 }
-
-scontype1 :: { (RdrName, [RdrNameBangType]) }
-       : btype '!' atype               {% splitForConApp $1 [Banged $3] }
-       | scontype1 satype              { (fst $1, snd $1 ++ [$2] ) }
 
-satype :: { RdrNameBangType }
-       : atype                         { Unbanged $1 }
-       | '!' atype                     { Banged   $2 }
+satypes        :: { [RdrNameBangType] }
+       : 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)] }
-       : fielddecls ',' fielddecl      { $3 : $1 }
+       : fielddecl ',' fielddecls      { $1 : $3 }
        | fielddecl                     { [$1] }
 
 fielddecl :: { ([RdrName],RdrNameBangType) }
-       : vars '::' stype               { (reverse $1, $3) }
+       : sig_vars '::' stype           { (reverse $1, $3) }
 
 stype :: { RdrNameBangType }
-       : type                          { 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
 
-valdef :: { RdrNameMonoBinds }
-       : infixexp {-ToDo: opt_sig-} srcloc rhs 
-                                       {% checkValDef $1 Nothing $3 $2 }
+{- There's an awkward overlap with a type signature.  Consider
+       f :: Int -> Int = ...rhs...
+   Then we can't tell whether it's a type signature or a value
+   definition with a result signature until we see the '='.
+   So we have to inline enough to postpone reductions until we know.
+-}
+
+{-
+  ATTENTION: Dirty Hackery Ahead! If the second alternative of vars is var
+  instead of qvar, we get another shift/reduce-conflict. Consider the
+  following programs:
+  
+     { (^^) :: Int->Int ; }          Type signature; only var allowed
+
+     { (^^) :: Int->Int = ... ; }    Value defn with result signature;
+                                    qvar allowed (because of instance decls)
+  
+  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 ]
+                                                }
+
 
 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
 
 exp   :: { RdrNameHsExpr }
-       : infixexp '::' sigtype         { ExprWithTySig $1 $3 }
+       : infixexp '::' sigtype         { (ExprWithTySig $1 $3) }
+       | infixexp 'with' dbinding      { HsWith $1 $3 }
        | infixexp                      { $1 }
 
 infixexp :: { RdrNameHsExpr }
        : exp10                         { $1 }
-       | infixexp qop exp10            { OpApp $1 $2 (panic "fixity") $3 }
+       | infixexp qop exp10            { (OpApp $1 (HsVar $2) 
+                                               (panic "fixity") $3 )}
 
 exp10 :: { RdrNameHsExpr }
-       : '\\' aexp aexps opt_asig '->' srcloc exp      
-                       {% checkPatterns ($2 : reverse $3) `thenP` \ ps -> 
-                          returnP (HsLam (Match [] ps $4 
-                                           (GRHSs (unguardedRHS $7 $6) 
-                                                  EmptyBinds Nothing))) }
+       : '\\' srcloc aexp aexps opt_asig '->' srcloc exp       
+                       {% checkPatterns $2 ($3 : reverse $4) `thenP` \ ps -> 
+                          returnP (HsLam (Match ps $5 
+                                           (GRHSs (unguardedRHS $8 $7) 
+                                                  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                              { NegApp $2 (error "NegApp") }
-       | srcloc 'do' stmtlist                  { HsDo DoStmt $3 $1 }
+       | '-' fexp                              { mkHsNegApp $2 }
+       | srcloc 'do' stmtlist                  {% checkDo $3  `thenP` \ stmts ->
+                                                  returnP (HsDo DoExpr stmts $1) }
 
-       | '_ccall_'    ccallid aexps0           { CCall $2 $3 False False cbot }
-       | '_ccall_GC_' ccallid aexps0           { CCall $2 $3 True  False cbot }
-       | '_casm_'     CLITLIT aexps0           { CCall $2 $3 False True  cbot }
-       | '_casm_GC_'  CLITLIT aexps0           { CCall $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_' STRING exp                   { if opt_SccProfilingOn
-                                                       then HsSCC $2 $3
-                                                       else HsPar $3 }
+        | scc_annot exp                                { if opt_SccProfilingOn
+                                                       then HsSCC $1 $2
+                                                       else HsPar $2 }
 
        | fexp                                  { $1 }
 
+scc_annot :: { FAST_STRING }
+       : '_scc_' STRING                        { $2 }
+       | '{-# SCC' STRING '#-}'                { $2 }
+
 ccallid :: { FAST_STRING }
        :  VARID                                { $1 }
        |  CONID                                { $1 }
 
 fexp   :: { RdrNameHsExpr }
-       : fexp aexp                             { HsApp $1 $2 }
+       : fexp aexp                             { (HsApp $1 $2) }
        | aexp                                  { $1 }
 
 aexps0         :: { [RdrNameHsExpr] }
-       : aexps                                 { reverse $1 }
+       : aexps                                 { (reverse $1) }
 
 aexps  :: { [RdrNameHsExpr] }
        : aexps aexp                            { $2 : $1 }
        | {- empty -}                           { [] }
 
 aexp   :: { RdrNameHsExpr }
-       : aexp '{' fbinds '}'           {% mkRecConstrOrUpdate $1 (reverse $3) }
-       | aexp1                         { $1 }
+        : 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 }
 
 aexp1  :: { RdrNameHsExpr }
-       : qvar                          { HsVar $1 }
-       | gcon                          { HsVar $1 }
-       | literal                       { HsLit $1 }
+       : ipvar                         { HsIPVar $1 }
+       | var_or_con                    { $1 }
+       | literal                       { HsLit $1 }
+       | INTEGER                       { HsOverLit (mkHsIntegral   $1) }
+       | RATIONAL                      { HsOverLit (mkHsFractional $1) }
        | '(' exp ')'                   { HsPar $2 }
-       | '(' exp ',' texps ')'         { ExplicitTuple ($2 : reverse $4) True }
-       | '(#' texps '#)'               { ExplicitTuple (reverse $2) False }
+       | '(' exp ',' texps ')'         { ExplicitTuple ($2 : reverse $4) Boxed}
+       | '(#' texps '#)'               { ExplicitTuple (reverse $2)      Unboxed }
        | '[' list ']'                  { $2 }
-       | '(' infixexp qop ')'          { SectionL $2 $3  }
-       | '(' qopm infixexp ')'         { SectionR $2 $3 }
+       | '(' infixexp qop ')'          { (SectionL $2 (HsVar $3))  }
+       | '(' qopm infixexp ')'         { (SectionR $2 $3) }
        | qvar '@' aexp                 { EAsPat $1 $3 }
        | '_'                           { EWildPat }
        | '~' aexp1                     { ELazyPat $2 }
 
-commas :: { Int }
-       : commas ','                    { $1 + 1 }
-       | ','                           { 2 }
-
 texps :: { [RdrNameHsExpr] }
        : texps ',' exp                 { $3 : $1 }
        | exp                           { [$1] }
 
+
 -----------------------------------------------------------------------------
 -- List expressions
 
@@ -688,14 +901,20 @@ 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) }
        | exp ',' exp '..' exp          { ArithSeqIn (FromThenTo $1 $3 $5) }
-       | exp srcloc '|' quals                  { HsDo ListComp (reverse 
-                                               (ReturnStmt $1 : $4)) $2 }
+       | exp srcloc pquals             {% let { body [qs] = qs;
+                                                body  qss = [ParStmt (map reverse qss)] }
+                                          in
+                                          returnP ( HsDo ListComp
+                                                          (reverse (ResultStmt $1 $2 : body $3))
+                                                          $2
+                                                 )
+                                       }
 
 lexps :: { [RdrNameHsExpr] }
        : lexps ',' exp                 { $3 : $1 }
@@ -704,15 +923,13 @@ lexps :: { [RdrNameHsExpr] }
 -----------------------------------------------------------------------------
 -- List Comprehensions
 
-quals :: { [RdrNameStmt] }
-       : quals ',' qual                { $3 : $1 }
-       | qual                          { [$1] }
+pquals :: { [[RdrNameStmt]] }
+       : pquals '|' quals              { $3 : $1 }
+       | '|' quals                     { [$2] }
 
-qual  :: { RdrNameStmt }
-       : srcloc infixexp '<-' exp      {% checkPattern $2 `thenP` \p ->
-                                          returnP (BindStmt p $4 $1) }
-       | srcloc exp                    { GuardStmt $2 $1 }
-       | srcloc 'let' declbinds        { LetStmt $3 }
+quals :: { [RdrNameStmt] }
+       : quals ',' stmt                { $3 : $1 }
+       | stmt                          { [$1] }
 
 -----------------------------------------------------------------------------
 -- Case alternatives
@@ -721,29 +938,23 @@ altslist :: { [RdrNameMatch] }
        : '{'            alts '}'       { reverse $2 }
        |     layout_on  alts  close    { reverse $2 }
 
+alts    :: { [RdrNameMatch] }
+        : alts1                                { $1 }
+       | ';' alts                      { $2 }
 
-alts   :: { [RdrNameMatch] }
-       : alts ';' alt                  { $3 : $1 }
-       | alts ';'                      { $1 }
+alts1  :: { [RdrNameMatch] }
+       : alts1 ';' alt                 { $3 : $1 }
+       | alts1 ';'                     { $1 }
        | alt                           { [$1] }
-       | {- empty -}                   { [] }
 
 alt    :: { RdrNameMatch }
-       : infixexp opt_sig ralt wherebinds
-                                       {% checkPattern $1 `thenP` \p ->
-                                          returnP (Match [] [p] $2
-                                                    (GRHSs $3 $4 Nothing)) }
-
-opt_sig :: { Maybe RdrNameHsType }
-       : {- empty -}                   { Nothing }
-       | '::' type                     { Just $2 }
-
-opt_asig :: { Maybe RdrNameHsType }
-       : {- empty -}                   { Nothing }
-       | '::' atype                    { Just $2 }
+       : srcloc infixexp opt_sig ralt wherebinds
+                                       {% (checkPattern $1 $2 `thenP` \p ->
+                                          returnP (Match [p] $3
+                                                    (GRHSs $4 $5 placeHolderType))  )}
 
 ralt :: { [RdrNameGRHS] }
-       : '->' srcloc exp               { [GRHS [ExprStmt $3 $2] $2] }
+       : '->' srcloc exp               { [GRHS [ResultStmt $3 $2] $2] }
        | gdpats                        { (reverse $1) }
 
 gdpats :: { [RdrNameGRHS] }
@@ -751,28 +962,39 @@ gdpats :: { [RdrNameGRHS] }
        | gdpat                         { [$1] }
 
 gdpat  :: { RdrNameGRHS }
-       : srcloc '|' quals '->' exp     { GRHS (reverse (ExprStmt $5 $1:$3)) $1}
+       : srcloc '|' quals '->' exp     { GRHS (reverse (ResultStmt $5 $1:$3)) $1}
 
 -----------------------------------------------------------------------------
 -- Statement sequences
 
 stmtlist :: { [RdrNameStmt] }
-       : '{'            stmts '}'      { reverse $2 }
-       |     layout_on  stmts close    { reverse $2 }
-
+       : '{'                   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] }
-       : ';' stmts1                    { $2 }
-       | stmts1                        { $1 }
+       : stmt stmts_help               { $1 : $2 }
+       | ';' stmts                     { $2 }
+       | {- empty -}                   { [] }
+
+stmts_help :: { [RdrNameStmt] }
+       : ';' stmts                     { $2 }
+       | {- empty -}                   { [] }
 
-stmts1 :: { [RdrNameStmt] }
-       : stmts1 ';' stmt               { $3 : $1 }
-       | stmts1 ';'                    { $1 }
-       | stmt                          { [$1] }
+-- For typing stmts at the GHCi prompt, where 
+-- the input may consist of just comments.
+maybe_stmt :: { Maybe RdrNameStmt }
+       : stmt                          { Just $1 }
+       | {- nothing -}                 { Nothing }
 
 stmt  :: { RdrNameStmt }
-       : srcloc infixexp '<-' exp      {% checkPattern $2 `thenP` \p ->
+       : 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 }
 
 -----------------------------------------------------------------------------
@@ -788,8 +1010,45 @@ fbind     :: { (RdrName, RdrNameHsExpr, Bool) }
        : qvar '=' exp                  { ($1,$3,False) }
 
 -----------------------------------------------------------------------------
+-- Implicit Parameter Bindings
+
+dbinding :: { [(IPName RdrName, RdrNameHsExpr)] }
+       : '{' dbinds '}'                { $2 }
+       | layout_on dbinds close        { $2 }
+
+dbinds         :: { [(IPName RdrName, RdrNameHsExpr)] }
+       : dbinds ';' dbind              { $3 : $1 }
+       | dbinds ';'                    { $1 }
+       | dbind                         { [$1] }
+       | {- empty -}                   { [] }
+
+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 }
+
+deprec_var :: { RdrName }
+deprec_var : var                       { $1 }
+          | tycon                      { $1 }
+
+gtycon         :: { RdrName }
+       : qtycon                        { $1 }
+       | '(' qtyconop ')'              { $2 }
+       | '(' ')'                       { unitTyCon_RDR }
+       | '(' '->' ')'                  { funTyCon_RDR }
+       | '[' ']'                       { listTyCon_RDR }
+       | '(' commas ')'                { tupleTyCon_RDR $2 }
+
 gcon   :: { RdrName }
        : '(' ')'               { unitCon_RDR }
        | '[' ']'               { nilCon_RDR }
@@ -802,11 +1061,15 @@ var      :: { RdrName }
 
 qvar   :: { RdrName }
        : qvarid                { $1 }
-       | '(' qvarsym ')'       { $2 }
+       | '(' varsym ')'        { $2 }
+       | '(' qvarsym1 ')'      { $2 }
+-- We've inlined qvarsym here so that the decision about
+-- whether it's a qvar or a var can be postponed until
+-- *after* we see the close paren.
 
-con    :: { RdrName }
-       : conid                 { $1 }
-       | '(' consym ')'        { $2 }
+ipvar  :: { IPName RdrName }
+       : IPDUPVARID            { Dupable (mkUnqual varName $1) }
+       | IPSPLITVARID          { Linear  (mkUnqual varName $1) }
 
 qcon   :: { RdrName }
        : qconid                { $1 }
@@ -821,7 +1084,7 @@ qvarop :: { RdrName }
        | '`' qvarid '`'        { $2 }
 
 qvaropm :: { RdrName }
-       : qvarsymm              { $1 }
+       : qvarsym_no_minus      { $1 }
        | '`' qvarid '`'        { $2 }
 
 conop :: { RdrName }
@@ -839,9 +1102,9 @@ op :: { RdrName }   -- used in infix decls
        : varop                 { $1 }
        | conop                 { $1 }
 
-qop    :: { RdrNameHsExpr }   -- used in sections
-       : qvarop                { HsVar $1 }
-       | qconop                { HsVar $1 }
+qop    :: { RdrName {-HsExpr-} }   -- used in sections
+       : qvarop                { $1 }
+       | qconop                { $1 }
 
 qopm   :: { RdrNameHsExpr }   -- used in sections
        : qvaropm               { HsVar $1 }
@@ -852,50 +1115,55 @@ qopm     :: { RdrNameHsExpr }   -- used in sections
 
 qvarid :: { RdrName }
        : varid                 { $1 }
-       | QVARID                { case $1 of { (mod,n) ->
-                                 mkSrcQual varName mod n } }
+       | QVARID                { mkQual varName $1 }
 
 varid :: { RdrName }
-       : VARID                 { mkSrcUnqual varName $1 }
-       | 'forall'              { forall_var_RDR }
-       | 'export'              { export_var_RDR }
-       | 'label'               { label_var_RDR }
-       | 'dynamic'             { dynamic_var_RDR }
-       | 'unsafe'              { unsafe_var_RDR }
+       : varid_no_unsafe       { $1 }
+       | 'unsafe'              { mkUnqual varName SLIT("unsafe") }
 
 varid_no_unsafe :: { RdrName }
-       : VARID                 { mkSrcUnqual varName $1 }
-       | 'forall'              { forall_var_RDR }
-       | 'export'              { export_var_RDR }
-       | 'label'               { label_var_RDR }
-       | 'dynamic'             { dynamic_var_RDR }
+       : VARID                 { mkUnqual varName $1 }
+       | special_id            { mkUnqual varName $1 }
+       | 'forall'              { mkUnqual varName SLIT("forall") }
 
--- ``special'' Ids
-'as'       :: { () } : VARID   {% checkAs $1 }
-'qualified' :: { () } : VARID  {% checkQualified $1 }
-'hiding'    :: { () } : VARID  {% checkHiding $1 }
+tyvar  :: { RdrName }
+       : VARID                 { mkUnqual tvName $1 }
+       | special_id            { mkUnqual tvName $1 }
+       | 'unsafe'              { mkUnqual tvName SLIT("unsafe") }
+
+-- These special_ids are treated as keywords in various places, 
+-- but as ordinary ids elsewhere.   A special_id collects all thsee
+-- 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                { case $1 of { (mod,n) ->
-                                 mkSrcQual dataName mod n } }
+       | QCONID                { mkQual dataName $1 }
 
 conid  :: { RdrName }
-       : CONID                 { mkSrcUnqual dataName $1 }
+       : CONID                 { mkUnqual dataName $1 }
 
 -----------------------------------------------------------------------------
 -- ConSyms
 
 qconsym :: { RdrName }
        : consym                { $1 }
-       | QCONSYM               { case $1 of { (mod,n) ->
-                                 mkSrcQual dataName mod n } }
+       | QCONSYM               { mkQual dataName $1 }
 
 consym :: { RdrName }
-       : CONSYM                { mkSrcUnqual dataName $1 }
+       : CONSYM                { mkUnqual dataName $1 }
 
 -----------------------------------------------------------------------------
 -- VarSyms
@@ -904,37 +1172,39 @@ qvarsym :: { RdrName }
        : varsym                { $1 }
        | qvarsym1              { $1 }
 
-qvarsymm :: { RdrName }
-       : varsymm               { $1 }
+qvarsym_no_minus :: { RdrName }
+       : varsym_no_minus       { $1 }
        | qvarsym1              { $1 }
 
+qvarsym1 :: { RdrName }
+qvarsym1 : QVARSYM             { mkQual varName $1 }
+
 varsym :: { RdrName }
-       : VARSYM                { mkSrcUnqual varName $1 }
-       | '-'                   { minus_RDR }
-       | '!'                   { pling_RDR }
-       | '.'                   { dot_RDR }
+       : varsym_no_minus       { $1 }
+       | '-'                   { mkUnqual varName SLIT("-") }
 
-varsymm :: { RdrName } -- varsym not including '-'
-       : VARSYM                { mkSrcUnqual varName $1 }
-       | '!'                   { pling_RDR }
-       | '.'                   { dot_RDR }
+varsym_no_minus :: { RdrName } -- varsym not including '-'
+       : VARSYM                { mkUnqual varName $1 }
+       | special_sym           { mkUnqual varName $1 }
 
-qvarsym1 :: { RdrName }
-       : QVARSYM               { case $1 of { (mod,n) ->
-                                 mkSrcQual varName mod n } }
 
-literal :: { HsLit }
-       : INTEGER               { HsInt    $1 }
-       | CHAR                  { HsChar   $1 }
-       | RATIONAL              { HsFrac   $1 }
-       | STRING                { HsString $1 }
+-- See comments with special_id
+special_sym :: { UserFS }
+special_sym : '!'      { SLIT("!") }
+           | '.'       { SLIT(".") }
+
+-----------------------------------------------------------------------------
+-- Literals
 
+literal :: { HsLit }
+       : CHAR                  { HsChar       $1 }
+       | STRING                { HsString     $1 }
        | PRIMINTEGER           { HsIntPrim    $1 }
        | PRIMCHAR              { HsCharPrim   $1 }
        | PRIMSTRING            { HsStringPrim $1 }
        | PRIMFLOAT             { HsFloatPrim  $1 }
        | PRIMDOUBLE            { HsDoublePrim $1 }
-       | CLITLIT               { HsLitLit     $1 }
+       | CLITLIT               { HsLitLit     $1 placeHolderType }
 
 srcloc :: { SrcLoc }   :       {% getSrcLocP }
  
@@ -945,32 +1215,37 @@ close :: { () }
        : vccurly               { () } -- context popped in lexer.
        | error                 {% popContext }
 
-layout_on  :: { () }   :       {% layoutOn  }
+layout_on        :: { () }     : {% layoutOn True{-strict-} }
+layout_on_for_do  :: { () }    : {% layoutOn False }
 
 -----------------------------------------------------------------------------
 -- Miscellaneous (mostly renamings)
 
 modid  :: { ModuleName }
-       : CONID                 { mkSrcModuleFS $1 }
+       : CONID                 { mkModuleNameFS $1 }
+        | QCONID               { mkModuleNameFS
+                                  (mkFastString
+                                    (unpackFS (fst $1) ++ 
+                                       '.':unpackFS (snd $1)))
+                               }
 
 tycon  :: { RdrName }
-       : CONID                 { mkSrcUnqual tcClsName $1 }
+       : CONID                 { mkUnqual tcClsName $1 }
+
+tyconop        :: { RdrName }
+       : CONSYM                { mkUnqual tcClsName $1 }
 
 qtycon :: { RdrName }
        : tycon                 { $1 }
-       | QCONID                { case $1 of { (mod,n) ->
-                                 mkSrcQual tcClsName mod n } }
+       | QCONID                { mkQual tcClsName $1 }
 
-qtycls         :: { RdrName }
-       : qtycon                { $1 }
+qtyconop :: { RdrName }
+         : tyconop             { $1 }
+         | QCONSYM             { mkQual tcClsName $1 }
 
-tyvar  :: { RdrName }
-       : VARID                 { mkSrcUnqual tvName $1 }
-       | 'export'              { export_var_RDR }
-       | 'label'               { label_var_RDR }
-       | 'dynamic'             { dynamic_var_RDR }
-       | 'unsafe'              { unsafe_var_RDR }
-       -- NOTE: no 'forall'
+commas :: { Int }
+       : commas ','                    { $1 + 1 }
+       | ','                           { 2 }
 
 -----------------------------------------------------------------------------