[project @ 1997-03-14 07:52:06 by simonpj]
[ghc-hetmet.git] / ghc / compiler / hsSyn / HsPat.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[PatSyntax]{Abstract Haskell syntax---patterns}
5
6 \begin{code}
7 #include "HsVersions.h"
8
9 module HsPat (
10         InPat(..),
11         OutPat(..),
12
13         irrefutablePat, irrefutablePats,
14         failureFreePat,
15         patsAreAllCons, isConPat,
16         patsAreAllLits, isLitPat,
17         collectPatBinders
18     ) where
19
20 IMP_Ubiq()
21
22 -- friends:
23 import HsBasic                  ( HsLit, Fixity )
24 IMPORT_DELOOPER(HsLoop)         ( HsExpr )
25
26 -- others:
27 import Id               ( dataConTyCon, GenId )
28 import Maybes           ( maybeToBool )
29 import Name             ( pprSym, pprNonSym )
30 import Outputable       ( interppSP, interpp'SP, ifPprShowAll )
31 import PprStyle         ( PprStyle(..) )
32 import Pretty
33 import TyCon            ( maybeTyConSingleCon )
34 import PprType          ( GenType )
35 \end{code}
36
37 Patterns come in distinct before- and after-typechecking flavo(u)rs.
38 \begin{code}
39 data InPat name
40   = WildPatIn                           -- wild card
41   | VarPatIn        name                -- variable
42   | LitPatIn        HsLit               -- literal
43   | LazyPatIn       (InPat name)        -- lazy pattern
44   | AsPatIn         name                -- as pattern
45                     (InPat name)
46   | ConPatIn        name                -- constructed type
47                     [InPat name]
48   | ConOpPatIn      (InPat name)
49                     name
50                     Fixity              -- c.f. OpApp in HsExpr
51                     (InPat name)
52
53   | NPlusKPatIn     name                --  n+k pattern
54                     HsLit
55
56   -- We preserve prefix negation and parenthesis for the precedence parser.
57
58   | NegPatIn        (InPat name)        -- negated pattern
59   | ParPatIn        (InPat name)        -- parenthesised pattern
60
61   | ListPatIn       [InPat name]        -- syntactic list
62                                         -- must have >= 1 elements
63   | TuplePatIn      [InPat name]        -- tuple
64
65   | RecPatIn        name                -- record
66                     [(name, InPat name, Bool)]  -- True <=> source used punning
67
68 data OutPat tyvar uvar id
69   = WildPat         (GenType tyvar uvar)        -- wild card
70
71   | VarPat          id                          -- variable (type is in the Id)
72
73   | LazyPat         (OutPat tyvar uvar id)      -- lazy pattern
74
75   | AsPat           id                          -- as pattern
76                     (OutPat tyvar uvar id)
77
78   | ConPat          Id                          -- Constructor is always an Id
79                     (GenType tyvar uvar)        -- the type of the pattern
80                     [OutPat tyvar uvar id]
81
82   | ConOpPat        (OutPat tyvar uvar id)      -- just a special case...
83                     Id
84                     (OutPat tyvar uvar id)
85                     (GenType tyvar uvar)
86   | ListPat                                     -- syntactic list
87                     (GenType tyvar uvar)        -- the type of the elements
88                     [OutPat tyvar uvar id]
89
90   | TuplePat        [OutPat tyvar uvar id]      -- tuple
91                                                 -- UnitPat is TuplePat []
92
93   | RecPat          Id                          -- record constructor
94                     (GenType tyvar uvar)        -- the type of the pattern
95                     [(Id, OutPat tyvar uvar id, Bool)]  -- True <=> source used punning
96
97   | LitPat          -- Used for *non-overloaded* literal patterns:
98                     -- Int#, Char#, Int, Char, String, etc.
99                     HsLit
100                     (GenType tyvar uvar)        -- type of pattern
101
102   | NPat            -- Used for *overloaded* literal patterns
103                     HsLit                       -- the literal is retained so that
104                                                 -- the desugarer can readily identify
105                                                 -- equations with identical literal-patterns
106                     (GenType tyvar uvar)        -- type of pattern, t
107                     (HsExpr tyvar uvar id (OutPat tyvar uvar id))
108                                                 -- of type t -> Bool; detects match
109
110   | NPlusKPat       id
111                     HsLit                       -- Same reason as for LitPat
112                                                 -- (This could be an Integer, but then
113                                                 -- it's harder to partitionEqnsByLit
114                                                 -- in the desugarer.)
115                     (GenType tyvar uvar)        -- Type of pattern, t
116                     (HsExpr tyvar uvar id (OutPat tyvar uvar id))       -- Of type t -> Bool; detects match
117                     (HsExpr tyvar uvar id (OutPat tyvar uvar id))       -- Of type t -> t; subtracts k
118
119   | DictPat         -- Used when destructing Dictionaries with an explicit case
120                     [id]                        -- superclass dicts
121                     [id]                        -- methods
122 \end{code}
123
124 \begin{code}
125 instance (Outputable name, NamedThing name) => Outputable (InPat name) where
126     ppr = pprInPat
127
128 pprInPat :: (Outputable name, NamedThing name) => PprStyle -> InPat name -> Pretty
129
130 pprInPat sty (WildPatIn)        = ppChar '_'
131 pprInPat sty (VarPatIn var)     = ppr sty var
132 pprInPat sty (LitPatIn s)       = ppr sty s
133 pprInPat sty (LazyPatIn pat)    = ppBeside (ppChar '~') (ppr sty pat)
134 pprInPat sty (AsPatIn name pat)
135     = ppBesides [ppLparen, ppr sty name, ppChar '@', ppr sty pat, ppRparen]
136
137 pprInPat sty (ConPatIn c pats)
138  = if null pats then
139       ppr sty c
140    else
141       ppCat [ppr sty c, interppSP sty pats] -- ParPats put in the parens
142
143 pprInPat sty (ConOpPatIn pat1 op fixity pat2)
144  = ppCat [ppr sty pat1, ppr sty op, ppr sty pat2] -- ParPats put in parens
145
146         -- ToDo: use pprSym to print op (but this involves fiddling various
147         -- contexts & I'm lazy...); *PatIns are *rarely* printed anyway... (WDP)
148
149 pprInPat sty (NegPatIn pat)
150   = let
151         pp_pat = pprInPat sty pat
152     in
153     ppBeside (ppChar '-') (
154     case pat of
155       LitPatIn _ -> pp_pat
156       _          -> ppParens pp_pat
157     )
158
159 pprInPat sty (ParPatIn pat)
160   = ppParens (pprInPat sty pat)
161
162 pprInPat sty (ListPatIn pats)
163   = ppBesides [ppLbrack, interpp'SP sty pats, ppRbrack]
164 pprInPat sty (TuplePatIn pats)
165   = ppParens (interpp'SP sty pats)
166 pprInPat sty (NPlusKPatIn n k)
167   = ppBesides [ppLparen, ppr sty n, ppChar '+', ppr sty k, ppRparen]
168
169 pprInPat sty (RecPatIn con rpats)
170   = ppCat [ppr sty con, ppCurlies (ppIntersperse pp'SP (map (pp_rpat sty) rpats))]
171   where
172     pp_rpat PprForUser (v, _, True) = ppr PprForUser v
173     pp_rpat sty        (v, p, _)    = ppCat [ppr sty v, ppChar '=', ppr sty p]
174 \end{code}
175
176 \begin{code}
177 instance (Eq tyvar, Outputable tyvar, Eq uvar, Outputable uvar, Outputable id)
178        => Outputable (OutPat tyvar uvar id) where
179     ppr = pprOutPat
180 \end{code}
181
182 \begin{code}
183 pprOutPat sty (WildPat ty)      = ppChar '_'
184 pprOutPat sty (VarPat var)      = ppr sty var
185 pprOutPat sty (LazyPat pat)     = ppBesides [ppChar '~', ppr sty pat]
186 pprOutPat sty (AsPat name pat)
187   = ppBesides [ppLparen, ppr sty name, ppChar '@', ppr sty pat, ppRparen]
188
189 pprOutPat sty (ConPat name ty [])
190   = ppBeside (ppr sty name)
191         (ifPprShowAll sty (pprConPatTy sty ty))
192
193 pprOutPat sty (ConPat name ty pats)
194   = ppBesides [ppLparen, ppr sty name, ppSP,
195          interppSP sty pats, ppRparen,
196          ifPprShowAll sty (pprConPatTy sty ty) ]
197
198 pprOutPat sty (ConOpPat pat1 op pat2 ty)
199   = ppBesides [ppLparen, ppr sty pat1, ppSP, pprSym sty op, ppSP, ppr sty pat2, ppRparen]
200
201 pprOutPat sty (ListPat ty pats)
202   = ppBesides [ppLbrack, interpp'SP sty pats, ppRbrack]
203 pprOutPat sty (TuplePat pats)
204   = ppParens (interpp'SP sty pats)
205
206 pprOutPat sty (RecPat con ty rpats)
207   = ppBesides [ppr sty con, ppCurlies (ppIntersperse pp'SP (map (pp_rpat sty) rpats))]
208   where
209     pp_rpat PprForUser (v, _, True) = ppr PprForUser v
210     pp_rpat sty (v, p, _)           = ppCat [ppr sty v, ppChar '=', ppr sty p]
211
212 pprOutPat sty (LitPat l ty)     = ppr sty l     -- ToDo: print more
213 pprOutPat sty (NPat   l ty e)   = ppr sty l     -- ToDo: print more
214 pprOutPat sty (NPlusKPat n k ty e1 e2)          -- ToDo: print more
215   = ppBesides [ppLparen, ppr sty n, ppChar '+', ppr sty k, ppRparen]
216
217 pprOutPat sty (DictPat dicts methods)
218  = ppSep [ppBesides [ppLparen, ppPStr SLIT("{-dict-}")],
219           ppBracket (interpp'SP sty dicts),
220           ppBesides [ppBracket (interpp'SP sty methods), ppRparen]]
221
222 pprConPatTy sty ty
223  = ppParens (ppr sty ty)
224 \end{code}
225
226 %************************************************************************
227 %*                                                                      *
228 %* predicates for checking things about pattern-lists in EquationInfo   *
229 %*                                                                      *
230 %************************************************************************
231 \subsection[Pat-list-predicates]{Look for interesting things in patterns}
232
233 Unlike in the Wadler chapter, where patterns are either ``variables''
234 or ``constructors,'' here we distinguish between:
235 \begin{description}
236 \item[unfailable:]
237 Patterns that cannot fail to match: variables, wildcards, and lazy
238 patterns.
239
240 These are the irrefutable patterns; the two other categories
241 are refutable patterns.
242
243 \item[constructor:]
244 A non-literal constructor pattern (see next category).
245
246 \item[literal patterns:]
247 At least the numeric ones may be overloaded.
248 \end{description}
249
250 A pattern is in {\em exactly one} of the above three categories; `as'
251 patterns are treated specially, of course.
252
253 The 1.3 report defines what ``irrefutable'' and ``failure-free'' patterns are.
254 \begin{code}
255 irrefutablePats :: [OutPat a b c] -> Bool
256 irrefutablePats pat_list = all irrefutablePat pat_list
257
258 irrefutablePat (AsPat   _ pat)  = irrefutablePat pat
259 irrefutablePat (WildPat _)      = True
260 irrefutablePat (VarPat  _)      = True
261 irrefutablePat (LazyPat _)      = True
262 irrefutablePat (DictPat ds ms)  = (length ds + length ms) <= 1
263 irrefutablePat other            = False
264
265 failureFreePat :: OutPat a b c -> Bool
266
267 failureFreePat (WildPat _)                = True
268 failureFreePat (VarPat _)                 = True
269 failureFreePat (LazyPat _)                = True
270 failureFreePat (AsPat _ pat)              = failureFreePat pat
271 failureFreePat (ConPat con tys pats)      = only_con con && all failureFreePat pats
272 failureFreePat (ConOpPat pat1 con pat2 _) = only_con con && failureFreePat pat1 && failureFreePat pat1
273 failureFreePat (RecPat con _ fields)      = only_con con && and [ failureFreePat pat | (_,pat,_) <- fields ]
274 failureFreePat (ListPat _ _)              = False
275 failureFreePat (TuplePat pats)            = all failureFreePat pats
276 failureFreePat (DictPat _ _)              = True
277 failureFreePat other_pat                  = False   -- Literals, NPat
278
279 only_con con = maybeToBool (maybeTyConSingleCon (dataConTyCon con))
280 \end{code}
281
282 \begin{code}
283 patsAreAllCons :: [OutPat a b c] -> Bool
284 patsAreAllCons pat_list = all isConPat pat_list
285
286 isConPat (AsPat _ pat)          = isConPat pat
287 isConPat (ConPat _ _ _)         = True
288 isConPat (ConOpPat _ _ _ _)     = True
289 isConPat (ListPat _ _)          = True
290 isConPat (TuplePat _)           = True
291 isConPat (RecPat _ _ _)         = True
292 isConPat (DictPat ds ms)        = (length ds + length ms) > 1
293 isConPat other                  = False
294
295 patsAreAllLits :: [OutPat a b c] -> Bool
296 patsAreAllLits pat_list = all isLitPat pat_list
297
298 isLitPat (AsPat _ pat)         = isLitPat pat
299 isLitPat (LitPat _ _)          = True
300 isLitPat (NPat   _ _ _)        = True
301 isLitPat (NPlusKPat _ _ _ _ _) = True
302 isLitPat other                 = False
303 \end{code}
304
305 This function @collectPatBinders@ works with the ``collectBinders''
306 functions for @HsBinds@, etc.  The order in which the binders are
307 collected is important; see @HsBinds.lhs@.
308 \begin{code}
309 collectPatBinders :: InPat a -> [a]
310
311 collectPatBinders WildPatIn              = []
312 collectPatBinders (VarPatIn var)         = [var]
313 collectPatBinders (LitPatIn _)           = []
314 collectPatBinders (LazyPatIn pat)        = collectPatBinders pat
315 collectPatBinders (AsPatIn a pat)        = a : collectPatBinders pat
316 collectPatBinders (NPlusKPatIn n _)      = [n]
317 collectPatBinders (ConPatIn c pats)      = concat (map collectPatBinders pats)
318 collectPatBinders (ConOpPatIn p1 c f p2) = collectPatBinders p1 ++ collectPatBinders p2
319 collectPatBinders (NegPatIn  pat)        = collectPatBinders pat
320 collectPatBinders (ParPatIn  pat)        = collectPatBinders pat
321 collectPatBinders (ListPatIn pats)       = concat (map collectPatBinders pats)
322 collectPatBinders (TuplePatIn pats)      = concat (map collectPatBinders pats)
323 collectPatBinders (RecPatIn c fields)    = concat (map (\ (f,pat,_) -> collectPatBinders pat) fields)
324 \end{code}