2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 \section[TcGenDeriv]{Generating derived instance declarations}
6 This module is nominally ``subordinate'' to @TcDeriv@, which is the
7 ``official'' interface to deriving-related things.
9 This is where we do all the grimy bindings' generation.
20 gen_tag_n_con_monobind,
22 con2tag_RDR, tag2con_RDR, maxtag_RDR,
27 #include "HsVersions.h"
29 import HsSyn ( Pat(..), HsConDetails(..), HsExpr(..), MonoBinds(..),
30 Match(..), GRHSs(..), Stmt(..), HsLit(..),
31 HsBinds(..), HsType(..), HsStmtContext(..),
32 unguardedRHS, mkSimpleMatch, mkMonoBind, andMonoBindList, placeHolderType
34 import RdrName ( RdrName, mkUnqual, nameRdrName, getRdrName )
35 import RdrHsSyn ( mkHsOpApp, RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat, mkHsDo )
36 import BasicTypes ( RecFlag(..), Fixity(..), FixityDirection(..)
40 import FieldLabel ( fieldLabelName )
41 import DataCon ( isNullaryDataCon, dataConTag,
42 dataConOrigArgTys, dataConSourceArity, fIRST_TAG,
45 import Name ( getOccString, getOccName, getSrcLoc, occNameString,
46 occNameUserString, varName,
48 isDataSymOcc, isSymOcc
51 import HscTypes ( FixityEnv, lookupFixity )
52 import PrelNames -- Lots of Names
53 import PrimOp -- Lots of Names
54 import SrcLoc ( generatedSrcLoc, SrcLoc )
55 import TyCon ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon,
56 maybeTyConSingleCon, tyConFamilySize, tyConTyVars
58 import TcType ( isUnLiftedType, tcEqType, Type )
59 import TysPrim ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy,
60 floatPrimTy, doublePrimTy
62 import Util ( zipWithEqual, isSingleton,
63 zipWith3Equal, nOfThem, zipEqual )
64 import Panic ( panic, assertPanic )
65 import Char ( ord, isAlpha )
67 import List ( partition, intersperse )
72 %************************************************************************
74 \subsection{Generating code, by derivable class}
76 %************************************************************************
78 %************************************************************************
80 \subsubsection{Generating @Eq@ instance declarations}
82 %************************************************************************
84 Here are the heuristics for the code we generate for @Eq@:
87 Let's assume we have a data type with some (possibly zero) nullary
88 data constructors and some ordinary, non-nullary ones (the rest,
89 also possibly zero of them). Here's an example, with both \tr{N}ullary
90 and \tr{O}rdinary data cons.
92 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
96 For the ordinary constructors (if any), we emit clauses to do The
100 (==) (O1 a1 b1) (O1 a2 b2) = a1 == a2 && b1 == b2
101 (==) (O2 a1) (O2 a2) = a1 == a2
102 (==) (O3 a1 b1 c1) (O3 a2 b2 c2) = a1 == a2 && b1 == b2 && c1 == c2
105 Note: if we're comparing unlifted things, e.g., if \tr{a1} and
106 \tr{a2} are \tr{Float#}s, then we have to generate
108 case (a1 `eqFloat#` a2) of
111 for that particular test.
114 If there are any nullary constructors, we emit a catch-all clause of
118 (==) a b = case (con2tag_Foo a) of { a# ->
119 case (con2tag_Foo b) of { b# ->
120 case (a# ==# b#) of {
125 If there aren't any nullary constructors, we emit a simpler
132 For the @(/=)@ method, we normally just use the default method.
134 If the type is an enumeration type, we could/may/should? generate
135 special code that calls @con2tag_Foo@, much like for @(==)@ shown
139 We thought about doing this: If we're also deriving @Ord@ for this
142 instance ... Eq (Foo ...) where
143 (==) a b = case (compare a b) of { _LT -> False; _EQ -> True ; _GT -> False}
144 (/=) a b = case (compare a b) of { _LT -> True ; _EQ -> False; _GT -> True }
146 However, that requires that \tr{Ord <whatever>} was put in the context
147 for the instance decl, which it probably wasn't, so the decls
148 produced don't get through the typechecker.
152 deriveEq :: RdrName -- Class
153 -> RdrName -- Type constructor
154 -> [ (RdrName, [RdrType]) ] -- Constructors
155 -> (RdrContext, -- Context for the inst decl
156 [RdrBind], -- Binds in the inst decl
157 [RdrBind]) -- Extra value bindings outside
159 deriveEq clas tycon constrs
160 = (context, [eq_bind, ne_bind], [])
162 context = [(clas, [ty]) | (_, tys) <- constrs, ty <- tys]
165 (nullary_cons, non_nullary_cons) = partition is_nullary constrs
166 is_nullary (_, args) = null args
169 gen_Eq_binds :: TyCon -> RdrNameMonoBinds
173 tycon_loc = getSrcLoc tycon
174 (nullary_cons, nonnullary_cons)
175 | isNewTyCon tycon = ([], tyConDataCons tycon)
176 | otherwise = partition isNullaryDataCon (tyConDataCons tycon)
179 = if (null nullary_cons) then
180 case maybeTyConSingleCon tycon of
182 Nothing -> -- if cons don't match, then False
183 [([wildPat, wildPat], false_Expr)]
184 else -- calc. and compare the tags
186 untag_Expr tycon [(a_RDR,ah_RDR), (b_RDR,bh_RDR)]
187 (genOpApp (HsVar ah_RDR) eqInt_RDR (HsVar bh_RDR)))]
189 mk_FunMonoBind tycon_loc eq_RDR ((map pats_etc nonnullary_cons) ++ rest)
191 mk_easy_FunMonoBind tycon_loc ne_RDR [a_Pat, b_Pat] [] (
192 HsApp (HsVar not_RDR) (HsPar (mkHsVarApps eq_RDR [a_RDR, b_RDR])))
194 ------------------------------------------------------------------
197 con1_pat = mkConPat data_con_RDR as_needed
198 con2_pat = mkConPat data_con_RDR bs_needed
200 data_con_RDR = getRdrName data_con
201 con_arity = length tys_needed
202 as_needed = take con_arity as_RDRs
203 bs_needed = take con_arity bs_RDRs
204 tys_needed = dataConOrigArgTys data_con
206 ([con1_pat, con2_pat], nested_eq_expr tys_needed as_needed bs_needed)
208 nested_eq_expr [] [] [] = true_Expr
209 nested_eq_expr tys as bs
210 = foldl1 and_Expr (zipWith3Equal "nested_eq" nested_eq tys as bs)
212 nested_eq ty a b = HsPar (eq_Expr ty (HsVar a) (HsVar b))
215 %************************************************************************
217 \subsubsection{Generating @Ord@ instance declarations}
219 %************************************************************************
221 For a derived @Ord@, we concentrate our attentions on @compare@
223 compare :: a -> a -> Ordering
224 data Ordering = LT | EQ | GT deriving ()
227 We will use the same example data type as above:
229 data Foo ... = N1 | N2 ... | Nn | O1 a b | O2 Int | O3 Double b b | ...
234 We do all the other @Ord@ methods with calls to @compare@:
236 instance ... (Ord <wurble> <wurble>) where
237 a < b = case (compare a b) of { LT -> True; EQ -> False; GT -> False }
238 a <= b = case (compare a b) of { LT -> True; EQ -> True; GT -> False }
239 a >= b = case (compare a b) of { LT -> False; EQ -> True; GT -> True }
240 a > b = case (compare a b) of { LT -> False; EQ -> False; GT -> True }
242 max a b = case (compare a b) of { LT -> b; EQ -> a; GT -> a }
243 min a b = case (compare a b) of { LT -> a; EQ -> b; GT -> b }
245 -- compare to come...
249 @compare@ always has two parts. First, we use the compared
250 data-constructors' tags to deal with the case of different
253 compare a b = case (con2tag_Foo a) of { a# ->
254 case (con2tag_Foo b) of { b# ->
255 case (a# ==# b#) of {
257 False -> case (a# <# b#) of
262 cmp_eq = ... to come ...
266 We are only left with the ``help'' function @cmp_eq@, to deal with
267 comparing data constructors with the same tag.
269 For the ordinary constructors (if any), we emit the sorta-obvious
270 compare-style stuff; for our example:
272 cmp_eq (O1 a1 b1) (O1 a2 b2)
273 = case (compare a1 a2) of { LT -> LT; EQ -> compare b1 b2; GT -> GT }
275 cmp_eq (O2 a1) (O2 a2)
278 cmp_eq (O3 a1 b1 c1) (O3 a2 b2 c2)
279 = case (compare a1 a2) of {
282 EQ -> case compare b1 b2 of {
290 Again, we must be careful about unlifted comparisons. For example,
291 if \tr{a1} and \tr{a2} were \tr{Int#}s in the 2nd example above, we'd need to
295 cmp_eq lt eq gt (O2 a1) (O2 a2)
297 -- or maybe the unfolded equivalent
301 For the remaining nullary constructors, we already know that the
308 If there is only one constructor in the Data Type we don't need the WildCard Pattern.
312 gen_Ord_binds :: TyCon -> RdrNameMonoBinds
315 = compare -- `AndMonoBinds` compare
316 -- The default declaration in PrelBase handles this
318 tycon_loc = getSrcLoc tycon
319 --------------------------------------------------------------------
320 compare = mk_easy_FunMonoBind tycon_loc compare_RDR
321 [a_Pat, b_Pat] [cmp_eq] compare_rhs
323 | single_con_type = cmp_eq_Expr a_Expr b_Expr
325 = untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
326 (cmp_tags_Expr eqInt_RDR ah_RDR bh_RDR
327 (cmp_eq_Expr a_Expr b_Expr) -- True case
328 -- False case; they aren't equal
329 -- So we need to do a less-than comparison on the tags
330 (cmp_tags_Expr ltInt_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr))
332 tycon_data_cons = tyConDataCons tycon
333 single_con_type = isSingleton tycon_data_cons
334 (nullary_cons, nonnullary_cons)
335 | isNewTyCon tycon = ([], tyConDataCons tycon)
336 | otherwise = partition isNullaryDataCon tycon_data_cons
338 cmp_eq = mk_FunMonoBind tycon_loc cmp_eq_RDR cmp_eq_match
340 | isEnumerationTyCon tycon
341 -- We know the tags are equal, so if it's an enumeration TyCon,
342 -- then there is nothing left to do
343 -- Catch this specially to avoid warnings
344 -- about overlapping patterns from the desugarer,
345 -- and to avoid unnecessary pattern-matching
346 = [([wildPat,wildPat], eqTag_Expr)]
348 = map pats_etc nonnullary_cons ++
349 (if single_con_type then -- Omit wildcards when there's just one
350 [] -- constructor, to silence desugarer
352 [([wildPat, wildPat], default_rhs)])
356 = ([con1_pat, con2_pat],
357 nested_compare_expr tys_needed as_needed bs_needed)
359 con1_pat = mkConPat data_con_RDR as_needed
360 con2_pat = mkConPat data_con_RDR bs_needed
362 data_con_RDR = getRdrName data_con
363 con_arity = length tys_needed
364 as_needed = take con_arity as_RDRs
365 bs_needed = take con_arity bs_RDRs
366 tys_needed = dataConOrigArgTys data_con
368 nested_compare_expr [ty] [a] [b]
369 = careful_compare_Case ty eqTag_Expr (HsVar a) (HsVar b)
371 nested_compare_expr (ty:tys) (a:as) (b:bs)
372 = let eq_expr = nested_compare_expr tys as bs
373 in careful_compare_Case ty eq_expr (HsVar a) (HsVar b)
375 default_rhs | null nullary_cons = impossible_Expr -- Keep desugarer from complaining about
376 -- inexhaustive patterns
377 | otherwise = eqTag_Expr -- Some nullary constructors;
378 -- Tags are equal, no args => return EQ
381 %************************************************************************
383 \subsubsection{Generating @Enum@ instance declarations}
385 %************************************************************************
387 @Enum@ can only be derived for enumeration types. For a type
389 data Foo ... = N1 | N2 | ... | Nn
392 we use both @con2tag_Foo@ and @tag2con_Foo@ functions, as well as a
393 @maxtag_Foo@ variable (all generated by @gen_tag_n_con_binds@).
396 instance ... Enum (Foo ...) where
397 succ x = toEnum (1 + fromEnum x)
398 pred x = toEnum (fromEnum x - 1)
400 toEnum i = tag2con_Foo i
402 enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo]
406 = case con2tag_Foo a of
407 a# -> map tag2con_Foo (enumFromTo (I# a#) maxtag_Foo)
410 = map tag2con_Foo [con2tag_Foo a, con2tag_Foo b .. maxtag_Foo]
414 = case con2tag_Foo a of { a# ->
415 case con2tag_Foo b of { b# ->
416 map tag2con_Foo (enumFromThenTo (I# a#) (I# b#) maxtag_Foo)
420 For @enumFromTo@ and @enumFromThenTo@, we use the default methods.
423 gen_Enum_binds :: TyCon -> RdrNameMonoBinds
426 = succ_enum `AndMonoBinds`
427 pred_enum `AndMonoBinds`
428 to_enum `AndMonoBinds`
429 enum_from `AndMonoBinds`
430 enum_from_then `AndMonoBinds`
433 tycon_loc = getSrcLoc tycon
434 occ_nm = getOccString tycon
437 = mk_easy_FunMonoBind tycon_loc succ_RDR [a_Pat] [] $
438 untag_Expr tycon [(a_RDR, ah_RDR)] $
439 HsIf (mkHsApps eq_RDR [HsVar (maxtag_RDR tycon),
440 mkHsVarApps mkInt_RDR [ah_RDR]])
441 (illegal_Expr "succ" occ_nm "tried to take `succ' of last tag in enumeration")
442 (HsApp (HsVar (tag2con_RDR tycon))
443 (mkHsApps plus_RDR [mkHsVarApps mkInt_RDR [ah_RDR],
448 = mk_easy_FunMonoBind tycon_loc pred_RDR [a_Pat] [] $
449 untag_Expr tycon [(a_RDR, ah_RDR)] $
450 HsIf (mkHsApps eq_RDR [mkHsIntLit 0,
451 mkHsVarApps mkInt_RDR [ah_RDR]])
452 (illegal_Expr "pred" occ_nm "tried to take `pred' of first tag in enumeration")
453 (HsApp (HsVar (tag2con_RDR tycon))
454 (mkHsApps plus_RDR [mkHsVarApps mkInt_RDR [ah_RDR],
455 HsLit (HsInt (-1))]))
459 = mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $
460 HsIf (mkHsApps and_RDR
461 [mkHsApps ge_RDR [HsVar a_RDR, mkHsIntLit 0],
462 mkHsApps le_RDR [HsVar a_RDR, HsVar (maxtag_RDR tycon)]])
463 (mkHsVarApps (tag2con_RDR tycon) [a_RDR])
464 (illegal_toEnum_tag occ_nm (maxtag_RDR tycon))
468 = mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $
469 untag_Expr tycon [(a_RDR, ah_RDR)] $
471 [HsVar (tag2con_RDR tycon),
472 HsPar (enum_from_to_Expr
473 (mkHsVarApps mkInt_RDR [ah_RDR])
474 (HsVar (maxtag_RDR tycon)))]
477 = mk_easy_FunMonoBind tycon_loc enumFromThen_RDR [a_Pat, b_Pat] [] $
478 untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)] $
479 HsApp (mkHsVarApps map_RDR [tag2con_RDR tycon]) $
480 HsPar (enum_from_then_to_Expr
481 (mkHsVarApps mkInt_RDR [ah_RDR])
482 (mkHsVarApps mkInt_RDR [bh_RDR])
483 (HsIf (mkHsApps gt_RDR [mkHsVarApps mkInt_RDR [ah_RDR],
484 mkHsVarApps mkInt_RDR [bh_RDR]])
486 (HsVar (maxtag_RDR tycon))
490 = mk_easy_FunMonoBind tycon_loc fromEnum_RDR [a_Pat] [] $
491 untag_Expr tycon [(a_RDR, ah_RDR)] $
492 (mkHsVarApps mkInt_RDR [ah_RDR])
495 %************************************************************************
497 \subsubsection{Generating @Bounded@ instance declarations}
499 %************************************************************************
502 gen_Bounded_binds tycon
503 = if isEnumerationTyCon tycon then
504 min_bound_enum `AndMonoBinds` max_bound_enum
506 ASSERT(isSingleton data_cons)
507 min_bound_1con `AndMonoBinds` max_bound_1con
509 data_cons = tyConDataCons tycon
510 tycon_loc = getSrcLoc tycon
512 ----- enum-flavored: ---------------------------
513 min_bound_enum = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] (HsVar data_con_1_RDR)
514 max_bound_enum = mk_easy_FunMonoBind tycon_loc maxBound_RDR [] [] (HsVar data_con_N_RDR)
516 data_con_1 = head data_cons
517 data_con_N = last data_cons
518 data_con_1_RDR = getRdrName data_con_1
519 data_con_N_RDR = getRdrName data_con_N
521 ----- single-constructor-flavored: -------------
522 arity = dataConSourceArity data_con_1
524 min_bound_1con = mk_easy_FunMonoBind tycon_loc minBound_RDR [] [] $
525 mkHsVarApps data_con_1_RDR (nOfThem arity minBound_RDR)
526 max_bound_1con = mk_easy_FunMonoBind tycon_loc maxBound_RDR [] [] $
527 mkHsVarApps data_con_1_RDR (nOfThem arity maxBound_RDR)
530 %************************************************************************
532 \subsubsection{Generating @Ix@ instance declarations}
534 %************************************************************************
536 Deriving @Ix@ is only possible for enumeration types and
537 single-constructor types. We deal with them in turn.
539 For an enumeration type, e.g.,
541 data Foo ... = N1 | N2 | ... | Nn
543 things go not too differently from @Enum@:
545 instance ... Ix (Foo ...) where
547 = map tag2con_Foo [con2tag_Foo a .. con2tag_Foo b]
551 = case (con2tag_Foo a) of { a# ->
552 case (con2tag_Foo b) of { b# ->
553 map tag2con_Foo (enumFromTo (I# a#) (I# b#))
558 then case (con2tag_Foo d -# con2tag_Foo a) of
560 else error "Ix.Foo.index: out of range"
564 p_tag = con2tag_Foo c
566 p_tag >= con2tag_Foo a && p_tag <= con2tag_Foo b
570 = case (con2tag_Foo a) of { a_tag ->
571 case (con2tag_Foo b) of { b_tag ->
572 case (con2tag_Foo c) of { c_tag ->
573 if (c_tag >=# a_tag) then
579 (modulo suitable case-ification to handle the unlifted tags)
581 For a single-constructor type (NB: this includes all tuples), e.g.,
583 data Foo ... = MkFoo a b Int Double c c
585 we follow the scheme given in Figure~19 of the Haskell~1.2 report
589 gen_Ix_binds :: TyCon -> RdrNameMonoBinds
592 = if isEnumerationTyCon tycon
596 tycon_str = getOccString tycon
597 tycon_loc = getSrcLoc tycon
599 --------------------------------------------------------------
600 enum_ixes = enum_range `AndMonoBinds`
601 enum_index `AndMonoBinds` enum_inRange
604 = mk_easy_FunMonoBind tycon_loc range_RDR
605 [TuplePat [a_Pat, b_Pat] Boxed] [] $
606 untag_Expr tycon [(a_RDR, ah_RDR)] $
607 untag_Expr tycon [(b_RDR, bh_RDR)] $
608 HsApp (mkHsVarApps map_RDR [tag2con_RDR tycon]) $
609 HsPar (enum_from_to_Expr
610 (mkHsVarApps mkInt_RDR [ah_RDR])
611 (mkHsVarApps mkInt_RDR [bh_RDR]))
614 = mk_easy_FunMonoBind tycon_loc index_RDR
615 [AsPat c_RDR (TuplePat [a_Pat, wildPat] Boxed),
617 HsIf (HsPar (mkHsVarApps inRange_RDR [c_RDR, d_RDR])) (
618 untag_Expr tycon [(a_RDR, ah_RDR)] (
619 untag_Expr tycon [(d_RDR, dh_RDR)] (
621 rhs = mkHsVarApps mkInt_RDR [c_RDR]
624 (genOpApp (HsVar dh_RDR) minusInt_RDR (HsVar ah_RDR))
625 [mkSimpleMatch [VarPat c_RDR] rhs placeHolderType tycon_loc]
629 HsApp (HsVar error_RDR) (HsLit (HsString (mkFastString ("Ix."++tycon_str++".index: out of range\n"))))
634 = mk_easy_FunMonoBind tycon_loc inRange_RDR
635 [TuplePat [a_Pat, b_Pat] Boxed, c_Pat] [] (
636 untag_Expr tycon [(a_RDR, ah_RDR)] (
637 untag_Expr tycon [(b_RDR, bh_RDR)] (
638 untag_Expr tycon [(c_RDR, ch_RDR)] (
639 HsIf (genOpApp (HsVar ch_RDR) geInt_RDR (HsVar ah_RDR)) (
640 (genOpApp (HsVar ch_RDR) leInt_RDR (HsVar bh_RDR))
645 --------------------------------------------------------------
647 = single_con_range `AndMonoBinds`
648 single_con_index `AndMonoBinds`
652 = case maybeTyConSingleCon tycon of -- just checking...
653 Nothing -> panic "get_Ix_binds"
654 Just dc -> if (any isUnLiftedType (dataConOrigArgTys dc)) then
655 error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
659 con_arity = dataConSourceArity data_con
660 data_con_RDR = getRdrName data_con
662 as_needed = take con_arity as_RDRs
663 bs_needed = take con_arity bs_RDRs
664 cs_needed = take con_arity cs_RDRs
666 con_pat xs = mkConPat data_con_RDR xs
667 con_expr = mkHsVarApps data_con_RDR cs_needed
669 --------------------------------------------------------------
671 = mk_easy_FunMonoBind tycon_loc range_RDR
672 [TuplePat [con_pat as_needed, con_pat bs_needed] Boxed] [] $
673 mkHsDo ListComp stmts tycon_loc
675 stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
677 [ResultStmt con_expr tycon_loc]
679 mk_qual a b c = BindStmt (VarPat c)
680 (HsApp (HsVar range_RDR)
681 (ExplicitTuple [HsVar a, HsVar b] Boxed))
686 = mk_easy_FunMonoBind tycon_loc index_RDR
687 [TuplePat [con_pat as_needed, con_pat bs_needed] Boxed,
688 con_pat cs_needed] [range_size] (
689 foldl mk_index (mkHsIntLit 0) (zip3 as_needed bs_needed cs_needed))
691 mk_index multiply_by (l, u, i)
693 (mkHsApps index_RDR [ExplicitTuple [HsVar l, HsVar u] Boxed,
697 (HsApp (HsVar rangeSize_RDR)
698 (ExplicitTuple [HsVar l, HsVar u] Boxed))
699 ) times_RDR multiply_by
703 = mk_easy_FunMonoBind tycon_loc rangeSize_RDR
704 [TuplePat [a_Pat, b_Pat] Boxed] [] (
706 (mkHsApps index_RDR [ExplicitTuple [a_Expr, b_Expr] Boxed,
708 ) plus_RDR (mkHsIntLit 1))
712 = mk_easy_FunMonoBind tycon_loc inRange_RDR
713 [TuplePat [con_pat as_needed, con_pat bs_needed] Boxed,
716 foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed))
718 in_range a b c = mkHsApps inRange_RDR [ExplicitTuple [HsVar a, HsVar b] Boxed,
722 %************************************************************************
724 \subsubsection{Generating @Read@ instance declarations}
726 %************************************************************************
736 instance Read T where
740 do x <- ReadP.step Read.readPrec
741 Symbol "%%" <- Lex.lex
742 y <- ReadP.step Read.readPrec
746 do Ident "T1" <- Lex.lex
748 Ident "f1" <- Lex.lex
750 x <- ReadP.reset Read.readPrec
752 return (T1 { f1 = x }))
755 do Ident "T2" <- Lex.lexP
756 x <- ReadP.step Read.readPrec
760 readListPrec = readListPrecDefault
761 readList = readListDefault
765 gen_Read_binds :: FixityEnv -> TyCon -> RdrNameMonoBinds
767 gen_Read_binds get_fixity tycon
768 = read_prec `AndMonoBinds` default_binds
770 -----------------------------------------------------------------------
772 = mk_easy_FunMonoBind loc readList_RDR [] [] (HsVar readListDefault_RDR)
774 mk_easy_FunMonoBind loc readListPrec_RDR [] [] (HsVar readListPrecDefault_RDR)
775 -----------------------------------------------------------------------
777 loc = getSrcLoc tycon
778 data_cons = tyConDataCons tycon
779 (nullary_cons, non_nullary_cons) = partition isNullaryDataCon data_cons
781 read_prec = mk_easy_FunMonoBind loc readPrec_RDR [] []
782 (HsApp (HsVar parens_RDR) read_cons)
784 read_cons = foldr1 mk_alt (read_nullary_cons ++ read_non_nullary_cons)
785 read_non_nullary_cons = map read_non_nullary_con non_nullary_cons
788 = case nullary_cons of
790 [con] -> [mkHsDo DoExpr [bindLex (ident_pat (data_con_str con)),
791 result_stmt con []] loc]
792 _ -> [HsApp (HsVar choose_RDR)
793 (ExplicitList placeHolderType (map mk_pair nullary_cons))]
795 mk_pair con = ExplicitTuple [HsLit (data_con_str con),
796 HsApp (HsVar returnM_RDR) (HsVar (getRdrName con))]
799 read_non_nullary_con data_con
800 = mkHsApps prec_RDR [mkHsIntLit prec, mkHsDo DoExpr stmts loc]
802 stmts | is_infix = infix_stmts
803 | length labels > 0 = lbl_stmts
804 | otherwise = prefix_stmts
806 prefix_stmts -- T a b c
807 = [bindLex (ident_pat (data_con_str data_con))]
808 ++ map read_arg as_needed
809 ++ [result_stmt data_con as_needed]
811 infix_stmts -- a %% b
813 bindLex (symbol_pat (data_con_str data_con)),
815 result_stmt data_con [a1,a2]]
817 lbl_stmts -- T { f1 = a, f2 = b }
818 = [bindLex (ident_pat (data_con_str data_con)),
820 ++ concat (intersperse [read_punc ","] field_stmts)
821 ++ [read_punc "}", result_stmt data_con as_needed]
823 field_stmts = zipWithEqual "lbl_stmts" read_field labels as_needed
825 con_arity = dataConSourceArity data_con
826 nullary_con = con_arity == 0
827 labels = dataConFieldLabels data_con
828 lab_fields = length labels
829 dc_nm = getName data_con
830 is_infix = isDataSymOcc (getOccName dc_nm)
831 as_needed = take con_arity as_RDRs
832 (a1:a2:_) = as_needed
833 prec = getPrec is_infix get_fixity dc_nm
835 ------------------------------------------------------------------------
837 ------------------------------------------------------------------------
838 mk_alt e1 e2 = genOpApp e1 alt_RDR e2
839 bindLex pat = BindStmt pat (HsVar lexP_RDR) loc
840 result_stmt c as = ResultStmt (HsApp (HsVar returnM_RDR) (con_app c as)) loc
841 con_app c as = mkHsVarApps (getRdrName c) as
843 punc_pat s = ConPatIn punc_RDR (PrefixCon [LitPat (mkHsString s)]) -- Punc 'c'
844 ident_pat s = ConPatIn ident_RDR (PrefixCon [LitPat s]) -- Ident "foo"
845 symbol_pat s = ConPatIn symbol_RDR (PrefixCon [LitPat s]) -- Symbol ">>"
847 data_con_str con = mkHsString (occNameUserString (getOccName con))
849 read_punc c = bindLex (punc_pat c)
850 read_arg a = BindStmt (VarPat a) (mkHsVarApps step_RDR [readPrec_RDR]) loc
852 read_field lbl a = read_lbl lbl ++
854 BindStmt (VarPat a) (mkHsVarApps reset_RDR [readPrec_RDR]) loc]
856 -- When reading field labels we might encounter
860 read_lbl lbl | isAlpha (head lbl_str)
861 = [bindLex (ident_pat lbl_lit)]
864 bindLex (symbol_pat lbl_lit),
867 lbl_str = occNameUserString (getOccName (fieldLabelName lbl))
868 lbl_lit = mkHsString lbl_str
872 %************************************************************************
874 \subsubsection{Generating @Show@ instance declarations}
876 %************************************************************************
882 data Tree a = Leaf a | Tree a :^: Tree a
884 instance (Show a) => Show (Tree a) where
886 showsPrec d (Leaf m) = showParen (d > app_prec) showStr
888 showStr = showString "Leaf " . showsPrec (app_prec+1) m
890 showsPrec d (u :^: v) = showParen (d > up_prec) showStr
892 showStr = showsPrec (up_prec+1) u .
894 showsPrec (up_prec+1) v
895 -- Note: right-associativity of :^: ignored
897 up_prec = 5 -- Precedence of :^:
898 app_prec = 10 -- Application has precedence one more than
899 -- the most tightly-binding operator
902 gen_Show_binds :: FixityEnv -> TyCon -> RdrNameMonoBinds
904 gen_Show_binds get_fixity tycon
905 = shows_prec `AndMonoBinds` show_list
907 tycon_loc = getSrcLoc tycon
908 -----------------------------------------------------------------------
909 show_list = mk_easy_FunMonoBind tycon_loc showList_RDR [] []
910 (HsApp (HsVar showList___RDR) (HsPar (HsApp (HsVar showsPrec_RDR) (mkHsIntLit 0))))
911 -----------------------------------------------------------------------
912 shows_prec = mk_FunMonoBind tycon_loc showsPrec_RDR (map pats_etc (tyConDataCons tycon))
915 | nullary_con = -- skip the showParen junk...
916 ASSERT(null bs_needed)
917 ([wildPat, con_pat], mk_showString_app con_str)
920 showParen_Expr (HsPar (genOpApp a_Expr ge_RDR (HsLit (HsInt con_prec_plus_one))))
921 (HsPar (nested_compose_Expr show_thingies)))
923 data_con_RDR = getRdrName data_con
924 con_arity = dataConSourceArity data_con
925 bs_needed = take con_arity bs_RDRs
926 con_pat = mkConPat data_con_RDR bs_needed
927 nullary_con = con_arity == 0
928 labels = dataConFieldLabels data_con
929 lab_fields = length labels
930 record_syntax = lab_fields > 0
932 dc_nm = getName data_con
933 dc_occ_nm = getOccName data_con
934 con_str = occNameUserString dc_occ_nm
937 | is_infix = [show_arg1, mk_showString_app (" " ++ con_str ++ " "), show_arg2]
938 | record_syntax = mk_showString_app (con_str ++ " {") :
939 show_record_args ++ [mk_showString_app "}"]
940 | otherwise = mk_showString_app (con_str ++ " ") : show_prefix_args
942 show_label l = mk_showString_app (the_name ++ " = ")
943 -- Note the spaces around the "=" sign. If we don't have them
944 -- then we get Foo { x=-1 } and the "=-" parses as a single
945 -- lexeme. Only the space after the '=' is necessary, but
946 -- it seems tidier to have them both sides.
948 occ_nm = getOccName (fieldLabelName l)
949 nm = occNameUserString occ_nm
951 is_op = isSymOcc occ_nm -- Legal, but rare.
953 | is_op = '(':nm ++ ")"
956 show_args = [ mkHsApps showsPrec_RDR [HsLit (HsInt arg_prec), HsVar b]
958 (show_arg1:show_arg2:_) = show_args
959 show_prefix_args = intersperse (HsVar showSpace_RDR) show_args
961 -- Assumption for record syntax: no of fields == no of labelled fields
962 -- (and in same order)
963 show_record_args = concat $
964 intersperse [mk_showString_app ", "] $
965 [ [show_label lbl, arg]
966 | (lbl,arg) <- zipEqual "gen_Show_binds"
970 is_infix = isDataSymOcc dc_occ_nm
971 con_prec_plus_one = 1 + getPrec is_infix get_fixity dc_nm
972 arg_prec | record_syntax = 0 -- Record fields don't need parens
973 | otherwise = con_prec_plus_one
975 mk_showString_app str = HsApp (HsVar showString_RDR) (HsLit (mkHsString str))
979 getPrec :: Bool -> FixityEnv -> Name -> Integer
980 getPrec is_infix get_fixity nm
981 | not is_infix = appPrecedence
982 | otherwise = getPrecedence get_fixity nm
984 appPrecedence :: Integer
985 appPrecedence = fromIntegral maxPrecedence + 1
986 -- One more than the precedence of the most
987 -- tightly-binding operator
989 getPrecedence :: FixityEnv -> Name -> Integer
990 getPrecedence get_fixity nm
991 = case lookupFixity get_fixity nm of
992 Fixity x _ -> fromIntegral x
994 isLRAssoc :: FixityEnv -> Name -> (Bool, Bool)
995 isLRAssoc get_fixity nm =
996 case lookupFixity get_fixity nm of
997 Fixity _ InfixN -> (False, False)
998 Fixity _ InfixR -> (False, True)
999 Fixity _ InfixL -> (True, False)
1003 %************************************************************************
1005 \subsection{Generating extra binds (@con2tag@ and @tag2con@)}
1007 %************************************************************************
1012 con2tag_Foo :: Foo ... -> Int#
1013 tag2con_Foo :: Int -> Foo ... -- easier if Int, not Int#
1014 maxtag_Foo :: Int -- ditto (NB: not unlifted)
1017 The `tags' here start at zero, hence the @fIRST_TAG@ (currently one)
1022 = GenCon2Tag | GenTag2Con | GenMaxTag
1024 gen_tag_n_con_monobind
1025 :: (RdrName, -- (proto)Name for the thing in question
1026 TyCon, -- tycon in question
1030 gen_tag_n_con_monobind (rdr_name, tycon, GenCon2Tag)
1031 | lots_of_constructors
1032 = mk_FunMonoBind loc rdr_name [([], get_tag_rhs)]
1035 = mk_FunMonoBind loc rdr_name (map mk_stuff (tyConDataCons tycon))
1038 loc = getSrcLoc tycon
1040 -- Give a signature to the bound variable, so
1041 -- that the case expression generated by getTag is
1042 -- monomorphic. In the push-enter model we get better code.
1043 get_tag_rhs = ExprWithTySig
1044 (HsLam (mk_match loc [VarPat a_RDR]
1045 (HsApp getTag_Expr a_Expr)
1047 (HsForAllTy Nothing [] con2tag_ty)
1048 -- Nothing => implicit quantification
1050 con2tag_ty = foldl HsAppTy (HsTyVar (getRdrName tycon))
1051 [HsTyVar (getRdrName tv) | tv <- tyConTyVars tycon]
1053 HsTyVar (getRdrName intPrimTyConName)
1055 lots_of_constructors = tyConFamilySize tycon > mAX_FAMILY_SIZE_FOR_VEC_RETURNS
1057 mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
1059 = ([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
1061 pat = ConPatIn var_RDR (PrefixCon (nOfThem (dataConSourceArity var) wildPat))
1062 var_RDR = getRdrName var
1064 gen_tag_n_con_monobind (rdr_name, tycon, GenTag2Con)
1065 = mk_FunMonoBind (getSrcLoc tycon) rdr_name
1066 [([mkConPat mkInt_RDR [a_RDR]],
1067 ExprWithTySig (HsApp tagToEnum_Expr a_Expr)
1068 (HsTyVar (getRdrName tycon)))]
1070 gen_tag_n_con_monobind (rdr_name, tycon, GenMaxTag)
1071 = mk_easy_FunMonoBind (getSrcLoc tycon)
1072 rdr_name [] [] (HsApp (HsVar mkInt_RDR) (HsLit (HsIntPrim max_tag)))
1074 max_tag = case (tyConDataCons tycon) of
1075 data_cons -> toInteger ((length data_cons) - fIRST_TAG)
1079 %************************************************************************
1081 \subsection{Utility bits for generating bindings}
1083 %************************************************************************
1085 @mk_easy_FunMonoBind fun pats binds expr@ generates:
1087 fun pat1 pat2 ... patN = expr where binds
1090 @mk_FunMonoBind fun [([p1a, p1b, ...], e1), ...]@ is for
1091 multi-clause definitions; it generates:
1093 fun p1a p1b ... p1N = e1
1094 fun p2a p2b ... p2N = e2
1096 fun pMa pMb ... pMN = eM
1100 mk_easy_FunMonoBind :: SrcLoc -> RdrName -> [RdrNamePat]
1101 -> [RdrNameMonoBinds] -> RdrNameHsExpr
1104 mk_easy_FunMonoBind loc fun pats binds expr
1105 = FunMonoBind fun False{-not infix-} [mk_easy_Match loc pats binds expr] loc
1107 mk_easy_Match loc pats binds expr
1108 = mk_match loc pats expr (mkMonoBind Recursive (andMonoBindList binds))
1109 -- The renamer expects everything in its input to be a
1110 -- "recursive" MonoBinds, and it is its job to sort things out
1113 mk_FunMonoBind :: SrcLoc -> RdrName
1114 -> [([RdrNamePat], RdrNameHsExpr)]
1117 mk_FunMonoBind loc fun [] = panic "TcGenDeriv:mk_FunMonoBind"
1118 mk_FunMonoBind loc fun pats_and_exprs
1119 = FunMonoBind fun False{-not infix-}
1120 [ mk_match loc p e EmptyBinds | (p,e) <-pats_and_exprs ]
1123 mk_match loc pats expr binds
1124 = Match (map paren pats) Nothing
1125 (GRHSs (unguardedRHS expr loc) binds placeHolderType)
1127 paren p@(VarPat _) = p
1128 paren other_p = ParPat other_p
1132 mkHsApps f xs = foldl HsApp (HsVar f) xs
1133 mkHsVarApps f xs = foldl HsApp (HsVar f) (map HsVar xs)
1135 mkHsIntLit n = HsLit (HsInt n)
1136 mkHsString s = HsString (mkFastString s)
1137 mkHsChar c = HsChar (ord c)
1139 mkConPat con vars = ConPatIn con (PrefixCon (map VarPat vars))
1140 mkNullaryConPat con = ConPatIn con (PrefixCon [])
1143 ToDo: Better SrcLocs.
1147 RdrNameHsExpr -- What to do for equality
1148 -> RdrNameHsExpr -> RdrNameHsExpr
1150 careful_compare_Case :: -- checks for primitive types...
1152 -> RdrNameHsExpr -- What to do for equality
1153 -> RdrNameHsExpr -> RdrNameHsExpr
1156 cmp_eq_Expr a b = HsApp (HsApp (HsVar cmp_eq_RDR) a) b
1157 -- Was: compare_gen_Case cmp_eq_RDR
1159 compare_gen_Case (HsVar eq_tag) a b | eq_tag == eqTag_RDR
1160 = HsApp (HsApp (HsVar compare_RDR) a) b -- Simple case
1161 compare_gen_Case eq a b -- General case
1162 = HsCase (HsPar (HsApp (HsApp (HsVar compare_RDR) a) b)) {-of-}
1163 [mkSimpleMatch [mkNullaryConPat ltTag_RDR] ltTag_Expr placeHolderType generatedSrcLoc,
1164 mkSimpleMatch [mkNullaryConPat eqTag_RDR] eq placeHolderType generatedSrcLoc,
1165 mkSimpleMatch [mkNullaryConPat gtTag_RDR] gtTag_Expr placeHolderType generatedSrcLoc]
1168 careful_compare_Case ty eq a b
1169 | not (isUnLiftedType ty) =
1170 compare_gen_Case eq a b
1172 -- we have to do something special for primitive things...
1173 HsIf (genOpApp a relevant_eq_op b)
1175 (HsIf (genOpApp a relevant_lt_op b) ltTag_Expr gtTag_Expr generatedSrcLoc)
1178 relevant_eq_op = assoc_ty_id eq_op_tbl ty
1179 relevant_lt_op = assoc_ty_id lt_op_tbl ty
1181 assoc_ty_id tyids ty
1182 = if null res then panic "assoc_ty"
1185 res = [id | (ty',id) <- tyids, ty `tcEqType` ty']
1188 [(charPrimTy, eqChar_RDR)
1189 ,(intPrimTy, eqInt_RDR)
1190 ,(wordPrimTy, eqWord_RDR)
1191 ,(addrPrimTy, eqAddr_RDR)
1192 ,(floatPrimTy, eqFloat_RDR)
1193 ,(doublePrimTy, eqDouble_RDR)
1197 [(charPrimTy, ltChar_RDR)
1198 ,(intPrimTy, ltInt_RDR)
1199 ,(wordPrimTy, ltWord_RDR)
1200 ,(addrPrimTy, ltAddr_RDR)
1201 ,(floatPrimTy, ltFloat_RDR)
1202 ,(doublePrimTy, ltDouble_RDR)
1205 -----------------------------------------------------------------------
1207 and_Expr, append_Expr :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1209 and_Expr a b = genOpApp a and_RDR b
1210 append_Expr a b = genOpApp a append_RDR b
1212 -----------------------------------------------------------------------
1214 eq_Expr :: Type -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1215 eq_Expr ty a b = genOpApp a eq_op b
1218 | not (isUnLiftedType ty) = eq_RDR
1220 -- we have to do something special for primitive things...
1221 assoc_ty_id eq_op_tbl ty
1226 untag_Expr :: TyCon -> [(RdrName, RdrName)] -> RdrNameHsExpr -> RdrNameHsExpr
1227 untag_Expr tycon [] expr = expr
1228 untag_Expr tycon ((untag_this, put_tag_here) : more) expr
1229 = HsCase (HsPar (HsApp (con2tag_Expr tycon) (HsVar untag_this))) {-of-}
1230 [mkSimpleMatch [VarPat put_tag_here] (untag_Expr tycon more expr) placeHolderType generatedSrcLoc]
1233 cmp_tags_Expr :: RdrName -- Comparison op
1234 -> RdrName -> RdrName -- Things to compare
1235 -> RdrNameHsExpr -- What to return if true
1236 -> RdrNameHsExpr -- What to return if false
1239 cmp_tags_Expr op a b true_case false_case
1240 = HsIf (genOpApp (HsVar a) op (HsVar b)) true_case false_case generatedSrcLoc
1243 :: RdrNameHsExpr -> RdrNameHsExpr
1245 enum_from_then_to_Expr
1246 :: RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
1249 enum_from_to_Expr f t2 = HsApp (HsApp (HsVar enumFromTo_RDR) f) t2
1250 enum_from_then_to_Expr f t t2 = HsApp (HsApp (HsApp (HsVar enumFromThenTo_RDR) f) t) t2
1253 :: RdrNameHsExpr -> RdrNameHsExpr
1256 showParen_Expr e1 e2 = HsApp (HsApp (HsVar showParen_RDR) e1) e2
1258 nested_compose_Expr :: [RdrNameHsExpr] -> RdrNameHsExpr
1260 nested_compose_Expr [e] = parenify e
1261 nested_compose_Expr (e:es)
1262 = HsApp (HsApp (HsVar compose_RDR) (parenify e)) (nested_compose_Expr es)
1264 -- impossible_Expr is used in case RHSs that should never happen.
1265 -- We generate these to keep the desugarer from complaining that they *might* happen!
1266 impossible_Expr = HsApp (HsVar error_RDR) (HsLit (HsString (mkFastString "Urk! in TcGenDeriv")))
1268 -- illegal_Expr is used when signalling error conditions in the RHS of a derived
1269 -- method. It is currently only used by Enum.{succ,pred}
1270 illegal_Expr meth tp msg =
1271 HsApp (HsVar error_RDR) (HsLit (HsString (mkFastString (meth ++ '{':tp ++ "}: " ++ msg))))
1273 -- illegal_toEnum_tag is an extended version of illegal_Expr, which also allows you
1274 -- to include the value of a_RDR in the error string.
1275 illegal_toEnum_tag tp maxtag =
1276 HsApp (HsVar error_RDR)
1277 (HsApp (HsApp (HsVar append_RDR)
1278 (HsLit (HsString (mkFastString ("toEnum{" ++ tp ++ "}: tag (")))))
1279 (HsApp (HsApp (HsApp
1280 (HsVar showsPrec_RDR)
1285 (HsLit (HsString (mkFastString ") is outside of enumeration's range (0,"))))
1286 (HsApp (HsApp (HsApp
1287 (HsVar showsPrec_RDR)
1290 (HsLit (HsString (mkFastString ")")))))))
1292 parenify e@(HsVar _) = e
1293 parenify e = HsPar e
1295 -- genOpApp wraps brackets round the operator application, so that the
1296 -- renamer won't subsequently try to re-associate it.
1297 -- For some reason the renamer doesn't reassociate it right, and I can't
1298 -- be bothered to find out why just now.
1300 genOpApp e1 op e2 = mkHsOpApp e1 op e2
1304 varUnqual n = mkUnqual OccName.varName n
1306 zz_a_RDR = varUnqual FSLIT("_a")
1307 a_RDR = varUnqual FSLIT("a")
1308 b_RDR = varUnqual FSLIT("b")
1309 c_RDR = varUnqual FSLIT("c")
1310 d_RDR = varUnqual FSLIT("d")
1311 ah_RDR = varUnqual FSLIT("a#")
1312 bh_RDR = varUnqual FSLIT("b#")
1313 ch_RDR = varUnqual FSLIT("c#")
1314 dh_RDR = varUnqual FSLIT("d#")
1315 cmp_eq_RDR = varUnqual FSLIT("cmp_eq")
1316 rangeSize_RDR = varUnqual FSLIT("rangeSize")
1318 as_RDRs = [ varUnqual (mkFastString ("a"++show i)) | i <- [(1::Int) .. ] ]
1319 bs_RDRs = [ varUnqual (mkFastString ("b"++show i)) | i <- [(1::Int) .. ] ]
1320 cs_RDRs = [ varUnqual (mkFastString ("c"++show i)) | i <- [(1::Int) .. ] ]
1322 zz_a_Expr = HsVar zz_a_RDR
1323 a_Expr = HsVar a_RDR
1324 b_Expr = HsVar b_RDR
1325 c_Expr = HsVar c_RDR
1326 d_Expr = HsVar d_RDR
1327 ltTag_Expr = HsVar ltTag_RDR
1328 eqTag_Expr = HsVar eqTag_RDR
1329 gtTag_Expr = HsVar gtTag_RDR
1330 false_Expr = HsVar false_RDR
1331 true_Expr = HsVar true_RDR
1333 getTag_Expr = HsVar getTag_RDR
1334 tagToEnum_Expr = HsVar tagToEnum_RDR
1335 con2tag_Expr tycon = HsVar (con2tag_RDR tycon)
1337 wildPat = WildPat placeHolderType
1338 zz_a_Pat = VarPat zz_a_RDR
1339 a_Pat = VarPat a_RDR
1340 b_Pat = VarPat b_RDR
1341 c_Pat = VarPat c_RDR
1342 d_Pat = VarPat d_RDR
1344 con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon -> RdrName
1346 con2tag_RDR tycon = varUnqual (mkFastString ("con2tag_" ++ occNameString (getOccName tycon) ++ "#"))
1347 tag2con_RDR tycon = varUnqual (mkFastString ("tag2con_" ++ occNameString (getOccName tycon) ++ "#"))
1348 maxtag_RDR tycon = varUnqual (mkFastString ("maxtag_" ++ occNameString (getOccName tycon) ++ "#"))
1351 RdrNames for PrimOps. Can't be done in PrelNames, because PrimOp imports
1352 PrelNames, so PrelNames can't import PrimOp.
1355 minusInt_RDR = nameRdrName minusIntName
1356 eqInt_RDR = nameRdrName eqIntName
1357 ltInt_RDR = nameRdrName ltIntName
1358 geInt_RDR = nameRdrName geIntName
1359 leInt_RDR = nameRdrName leIntName
1360 eqChar_RDR = nameRdrName eqCharName
1361 eqWord_RDR = nameRdrName eqWordName
1362 eqAddr_RDR = nameRdrName eqAddrName
1363 eqFloat_RDR = nameRdrName eqFloatName
1364 eqDouble_RDR = nameRdrName eqDoubleName
1365 ltChar_RDR = nameRdrName ltCharName
1366 ltWord_RDR = nameRdrName ltWordName
1367 ltAddr_RDR = nameRdrName ltAddrName
1368 ltFloat_RDR = nameRdrName ltFloatName
1369 ltDouble_RDR = nameRdrName ltDoubleName
1370 tagToEnum_RDR = nameRdrName tagToEnumName