New syntax for GADT-style record declarations, and associated refactoring
[ghc-hetmet.git] / compiler / hsSyn / HsPat.lhs
index ddd6ec2..9e954a6 100644 (file)
@@ -5,7 +5,7 @@
 \section[PatSyntax]{Abstract Haskell syntax---patterns}
 
 \begin{code}
-{-# OPTIONS -w #-}
+{-# OPTIONS -fno-warn-incomplete-patterns #-}
 -- The above warning supression flag is a temporary kludge.
 -- While working on this module you are encouraged to remove it and fix
 -- any warnings in the module. See
@@ -19,6 +19,8 @@ module HsPat (
        HsConPatDetails, hsConPatArgs, 
        HsRecFields(..), HsRecField(..), hsRecFields,
 
+       HsQuasiQuote(..),
+
        mkPrefixConPat, mkCharLitPat, mkNilPat, mkCoPat, mkCoPatCoI,
 
        isBangHsBind,   
@@ -26,10 +28,7 @@ module HsPat (
        patsAreAllLits, isLitPat, isIrrefutableHsPat
     ) where
 
-#include "HsVersions.h"
-
-
-import {-# SOURCE #-} HsExpr           ( SyntaxExpr )
+import {-# SOURCE #-} HsExpr           (SyntaxExpr, LHsExpr, pprLExpr)
 
 -- friends:
 import HsBinds
@@ -46,6 +45,7 @@ import TyCon
 import Outputable      
 import Type
 import SrcLoc
+import FastString
 \end{code}
 
 
@@ -67,7 +67,7 @@ data Pat id
   | LazyPat    (LPat id)               -- Lazy pattern
   | AsPat      (Located id) (LPat id)  -- As pattern
   | ParPat      (LPat id)              -- Parenthesised pattern
-  | BangPat    (LPat id)               -- Bang patterng
+  | BangPat    (LPat id)               -- Bang pattern
 
        ------------ Lists, tuples, arrays ---------------
   | ListPat    [LPat id]               -- Syntactic list
@@ -97,14 +97,26 @@ data Pat id
 
   | ConPatOut {
        pat_con   :: Located DataCon,
-       pat_tvs   :: [TyVar],           -- Existentially bound type variables
-                                       --   including any bound coercion variables
-       pat_dicts :: [id],              -- Ditto dictionaries
+       pat_tvs   :: [TyVar],           -- Existentially bound type variables (tyvars only)
+       pat_dicts :: [id],              -- Ditto *coercion variables* and *dictionaries*
+                                       -- One reason for putting coercion variable here, I think,
+                                       --      is to ensure their kinds are zonked
        pat_binds :: DictBinds id,      -- Bindings involving those dictionaries
        pat_args  :: HsConPatDetails id,
        pat_ty    :: Type               -- The type of the pattern
     }
 
+       ------------ View patterns ---------------
+  | ViewPat       (LHsExpr id)      
+                  (LPat id)
+                  PostTcType        -- The overall type of the pattern
+                                    -- (= the argument type of the view function)
+                                    -- for hsPatType.
+
+       ------------ Quasiquoted patterns ---------------
+       -- See Note [Quasi-quote overview] in TcSplice
+  | QuasiQuotePat   (HsQuasiQuote id)
+
        ------------ Literal and n+k patterns ---------------
   | LitPat         HsLit               -- Used for *non-overloaded* literal patterns:
                                        -- Int#, Char#, Int, Char, String, etc.
@@ -113,7 +125,6 @@ data Pat id
                    (Maybe (SyntaxExpr id))     -- Just (Name of 'negate') for negative
                                                -- patterns, Nothing otherwise
                    (SyntaxExpr id)             -- Equality checker, of type t->t->Bool
-                   PostTcType                  -- Type of the pattern
 
   | NPlusKPat      (Located id)        -- n+k pattern
                    (HsOverLit id)      -- It'll always be an HsIntegral
@@ -193,6 +204,23 @@ hsRecFields :: HsRecFields id arg -> [id]
 hsRecFields rbinds = map (unLoc . hsRecFieldId) (rec_flds rbinds)
 \end{code}
 
+\begin{code}
+data HsQuasiQuote id = HsQuasiQuote 
+                      id
+                      id
+                      SrcSpan
+                      FastString
+
+instance OutputableBndr id => Outputable (HsQuasiQuote id) where
+    ppr = ppr_qq
+
+ppr_qq :: OutputableBndr id => HsQuasiQuote id -> SDoc
+ppr_qq (HsQuasiQuote name quoter _ quote) =
+    char '$' <> brackets (ppr name) <>
+    ptext (sLit "[:") <> ppr quoter <> ptext (sLit "|") <>
+    ppr quote <> ptext (sLit "|]")
+\end{code}
+
 
 %************************************************************************
 %*                                                                     *
@@ -220,6 +248,7 @@ pprPat (WildPat _)    = char '_'
 pprPat (LazyPat pat)      = char '~' <> ppr pat
 pprPat (BangPat pat)      = char '!' <> ppr pat
 pprPat (AsPat name pat)   = parens (hcat [ppr name, char '@', ppr pat])
+pprPat (ViewPat expr pat _)   = parens (hcat [pprLExpr expr, text " -> ", ppr pat])
 pprPat (ParPat pat)      = parens (ppr pat)
 pprPat (ListPat pats _)     = brackets (interpp'SP pats)
 pprPat (PArrPat pats _)     = pabrackets (interpp'SP pats)
@@ -236,17 +265,23 @@ pprPat (ConPatOut { pat_con = con, pat_tvs = tvs, pat_dicts = dicts,
     else pprUserCon con details
 
 pprPat (LitPat s)            = ppr s
-pprPat (NPat l Nothing  _ _)  = ppr l
-pprPat (NPat l (Just _) _ _)  = char '-' <> ppr l
+pprPat (NPat l Nothing  _)  = ppr l
+pprPat (NPat l (Just _) _)  = char '-' <> ppr l
 pprPat (NPlusKPat n k _ _)    = hcat [ppr n, char '+', ppr k]
-pprPat (TypePat ty)          = ptext SLIT("{|") <> ppr ty <> ptext SLIT("|}")
+pprPat (QuasiQuotePat (HsQuasiQuote name quoter _ quote)) 
+    = char '$' <> brackets (ppr name) <>
+      ptext (sLit "[:") <> ppr quoter <> ptext (sLit "|") <>
+      ppr quote <> ptext (sLit "|]")
+pprPat (TypePat ty)          = ptext (sLit "{|") <> ppr ty <> ptext (sLit "|}")
 pprPat (CoPat co pat _)              = parens (pprHsWrapper (ppr pat) co)
 pprPat (SigPatIn pat ty)      = ppr pat <+> dcolon <+> ppr ty
 pprPat (SigPatOut pat ty)     = ppr pat <+> dcolon <+> ppr ty
 
+pprUserCon :: (Outputable con, OutputableBndr id) => con -> HsConPatDetails id -> SDoc
 pprUserCon c (InfixCon p1 p2) = ppr p1 <+> ppr c <+> ppr p2
 pprUserCon c details          = ppr c <+> pprConArgs details
 
+pprConArgs ::  OutputableBndr id => HsConPatDetails id -> SDoc
 pprConArgs (PrefixCon pats) = interppSP pats
 pprConArgs (InfixCon p1 p2) = interppSP [p1,p2]
 pprConArgs (RecCon rpats)   = ppr rpats
@@ -258,7 +293,7 @@ instance (OutputableBndr id, Outputable arg)
   ppr (HsRecFields { rec_flds = flds, rec_dotdot = Just n })
        = braces (fsep (punctuate comma (map ppr (take n flds) ++ [dotdot])))
        where
-         dotdot = ptext SLIT("..") <+> ifPprDebug (ppr (drop n flds))
+         dotdot = ptext (sLit "..") <+> ifPprDebug (ppr (drop n flds))
 
 instance (OutputableBndr id, Outputable arg)
       => Outputable (HsRecField id arg) where
@@ -269,7 +304,7 @@ instance (OutputableBndr id, Outputable arg)
 -- add parallel array brackets around a document
 --
 pabrackets   :: SDoc -> SDoc
-pabrackets p  = ptext SLIT("[:") <> p <> ptext SLIT(":]")
+pabrackets p  = ptext (sLit "[:") <> p <> ptext (sLit ":]")
 \end{code}
 
 
@@ -299,8 +334,8 @@ mkCoPat co pat ty
   | otherwise        = CoPat co pat ty
 
 mkCoPatCoI :: CoercionI -> Pat id -> Type -> Pat id
-mkCoPatCoI IdCo     pat ty = pat
-mkCoPatCoI (ACo co) pat ty = mkCoPat (WpCo co) pat ty
+mkCoPatCoI IdCo     pat _  = pat
+mkCoPatCoI (ACo co) pat ty = mkCoPat (WpCast co) pat ty
 \end{code}
 
 
@@ -334,40 +369,49 @@ patterns are treated specially, of course.
 
 The 1.3 report defines what ``irrefutable'' and ``failure-free'' patterns are.
 \begin{code}
+isWildPat :: Pat id -> Bool
 isWildPat (WildPat _) = True
-isWildPat other              = False
+isWildPat _           = False
 
 patsAreAllCons :: [Pat id] -> Bool
 patsAreAllCons pat_list = all isConPat pat_list
 
+isConPat :: Pat id -> Bool
 isConPat (AsPat _ pat)  = isConPat (unLoc pat)
 isConPat (ConPatIn {})  = True
 isConPat (ConPatOut {})  = True
 isConPat (ListPat {})   = True
 isConPat (PArrPat {})   = True
 isConPat (TuplePat {})  = True
-isConPat other          = False
+isConPat _               = False
 
+isSigPat :: Pat id -> Bool
 isSigPat (SigPatIn _ _)  = True
 isSigPat (SigPatOut _ _) = True
-isSigPat other          = False
+isSigPat _               = False
 
 patsAreAllLits :: [Pat id] -> Bool
 patsAreAllLits pat_list = all isLitPat pat_list
 
+isLitPat :: Pat id -> Bool
 isLitPat (AsPat _ pat)         = isLitPat (unLoc pat)
 isLitPat (LitPat _)            = True
-isLitPat (NPat _ _ _ _)                = True
+isLitPat (NPat _ _ _)          = True
 isLitPat (NPlusKPat _ _ _ _)    = True
-isLitPat other                 = False
+isLitPat _                      = False
 
 isBangHsBind :: HsBind id -> Bool
 -- In this module because HsPat is above HsBinds in the import graph
-isBangHsBind (PatBind { pat_lhs = L _ (BangPat p) }) = True
-isBangHsBind bind                                   = False
-
-isIrrefutableHsPat :: LPat id -> Bool
--- This function returns False if it's in doubt; specifically
+isBangHsBind (PatBind { pat_lhs = L _ (BangPat _) }) = True
+isBangHsBind _                                       = False
+
+isIrrefutableHsPat :: OutputableBndr id => LPat id -> Bool
+-- (isIrrefutableHsPat p) is true if matching against p cannot fail,
+-- in the sense of falling through to the next pattern.
+--     (NB: this is not quite the same as the (silly) defn
+--     in 3.17.2 of the Haskell 98 report.)
+-- 
+-- isIrrefutableHsPat returns False if it's in doubt; specifically
 -- on a ConPatIn it doesn't know the size of the constructor family
 -- But if it returns True, the pattern is definitely irrefutable
 isIrrefutableHsPat pat
@@ -378,16 +422,17 @@ isIrrefutableHsPat pat
     go1 (WildPat _)         = True
     go1 (VarPat _)          = True
     go1 (VarPatOut _ _)     = True
-    go1 (LazyPat pat)       = True
+    go1 (LazyPat _)         = True
     go1 (BangPat pat)       = go pat
     go1 (CoPat _ pat _)     = go1 pat
     go1 (ParPat pat)        = go pat
     go1 (AsPat _ pat)       = go pat
+    go1 (ViewPat _ pat _)   = go pat
     go1 (SigPatIn pat _)    = go pat
     go1 (SigPatOut pat _)   = go pat
     go1 (TuplePat pats _ _) = all go pats
-    go1 (ListPat pats _)    = False
-    go1 (PArrPat pats _)    = False    -- ?
+    go1 (ListPat _ _)       = False
+    go1 (PArrPat _ _)       = False    -- ?
 
     go1 (ConPatIn _ _) = False -- Conservative
     go1 (ConPatOut{ pat_con = L _ con, pat_args = details }) 
@@ -395,9 +440,13 @@ isIrrefutableHsPat pat
        && all go (hsConPatArgs details)
 
     go1 (LitPat _)        = False
-    go1 (NPat _ _ _ _)    = False
+    go1 (NPat _ _ _)      = False
     go1 (NPlusKPat _ _ _ _) = False
 
-    go1 (TypePat _)   = panic "isIrrefutableHsPat: type pattern"
+    go1 (QuasiQuotePat {}) = urk pat   -- Gotten rid of by renamer, before
+                                       -- isIrrefutablePat is called
+    go1 (TypePat {})       = urk pat
+
+    urk pat = pprPanic "isIrrefutableHsPat:" (ppr pat)
 \end{code}