[project @ 2003-07-24 14:41:48 by simonpj]
authorsimonpj <unknown>
Thu, 24 Jul 2003 14:41:56 +0000 (14:41 +0000)
committersimonpj <unknown>
Thu, 24 Jul 2003 14:41:56 +0000 (14:41 +0000)
Sync deriving( Data ) with the new Data class

ghc/compiler/basicTypes/OccName.lhs
ghc/compiler/hsSyn/HsExpr.lhs
ghc/compiler/prelude/PrelNames.lhs
ghc/compiler/typecheck/TcDeriv.lhs
ghc/compiler/typecheck/TcGenDeriv.lhs

index 0faa870..4ff4c87 100644 (file)
@@ -20,7 +20,7 @@ module OccName (
        mkSuperDictSelOcc, mkDFunOcc, mkForeignExportOcc,
        mkDictOcc, mkIPOcc, mkWorkerOcc, mkMethodOcc, mkDefaultMethodOcc,
        mkDerivedTyConOcc, mkClassTyConOcc, mkClassDataConOcc, mkSpecOcc,
-       mkGenOcc1, mkGenOcc2, mkLocalOcc, 
+       mkGenOcc1, mkGenOcc2, mkLocalOcc, mkDataTOcc, mkDataCOcc,
        mkDataConWrapperOcc, mkDataConWorkerOcc,
        
        isTvOcc, isTcOcc, isDataOcc, isDataSymOcc, isSymOcc, isValOcc,
@@ -360,8 +360,17 @@ mkDictOcc      = mk_simple_deriv varName  "$d"
 mkIPOcc                    = mk_simple_deriv varName  "$i"
 mkSpecOcc          = mk_simple_deriv varName  "$s"
 mkForeignExportOcc  = mk_simple_deriv varName  "$f"
-mkGenOcc1           = mk_simple_deriv varName  "$gfrom"      -- Generics
-mkGenOcc2           = mk_simple_deriv varName  "$gto"        -- Generics
+
+-- Generic derivable classes
+mkGenOcc1           = mk_simple_deriv varName  "$gfrom"
+mkGenOcc2           = mk_simple_deriv varName  "$gto" 
+
+-- data T = MkT ... deriving( Data ) needs defintions for 
+--     $tT   :: Data.Generics.Basics.DataType
+--     $cMkT :: Data.Generics.Basics.Constr
+mkDataTOcc = mk_simple_deriv varName  "$t"
+mkDataCOcc = mk_simple_deriv varName  "$c"
+
 mk_simple_deriv sp px occ = mk_deriv sp px (occNameString occ)
 
 
index 6969de2..5eff473 100644 (file)
@@ -286,7 +286,7 @@ ppr_expr (HsLam match) = pprMatch LambdaExpr match
 
 ppr_expr expr@(HsApp e1 e2)
   = let (fun, args) = collect_args expr [] in
-    (ppr_expr fun) <+> (sep (map ppr_expr args))
+    (ppr_expr fun) <+> (sep (map pprParendExpr args))
   where
     collect_args (HsApp fun arg) args = collect_args fun (arg:args)
     collect_args fun            args = (fun, args)
index 4d834df..1c597a8 100644 (file)
@@ -268,7 +268,7 @@ pREL_TOP_HANDLER_Name = mkModuleName "GHC.TopHandler"
 sYSTEM_IO_Name   = mkModuleName "System.IO"
 dYNAMIC_Name     = mkModuleName "Data.Dynamic"
 tYPEABLE_Name    = mkModuleName "Data.Typeable"
-gENERICS_Name    = mkModuleName "Data.Generics"
+gENERICS_Name    = mkModuleName "Data.Generics.Basics"
 dOTNET_Name       = mkModuleName "GHC.Dotnet"
 
 rEAD_PREC_Name = mkModuleName "Text.ParserCombinators.ReadPrec"
@@ -449,16 +449,6 @@ typeOf_RDR     = varQual_RDR tYPEABLE_Name FSLIT("typeOf")
 mkTypeRep_RDR  = varQual_RDR tYPEABLE_Name FSLIT("mkAppTy")
 mkTyConRep_RDR = varQual_RDR tYPEABLE_Name FSLIT("mkTyCon")
 
-constr_RDR  = dataQual_RDR gENERICS_Name FSLIT("Constr")
-gfoldl_RDR  = varQual_RDR gENERICS_Name FSLIT("gfoldl")
-gfoldr_RDR  = varQual_RDR gENERICS_Name FSLIT("gfoldr")
-gunfold_RDR = varQual_RDR gENERICS_Name FSLIT("gunfold")
-gmapT_RDR   = varQual_RDR gENERICS_Name FSLIT("gmapT")
-gmapQ_RDR   = varQual_RDR gENERICS_Name FSLIT("gmapQ")
-gmapM_RDR   = varQual_RDR gENERICS_Name FSLIT("gmapM")
-conOf_RDR   = varQual_RDR gENERICS_Name FSLIT("conOf")
-consOf_RDR  = varQual_RDR gENERICS_Name FSLIT("consOf")
-
 undefined_RDR = varQual_RDR pREL_ERR_Name FSLIT("undefined")
 \end{code}
 
index 52b02ca..9ea0190 100644 (file)
@@ -10,7 +10,7 @@ module TcDeriv ( tcDeriving ) where
 
 #include "HsVersions.h"
 
-import HsSyn           ( HsBinds(..), TyClDecl(..),
+import HsSyn           ( HsBinds(..), TyClDecl(..), MonoBinds(..),
                          andMonoBindList, collectMonoBinders )
 import RdrHsSyn                ( RdrNameMonoBinds )
 import RnHsSyn         ( RenamedHsBinds, RenamedTyClDecl, RenamedHsPred )
@@ -260,19 +260,33 @@ deriveOrdinaryStuff eqns
        -- over the method bindings for the instances.
        bindLocalsFV (ptext (SLIT("deriving"))) mbinders        $ \ _ ->
        rnTopMonoBinds extra_mbinds []                  `thenM` \ (rn_extra_binds, dus) ->
-       mapAndUnzipM rn_inst_info rdr_name_inst_infos   `thenM` \ (rn_inst_infos, fvs_s) ->
-       returnM ((rn_inst_infos, rn_extra_binds), 
-                 duUses dus `plusFV` plusFVs fvs_s)
+
+       mapAndUnzipM rn_inst_info rdr_name_inst_infos   `thenM` \ (pairs, fvs_s) ->
+
+       let
+          (rn_inst_infos, aux_binds_s) = unzip pairs
+          all_binds = rn_extra_binds `ThenBinds` foldr ThenBinds EmptyBinds aux_binds_s
+       in
+       returnM ((rn_inst_infos, all_binds),
+                duUses dus `plusFV` plusFVs fvs_s)
     )                          `thenM` \ ((rn_inst_infos, rn_extra_binds), fvs) ->
    returnM (rn_inst_infos, rn_extra_binds, fvs)
 
   where
-    rn_inst_info (dfun, binds) 
-       = extendTyVarEnvFVRn (map varName tyvars)       $
+    rn_inst_info (dfun, (meth_binds, aux_binds)) 
+       =       -- Rename the auxiliary bindings
+         bindLocalsFV (ptext (SLIT("deriving"))) mbinders      $ \ _ ->
+         rnTopMonoBinds aux_binds []                   `thenM` \ (rn_aux_binds, dus) ->
+
                -- Bring the right type variables into scope
-         rnMethodBinds (className cls) [] binds        `thenM` \ (rn_binds, fvs) ->
-         return (InstInfo { iDFunId = dfun, iBinds = VanillaInst rn_binds [] }, fvs)
+         extendTyVarEnvFVRn (map varName tyvars)       $
+         rnMethodBinds (className cls) [] meth_binds   `thenM` \ (rn_meth_binds, fvs) ->
+
+         return ((InstInfo { iDFunId = dfun, iBinds = VanillaInst rn_meth_binds [] }, 
+                  rn_aux_binds), 
+                 duUses dus `plusFV` fvs)
        where
+         mbinders = collectMonoBinders aux_binds
          (tyvars, _, cls, _) = tcSplitDFunTy (idType dfun)
 \end{code}
 
@@ -750,7 +764,7 @@ the renamer.  What a great hack!
 -- Generate the method bindings for the required instance
 -- (paired with DFunId, as we need that when renaming
 --  the method binds)
-gen_bind :: DFunId -> TcM (DFunId, RdrNameMonoBinds)
+gen_bind :: DFunId -> TcM (DFunId, (RdrNameMonoBinds, RdrNameMonoBinds))
 gen_bind dfun
   = getFixityEnv               `thenM` \ fix_env -> 
     let
@@ -758,16 +772,20 @@ gen_bind dfun
        gen_binds_fn  = assoc "gen_bind:bad derived class"
                              gen_list (getUnique clas)
     
-       gen_list = [(eqClassKey,      gen_Eq_binds)
-                  ,(ordClassKey,     gen_Ord_binds)
-                  ,(enumClassKey,    gen_Enum_binds)
-                  ,(boundedClassKey, gen_Bounded_binds)
-                  ,(ixClassKey,      gen_Ix_binds)
-                  ,(showClassKey,    gen_Show_binds fix_env)
-                  ,(readClassKey,    gen_Read_binds fix_env)
-                  ,(typeableClassKey,gen_Typeable_binds)
-                  ,(dataClassKey,    gen_Data_binds)
+       gen_list = [(eqClassKey,      no_aux_binds gen_Eq_binds)
+                  ,(ordClassKey,     no_aux_binds gen_Ord_binds)
+                  ,(enumClassKey,    no_aux_binds gen_Enum_binds)
+                  ,(boundedClassKey, no_aux_binds gen_Bounded_binds)
+                  ,(ixClassKey,      no_aux_binds gen_Ix_binds)
+                  ,(showClassKey,    no_aux_binds (gen_Show_binds fix_env))
+                  ,(readClassKey,    no_aux_binds (gen_Read_binds fix_env))
+                  ,(typeableClassKey,no_aux_binds gen_Typeable_binds)
+                  ,(dataClassKey,    gen_Data_binds fix_env)
                   ]
+
+               -- Used for generators that don't need to produce       
+               -- any auxiliary bindings
+       no_aux_binds f tc = (f tc, EmptyMonoBinds)
     in
     returnM (dfun, gen_binds_fn tycon)
 \end{code}
index 5e4a31a..f0269f1 100644 (file)
@@ -33,7 +33,7 @@ import HsSyn          ( Pat(..), HsConDetails(..), HsExpr(..), MonoBinds(..),
                          HsBinds(..), HsType(..), HsStmtContext(..),
                          unguardedRHS, mkSimpleMatch, mkMonoBind, andMonoBindList, placeHolderType
                        )
-import RdrName         ( RdrName, mkUnqual, nameRdrName, getRdrName )
+import RdrName         ( RdrName, mkUnqual, mkRdrUnqual, nameRdrName, getRdrName )
 import RdrHsSyn                ( mkHsOpApp, RdrNameMonoBinds, RdrNameHsExpr, RdrNamePat, mkHsDo )
 import BasicTypes      ( RecFlag(..), Fixity(..), FixityDirection(..)
                        , maxPrecedence
@@ -151,22 +151,6 @@ instance ... Eq (Foo ...) where
 \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
 
@@ -624,7 +608,7 @@ gen_Ix_binds tycon
           in
           HsCase
             (genOpApp (HsVar dh_RDR) minusInt_RDR (HsVar ah_RDR))
-            [mkSimpleMatch [VarPat c_RDR] rhs placeHolderType tycon_loc]
+            [mk_triv_Match (VarPat c_RDR) rhs]
             tycon_loc
           ))
        ) {-else-} (
@@ -1059,25 +1043,33 @@ From the data type
 
 we generate
 
-  instance (Data a, Data b) => Data (T a b) where
-       gfoldl k z (T1 a b) = z T `k` a `k` b
-       gfoldl k z T2       = z T2
-       -- ToDo: add gmapT,Q,M, gfoldr
-
-       gunfold k z (Constr "T1") = k (k (z T1))
-       gunfold k z (Constr "T2") = z T2
+  $cT1 = mkConstr 1 "T1" Prefix
+  $cT2 = mkConstr 2 "T2" Prefix
+  $dT  = mkDataType [$con_T1, $con_T2]
 
-       conOf (T1 _ _) = Constr "T1"
-       conOf T2       = Constr "T2"
-       
-       consOf _ = [Constr "T1", Constr "T2"]
-
-ToDo: generate auxiliary bindings for the Constrs?
+  instance (Data a, Data b) => Data (T a b) where
+    gfoldl k z (T1 a b) = z T `k` a `k` b
+    gfoldl k z T2          = z T2
+    -- ToDo: add gmapT,Q,M, gfoldr
+    
+    fromConstr c = case conIndex c of
+               1 -> T1 undefined undefined
+               2 -> T2
+    
+    toConstr (T1 _ _) = $cT1
+    toConstr T2              = $cT2
+    
+    dataTypeOf _ = $dT
 
 \begin{code}
-gen_Data_binds :: TyCon -> RdrNameMonoBinds
-gen_Data_binds tycon
-  = andMonoBindList [gfoldl_bind, gunfold_bind, conOf_bind, consOf_bind]
+gen_Data_binds :: FixityEnv
+              -> TyCon 
+              -> (RdrNameMonoBinds,    -- The method bindings
+                  RdrNameMonoBinds)    -- Auxiliary bindings
+gen_Data_binds fix_env tycon
+  = (andMonoBindList [gfoldl_bind, fromCon_bind, toCon_bind, dataTypeOf_bind],
+               -- Auxiliary definitions: the data type and constructors
+     datatype_bind `AndMonoBinds` andMonoBindList (map mk_con_bind data_cons))
   where
     tycon_loc = getSrcLoc tycon
     data_cons = tyConDataCons tycon
@@ -1092,23 +1084,55 @@ gen_Data_binds tycon
                     as_needed = take (dataConSourceArity con) as_RDRs
                     mk_k_app e v = HsPar (mkHsOpApp e k_RDR (HsVar v))
 
-       ------------ gunfold
-    gunfold_bind = mk_FunMonoBind tycon_loc gunfold_RDR (map gunfold_eqn data_cons)
-    gunfold_eqn con = ([VarPat k_RDR, VarPat z_RDR,  
-                       ConPatIn constr_RDR (PrefixCon [LitPat (mk_constr_string con)])],
-                      apN (dataConSourceArity con)
-                          (\e -> HsVar k_RDR `HsApp` e) 
-                          (z_Expr `HsApp` HsVar (getRdrName con)))
-    mk_constr_string con = mkHsString (occNameUserString (getOccName con))
-
-       ------------ conOf
-    conOf_bind = mk_FunMonoBind tycon_loc conOf_RDR (map conOf_eqn data_cons)
-    conOf_eqn con = ([mkWildConPat con], mk_constr con)
-
-       ------------ consOf
-    consOf_bind = mk_easy_FunMonoBind tycon_loc consOf_RDR [wildPat] []
-                               (ExplicitList placeHolderType (map mk_constr data_cons))
-    mk_constr con = HsVar constr_RDR `HsApp` (HsLit (mk_constr_string con))
+       ------------ fromConstr
+    fromCon_bind = mk_FunMonoBind tycon_loc fromConstr_RDR [([c_Pat], from_con_rhs)]
+    from_con_rhs = HsCase (HsVar conIndex_RDR `HsApp` c_Expr) 
+                         (map from_con_alt data_cons) tycon_loc
+    from_con_alt dc = mk_triv_Match (LitPat (HsInt (toInteger (dataConTag dc))))
+                                   (mkHsVarApps (getRdrName dc)
+                                                (replicate (dataConSourceArity dc) undefined_RDR))
+                         
+       ------------ toConstr
+    toCon_bind = mk_FunMonoBind tycon_loc toConstr_RDR (map to_con_eqn data_cons)
+    to_con_eqn dc = ([mkWildConPat dc], HsVar (mkConstrName dc))
+    
+       ------------ dataTypeOf
+    dataTypeOf_bind = mk_easy_FunMonoBind tycon_loc dataTypeOf_RDR [wildPat] 
+                                         [] (HsVar data_type_name)
+
+       ------------ $dT
+    data_type_name = mkDataTypeName tycon
+    datatype_bind  = mkVarMonoBind tycon_loc data_type_name
+                                            (ExplicitList placeHolderType constrs)
+    constrs = [HsVar (mkConstrName con) | con <- data_cons]
+
+       ------------ $cT1 etc
+    mk_con_bind dc = mkVarMonoBind tycon_loc (mkConstrName dc) 
+                                            (mkHsApps mkConstr_RDR (constr_args dc))
+    constr_args dc = [mkHsIntLit (toInteger (dataConTag dc)),          -- Tag
+                     HsLit (mkHsString (occNameUserString dc_occ)),    -- String name
+                     HsVar fixity]                                     -- Fixity
+       where
+         dc_occ   = getOccName dc
+         is_infix = isDataSymOcc dc_occ
+         fixity | is_infix  = infix_RDR
+                | otherwise = prefix_RDR
+
+gfoldl_RDR     = varQual_RDR gENERICS_Name FSLIT("gfoldl")
+fromConstr_RDR = varQual_RDR gENERICS_Name FSLIT("fromConstr")
+toConstr_RDR   = varQual_RDR gENERICS_Name FSLIT("toConstr")
+dataTypeOf_RDR = varQual_RDR gENERICS_Name FSLIT("dataTypeOf")
+mkConstr_RDR   = varQual_RDR gENERICS_Name FSLIT("mkConstr")
+mkDataType_RDR = varQual_RDR gENERICS_Name FSLIT("mkDataType")
+conIndex_RDR   = varQual_RDR gENERICS_Name FSLIT("conIndex")
+prefix_RDR     = dataQual_RDR gENERICS_Name FSLIT("Prefix")
+infix_RDR      = dataQual_RDR gENERICS_Name FSLIT("Infix")
+
+mkDataTypeName :: TyCon -> RdrName     -- $tT
+mkDataTypeName tc = mkRdrUnqual (mkDataTOcc (getOccName tc))
+
+mkConstrName :: DataCon -> RdrName     -- $cT1
+mkConstrName con = mkRdrUnqual (mkDataCOcc (getOccName con))
 
 
 apN :: Int -> (a -> a) -> a -> a
@@ -1226,6 +1250,8 @@ mk_easy_Match loc pats binds expr
        -- "recursive" MonoBinds, and it is its job to sort things out
        -- from there.
 
+mk_triv_Match pat expr = mkSimpleMatch [pat] expr placeHolderType generatedSrcLoc
+
 mk_FunMonoBind :: SrcLoc -> RdrName
                -> [([RdrNamePat], RdrNameHsExpr)]
                -> RdrNameMonoBinds
@@ -1278,9 +1304,9 @@ compare_gen_Case (HsVar eq_tag) a b | eq_tag == eqTag_RDR
   = HsApp (HsApp (HsVar compare_RDR) a) b      -- Simple case 
 compare_gen_Case eq a b                                -- General case
   = HsCase (HsPar (HsApp (HsApp (HsVar compare_RDR) a) b)) {-of-}
-      [mkSimpleMatch [mkNullaryConPat ltTag_RDR] ltTag_Expr placeHolderType generatedSrcLoc,
-       mkSimpleMatch [mkNullaryConPat eqTag_RDR] eq placeHolderType generatedSrcLoc,
-       mkSimpleMatch [mkNullaryConPat gtTag_RDR] gtTag_Expr placeHolderType generatedSrcLoc]
+      [mk_triv_Match (mkNullaryConPat ltTag_RDR) ltTag_Expr,
+       mk_triv_Match (mkNullaryConPat eqTag_RDR) eq,
+       mk_triv_Match (mkNullaryConPat gtTag_RDR) gtTag_Expr]
       generatedSrcLoc
 
 careful_compare_Case tycon ty eq a b
@@ -1371,7 +1397,7 @@ untag_Expr :: TyCon -> [(RdrName, RdrName)] -> RdrNameHsExpr -> RdrNameHsExpr
 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-}
-      [mkSimpleMatch [VarPat put_tag_here] (untag_Expr tycon more expr) placeHolderType generatedSrcLoc]
+      [mk_triv_Match (VarPat put_tag_here) (untag_Expr tycon more expr)]
       generatedSrcLoc
 
 cmp_tags_Expr :: RdrName               -- Comparison op