Fix Trac #2130: improve derived Ord for primmitive types
[ghc-hetmet.git] / compiler / typecheck / TcGenDeriv.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %
5
6 TcGenDeriv: Generating derived instance declarations
7
8 This module is nominally ``subordinate'' to @TcDeriv@, which is the
9 ``official'' interface to deriving-related things.
10
11 This is where we do all the grimy bindings' generation.
12
13 \begin{code}
14 {-# OPTIONS -w #-}
15 -- The above warning supression flag is a temporary kludge.
16 -- While working on this module you are encouraged to remove it and fix
17 -- any warnings in the module. See
18 --     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
19 -- for details
20
21 module TcGenDeriv (
22         DerivAuxBind(..), DerivAuxBinds, isDupAux,
23
24         gen_Bounded_binds,
25         gen_Enum_binds,
26         gen_Eq_binds,
27         gen_Ix_binds,
28         gen_Ord_binds,
29         gen_Read_binds,
30         gen_Show_binds,
31         gen_Data_binds,
32         gen_Typeable_binds,
33         genAuxBind,
34
35         con2tag_RDR, tag2con_RDR, maxtag_RDR
36     ) where
37
38 #include "HsVersions.h"
39
40 import HsSyn
41 import RdrName
42 import BasicTypes
43 import DataCon
44 import Name
45
46 import HscTypes
47 import PrelInfo
48 import PrelNames
49 import MkId
50 import PrimOp
51 import SrcLoc
52 import TyCon
53 import TcType
54 import TysPrim
55 import TysWiredIn
56 import Util
57 import Outputable
58 import FastString
59 import OccName
60 import Bag
61
62 import Data.List        ( partition, intersperse )
63 \end{code}
64
65 \begin{code}
66 type DerivAuxBinds = [DerivAuxBind]
67
68 data DerivAuxBind               -- Please add these auxiliary top-level bindings
69   = DerivAuxBind (LHsBind RdrName)
70   | GenCon2Tag TyCon            -- The con2Tag for given TyCon
71   | GenTag2Con TyCon            -- ...ditto tag2Con
72   | GenMaxTag  TyCon            -- ...and maxTag
73
74 isDupAux :: DerivAuxBind -> DerivAuxBind -> Bool
75 isDupAux (GenCon2Tag tc1) (GenCon2Tag tc2) = tc1==tc2
76 isDupAux (GenTag2Con tc1) (GenTag2Con tc2) = tc1==tc2
77 isDupAux (GenMaxTag tc1)  (GenMaxTag tc2)  = tc1==tc2
78 isDupAux b1               b2               = False
79 \end{code}
80
81
82 %************************************************************************
83 %*                                                                      *
84                 Eq instances
85 %*                                                                      *
86 %************************************************************************
87
88 Here are the heuristics for the code we generate for @Eq@:
89 \begin{itemize}
90 \item
91   Let's assume we have a data type with some (possibly zero) nullary
92   data constructors and some ordinary, non-nullary ones (the rest,
93   also possibly zero of them).  Here's an example, with both \tr{N}ullary
94   and \tr{O}rdinary data cons.
95 \begin{verbatim}
96 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
97 \end{verbatim}
98
99 \item
100   For the ordinary constructors (if any), we emit clauses to do The
101   Usual Thing, e.g.,:
102
103 \begin{verbatim}
104 (==) (O1 a1 b1)    (O1 a2 b2)    = a1 == a2 && b1 == b2
105 (==) (O2 a1)       (O2 a2)       = a1 == a2
106 (==) (O3 a1 b1 c1) (O3 a2 b2 c2) = a1 == a2 && b1 == b2 && c1 == c2
107 \end{verbatim}
108
109   Note: if we're comparing unlifted things, e.g., if \tr{a1} and
110   \tr{a2} are \tr{Float#}s, then we have to generate
111 \begin{verbatim}
112 case (a1 `eqFloat#` a2) of
113   r -> r
114 \end{verbatim}
115   for that particular test.
116
117 \item
118   If there are any nullary constructors, we emit a catch-all clause of
119   the form:
120
121 \begin{verbatim}
122 (==) a b  = case (con2tag_Foo a) of { a# ->
123             case (con2tag_Foo b) of { b# ->
124             case (a# ==# b#)     of {
125               r -> r
126             }}}
127 \end{verbatim}
128
129   If there aren't any nullary constructors, we emit a simpler
130   catch-all:
131 \begin{verbatim}
132 (==) a b  = False
133 \end{verbatim}
134
135 \item
136   For the @(/=)@ method, we normally just use the default method.
137
138   If the type is an enumeration type, we could/may/should? generate
139   special code that calls @con2tag_Foo@, much like for @(==)@ shown
140   above.
141
142 \item
143   We thought about doing this: If we're also deriving @Ord@ for this
144   tycon, we generate:
145 \begin{verbatim}
146 instance ... Eq (Foo ...) where
147   (==) a b  = case (compare a b) of { _LT -> False; _EQ -> True ; _GT -> False}
148   (/=) a b  = case (compare a b) of { _LT -> True ; _EQ -> False; _GT -> True }
149 \begin{verbatim}
150   However, that requires that \tr{Ord <whatever>} was put in the context
151   for the instance decl, which it probably wasn't, so the decls
152   produced don't get through the typechecker.
153 \end{itemize}
154
155
156 \begin{code}
157 gen_Eq_binds :: TyCon -> (LHsBinds RdrName, DerivAuxBinds)
158 gen_Eq_binds tycon
159   = (method_binds, aux_binds)
160   where
161     tycon_loc = getSrcSpan tycon
162
163     (nullary_cons, nonnullary_cons)
164        | isNewTyCon tycon = ([], tyConDataCons tycon)
165        | otherwise            = partition isNullarySrcDataCon (tyConDataCons tycon)
166
167     no_nullary_cons = null nullary_cons
168
169     rest | no_nullary_cons
170          = case maybeTyConSingleCon tycon of
171                   Just _ -> []
172                   Nothing -> -- if cons don't match, then False
173                      [([nlWildPat, nlWildPat], false_Expr)]
174          | otherwise -- calc. and compare the tags
175          = [([a_Pat, b_Pat],
176             untag_Expr tycon [(a_RDR,ah_RDR), (b_RDR,bh_RDR)]
177                        (genOpApp (nlHsVar ah_RDR) eqInt_RDR (nlHsVar bh_RDR)))]
178
179     aux_binds | no_nullary_cons = []
180               | otherwise       = [GenCon2Tag tycon]
181
182     method_binds = listToBag [
183                         mk_FunBind tycon_loc eq_RDR ((map pats_etc nonnullary_cons) ++ rest),
184                         mk_easy_FunBind tycon_loc ne_RDR [a_Pat, b_Pat] (
185                         nlHsApp (nlHsVar not_RDR) (nlHsPar (nlHsVarApps eq_RDR [a_RDR, b_RDR])))]
186
187     ------------------------------------------------------------------
188     pats_etc data_con
189       = let
190             con1_pat = nlConVarPat data_con_RDR as_needed
191             con2_pat = nlConVarPat data_con_RDR bs_needed
192
193             data_con_RDR = getRdrName data_con
194             con_arity   = length tys_needed
195             as_needed   = take con_arity as_RDRs
196             bs_needed   = take con_arity bs_RDRs
197             tys_needed  = dataConOrigArgTys data_con
198         in
199         ([con1_pat, con2_pat], nested_eq_expr tys_needed as_needed bs_needed)
200       where
201         nested_eq_expr []  [] [] = true_Expr
202         nested_eq_expr tys as bs
203           = foldl1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
204           where
205             nested_eq ty a b = nlHsPar (eq_Expr tycon ty (nlHsVar a) (nlHsVar b))
206 \end{code}
207
208 %************************************************************************
209 %*                                                                      *
210         Ord instances
211 %*                                                                      *
212 %************************************************************************
213
214 For a derived @Ord@, we concentrate our attentions on @compare@
215 \begin{verbatim}
216 compare :: a -> a -> Ordering
217 data Ordering = LT | EQ | GT deriving ()
218 \end{verbatim}
219
220 We will use the same example data type as above:
221 \begin{verbatim}
222 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
223 \end{verbatim}
224
225 \begin{itemize}
226 \item
227   We do all the other @Ord@ methods with calls to @compare@:
228 \begin{verbatim}
229 instance ... (Ord <wurble> <wurble>) where
230     a <  b  = case (compare a b) of { LT -> True;  EQ -> False; GT -> False }
231     a <= b  = case (compare a b) of { LT -> True;  EQ -> True;  GT -> False }
232     a >= b  = case (compare a b) of { LT -> False; EQ -> True;  GT -> True  }
233     a >  b  = case (compare a b) of { LT -> False; EQ -> False; GT -> True  }
234
235     max a b = case (compare a b) of { LT -> b; EQ -> a;  GT -> a }
236     min a b = case (compare a b) of { LT -> a; EQ -> b;  GT -> b }
237
238     -- compare to come...
239 \end{verbatim}
240
241 \item
242   @compare@ always has two parts.  First, we use the compared
243   data-constructors' tags to deal with the case of different
244   constructors:
245 \begin{verbatim}
246 compare a b = case (con2tag_Foo a) of { a# ->
247               case (con2tag_Foo b) of { b# ->
248               case (a# ==# b#)     of {
249                True  -> cmp_eq a b
250                False -> case (a# <# b#) of
251                          True  -> _LT
252                          False -> _GT
253               }}}
254   where
255     cmp_eq = ... to come ...
256 \end{verbatim}
257
258 \item
259   We are only left with the ``help'' function @cmp_eq@, to deal with
260   comparing data constructors with the same tag.
261
262   For the ordinary constructors (if any), we emit the sorta-obvious
263   compare-style stuff; for our example:
264 \begin{verbatim}
265 cmp_eq (O1 a1 b1) (O1 a2 b2)
266   = case (compare a1 a2) of { LT -> LT; EQ -> compare b1 b2; GT -> GT }
267
268 cmp_eq (O2 a1) (O2 a2)
269   = compare a1 a2
270
271 cmp_eq (O3 a1 b1 c1) (O3 a2 b2 c2)
272   = case (compare a1 a2) of {
273       LT -> LT;
274       GT -> GT;
275       EQ -> case compare b1 b2 of {
276               LT -> LT;
277               GT -> GT;
278               EQ -> compare c1 c2
279             }
280     }
281 \end{verbatim}
282
283   Again, we must be careful about unlifted comparisons.  For example,
284   if \tr{a1} and \tr{a2} were \tr{Int#}s in the 2nd example above, we'd need to
285   generate:
286
287 \begin{verbatim}
288 cmp_eq lt eq gt (O2 a1) (O2 a2)
289   = compareInt# a1 a2
290   -- or maybe the unfolded equivalent
291 \end{verbatim}
292
293 \item
294   For the remaining nullary constructors, we already know that the
295   tags are equal so:
296 \begin{verbatim}
297 cmp_eq _ _ = EQ
298 \end{verbatim}
299 \end{itemize}
300
301 If there is only one constructor in the Data Type we don't need the WildCard Pattern. 
302 JJQC-30-Nov-1997
303
304 \begin{code}
305 gen_Ord_binds :: TyCon -> (LHsBinds RdrName, DerivAuxBinds)
306
307 gen_Ord_binds tycon
308   | Just (con, prim_tc) <- primWrapperType_maybe tycon
309   = gen_PrimOrd_binds con prim_tc
310
311   | otherwise 
312   = (unitBag compare, aux_binds)
313         -- `AndMonoBinds` compare       
314         -- The default declaration in PrelBase handles this
315   where
316     tycon_loc = getSrcSpan tycon
317     --------------------------------------------------------------------
318     aux_binds | single_con_type = []
319               | otherwise       = [GenCon2Tag tycon]
320
321     compare = L tycon_loc (mkFunBind (L tycon_loc compare_RDR) compare_matches)
322     compare_matches = [mkMatch [a_Pat, b_Pat] compare_rhs cmp_eq_binds]
323     cmp_eq_binds    = HsValBinds (ValBindsIn (unitBag cmp_eq) [])
324
325     compare_rhs
326         | single_con_type = cmp_eq_Expr a_Expr b_Expr
327         | otherwise
328         = untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
329                   (cmp_tags_Expr eqInt_RDR ah_RDR bh_RDR
330                         (cmp_eq_Expr a_Expr b_Expr)     -- True case
331                         -- False case; they aren't equal
332                         -- So we need to do a less-than comparison on the tags
333                         (cmp_tags_Expr ltInt_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr))
334
335     tycon_data_cons = tyConDataCons tycon
336     single_con_type = isSingleton tycon_data_cons
337     (nullary_cons, nonnullary_cons)
338        | isNewTyCon tycon = ([], tyConDataCons tycon)
339        | otherwise        = partition isNullarySrcDataCon tycon_data_cons
340
341     cmp_eq = mk_FunBind tycon_loc cmp_eq_RDR cmp_eq_match
342     cmp_eq_match
343       | isEnumerationTyCon tycon
344                            -- We know the tags are equal, so if it's an enumeration TyCon,
345                            -- then there is nothing left to do
346                            -- Catch this specially to avoid warnings
347                            -- about overlapping patterns from the desugarer,
348                            -- and to avoid unnecessary pattern-matching
349       = [([nlWildPat,nlWildPat], eqTag_Expr)]
350       | otherwise
351       = map pats_etc nonnullary_cons ++
352         (if single_con_type then        -- Omit wildcards when there's just one 
353               []                        -- constructor, to silence desugarer
354         else
355               [([nlWildPat, nlWildPat], default_rhs)])
356
357     default_rhs | null nullary_cons = impossible_Expr   -- Keep desugarer from complaining about
358                                                         -- inexhaustive patterns
359                 | otherwise         = eqTag_Expr        -- Some nullary constructors;
360                                                         -- Tags are equal, no args => return EQ
361     pats_etc data_con
362         = ([con1_pat, con2_pat],
363            nested_compare_expr tys_needed as_needed bs_needed)
364         where
365           con1_pat = nlConVarPat data_con_RDR as_needed
366           con2_pat = nlConVarPat data_con_RDR bs_needed
367
368           data_con_RDR = getRdrName data_con
369           con_arity   = length tys_needed
370           as_needed   = take con_arity as_RDRs
371           bs_needed   = take con_arity bs_RDRs
372           tys_needed  = dataConOrigArgTys data_con
373
374           nested_compare_expr [ty] [a] [b]
375             = careful_compare_Case tycon ty eqTag_Expr (nlHsVar a) (nlHsVar b)
376
377           nested_compare_expr (ty:tys) (a:as) (b:bs)
378             = let eq_expr = nested_compare_expr tys as bs
379                 in  careful_compare_Case tycon ty eq_expr (nlHsVar a) (nlHsVar b)
380
381           nested_compare_expr _ _ _ = panic "nested_compare_expr"       -- Args always equal length
382 \end{code}
383
384 Note [Comparision of primitive types]
385 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
386 The general plan does not work well for data types like
387         data T = MkT Int# deriving( Ord )
388 The general plan defines the 'compare' method, gets (<) etc from it.  But
389 that means we get silly code like:
390    instance Ord T where
391      (>) (I# x) (I# y) = case <# x y of
392                             True -> False
393                             False -> case ==# x y of 
394                                        True  -> False
395                                        False -> True
396 We would prefer to use the (>#) primop.  See also Trac #2130
397                             
398
399 \begin{code}
400 gen_PrimOrd_binds :: DataCon -> TyCon ->  (LHsBinds RdrName, DerivAuxBinds)
401 -- See Note [Comparison of primitive types]
402 gen_PrimOrd_binds data_con prim_tc 
403   = (listToBag [mk_op lt_RDR lt_op, mk_op le_RDR le_op, 
404                 mk_op ge_RDR ge_op, mk_op gt_RDR gt_op], [])
405   where
406     mk_op op_RDR op = mk_FunBind (getSrcSpan data_con) op_RDR 
407                                  [([apat, bpat], genOpApp a_Expr (primOpRdrName op) b_Expr)]
408     con_RDR = getRdrName data_con
409     apat = nlConVarPat con_RDR [a_RDR]
410     bpat = nlConVarPat con_RDR [b_RDR]
411
412     (lt_op, le_op, ge_op, gt_op)
413        | prim_tc == charPrimTyCon   = (CharLtOp,   CharLeOp,   CharGeOp,   CharGtOp)
414        | prim_tc == intPrimTyCon    = (IntLtOp,    IntLeOp,    IntGeOp,    IntGtOp)
415        | prim_tc == wordPrimTyCon   = (WordLtOp,   WordLeOp,   WordGeOp,   WordGtOp)
416        | prim_tc == addrPrimTyCon   = (AddrLtOp,   AddrLeOp,   AddrGeOp,   AddrGtOp)
417        | prim_tc == floatPrimTyCon  = (FloatLtOp,  FloatLeOp,  FloatGeOp,  FloatGtOp)
418        | prim_tc == doublePrimTyCon = (DoubleLtOp, DoubleLeOp, DoubleGeOp, DoubleGtOp)
419        | otherwise = pprPanic "Unexpected primitive tycon" (ppr prim_tc)
420
421
422 primWrapperType_maybe :: TyCon -> Maybe (DataCon, TyCon)
423 -- True of data types that are wrappers around prmitive types
424 --      data T = MkT Word#
425 -- For these we want to generate all the (<), (<=) etc operations individually
426 primWrapperType_maybe tc 
427   | [con] <- tyConDataCons tc
428   , [ty]  <- dataConOrigArgTys con
429   , Just (prim_tc, []) <- tcSplitTyConApp_maybe ty
430   , isPrimTyCon prim_tc
431   = Just (con, prim_tc)
432   | otherwise
433   = Nothing
434 \end{code}
435
436 %************************************************************************
437 %*                                                                      *
438         Enum instances
439 %*                                                                      *
440 %************************************************************************
441
442 @Enum@ can only be derived for enumeration types.  For a type
443 \begin{verbatim}
444 data Foo ... = N1 | N2 | ... | Nn
445 \end{verbatim}
446
447 we use both @con2tag_Foo@ and @tag2con_Foo@ functions, as well as a
448 @maxtag_Foo@ variable (all generated by @gen_tag_n_con_binds@).
449
450 \begin{verbatim}
451 instance ... Enum (Foo ...) where
452     succ x   = toEnum (1 + fromEnum x)
453     pred x   = toEnum (fromEnum x - 1)
454
455     toEnum i = tag2con_Foo i
456
457     enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo]
458
459     -- or, really...
460     enumFrom a
461       = case con2tag_Foo a of
462           a# -> map tag2con_Foo (enumFromTo (I# a#) maxtag_Foo)
463
464    enumFromThen a b
465      = map tag2con_Foo [con2tag_Foo a, con2tag_Foo b .. maxtag_Foo]
466
467     -- or, really...
468     enumFromThen a b
469       = case con2tag_Foo a of { a# ->
470         case con2tag_Foo b of { b# ->
471         map tag2con_Foo (enumFromThenTo (I# a#) (I# b#) maxtag_Foo)
472         }}
473 \end{verbatim}
474
475 For @enumFromTo@ and @enumFromThenTo@, we use the default methods.
476
477 \begin{code}
478 gen_Enum_binds :: TyCon -> (LHsBinds RdrName, DerivAuxBinds)
479 gen_Enum_binds tycon
480   = (method_binds, aux_binds)
481   where
482     method_binds = listToBag [
483                         succ_enum,
484                         pred_enum,
485                         to_enum,
486                         enum_from,
487                         enum_from_then,
488                         from_enum
489                     ]
490     aux_binds = [GenCon2Tag tycon, GenTag2Con tycon, GenMaxTag tycon]
491
492     tycon_loc = getSrcSpan tycon
493     occ_nm    = getOccString tycon
494
495     succ_enum
496       = mk_easy_FunBind tycon_loc succ_RDR [a_Pat] $
497         untag_Expr tycon [(a_RDR, ah_RDR)] $
498         nlHsIf (nlHsApps eq_RDR [nlHsVar (maxtag_RDR tycon),
499                                nlHsVarApps intDataCon_RDR [ah_RDR]])
500              (illegal_Expr "succ" occ_nm "tried to take `succ' of last tag in enumeration")
501              (nlHsApp (nlHsVar (tag2con_RDR tycon))
502                     (nlHsApps plus_RDR [nlHsVarApps intDataCon_RDR [ah_RDR],
503                                         nlHsIntLit 1]))
504                     
505     pred_enum
506       = mk_easy_FunBind tycon_loc pred_RDR [a_Pat] $
507         untag_Expr tycon [(a_RDR, ah_RDR)] $
508         nlHsIf (nlHsApps eq_RDR [nlHsIntLit 0,
509                                nlHsVarApps intDataCon_RDR [ah_RDR]])
510              (illegal_Expr "pred" occ_nm "tried to take `pred' of first tag in enumeration")
511              (nlHsApp (nlHsVar (tag2con_RDR tycon))
512                            (nlHsApps plus_RDR [nlHsVarApps intDataCon_RDR [ah_RDR],
513                                                nlHsLit (HsInt (-1))]))
514
515     to_enum
516       = mk_easy_FunBind tycon_loc toEnum_RDR [a_Pat] $
517         nlHsIf (nlHsApps and_RDR
518                 [nlHsApps ge_RDR [nlHsVar a_RDR, nlHsIntLit 0],
519                  nlHsApps le_RDR [nlHsVar a_RDR, nlHsVar (maxtag_RDR tycon)]])
520              (nlHsVarApps (tag2con_RDR tycon) [a_RDR])
521              (illegal_toEnum_tag occ_nm (maxtag_RDR tycon))
522
523     enum_from
524       = mk_easy_FunBind tycon_loc enumFrom_RDR [a_Pat] $
525           untag_Expr tycon [(a_RDR, ah_RDR)] $
526           nlHsApps map_RDR 
527                 [nlHsVar (tag2con_RDR tycon),
528                  nlHsPar (enum_from_to_Expr
529                             (nlHsVarApps intDataCon_RDR [ah_RDR])
530                             (nlHsVar (maxtag_RDR tycon)))]
531
532     enum_from_then
533       = mk_easy_FunBind tycon_loc enumFromThen_RDR [a_Pat, b_Pat] $
534           untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)] $
535           nlHsApp (nlHsVarApps map_RDR [tag2con_RDR tycon]) $
536             nlHsPar (enum_from_then_to_Expr
537                     (nlHsVarApps intDataCon_RDR [ah_RDR])
538                     (nlHsVarApps intDataCon_RDR [bh_RDR])
539                     (nlHsIf  (nlHsApps gt_RDR [nlHsVarApps intDataCon_RDR [ah_RDR],
540                                              nlHsVarApps intDataCon_RDR [bh_RDR]])
541                            (nlHsIntLit 0)
542                            (nlHsVar (maxtag_RDR tycon))
543                            ))
544
545     from_enum
546       = mk_easy_FunBind tycon_loc fromEnum_RDR [a_Pat] $
547           untag_Expr tycon [(a_RDR, ah_RDR)] $
548           (nlHsVarApps intDataCon_RDR [ah_RDR])
549 \end{code}
550
551 %************************************************************************
552 %*                                                                      *
553         Bounded instances
554 %*                                                                      *
555 %************************************************************************
556
557 \begin{code}
558 gen_Bounded_binds :: TyCon -> (LHsBinds RdrName, DerivAuxBinds)
559 gen_Bounded_binds tycon
560   | isEnumerationTyCon tycon
561   = (listToBag [ min_bound_enum, max_bound_enum ], [])
562   | otherwise
563   = ASSERT(isSingleton data_cons)
564     (listToBag [ min_bound_1con, max_bound_1con ], [])
565   where
566     data_cons = tyConDataCons tycon
567     tycon_loc = getSrcSpan tycon
568
569     ----- enum-flavored: ---------------------------
570     min_bound_enum = mkVarBind tycon_loc minBound_RDR (nlHsVar data_con_1_RDR)
571     max_bound_enum = mkVarBind tycon_loc maxBound_RDR (nlHsVar data_con_N_RDR)
572
573     data_con_1    = head data_cons
574     data_con_N    = last data_cons
575     data_con_1_RDR = getRdrName data_con_1
576     data_con_N_RDR = getRdrName data_con_N
577
578     ----- single-constructor-flavored: -------------
579     arity          = dataConSourceArity data_con_1
580
581     min_bound_1con = mkVarBind tycon_loc minBound_RDR $
582                      nlHsVarApps data_con_1_RDR (nOfThem arity minBound_RDR)
583     max_bound_1con = mkVarBind tycon_loc maxBound_RDR $
584                      nlHsVarApps data_con_1_RDR (nOfThem arity maxBound_RDR)
585 \end{code}
586
587 %************************************************************************
588 %*                                                                      *
589         Ix instances
590 %*                                                                      *
591 %************************************************************************
592
593 Deriving @Ix@ is only possible for enumeration types and
594 single-constructor types.  We deal with them in turn.
595
596 For an enumeration type, e.g.,
597 \begin{verbatim}
598     data Foo ... = N1 | N2 | ... | Nn
599 \end{verbatim}
600 things go not too differently from @Enum@:
601 \begin{verbatim}
602 instance ... Ix (Foo ...) where
603     range (a, b)
604       = map tag2con_Foo [con2tag_Foo a .. con2tag_Foo b]
605
606     -- or, really...
607     range (a, b)
608       = case (con2tag_Foo a) of { a# ->
609         case (con2tag_Foo b) of { b# ->
610         map tag2con_Foo (enumFromTo (I# a#) (I# b#))
611         }}
612
613     -- Generate code for unsafeIndex, becuase using index leads
614     -- to lots of redundant range tests
615     unsafeIndex c@(a, b) d
616       = case (con2tag_Foo d -# con2tag_Foo a) of
617                r# -> I# r#
618
619     inRange (a, b) c
620       = let
621             p_tag = con2tag_Foo c
622         in
623         p_tag >= con2tag_Foo a && p_tag <= con2tag_Foo b
624
625     -- or, really...
626     inRange (a, b) c
627       = case (con2tag_Foo a)   of { a_tag ->
628         case (con2tag_Foo b)   of { b_tag ->
629         case (con2tag_Foo c)   of { c_tag ->
630         if (c_tag >=# a_tag) then
631           c_tag <=# b_tag
632         else
633           False
634         }}}
635 \end{verbatim}
636 (modulo suitable case-ification to handle the unlifted tags)
637
638 For a single-constructor type (NB: this includes all tuples), e.g.,
639 \begin{verbatim}
640     data Foo ... = MkFoo a b Int Double c c
641 \end{verbatim}
642 we follow the scheme given in Figure~19 of the Haskell~1.2 report
643 (p.~147).
644
645 \begin{code}
646 gen_Ix_binds :: TyCon -> (LHsBinds RdrName, DerivAuxBinds)
647
648 gen_Ix_binds tycon
649   | isEnumerationTyCon tycon
650   = (enum_ixes, [GenCon2Tag tycon, GenTag2Con tycon, GenMaxTag tycon])
651   | otherwise
652   = (single_con_ixes, [GenCon2Tag tycon])
653   where
654     tycon_loc = getSrcSpan tycon
655
656     --------------------------------------------------------------
657     enum_ixes = listToBag [ enum_range, enum_index, enum_inRange ]
658
659     enum_range
660       = mk_easy_FunBind tycon_loc range_RDR [nlTuplePat [a_Pat, b_Pat] Boxed] $
661           untag_Expr tycon [(a_RDR, ah_RDR)] $
662           untag_Expr tycon [(b_RDR, bh_RDR)] $
663           nlHsApp (nlHsVarApps map_RDR [tag2con_RDR tycon]) $
664               nlHsPar (enum_from_to_Expr
665                         (nlHsVarApps intDataCon_RDR [ah_RDR])
666                         (nlHsVarApps intDataCon_RDR [bh_RDR]))
667
668     enum_index
669       = mk_easy_FunBind tycon_loc unsafeIndex_RDR 
670                 [noLoc (AsPat (noLoc c_RDR) 
671                            (nlTuplePat [a_Pat, nlWildPat] Boxed)), 
672                                 d_Pat] (
673            untag_Expr tycon [(a_RDR, ah_RDR)] (
674            untag_Expr tycon [(d_RDR, dh_RDR)] (
675            let
676                 rhs = nlHsVarApps intDataCon_RDR [c_RDR]
677            in
678            nlHsCase
679              (genOpApp (nlHsVar dh_RDR) minusInt_RDR (nlHsVar ah_RDR))
680              [mkSimpleHsAlt (nlVarPat c_RDR) rhs]
681            ))
682         )
683
684     enum_inRange
685       = mk_easy_FunBind tycon_loc inRange_RDR [nlTuplePat [a_Pat, b_Pat] Boxed, c_Pat] $
686           untag_Expr tycon [(a_RDR, ah_RDR)] (
687           untag_Expr tycon [(b_RDR, bh_RDR)] (
688           untag_Expr tycon [(c_RDR, ch_RDR)] (
689           nlHsIf (genOpApp (nlHsVar ch_RDR) geInt_RDR (nlHsVar ah_RDR)) (
690              (genOpApp (nlHsVar ch_RDR) leInt_RDR (nlHsVar bh_RDR))
691           ) {-else-} (
692              false_Expr
693           ))))
694
695     --------------------------------------------------------------
696     single_con_ixes 
697       = listToBag [single_con_range, single_con_index, single_con_inRange]
698
699     data_con
700       = case maybeTyConSingleCon tycon of -- just checking...
701           Nothing -> panic "get_Ix_binds"
702           Just dc | any isUnLiftedType (dataConOrigArgTys dc)
703                   -> pprPanic "Can't derive Ix for a single-constructor type with primitive argument types:" (ppr tycon)
704                   | otherwise -> dc
705
706     con_arity    = dataConSourceArity data_con
707     data_con_RDR = getRdrName data_con
708
709     as_needed = take con_arity as_RDRs
710     bs_needed = take con_arity bs_RDRs
711     cs_needed = take con_arity cs_RDRs
712
713     con_pat  xs  = nlConVarPat data_con_RDR xs
714     con_expr     = nlHsVarApps data_con_RDR cs_needed
715
716     --------------------------------------------------------------
717     single_con_range
718       = mk_easy_FunBind tycon_loc range_RDR 
719           [nlTuplePat [con_pat as_needed, con_pat bs_needed] Boxed] $
720         nlHsDo ListComp stmts con_expr
721       where
722         stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
723
724         mk_qual a b c = noLoc $ mkBindStmt (nlVarPat c)
725                                  (nlHsApp (nlHsVar range_RDR) 
726                                         (nlTuple [nlHsVar a, nlHsVar b] Boxed))
727
728     ----------------
729     single_con_index
730       = mk_easy_FunBind tycon_loc unsafeIndex_RDR 
731                 [nlTuplePat [con_pat as_needed, con_pat bs_needed] Boxed, 
732                  con_pat cs_needed] 
733                 (mk_index (zip3 as_needed bs_needed cs_needed))
734       where
735         -- index (l1,u1) i1 + rangeSize (l1,u1) * (index (l2,u2) i2 + ...)
736         mk_index []        = nlHsIntLit 0
737         mk_index [(l,u,i)] = mk_one l u i
738         mk_index ((l,u,i) : rest)
739           = genOpApp (
740                 mk_one l u i
741             ) plus_RDR (
742                 genOpApp (
743                     (nlHsApp (nlHsVar unsafeRangeSize_RDR) 
744                            (nlTuple [nlHsVar l, nlHsVar u] Boxed))
745                 ) times_RDR (mk_index rest)
746            )
747         mk_one l u i
748           = nlHsApps unsafeIndex_RDR [nlTuple [nlHsVar l, nlHsVar u] Boxed, nlHsVar i]
749
750     ------------------
751     single_con_inRange
752       = mk_easy_FunBind tycon_loc inRange_RDR 
753                 [nlTuplePat [con_pat as_needed, con_pat bs_needed] Boxed, 
754                  con_pat cs_needed] $
755           foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed)
756       where
757         in_range a b c = nlHsApps inRange_RDR [nlTuple [nlHsVar a, nlHsVar b] Boxed,
758                                                nlHsVar c]
759 \end{code}
760
761 %************************************************************************
762 %*                                                                      *
763         Read instances
764 %*                                                                      *
765 %************************************************************************
766
767 Example
768
769   infix 4 %%
770   data T = Int %% Int
771          | T1 { f1 :: Int }
772          | T2 T
773
774
775 instance Read T where
776   readPrec =
777     parens
778     ( prec 4 (
779         do x           <- ReadP.step Read.readPrec
780            Symbol "%%" <- Lex.lex
781            y           <- ReadP.step Read.readPrec
782            return (x %% y))
783       +++
784       prec (appPrec+1) (
785         -- Note the "+1" part; "T2 T1 {f1=3}" should parse ok
786         -- Record construction binds even more tightly than application
787         do Ident "T1" <- Lex.lex
788            Punc '{' <- Lex.lex
789            Ident "f1" <- Lex.lex
790            Punc '=' <- Lex.lex
791            x          <- ReadP.reset Read.readPrec
792            Punc '}' <- Lex.lex
793            return (T1 { f1 = x }))
794       +++
795       prec appPrec (
796         do Ident "T2" <- Lex.lexP
797            x          <- ReadP.step Read.readPrec
798            return (T2 x))
799     )
800
801   readListPrec = readListPrecDefault
802   readList     = readListDefault
803
804
805 \begin{code}
806 gen_Read_binds :: FixityEnv -> TyCon -> (LHsBinds RdrName, DerivAuxBinds)
807
808 gen_Read_binds get_fixity tycon
809   = (listToBag [read_prec, default_readlist, default_readlistprec], [])
810   where
811     -----------------------------------------------------------------------
812     default_readlist 
813         = mkVarBind loc readList_RDR     (nlHsVar readListDefault_RDR)
814
815     default_readlistprec
816         = mkVarBind loc readListPrec_RDR (nlHsVar readListPrecDefault_RDR)
817     -----------------------------------------------------------------------
818
819     loc       = getSrcSpan tycon
820     data_cons = tyConDataCons tycon
821     (nullary_cons, non_nullary_cons) = partition isNullarySrcDataCon data_cons
822     
823     read_prec = mkVarBind loc readPrec_RDR
824                               (nlHsApp (nlHsVar parens_RDR) read_cons)
825
826     read_cons             = foldr1 mk_alt (read_nullary_cons ++ read_non_nullary_cons)
827     read_non_nullary_cons = map read_non_nullary_con non_nullary_cons
828     
829     read_nullary_cons 
830       = case nullary_cons of
831             []    -> []
832             [con] -> [nlHsDo DoExpr [bindLex (ident_pat (data_con_str con))]
833                                     (result_expr con [])]
834             _     -> [nlHsApp (nlHsVar choose_RDR) 
835                               (nlList (map mk_pair nullary_cons))]
836     
837     mk_pair con = nlTuple [nlHsLit (mkHsString (data_con_str con)), 
838                            result_expr con []]
839                           Boxed
840     
841     read_non_nullary_con data_con
842       | is_infix  = mk_parser infix_prec  infix_stmts  body
843       | is_record = mk_parser record_prec record_stmts body
844 --              Using these two lines instead allows the derived
845 --              read for infix and record bindings to read the prefix form
846 --      | is_infix  = mk_alt prefix_parser (mk_parser infix_prec  infix_stmts  body)
847 --      | is_record = mk_alt prefix_parser (mk_parser record_prec record_stmts body)
848       | otherwise = prefix_parser
849       where
850         body = result_expr data_con as_needed
851         con_str = data_con_str data_con
852         
853         prefix_parser = mk_parser prefix_prec prefix_stmts body
854         prefix_stmts            -- T a b c
855           = (if not (isSym con_str) then
856                   [bindLex (ident_pat con_str)]
857              else [read_punc "(", bindLex (symbol_pat con_str), read_punc ")"])
858             ++ read_args
859          
860         infix_stmts             -- a %% b, or  a `T` b 
861           = [read_a1]
862             ++  (if isSym con_str
863                  then [bindLex (symbol_pat con_str)]
864                  else [read_punc "`", bindLex (ident_pat con_str), read_punc "`"])
865             ++ [read_a2]
866      
867         record_stmts            -- T { f1 = a, f2 = b }
868           = [bindLex (ident_pat (wrapOpParens con_str)),
869              read_punc "{"]
870             ++ concat (intersperse [read_punc ","] field_stmts)
871             ++ [read_punc "}"]
872      
873         field_stmts  = zipWithEqual "lbl_stmts" read_field labels as_needed
874      
875         con_arity    = dataConSourceArity data_con
876         labels       = dataConFieldLabels data_con
877         dc_nm        = getName data_con
878         is_infix     = dataConIsInfix data_con
879         is_record    = length labels > 0
880         as_needed    = take con_arity as_RDRs
881         read_args    = zipWithEqual "gen_Read_binds" read_arg as_needed (dataConOrigArgTys data_con)
882         (read_a1:read_a2:_) = read_args
883         
884         prefix_prec = appPrecedence
885         infix_prec  = getPrecedence get_fixity dc_nm
886         record_prec = appPrecedence + 1 -- Record construction binds even more tightly
887                                         -- than application; e.g. T2 T1 {x=2} means T2 (T1 {x=2})
888
889     ------------------------------------------------------------------------
890     --          Helpers
891     ------------------------------------------------------------------------
892     mk_alt e1 e2       = genOpApp e1 alt_RDR e2                                 -- e1 +++ e2
893     mk_parser p ss b   = nlHsApps prec_RDR [nlHsIntLit p, nlHsDo DoExpr ss b]   -- prec p (do { ss ; b })
894     bindLex pat        = noLoc (mkBindStmt pat (nlHsVar lexP_RDR))              -- pat <- lexP
895     con_app con as     = nlHsVarApps (getRdrName con) as                        -- con as
896     result_expr con as = nlHsApp (nlHsVar returnM_RDR) (con_app con as)         -- return (con as)
897     
898     punc_pat s   = nlConPat punc_RDR   [nlLitPat (mkHsString s)]  -- Punc 'c'
899     ident_pat s  = nlConPat ident_RDR  [nlLitPat (mkHsString s)]  -- Ident "foo"
900     symbol_pat s = nlConPat symbol_RDR [nlLitPat (mkHsString s)]  -- Symbol ">>"
901     
902     data_con_str con = occNameString (getOccName con)
903     
904     read_punc c = bindLex (punc_pat c)
905     read_arg a ty 
906         | isUnLiftedType ty = pprPanic "Error in deriving:" (text "Can't read unlifted types yet:" <+> ppr ty)
907         | otherwise = noLoc (mkBindStmt (nlVarPat a) (nlHsVarApps step_RDR [readPrec_RDR]))
908     
909     read_field lbl a = read_lbl lbl ++
910                        [read_punc "=",
911                         noLoc (mkBindStmt (nlVarPat a) (nlHsVarApps reset_RDR [readPrec_RDR]))]
912
913         -- When reading field labels we might encounter
914         --      a  = 3
915         --      _a = 3
916         -- or   (#) = 4
917         -- Note the parens!
918     read_lbl lbl | isSym lbl_str 
919                  = [read_punc "(", 
920                     bindLex (symbol_pat lbl_str),
921                     read_punc ")"]
922                  | otherwise
923                  = [bindLex (ident_pat lbl_str)]
924                  where  
925                    lbl_str = occNameString (getOccName lbl) 
926 \end{code}
927
928
929 %************************************************************************
930 %*                                                                      *
931         Show instances
932 %*                                                                      *
933 %************************************************************************
934
935 Example
936
937     infixr 5 :^:
938
939     data Tree a =  Leaf a  |  Tree a :^: Tree a
940
941     instance (Show a) => Show (Tree a) where
942
943         showsPrec d (Leaf m) = showParen (d > app_prec) showStr
944           where
945              showStr = showString "Leaf " . showsPrec (app_prec+1) m
946
947         showsPrec d (u :^: v) = showParen (d > up_prec) showStr
948           where
949              showStr = showsPrec (up_prec+1) u . 
950                        showString " :^: "      .
951                        showsPrec (up_prec+1) v
952                 -- Note: right-associativity of :^: ignored
953
954     up_prec  = 5    -- Precedence of :^:
955     app_prec = 10   -- Application has precedence one more than
956                     -- the most tightly-binding operator
957
958 \begin{code}
959 gen_Show_binds :: FixityEnv -> TyCon -> (LHsBinds RdrName, DerivAuxBinds)
960
961 gen_Show_binds get_fixity tycon
962   = (listToBag [shows_prec, show_list], [])
963   where
964     tycon_loc = getSrcSpan tycon
965     -----------------------------------------------------------------------
966     show_list = mkVarBind tycon_loc showList_RDR
967                   (nlHsApp (nlHsVar showList___RDR) (nlHsPar (nlHsApp (nlHsVar showsPrec_RDR) (nlHsIntLit 0))))
968     -----------------------------------------------------------------------
969     shows_prec = mk_FunBind tycon_loc showsPrec_RDR (map pats_etc (tyConDataCons tycon))
970       where
971         pats_etc data_con
972           | nullary_con =  -- skip the showParen junk...
973              ASSERT(null bs_needed)
974              ([nlWildPat, con_pat], mk_showString_app con_str)
975           | otherwise   =
976              ([a_Pat, con_pat],
977                   showParen_Expr (nlHsPar (genOpApp a_Expr ge_RDR (nlHsLit (HsInt con_prec_plus_one))))
978                                  (nlHsPar (nested_compose_Expr show_thingies)))
979             where
980              data_con_RDR  = getRdrName data_con
981              con_arity     = dataConSourceArity data_con
982              bs_needed     = take con_arity bs_RDRs
983              arg_tys       = dataConOrigArgTys data_con         -- Correspond 1-1 with bs_needed
984              con_pat       = nlConVarPat data_con_RDR bs_needed
985              nullary_con   = con_arity == 0
986              labels        = dataConFieldLabels data_con
987              lab_fields    = length labels
988              record_syntax = lab_fields > 0
989
990              dc_nm          = getName data_con
991              dc_occ_nm      = getOccName data_con
992              con_str        = occNameString dc_occ_nm
993              op_con_str     = wrapOpParens con_str
994              backquote_str  = wrapOpBackquotes con_str
995
996              show_thingies 
997                 | is_infix      = [show_arg1, mk_showString_app (" " ++ backquote_str ++ " "), show_arg2]
998                 | record_syntax = mk_showString_app (op_con_str ++ " {") : 
999                                   show_record_args ++ [mk_showString_app "}"]
1000                 | otherwise     = mk_showString_app (op_con_str ++ " ") : show_prefix_args
1001                 
1002              show_label l = mk_showString_app (nm ++ " = ")
1003                         -- Note the spaces around the "=" sign.  If we don't have them
1004                         -- then we get Foo { x=-1 } and the "=-" parses as a single
1005                         -- lexeme.  Only the space after the '=' is necessary, but
1006                         -- it seems tidier to have them both sides.
1007                  where
1008                    occ_nm   = getOccName l
1009                    nm       = wrapOpParens (occNameString occ_nm)
1010
1011              show_args               = zipWith show_arg bs_needed arg_tys
1012              (show_arg1:show_arg2:_) = show_args
1013              show_prefix_args        = intersperse (nlHsVar showSpace_RDR) show_args
1014
1015                 --  Assumption for record syntax: no of fields == no of labelled fields 
1016                 --            (and in same order)
1017              show_record_args = concat $
1018                                 intersperse [mk_showString_app ", "] $
1019                                 [ [show_label lbl, arg] 
1020                                 | (lbl,arg) <- zipEqual "gen_Show_binds" 
1021                                                         labels show_args ]
1022                                
1023                 -- Generates (showsPrec p x) for argument x, but it also boxes
1024                 -- the argument first if necessary.  Note that this prints unboxed
1025                 -- things without any '#' decorations; could change that if need be
1026              show_arg b arg_ty = nlHsApps showsPrec_RDR [nlHsLit (HsInt arg_prec), 
1027                                                          box_if_necy "Show" tycon (nlHsVar b) arg_ty]
1028
1029                 -- Fixity stuff
1030              is_infix = dataConIsInfix data_con
1031              con_prec_plus_one = 1 + getPrec is_infix get_fixity dc_nm
1032              arg_prec | record_syntax = 0       -- Record fields don't need parens
1033                       | otherwise     = con_prec_plus_one
1034
1035 wrapOpParens :: String -> String
1036 wrapOpParens s | isSym s   = '(' : s ++ ")"
1037                | otherwise = s
1038
1039 wrapOpBackquotes :: String -> String
1040 wrapOpBackquotes s | isSym s   = s
1041                    | otherwise = '`' : s ++ "`"
1042
1043 isSym :: String -> Bool
1044 isSym ""     = False
1045 isSym (c:cs) = startsVarSym c || startsConSym c
1046
1047 mk_showString_app str = nlHsApp (nlHsVar showString_RDR) (nlHsLit (mkHsString str))
1048 \end{code}
1049
1050 \begin{code}
1051 getPrec :: Bool -> FixityEnv -> Name -> Integer
1052 getPrec is_infix get_fixity nm 
1053   | not is_infix   = appPrecedence
1054   | otherwise      = getPrecedence get_fixity nm
1055                   
1056 appPrecedence :: Integer
1057 appPrecedence = fromIntegral maxPrecedence + 1
1058   -- One more than the precedence of the most 
1059   -- tightly-binding operator
1060
1061 getPrecedence :: FixityEnv -> Name -> Integer
1062 getPrecedence get_fixity nm 
1063    = case lookupFixity get_fixity nm of
1064         Fixity x _assoc -> fromIntegral x
1065           -- NB: the Report says that associativity is not taken 
1066           --     into account for either Read or Show; hence we 
1067           --     ignore associativity here
1068 \end{code}
1069
1070
1071 %************************************************************************
1072 %*                                                                      *
1073 \subsection{Typeable}
1074 %*                                                                      *
1075 %************************************************************************
1076
1077 From the data type
1078
1079         data T a b = ....
1080
1081 we generate
1082
1083         instance Typeable2 T where
1084                 typeOf2 _ = mkTyConApp (mkTyConRep "T") []
1085
1086 We are passed the Typeable2 class as well as T
1087
1088 \begin{code}
1089 gen_Typeable_binds :: TyCon -> LHsBinds RdrName
1090 gen_Typeable_binds tycon
1091   = unitBag $
1092         mk_easy_FunBind tycon_loc 
1093                 (mk_typeOf_RDR tycon)   -- Name of appropriate type0f function
1094                 [nlWildPat] 
1095                 (nlHsApps mkTypeRep_RDR [tycon_rep, nlList []])
1096   where
1097     tycon_loc = getSrcSpan tycon
1098     tycon_rep = nlHsVar mkTyConRep_RDR `nlHsApp` nlHsLit (mkHsString (showSDoc (ppr tycon)))
1099
1100 mk_typeOf_RDR :: TyCon -> RdrName
1101 -- Use the arity of the TyCon to make the right typeOfn function
1102 mk_typeOf_RDR tycon = varQual_RDR tYPEABLE (mkFastString ("typeOf" ++ suffix))
1103                 where
1104                   arity = tyConArity tycon
1105                   suffix | arity == 0 = ""
1106                          | otherwise  = show arity
1107 \end{code}
1108
1109
1110
1111 %************************************************************************
1112 %*                                                                      *
1113         Data instances
1114 %*                                                                      *
1115 %************************************************************************
1116
1117 From the data type
1118
1119   data T a b = T1 a b | T2
1120
1121 we generate
1122
1123   $cT1 = mkDataCon $dT "T1" Prefix
1124   $cT2 = mkDataCon $dT "T2" Prefix
1125   $dT  = mkDataType "Module.T" [] [$con_T1, $con_T2]
1126   -- the [] is for field labels.
1127
1128   instance (Data a, Data b) => Data (T a b) where
1129     gfoldl k z (T1 a b) = z T `k` a `k` b
1130     gfoldl k z T2           = z T2
1131     -- ToDo: add gmapT,Q,M, gfoldr
1132  
1133     gunfold k z c = case conIndex c of
1134                         I# 1# -> k (k (z T1))
1135                         I# 2# -> z T2
1136
1137     toConstr (T1 _ _) = $cT1
1138     toConstr T2       = $cT2
1139     
1140     dataTypeOf _ = $dT
1141
1142 \begin{code}
1143 gen_Data_binds :: FixityEnv
1144                -> TyCon 
1145                -> (LHsBinds RdrName,    -- The method bindings
1146                    DerivAuxBinds)       -- Auxiliary bindings
1147 gen_Data_binds fix_env tycon
1148   = (listToBag [gfoldl_bind, gunfold_bind, toCon_bind, dataTypeOf_bind],
1149                 -- Auxiliary definitions: the data type and constructors
1150      DerivAuxBind datatype_bind : map mk_con_bind data_cons)
1151   where
1152     tycon_loc  = getSrcSpan tycon
1153     tycon_name = tyConName tycon
1154     data_cons  = tyConDataCons tycon
1155     n_cons     = length data_cons
1156     one_constr = n_cons == 1
1157
1158         ------------ gfoldl
1159     gfoldl_bind = mk_FunBind tycon_loc gfoldl_RDR (map gfoldl_eqn data_cons)
1160     gfoldl_eqn con = ([nlVarPat k_RDR, nlVarPat z_RDR, nlConVarPat con_name as_needed], 
1161                        foldl mk_k_app (nlHsVar z_RDR `nlHsApp` nlHsVar con_name) as_needed)
1162                    where
1163                      con_name ::  RdrName
1164                      con_name = getRdrName con
1165                      as_needed = take (dataConSourceArity con) as_RDRs
1166                      mk_k_app e v = nlHsPar (nlHsOpApp e k_RDR (nlHsVar v))
1167
1168         ------------ gunfold
1169     gunfold_bind = mk_FunBind tycon_loc
1170                               gunfold_RDR
1171                               [([k_Pat, z_Pat, if one_constr then nlWildPat else c_Pat], 
1172                                 gunfold_rhs)]
1173
1174     gunfold_rhs 
1175         | one_constr = mk_unfold_rhs (head data_cons)   -- No need for case
1176         | otherwise  = nlHsCase (nlHsVar conIndex_RDR `nlHsApp` c_Expr) 
1177                                 (map gunfold_alt data_cons)
1178
1179     gunfold_alt dc = mkSimpleHsAlt (mk_unfold_pat dc) (mk_unfold_rhs dc)
1180     mk_unfold_rhs dc = foldr nlHsApp
1181                            (nlHsVar z_RDR `nlHsApp` nlHsVar (getRdrName dc))
1182                            (replicate (dataConSourceArity dc) (nlHsVar k_RDR))
1183
1184     mk_unfold_pat dc    -- Last one is a wild-pat, to avoid 
1185                         -- redundant test, and annoying warning
1186       | tag-fIRST_TAG == n_cons-1 = nlWildPat   -- Last constructor
1187       | otherwise = nlConPat intDataCon_RDR [nlLitPat (HsIntPrim (toInteger tag))]
1188       where 
1189         tag = dataConTag dc
1190                           
1191         ------------ toConstr
1192     toCon_bind = mk_FunBind tycon_loc toConstr_RDR (map to_con_eqn data_cons)
1193     to_con_eqn dc = ([nlWildConPat dc], nlHsVar (mk_constr_name dc))
1194     
1195         ------------ dataTypeOf
1196     dataTypeOf_bind = mk_easy_FunBind
1197                         tycon_loc
1198                         dataTypeOf_RDR
1199                         [nlWildPat]
1200                         (nlHsVar data_type_name)
1201
1202         ------------  $dT
1203
1204     data_type_name = mkDerivedRdrName tycon_name mkDataTOcc
1205     datatype_bind  = mkVarBind
1206                        tycon_loc
1207                        data_type_name
1208                        (           nlHsVar mkDataType_RDR 
1209                          `nlHsApp` nlHsLit (mkHsString (showSDoc (ppr tycon)))
1210                          `nlHsApp` nlList constrs
1211                        )
1212     constrs = [nlHsVar (mk_constr_name con) | con <- data_cons]
1213
1214
1215         ------------  $cT1 etc
1216     mk_constr_name con = mkDerivedRdrName (dataConName con) mkDataCOcc
1217     mk_con_bind dc = DerivAuxBind $ 
1218                      mkVarBind
1219                        tycon_loc
1220                        (mk_constr_name dc) 
1221                        (nlHsApps mkConstr_RDR (constr_args dc))
1222     constr_args dc =
1223          [ -- nlHsIntLit (toInteger (dataConTag dc)),           -- Tag
1224            nlHsVar data_type_name,                              -- DataType
1225            nlHsLit (mkHsString (occNameString dc_occ)), -- String name
1226            nlList  labels,                                      -- Field labels
1227            nlHsVar fixity]                                      -- Fixity
1228         where
1229           labels   = map (nlHsLit . mkHsString . getOccString)
1230                          (dataConFieldLabels dc)
1231           dc_occ   = getOccName dc
1232           is_infix = isDataSymOcc dc_occ
1233           fixity | is_infix  = infix_RDR
1234                  | otherwise = prefix_RDR
1235
1236 gfoldl_RDR     = varQual_RDR gENERICS FSLIT("gfoldl")
1237 gunfold_RDR    = varQual_RDR gENERICS FSLIT("gunfold")
1238 toConstr_RDR   = varQual_RDR gENERICS FSLIT("toConstr")
1239 dataTypeOf_RDR = varQual_RDR gENERICS FSLIT("dataTypeOf")
1240 mkConstr_RDR   = varQual_RDR gENERICS FSLIT("mkConstr")
1241 mkDataType_RDR = varQual_RDR gENERICS FSLIT("mkDataType")
1242 conIndex_RDR   = varQual_RDR gENERICS FSLIT("constrIndex")
1243 prefix_RDR     = dataQual_RDR gENERICS FSLIT("Prefix")
1244 infix_RDR      = dataQual_RDR gENERICS FSLIT("Infix")
1245 \end{code}
1246
1247 %************************************************************************
1248 %*                                                                      *
1249 \subsection{Generating extra binds (@con2tag@ and @tag2con@)}
1250 %*                                                                      *
1251 %************************************************************************
1252
1253 \begin{verbatim}
1254 data Foo ... = ...
1255
1256 con2tag_Foo :: Foo ... -> Int#
1257 tag2con_Foo :: Int -> Foo ...   -- easier if Int, not Int#
1258 maxtag_Foo  :: Int              -- ditto (NB: not unlifted)
1259 \end{verbatim}
1260
1261 The `tags' here start at zero, hence the @fIRST_TAG@ (currently one)
1262 fiddling around.
1263
1264 \begin{code}
1265 genAuxBind :: DerivAuxBind -> LHsBind RdrName
1266
1267 genAuxBind (DerivAuxBind bind) 
1268   = bind
1269
1270 genAuxBind (GenCon2Tag tycon)
1271   | lots_of_constructors
1272   = mk_FunBind tycon_loc rdr_name [([], get_tag_rhs)]
1273
1274   | otherwise
1275   = mk_FunBind tycon_loc rdr_name (map mk_stuff (tyConDataCons tycon))
1276
1277   where
1278     rdr_name = con2tag_RDR tycon
1279     tycon_loc = getSrcSpan tycon
1280
1281     tvs = map (mkRdrUnqual . getOccName) (tyConTyVars tycon)
1282         -- We can't use gerRdrName because that makes an Exact  RdrName
1283         -- and we can't put them in the LocalRdrEnv
1284
1285         -- Give a signature to the bound variable, so 
1286         -- that the case expression generated by getTag is
1287         -- monomorphic.  In the push-enter model we get better code.
1288     get_tag_rhs = noLoc $ ExprWithTySig 
1289                         (nlHsLam (mkSimpleHsAlt (nlVarPat a_RDR) 
1290                                               (nlHsApp (nlHsVar getTag_RDR) a_Expr)))
1291                         (noLoc (mkExplicitHsForAllTy (map (noLoc.UserTyVar) tvs) (noLoc []) con2tag_ty))
1292
1293     con2tag_ty = nlHsTyConApp (getRdrName tycon) (map nlHsTyVar tvs)
1294                 `nlHsFunTy` 
1295                 nlHsTyVar (getRdrName intPrimTyCon)
1296
1297     lots_of_constructors = tyConFamilySize tycon > 8
1298                                 -- was: mAX_FAMILY_SIZE_FOR_VEC_RETURNS
1299                                 -- but we don't do vectored returns any more.
1300
1301     mk_stuff :: DataCon -> ([LPat RdrName], LHsExpr RdrName)
1302     mk_stuff con = ([nlWildConPat con], 
1303                     nlHsLit (HsIntPrim (toInteger ((dataConTag con) - fIRST_TAG))))
1304
1305 genAuxBind (GenTag2Con tycon)
1306   = mk_FunBind (getSrcSpan tycon) rdr_name 
1307         [([nlConVarPat intDataCon_RDR [a_RDR]], 
1308            noLoc (ExprWithTySig (nlHsApp (nlHsVar tagToEnum_RDR) a_Expr) 
1309                          (nlHsTyVar (getRdrName tycon))))]
1310   where
1311     rdr_name = tag2con_RDR tycon
1312
1313 genAuxBind (GenMaxTag tycon)
1314   = mkVarBind (getSrcSpan tycon) rdr_name 
1315                   (nlHsApp (nlHsVar intDataCon_RDR) (nlHsLit (HsIntPrim max_tag)))
1316   where
1317     rdr_name = maxtag_RDR tycon
1318     max_tag =  case (tyConDataCons tycon) of
1319                  data_cons -> toInteger ((length data_cons) - fIRST_TAG)
1320 \end{code}
1321
1322 %************************************************************************
1323 %*                                                                      *
1324 \subsection{Utility bits for generating bindings}
1325 %*                                                                      *
1326 %************************************************************************
1327
1328
1329 ToDo: Better SrcLocs.
1330
1331 \begin{code}
1332 compare_gen_Case ::
1333           LHsExpr RdrName       -- What to do for equality
1334           -> LHsExpr RdrName -> LHsExpr RdrName
1335           -> LHsExpr RdrName
1336 careful_compare_Case :: -- checks for primitive types...
1337           TyCon                 -- The tycon we are deriving for
1338           -> Type
1339           -> LHsExpr RdrName    -- What to do for equality
1340           -> LHsExpr RdrName -> LHsExpr RdrName
1341           -> LHsExpr RdrName
1342
1343 cmp_eq_Expr a b = nlHsApp (nlHsApp (nlHsVar cmp_eq_RDR) a) b
1344         -- Was: compare_gen_Case cmp_eq_RDR
1345
1346 compare_gen_Case (L _ (HsVar eq_tag)) a b | eq_tag == eqTag_RDR
1347   = nlHsApp (nlHsApp (nlHsVar compare_RDR) a) b -- Simple case 
1348 compare_gen_Case eq a b                         -- General case
1349   = nlHsCase (nlHsPar (nlHsApp (nlHsApp (nlHsVar compare_RDR) a) b)) {-of-}
1350       [mkSimpleHsAlt (nlNullaryConPat ltTag_RDR) ltTag_Expr,
1351        mkSimpleHsAlt (nlNullaryConPat eqTag_RDR) eq,
1352        mkSimpleHsAlt (nlNullaryConPat gtTag_RDR) gtTag_Expr]
1353
1354 careful_compare_Case tycon ty eq a b
1355   | not (isUnLiftedType ty)
1356   = compare_gen_Case eq a b
1357   | otherwise      -- We have to do something special for primitive things...
1358   = nlHsIf (genOpApp a relevant_lt_op b)        -- Test (<) first, not (==), becuase the latter
1359            ltTag_Expr                           -- is true less often, so putting it first would
1360                                                 -- mean more tests (dynamically)
1361            (nlHsIf (genOpApp a relevant_eq_op b) eq gtTag_Expr)
1362   where
1363     relevant_eq_op = primOpRdrName (assoc_ty_id "Ord" tycon eq_op_tbl ty)
1364     relevant_lt_op = primOpRdrName (assoc_ty_id "Ord" tycon lt_op_tbl ty)
1365
1366
1367 box_if_necy :: String           -- The class involved
1368             -> TyCon            -- The tycon involved
1369             -> LHsExpr RdrName  -- The argument
1370             -> Type             -- The argument type
1371             -> LHsExpr RdrName  -- Boxed version of the arg
1372 box_if_necy cls_str tycon arg arg_ty
1373   | isUnLiftedType arg_ty = nlHsApp (nlHsVar box_con) arg
1374   | otherwise             = arg
1375   where
1376     box_con = assoc_ty_id cls_str tycon box_con_tbl arg_ty
1377
1378 assoc_ty_id :: String           -- The class involved
1379             -> TyCon            -- The tycon involved
1380             -> [(Type,a)]       -- The table
1381             -> Type             -- The type
1382             -> a                -- The result of the lookup
1383 assoc_ty_id cls_str tycon tbl ty 
1384   | null res = pprPanic "Error in deriving:" (text "Can't derive" <+> text cls_str <+> 
1385                                               text "for primitive type" <+> ppr ty)
1386   | otherwise = head res
1387   where
1388     res = [id | (ty',id) <- tbl, ty `tcEqType` ty']
1389
1390 eq_op_tbl :: [(Type, PrimOp)]
1391 eq_op_tbl =
1392     [(charPrimTy,       CharEqOp)
1393     ,(intPrimTy,        IntEqOp)
1394     ,(wordPrimTy,       WordEqOp)
1395     ,(addrPrimTy,       AddrEqOp)
1396     ,(floatPrimTy,      FloatEqOp)
1397     ,(doublePrimTy,     DoubleEqOp)
1398     ]
1399
1400 lt_op_tbl :: [(Type, PrimOp)]
1401 lt_op_tbl =
1402     [(charPrimTy,       CharLtOp)
1403     ,(intPrimTy,        IntLtOp)
1404     ,(wordPrimTy,       WordLtOp)
1405     ,(addrPrimTy,       AddrLtOp)
1406     ,(floatPrimTy,      FloatLtOp)
1407     ,(doublePrimTy,     DoubleLtOp)
1408     ]
1409
1410 box_con_tbl =
1411     [(charPrimTy,       getRdrName charDataCon)
1412     ,(intPrimTy,        getRdrName intDataCon)
1413     ,(wordPrimTy,       wordDataCon_RDR)
1414     ,(floatPrimTy,      getRdrName floatDataCon)
1415     ,(doublePrimTy,     getRdrName doubleDataCon)
1416     ]
1417
1418 -----------------------------------------------------------------------
1419
1420 and_Expr :: LHsExpr RdrName -> LHsExpr RdrName -> LHsExpr RdrName
1421 and_Expr a b = genOpApp a and_RDR    b
1422
1423 -----------------------------------------------------------------------
1424
1425 eq_Expr :: TyCon -> Type -> LHsExpr RdrName -> LHsExpr RdrName -> LHsExpr RdrName
1426 eq_Expr tycon ty a b = genOpApp a eq_op b
1427  where
1428    eq_op
1429     | not (isUnLiftedType ty) = eq_RDR
1430     | otherwise               = primOpRdrName (assoc_ty_id "Eq" tycon eq_op_tbl ty)
1431          -- we have to do something special for primitive things...
1432 \end{code}
1433
1434 \begin{code}
1435 untag_Expr :: TyCon -> [( RdrName,  RdrName)] -> LHsExpr RdrName -> LHsExpr RdrName
1436 untag_Expr tycon [] expr = expr
1437 untag_Expr tycon ((untag_this, put_tag_here) : more) expr
1438   = nlHsCase (nlHsPar (nlHsVarApps (con2tag_RDR tycon) [untag_this])) {-of-}
1439       [mkSimpleHsAlt (nlVarPat put_tag_here) (untag_Expr tycon more expr)]
1440
1441 cmp_tags_Expr ::  RdrName               -- Comparison op
1442              ->  RdrName ->  RdrName    -- Things to compare
1443              -> LHsExpr RdrName                 -- What to return if true
1444              -> LHsExpr RdrName         -- What to return if false
1445              -> LHsExpr RdrName
1446
1447 cmp_tags_Expr op a b true_case false_case
1448   = nlHsIf (genOpApp (nlHsVar a) op (nlHsVar b)) true_case false_case
1449
1450 enum_from_to_Expr
1451         :: LHsExpr RdrName -> LHsExpr RdrName
1452         -> LHsExpr RdrName
1453 enum_from_then_to_Expr
1454         :: LHsExpr RdrName -> LHsExpr RdrName -> LHsExpr RdrName
1455         -> LHsExpr RdrName
1456
1457 enum_from_to_Expr      f   t2 = nlHsApp (nlHsApp (nlHsVar enumFromTo_RDR) f) t2
1458 enum_from_then_to_Expr f t t2 = nlHsApp (nlHsApp (nlHsApp (nlHsVar enumFromThenTo_RDR) f) t) t2
1459
1460 showParen_Expr
1461         :: LHsExpr RdrName -> LHsExpr RdrName
1462         -> LHsExpr RdrName
1463
1464 showParen_Expr e1 e2 = nlHsApp (nlHsApp (nlHsVar showParen_RDR) e1) e2
1465
1466 nested_compose_Expr :: [LHsExpr RdrName] -> LHsExpr RdrName
1467
1468 nested_compose_Expr []  = panic "nested_compose_expr"   -- Arg is always non-empty
1469 nested_compose_Expr [e] = parenify e
1470 nested_compose_Expr (e:es)
1471   = nlHsApp (nlHsApp (nlHsVar compose_RDR) (parenify e)) (nested_compose_Expr es)
1472
1473 -- impossible_Expr is used in case RHSs that should never happen.
1474 -- We generate these to keep the desugarer from complaining that they *might* happen!
1475 impossible_Expr = nlHsApp (nlHsVar error_RDR) (nlHsLit (mkHsString "Urk! in TcGenDeriv"))
1476
1477 -- illegal_Expr is used when signalling error conditions in the RHS of a derived
1478 -- method. It is currently only used by Enum.{succ,pred}
1479 illegal_Expr meth tp msg = 
1480    nlHsApp (nlHsVar error_RDR) (nlHsLit (mkHsString (meth ++ '{':tp ++ "}: " ++ msg)))
1481
1482 -- illegal_toEnum_tag is an extended version of illegal_Expr, which also allows you
1483 -- to include the value of a_RDR in the error string.
1484 illegal_toEnum_tag tp maxtag =
1485    nlHsApp (nlHsVar error_RDR) 
1486            (nlHsApp (nlHsApp (nlHsVar append_RDR)
1487                        (nlHsLit (mkHsString ("toEnum{" ++ tp ++ "}: tag ("))))
1488                     (nlHsApp (nlHsApp (nlHsApp 
1489                            (nlHsVar showsPrec_RDR)
1490                            (nlHsIntLit 0))
1491                            (nlHsVar a_RDR))
1492                            (nlHsApp (nlHsApp 
1493                                (nlHsVar append_RDR)
1494                                (nlHsLit (mkHsString ") is outside of enumeration's range (0,")))
1495                                (nlHsApp (nlHsApp (nlHsApp 
1496                                         (nlHsVar showsPrec_RDR)
1497                                         (nlHsIntLit 0))
1498                                         (nlHsVar maxtag))
1499                                         (nlHsLit (mkHsString ")"))))))
1500
1501 parenify e@(L _ (HsVar _)) = e
1502 parenify e                 = mkHsPar e
1503
1504 -- genOpApp wraps brackets round the operator application, so that the
1505 -- renamer won't subsequently try to re-associate it. 
1506 genOpApp e1 op e2 = nlHsPar (nlHsOpApp e1 op e2)
1507 \end{code}
1508
1509 \begin{code}
1510 a_RDR           = mkVarUnqual FSLIT("a")
1511 b_RDR           = mkVarUnqual FSLIT("b")
1512 c_RDR           = mkVarUnqual FSLIT("c")
1513 d_RDR           = mkVarUnqual FSLIT("d")
1514 k_RDR           = mkVarUnqual FSLIT("k")
1515 z_RDR           = mkVarUnqual FSLIT("z")
1516 ah_RDR          = mkVarUnqual FSLIT("a#")
1517 bh_RDR          = mkVarUnqual FSLIT("b#")
1518 ch_RDR          = mkVarUnqual FSLIT("c#")
1519 dh_RDR          = mkVarUnqual FSLIT("d#")
1520 cmp_eq_RDR      = mkVarUnqual FSLIT("cmp_eq")
1521
1522 as_RDRs         = [ mkVarUnqual (mkFastString ("a"++show i)) | i <- [(1::Int) .. ] ]
1523 bs_RDRs         = [ mkVarUnqual (mkFastString ("b"++show i)) | i <- [(1::Int) .. ] ]
1524 cs_RDRs         = [ mkVarUnqual (mkFastString ("c"++show i)) | i <- [(1::Int) .. ] ]
1525
1526 a_Expr          = nlHsVar a_RDR
1527 b_Expr          = nlHsVar b_RDR
1528 c_Expr          = nlHsVar c_RDR
1529 ltTag_Expr      = nlHsVar ltTag_RDR
1530 eqTag_Expr      = nlHsVar eqTag_RDR
1531 gtTag_Expr      = nlHsVar gtTag_RDR
1532 false_Expr      = nlHsVar false_RDR
1533 true_Expr       = nlHsVar true_RDR
1534
1535 a_Pat           = nlVarPat a_RDR
1536 b_Pat           = nlVarPat b_RDR
1537 c_Pat           = nlVarPat c_RDR
1538 d_Pat           = nlVarPat d_RDR
1539 k_Pat           = nlVarPat k_RDR
1540 z_Pat           = nlVarPat z_RDR
1541
1542 con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon ->  RdrName
1543 -- Generates Orig s RdrName, for the binding positions
1544 con2tag_RDR tycon = mk_tc_deriv_name tycon "con2tag_"
1545 tag2con_RDR tycon = mk_tc_deriv_name tycon "tag2con_"
1546 maxtag_RDR  tycon = mk_tc_deriv_name tycon "maxtag_"
1547
1548 mk_tc_deriv_name tycon str 
1549   = mkDerivedRdrName tc_name mk_occ
1550   where
1551     tc_name = tyConName tycon
1552     mk_occ tc_occ = mkVarOccFS (mkFastString new_str)
1553                   where
1554                     new_str = str ++ occNameString tc_occ ++ "#"
1555 \end{code}
1556
1557 s RdrName for PrimOps.  Can't be done in PrelNames, because PrimOp imports
1558 PrelNames, so PrelNames can't import PrimOp.
1559
1560 \begin{code}
1561 primOpRdrName op = getRdrName (primOpId op)
1562
1563 minusInt_RDR  = primOpRdrName IntSubOp
1564 eqInt_RDR     = primOpRdrName IntEqOp
1565 ltInt_RDR     = primOpRdrName IntLtOp
1566 geInt_RDR     = primOpRdrName IntGeOp
1567 leInt_RDR     = primOpRdrName IntLeOp
1568 tagToEnum_RDR = primOpRdrName TagToEnumOp
1569
1570 error_RDR = getRdrName eRROR_ID
1571 \end{code}