%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
\section[TcGenDeriv]{Generating derived instance declarations}
This is where we do all the grimy bindings' generation.
\begin{code}
-#include "HsVersions.h"
-
module TcGenDeriv (
gen_Bounded_binds,
gen_Enum_binds,
- gen_Eval_binds,
gen_Eq_binds,
gen_Ix_binds,
gen_Ord_binds,
TagThingWanted(..)
) where
-IMP_Ubiq()
-IMPORT_1_3(List(partition,intersperse))
+#include "HsVersions.h"
-import HsSyn ( HsBinds(..), MonoBinds(..), Match(..), GRHSsAndBinds(..),
- GRHS(..), HsExpr(..), HsLit(..), InPat(..), Stmt(..), DoOrListComp(..),
- SYN_IE(RecFlag), recursive,
- ArithSeqInfo, Sig, HsType, FixityDecl, Fixity, Fake )
-import RdrHsSyn ( RdrName(..), varQual, varUnqual, mkOpApp,
- SYN_IE(RdrNameMonoBinds), SYN_IE(RdrNameHsExpr), SYN_IE(RdrNamePat)
+import HsSyn ( InPat(..), HsExpr(..), MonoBinds(..),
+ Match(..), GRHSs(..), Stmt(..), HsLit(..),
+ HsBinds(..), StmtCtxt(..),
+ unguardedRHS, mkSimpleMatch
)
-import BasicTypes ( IfaceFlavour(..) )
+import RdrHsSyn ( mkOpApp, RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat )
+import RdrName ( RdrName, mkSrcUnqual )
+import BasicTypes ( RecFlag(..) )
import FieldLabel ( fieldLabelName )
-import Id ( GenId, isNullaryDataCon, dataConTag,
+import DataCon ( isNullaryDataCon, dataConTag,
dataConRawArgTys, fIRST_TAG,
- isDataCon, SYN_IE(DataCon), SYN_IE(ConTag),
- dataConFieldLabels, SYN_IE(Id) )
-import Maybes ( maybeToBool )
+ DataCon, ConTag,
+ dataConFieldLabels )
import Name ( getOccString, getOccName, getSrcLoc, occNameString,
- modAndOcc, OccName, Name )
+ nameRdrName, varName,
+ OccName, Name, NamedThing(..), NameSpace
+ )
import PrimOp ( PrimOp(..) )
import PrelInfo -- Lots of RdrNames
import SrcLoc ( mkGeneratedSrcLoc, SrcLoc )
-import TyCon ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon, maybeTyConSingleCon )
-import Type ( eqTy, isPrimType, SYN_IE(Type) )
+import TyCon ( TyCon, isNewTyCon, tyConDataCons, isEnumerationTyCon,
+ maybeTyConSingleCon
+ )
+import Type ( isUnLiftedType, isUnboxedType, Type )
import TysPrim ( charPrimTy, intPrimTy, wordPrimTy, addrPrimTy,
floatPrimTy, doublePrimTy
)
import Util ( mapAccumL, zipEqual, zipWithEqual,
- zipWith3Equal, nOfThem, panic, assertPanic )
-
-
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ <= 200
-intersperse :: a -> [a] -> [a]
-intersperse s [] = []
-intersperse s [x] = [x]
-intersperse s (x:xs) = x : s : intersperse s xs
-#endif
-
+ zipWith3Equal, nOfThem )
+import Panic ( panic, assertPanic )
+import Maybes ( maybeToBool )
+import List ( partition, intersperse )
\end{code}
%************************************************************************
produced don't get through the typechecker.
\end{itemize}
+
+deriveEq :: RdrName -- Class
+ -> RdrName -- Type constructor
+ -> [ (RdrName, [RdrType]) ] -- Constructors
+ -> (RdrContext, -- Context for the inst decl
+ [RdrBind], -- Binds in the inst decl
+ [RdrBind]) -- Extra value bindings outside
+
+deriveEq clas tycon constrs
+ = (context, [eq_bind, ne_bind], [])
+ where
+ context = [(clas, [ty]) | (_, tys) <- constrs, ty <- tys]
+
+ ne_bind = mkBind
+ (nullary_cons, non_nullary_cons) = partition is_nullary constrs
+ is_nullary (_, args) = null args
+
\begin{code}
gen_Eq_binds :: TyCon -> RdrNameMonoBinds
Again, we must be careful about unboxed comparisons. For example,
if \tr{a1} and \tr{a2} were \tr{Int#}s in the 2nd example above, we'd need to
generate:
+
\begin{verbatim}
cmp_eq lt eq gt (O2 a1) (O2 a2)
= compareInt# a1 a2
\end{verbatim}
\end{itemize}
+If there is only one constructor in the Data Type we don't need the WildCard Pattern.
+JJQC-30-Nov-1997
+
\begin{code}
gen_Ord_binds :: TyCon -> RdrNameMonoBinds
[a_Pat, b_Pat]
[cmp_eq]
(if maybeToBool (maybeTyConSingleCon tycon) then
- cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
+
+-- cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
+-- Wierd. Was: case (cmp a b) of { LT -> LT; EQ -> EQ; GT -> GT }
+
+ cmp_eq_Expr a_Expr b_Expr
else
untag_Expr tycon [(a_RDR, ah_RDR), (b_RDR, bh_RDR)]
(cmp_tags_Expr eqH_Int_RDR ah_RDR bh_RDR
(if isEnumerationTyCon tycon then
eqTag_Expr
else
- cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
+-- cmp_eq_Expr ltTag_Expr eqTag_Expr gtTag_Expr a_Expr b_Expr
+-- Ditto
+ cmp_eq_Expr a_Expr b_Expr
)
-- False case; they aren't equal
-- So we need to do a less-than comparison on the tags
(cmp_tags_Expr ltH_Int_RDR ah_RDR bh_RDR ltTag_Expr gtTag_Expr)))
+ tycon_data_cons = tyConDataCons tycon
(nullary_cons, nonnullary_cons)
| isNewTyCon tycon = ([], tyConDataCons tycon)
- | otherwise = partition isNullaryDataCon (tyConDataCons tycon)
-
- cmp_eq
- = mk_FunMonoBind tycon_loc cmp_eq_RDR (map pats_etc nonnullary_cons ++
- [([WildPatIn, WildPatIn], default_rhs)])
+ | otherwise = partition isNullaryDataCon tycon_data_cons
+
+ cmp_eq =
+ mk_FunMonoBind tycon_loc
+ cmp_eq_RDR
+ (if null nonnullary_cons && (length nullary_cons == 1) then
+ -- catch this specially to avoid warnings
+ -- about overlapping patterns from the desugarer.
+ let
+ data_con = head nullary_cons
+ data_con_RDR = qual_orig_name data_con
+ pat = ConPatIn data_con_RDR []
+ in
+ [([pat,pat], eqTag_Expr)]
+ else
+ map pats_etc nonnullary_cons ++
+ -- leave out wildcards to silence desugarer.
+ (if length tycon_data_cons == 1 then
+ []
+ else
+ [([WildPatIn, WildPatIn], default_rhs)]))
where
pats_etc data_con
= ([con1_pat, con2_pat],
\begin{verbatim}
instance ... Enum (Foo ...) where
+ succ x = toEnum (1 + fromEnum x)
+ pred x = toEnum (fromEnum x - 1)
+
toEnum i = tag2con_Foo i
enumFrom a = map tag2con_Foo [con2tag_Foo a .. maxtag_Foo]
gen_Enum_binds :: TyCon -> RdrNameMonoBinds
gen_Enum_binds tycon
- = to_enum `AndMonoBinds`
+ = succ_enum `AndMonoBinds`
+ pred_enum `AndMonoBinds`
+ to_enum `AndMonoBinds`
enum_from `AndMonoBinds`
enum_from_then `AndMonoBinds`
from_enum
where
tycon_loc = getSrcLoc tycon
+ occ_nm = getOccString tycon
+
+ succ_enum
+ = mk_easy_FunMonoBind tycon_loc succ_RDR [a_Pat] [] $
+ untag_Expr tycon [(a_RDR, ah_RDR)] $
+ HsIf (HsApp (HsApp (HsVar eq_RDR)
+ (HsVar (maxtag_RDR tycon)))
+ (mk_easy_App mkInt_RDR [ah_RDR]))
+ (illegal_Expr "succ" occ_nm "tried to take `succ' of last tag in enumeration")
+ (HsApp (HsVar (tag2con_RDR tycon))
+ (HsApp (HsApp (HsVar plus_RDR)
+ (mk_easy_App mkInt_RDR [ah_RDR]))
+ (HsLit (HsInt 1))))
+ tycon_loc
+
+ pred_enum
+ = mk_easy_FunMonoBind tycon_loc pred_RDR [a_Pat] [] $
+ untag_Expr tycon [(a_RDR, ah_RDR)] $
+ HsIf (HsApp (HsApp (HsVar eq_RDR) (HsLit (HsInt 0)))
+ (mk_easy_App mkInt_RDR [ah_RDR]))
+ (illegal_Expr "pred" occ_nm "tried to take `pred' of first tag in enumeration")
+ (HsApp (HsVar (tag2con_RDR tycon))
+ (HsApp (HsApp (HsVar plus_RDR)
+ (mk_easy_App mkInt_RDR [ah_RDR]))
+ (HsLit (HsInt (-1)))))
+ tycon_loc
to_enum
= mk_easy_FunMonoBind tycon_loc toEnum_RDR [a_Pat] [] $
- mk_easy_App (tag2con_RDR tycon) [a_RDR]
+ HsIf (HsApp (HsApp
+ (HsVar and_RDR)
+ (HsApp (HsApp (HsVar ge_RDR)
+ (HsVar a_RDR))
+ (HsLit (HsInt 0))))
+ (HsApp (HsApp (HsVar le_RDR)
+ (HsVar a_RDR))
+ (HsVar (maxtag_RDR tycon))))
+ (mk_easy_App (tag2con_RDR tycon) [a_RDR])
+ (illegal_toEnum_tag occ_nm (maxtag_RDR tycon))
+ tycon_loc
enum_from
= mk_easy_FunMonoBind tycon_loc enumFrom_RDR [a_Pat] [] $
HsPar (enum_from_then_to_Expr
(mk_easy_App mkInt_RDR [ah_RDR])
(mk_easy_App mkInt_RDR [bh_RDR])
- (HsVar (maxtag_RDR tycon)))
+ (HsIf (HsApp (HsApp (HsVar gt_RDR)
+ (HsVar a_RDR))
+ (HsVar b_RDR))
+ (HsLit (HsInt 0))
+ (HsVar (maxtag_RDR tycon))
+ tycon_loc))
from_enum
= mk_easy_FunMonoBind tycon_loc fromEnum_RDR [a_Pat] [] $
%************************************************************************
%* *
-\subsubsection{Generating @Eval@ instance declarations}
-%* *
-%************************************************************************
-
-\begin{code}
-gen_Eval_binds tycon = EmptyMonoBinds
-\end{code}
-
-%************************************************************************
-%* *
\subsubsection{Generating @Bounded@ instance declarations}
%* *
%************************************************************************
enum_index `AndMonoBinds` enum_inRange
enum_range
- = mk_easy_FunMonoBind tycon_loc range_RDR [TuplePatIn [a_Pat, b_Pat]] [] $
+ = mk_easy_FunMonoBind tycon_loc range_RDR
+ [TuplePatIn [a_Pat, b_Pat] True{-boxed-}] [] $
untag_Expr tycon [(a_RDR, ah_RDR)] $
untag_Expr tycon [(b_RDR, bh_RDR)] $
HsApp (mk_easy_App map_RDR [tag2con_RDR tycon]) $
(mk_easy_App mkInt_RDR [bh_RDR]))
enum_index
- = mk_easy_FunMonoBind tycon_loc index_RDR [AsPatIn c_RDR (TuplePatIn [a_Pat, b_Pat]), d_Pat] [] (
+ = mk_easy_FunMonoBind tycon_loc index_RDR
+ [AsPatIn c_RDR (TuplePatIn [a_Pat, b_Pat] True{-boxed-}),
+ d_Pat] [] (
HsIf (HsPar (mk_easy_App inRange_RDR [c_RDR, d_RDR])) (
untag_Expr tycon [(a_RDR, ah_RDR)] (
untag_Expr tycon [(d_RDR, dh_RDR)] (
let
- grhs = [OtherwiseGRHS (mk_easy_App mkInt_RDR [c_RDR]) tycon_loc]
+ rhs = mk_easy_App mkInt_RDR [c_RDR]
in
HsCase
(genOpApp (HsVar dh_RDR) minusH_RDR (HsVar ah_RDR))
- [PatMatch (VarPatIn c_RDR)
- (GRHSMatch (GRHSsAndBindsIn grhs EmptyBinds))]
+ [mkSimpleMatch [VarPatIn c_RDR] rhs Nothing tycon_loc]
tycon_loc
))
) {-else-} (
tycon_loc)
enum_inRange
- = mk_easy_FunMonoBind tycon_loc inRange_RDR [TuplePatIn [a_Pat, b_Pat], c_Pat] [] (
+ = mk_easy_FunMonoBind tycon_loc inRange_RDR
+ [TuplePatIn [a_Pat, b_Pat] True{-boxed-}, c_Pat] [] (
untag_Expr tycon [(a_RDR, ah_RDR)] (
untag_Expr tycon [(b_RDR, bh_RDR)] (
untag_Expr tycon [(c_RDR, ch_RDR)] (
data_con
= case maybeTyConSingleCon tycon of -- just checking...
Nothing -> panic "get_Ix_binds"
- Just dc -> if (any isPrimType (dataConRawArgTys dc)) then
+ Just dc -> if (any isUnLiftedType (dataConRawArgTys dc)) then
error ("ERROR: Can't derive Ix for a single-constructor type with primitive argument types: "++tycon_str)
else
dc
--------------------------------------------------------------
single_con_range
- = mk_easy_FunMonoBind tycon_loc range_RDR [TuplePatIn [con_pat as_needed, con_pat bs_needed]] [] $
+ = mk_easy_FunMonoBind tycon_loc range_RDR
+ [TuplePatIn [con_pat as_needed, con_pat bs_needed] True{-boxed-}] [] $
HsDo ListComp stmts tycon_loc
where
stmts = zipWith3Equal "single_con_range" mk_qual as_needed bs_needed cs_needed
[ReturnStmt con_expr]
mk_qual a b c = BindStmt (VarPatIn c)
- (HsApp (HsVar range_RDR) (ExplicitTuple [HsVar a, HsVar b]))
+ (HsApp (HsVar range_RDR)
+ (ExplicitTuple [HsVar a, HsVar b] True))
tycon_loc
----------------
single_con_index
- = mk_easy_FunMonoBind tycon_loc index_RDR [TuplePatIn [con_pat as_needed, con_pat bs_needed], con_pat cs_needed] [range_size] (
+ = mk_easy_FunMonoBind tycon_loc index_RDR
+ [TuplePatIn [con_pat as_needed, con_pat bs_needed] True,
+ con_pat cs_needed] [range_size] (
foldl mk_index (HsLit (HsInt 0)) (zip3 as_needed bs_needed cs_needed))
where
- mk_index (HsLit (HsInt 0)) (l, u, i) -- optim.
- = HsApp (HsApp (HsVar index_RDR) (ExplicitTuple [HsVar l, HsVar u])) (HsVar i)
mk_index multiply_by (l, u, i)
= genOpApp (
- (HsApp (HsApp (HsVar index_RDR) (ExplicitTuple [HsVar l, HsVar u])) (HsVar i))
+ (HsApp (HsApp (HsVar index_RDR)
+ (ExplicitTuple [HsVar l, HsVar u] True)) (HsVar i))
) plus_RDR (
genOpApp (
- (HsApp (HsVar rangeSize_RDR) (ExplicitTuple [HsVar l, HsVar u]))
+ (HsApp (HsVar rangeSize_RDR)
+ (ExplicitTuple [HsVar l, HsVar u] True))
) times_RDR multiply_by
)
range_size
- = mk_easy_FunMonoBind tycon_loc rangeSize_RDR [TuplePatIn [a_Pat, b_Pat]] [] (
+ = mk_easy_FunMonoBind tycon_loc rangeSize_RDR
+ [TuplePatIn [a_Pat, b_Pat] True] [] (
genOpApp (
- (HsApp (HsApp (HsVar index_RDR) (ExplicitTuple [a_Expr, b_Expr])) b_Expr)
+ (HsApp (HsApp (HsVar index_RDR)
+ (ExplicitTuple [a_Expr, b_Expr] True)) b_Expr)
) plus_RDR (HsLit (HsInt 1)))
------------------
single_con_inRange
= mk_easy_FunMonoBind tycon_loc inRange_RDR
- [TuplePatIn [con_pat as_needed, con_pat bs_needed], con_pat cs_needed]
+ [TuplePatIn [con_pat as_needed, con_pat bs_needed] True,
+ con_pat cs_needed]
[] (
foldl1 and_Expr (zipWith3Equal "single_con_inRange" in_range as_needed bs_needed cs_needed))
where
- in_range a b c = HsApp (HsApp (HsVar inRange_RDR) (ExplicitTuple [HsVar a, HsVar b])) (HsVar c)
+ in_range a b c = HsApp (HsApp (HsVar inRange_RDR)
+ (ExplicitTuple [HsVar a, HsVar b] True))
+ (HsVar c)
\end{code}
%************************************************************************
read_con data_con -- note: "b" is the string being "read"
= let
data_con_RDR = qual_orig_name data_con
- data_con_str= occNameString (getOccName data_con)
+ data_con_str= occNameUserString (getOccName data_con)
con_arity = argFieldCount data_con
con_expr = mk_easy_App data_con_RDR as_needed
nullary_con = con_arity == 0
-- (label, '=' and field)*n, (n-1)*',' + '{' + '}'
con_qual
= BindStmt
- (TuplePatIn [LitPatIn (HsString data_con_str), d_Pat])
+ (TuplePatIn [LitPatIn (mkHsString data_con_str),
+ d_Pat] True)
(HsApp (HsVar lex_RDR) c_Expr)
tycon_loc
str_qual str res draw_from
= BindStmt
- (TuplePatIn [LitPatIn (HsString str), VarPatIn res])
+ (TuplePatIn [LitPatIn (mkHsString str), VarPatIn res] True)
(HsApp (HsVar lex_RDR) draw_from)
tycon_loc
read_label f
- = let nm = occNameString (getOccName (fieldLabelName f))
+ = let nm = occNameUserString (getOccName (fieldLabelName f))
in
- [str_qual nm, str_qual SLIT("=")]
+ [str_qual nm, str_qual "="]
-- There might be spaces between the label and '='
field_quals
snd $
mapAccumL mk_qual d_Expr
(zipEqual "bs_needed"
- ((str_qual (SLIT("{")):
+ ((str_qual "{":
concat (
- intersperse ([str_qual SLIT(",")]) $
+ intersperse [str_qual ","] $
zipWithEqual
"field_quals"
(\ as b -> as ++ [b])
-- The labels
(map read_label labels)
-- The fields
- (map mk_read_qual as_needed))) ++ [str_qual (SLIT("}"))])
+ (map mk_read_qual as_needed))) ++ [str_qual "}"])
bs_needed)
mk_qual draw_from (f, str_left)
mk_read_qual con_field res draw_from =
BindStmt
- (TuplePatIn [VarPatIn con_field, VarPatIn res])
+ (TuplePatIn [VarPatIn con_field, VarPatIn res] True)
(HsApp (HsApp (HsVar readsPrec_RDR) (HsLit (HsInt 10))) draw_from)
tycon_loc
result_expr = ExplicitTuple [con_expr, if null bs_needed
then d_Expr
- else HsVar (last bs_needed)]
+ else HsVar (last bs_needed)] True
stmts = con_qual:field_quals ++ [ReturnStmt result_expr]
lab_fields = length labels
show_con
- = let nm = occNameString (getOccName data_con)
+ = let nm = occNameUserString (getOccName data_con)
space_ocurly_maybe
- | nullary_con = _NIL_
- | lab_fields == 0 = SLIT(" ")
- | otherwise = SLIT("{")
+ | nullary_con = ""
+ | lab_fields == 0 = " "
+ | otherwise = "{"
in
- mk_showString_app (nm _APPEND_ space_ocurly_maybe)
+ mk_showString_app (nm ++ space_ocurly_maybe)
show_all con fs
= let
ccurly_maybe
- | lab_fields > 0 = [mk_showString_app (SLIT("}"))]
+ | lab_fields > 0 = [mk_showString_app "}"]
| otherwise = []
in
con:fs ++ ccurly_maybe
show_thingies = show_all show_con real_show_thingies_with_labs
show_label l
- = let nm = occNameString (getOccName (fieldLabelName l))
+ = let nm = occNameUserString (getOccName (fieldLabelName l))
in
- mk_showString_app (nm _APPEND_ SLIT("="))
+ mk_showString_app (nm ++ "=")
mk_showString_app str = HsApp (HsVar showString_RDR)
- (HsLit (HsString str))
+ (HsLit (mkHsString str))
real_show_thingies =
[ HsApp (HsApp (HsVar showsPrec_RDR) (HsLit (HsInt 10))) (HsVar b)
| otherwise = --Assumption: no of fields == no of labelled fields
-- (and in same order)
concat $
- intersperse ([mk_showString_app (_CONS_ ',' _NIL_ )]) $ -- Using SLIT() is not cool here.
+ intersperse ([mk_showString_app ","]) $ -- Using SLIT()s containing ,s spells trouble.
zipWithEqual "gen_Show_binds"
(\ a b -> [a,b])
(map show_label labels)
mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
mk_stuff var
- = ASSERT(isDataCon var)
- ([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
+ = ([pat], HsLit (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG))))
where
pat = ConPatIn var_RDR (nOfThem (argFieldCount var) WildPatIn)
var_RDR = qual_orig_name var
[([WildPatIn], impossible_Expr)])
where
mk_stuff :: DataCon -> ([RdrNamePat], RdrNameHsExpr)
-
- mk_stuff var
- = ASSERT(isDataCon var)
- ([lit_pat], HsVar var_RDR)
+ mk_stuff var = ([lit_pat], HsVar var_RDR)
where
lit_pat = ConPatIn mkInt_RDR [LitPatIn (HsIntPrim (toInteger ((dataConTag var) - fIRST_TAG)))]
var_RDR = qual_orig_name var
= mk_match loc pats expr (mkbind binds)
where
mkbind [] = EmptyBinds
- mkbind bs = MonoBind (foldr1 AndMonoBinds bs) [] recursive
+ mkbind bs = MonoBind (foldr1 AndMonoBinds bs) [] Recursive
-- The renamer expects everything in its input to be a
-- "recursive" MonoBinds, and it is its job to sort things out
-- from there.
loc
mk_match loc pats expr binds
- = foldr PatMatch
- (GRHSMatch (GRHSsAndBindsIn [OtherwiseGRHS expr loc] binds))
- (map paren pats)
+ = Match [] (map paren pats) Nothing
+ (GRHSs (unguardedRHS expr loc) binds Nothing)
where
paren p@(VarPatIn _) = p
paren other_p = ParPatIn other_p
ToDo: Better SrcLocs.
\begin{code}
-compare_Case, cmp_eq_Expr ::
+compare_Case ::
RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
-> RdrNameHsExpr -> RdrNameHsExpr
-> RdrNameHsExpr
-> RdrNameHsExpr
compare_Case = compare_gen_Case compare_RDR
-cmp_eq_Expr = compare_gen_Case cmp_eq_RDR
+cmp_eq_Expr a b = HsApp (HsApp (HsVar cmp_eq_RDR) a) b
+ -- Was: compare_gen_Case cmp_eq_RDR
compare_gen_Case fun lt eq gt a b
= HsCase (HsPar (HsApp (HsApp (HsVar fun) a) b)) {-of-}
- [PatMatch (ConPatIn ltTag_RDR [])
- (GRHSMatch (GRHSsAndBindsIn [OtherwiseGRHS lt mkGeneratedSrcLoc] EmptyBinds)),
-
- PatMatch (ConPatIn eqTag_RDR [])
- (GRHSMatch (GRHSsAndBindsIn [OtherwiseGRHS eq mkGeneratedSrcLoc] EmptyBinds)),
-
- PatMatch (ConPatIn gtTag_RDR [])
- (GRHSMatch (GRHSsAndBindsIn [OtherwiseGRHS gt mkGeneratedSrcLoc] EmptyBinds))]
- mkGeneratedSrcLoc
+ [mkSimpleMatch [ConPatIn ltTag_RDR []] lt Nothing mkGeneratedSrcLoc,
+ mkSimpleMatch [ConPatIn eqTag_RDR []] eq Nothing mkGeneratedSrcLoc,
+ mkSimpleMatch [ConPatIn gtTag_RDR []] gt Nothing mkGeneratedSrcLoc]
+ mkGeneratedSrcLoc
careful_compare_Case ty lt eq gt a b
- = if not (isPrimType ty) then
+ = if not (isUnboxedType ty) then
compare_gen_Case compare_RDR lt eq gt a b
else -- we have to do something special for primitive things...
= if null res then panic "assoc_ty"
else head res
where
- res = [id | (ty',id) <- tyids, eqTy ty ty']
+ res = [id | (ty',id) <- tyids, ty == ty']
eq_op_tbl =
[(charPrimTy, eqH_Char_RDR)
eq_Expr :: Type -> RdrNameHsExpr -> RdrNameHsExpr -> RdrNameHsExpr
eq_Expr ty a b
- = if not (isPrimType ty) then
+ = if not (isUnboxedType ty) then
genOpApp a eq_RDR b
else -- we have to do something special for primitive things...
genOpApp a relevant_eq_op b
\end{code}
\begin{code}
-argFieldCount :: Id -> Int -- Works on data and newtype constructors
+argFieldCount :: DataCon -> Int -- Works on data and newtype constructors
argFieldCount con = length (dataConRawArgTys con)
\end{code}
untag_Expr tycon [] expr = expr
untag_Expr tycon ((untag_this, put_tag_here) : more) expr
= HsCase (HsPar (HsApp (con2tag_Expr tycon) (HsVar untag_this))) {-of-}
- [PatMatch (VarPatIn put_tag_here)
- (GRHSMatch (GRHSsAndBindsIn grhs EmptyBinds))]
+ [mkSimpleMatch [VarPatIn put_tag_here] (untag_Expr tycon more expr) Nothing mkGeneratedSrcLoc]
mkGeneratedSrcLoc
- where
- grhs = [OtherwiseGRHS (untag_Expr tycon more expr) mkGeneratedSrcLoc]
cmp_tags_Expr :: RdrName -- Comparison op
-> RdrName -> RdrName -- Things to compare
-- We generate these to keep the desugarer from complaining that they *might* happen!
impossible_Expr = HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ "Urk! in TcGenDeriv")))
+-- illegal_Expr is used when signalling error conditions in the RHS of a derived
+-- method. It is currently only used by Enum.{succ,pred}
+illegal_Expr meth tp msg =
+ HsApp (HsVar error_RDR) (HsLit (HsString (_PK_ (meth ++ '{':tp ++ "}: " ++ msg))))
+
+-- illegal_toEnum_tag is an extended version of illegal_Expr, which also allows you
+-- to include the value of a_RDR in the error string.
+illegal_toEnum_tag tp maxtag =
+ HsApp (HsVar error_RDR)
+ (HsApp (HsApp (HsVar append_RDR)
+ (HsLit (HsString (_PK_ ("toEnum{" ++ tp ++ "}: tag (")))))
+ (HsApp (HsApp (HsApp
+ (HsVar showsPrec_RDR)
+ (HsLit (HsInt 0)))
+ (HsVar a_RDR))
+ (HsApp (HsApp
+ (HsVar append_RDR)
+ (HsLit (HsString (_PK_ ") is outside of enumeration's range (0,"))))
+ (HsApp (HsApp (HsApp
+ (HsVar showsPrec_RDR)
+ (HsLit (HsInt 0)))
+ (HsVar maxtag))
+ (HsLit (HsString (_PK_ ")")))))))
+
parenify e@(HsVar _) = e
parenify e = HsPar e
\end{code}
\begin{code}
-qual_orig_name n = case modAndOcc n of { (m,n) -> Qual m n HiFile }
+qual_orig_name n = nameRdrName (getName n)
+varUnqual n = mkSrcUnqual varName n
a_RDR = varUnqual SLIT("a")
b_RDR = varUnqual SLIT("b")
bs_RDRs = [ varUnqual (_PK_ ("b"++show i)) | i <- [(1::Int) .. ] ]
cs_RDRs = [ varUnqual (_PK_ ("c"++show i)) | i <- [(1::Int) .. ] ]
+mkHsString s = HsString (_PK_ s)
+
a_Expr = HsVar a_RDR
b_Expr = HsVar b_RDR
c_Expr = HsVar c_RDR
con2tag_RDR, tag2con_RDR, maxtag_RDR :: TyCon -> RdrName
-con2tag_RDR tycon = varUnqual (SLIT("con2tag_") _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
-tag2con_RDR tycon = varUnqual (SLIT("tag2con_") _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
-maxtag_RDR tycon = varUnqual (SLIT("maxtag_") _APPEND_ occNameString (getOccName tycon) _APPEND_ SLIT("#"))
+con2tag_RDR tycon = varUnqual (_PK_ ("con2tag_" ++ occNameString (getOccName tycon) ++ "#"))
+tag2con_RDR tycon = varUnqual (_PK_ ("tag2con_" ++ occNameString (getOccName tycon) ++ "#"))
+maxtag_RDR tycon = varUnqual (_PK_ ("maxtag_" ++ occNameString (getOccName tycon) ++ "#"))
\end{code}