collectAnnValBinders,
mkDataConTag,
splitClosureTy,
- mkPReprType, mkPReprAlts,
- mkPADictType, mkPArrayType,
+ mkPRepr, mkToPRepr, mkFromPRepr,
+ mkPADictType, mkPArrayType, mkPReprType,
parrayReprTyCon, parrayReprDataCon, mkVScrut,
+ prDictOfType, prCoerce,
paDictArgType, paDictOfType, paDFunType,
paMethod, lengthPA, replicatePA, emptyPA, liftPA,
polyAbstract, polyApply, polyVApply,
import DsUtils
import CoreSyn
import CoreUtils
+import Coercion
import Type
import TypeRep
import TyCon
import Var
import Id ( mkWildId )
import MkId ( unwrapFamInstScrut )
+import Name ( Name )
import PrelNames
import TysWiredIn
import BasicTypes ( Boxity(..) )
import Outputable
import FastString
-import Control.Monad ( liftM, zipWithM_ )
+import Control.Monad ( liftM, liftM2, zipWithM_ )
collectAnnTypeArgs :: AnnExpr b ann -> (AnnExpr b ann, [Type])
collectAnnTypeArgs expr = go expr []
mkDataConTag :: DataCon -> CoreExpr
mkDataConTag dc = mkConApp intDataCon [mkIntLitInt $ dataConTag dc]
-isClosureTyCon :: TyCon -> Bool
-isClosureTyCon tc = tyConName tc == closureTyConName
+splitUnTy :: String -> Name -> Type -> Type
+splitUnTy s name ty
+ | Just (tc, [ty']) <- splitTyConApp_maybe ty
+ , tyConName tc == name
+ = ty'
-splitClosureTy :: Type -> (Type, Type)
-splitClosureTy ty
- | Just (tc, [arg_ty, res_ty]) <- splitTyConApp_maybe ty
- , isClosureTyCon tc
- = (arg_ty, res_ty)
+ | otherwise = pprPanic s (ppr ty)
- | otherwise = pprPanic "splitClosureTy" (ppr ty)
+splitBinTy :: String -> Name -> Type -> (Type, Type)
+splitBinTy s name ty
+ | Just (tc, [ty1, ty2]) <- splitTyConApp_maybe ty
+ , tyConName tc == name
+ = (ty1, ty2)
-isPArrayTyCon :: TyCon -> Bool
-isPArrayTyCon tc = tyConName tc == parrayTyConName
+ | otherwise = pprPanic s (ppr ty)
-splitPArrayTy :: Type -> Type
-splitPArrayTy ty
- | Just (tc, [arg_ty]) <- splitTyConApp_maybe ty
- , isPArrayTyCon tc
- = arg_ty
+splitCrossTy :: Type -> (Type, Type)
+splitCrossTy = splitBinTy "splitCrossTy" ndpCrossTyConName
+
+splitPlusTy :: Type -> (Type, Type)
+splitPlusTy = splitBinTy "splitSumTy" ndpPlusTyConName
+
+splitEmbedTy :: Type -> Type
+splitEmbedTy = splitUnTy "splitEmbedTy" embedTyConName
- | otherwise = pprPanic "splitPArrayTy" (ppr ty)
+splitClosureTy :: Type -> (Type, Type)
+splitClosureTy = splitBinTy "splitClosureTy" closureTyConName
+
+splitPArrayTy :: Type -> Type
+splitPArrayTy = splitUnTy "splitPArrayTy" parrayTyConName
mkBuiltinTyConApp :: (Builtins -> TyCon) -> [Type] -> VM Type
mkBuiltinTyConApp get_tc tys
where
mk tc ty1 ty2 = mkTyConApp tc [ty1,ty2]
-mkPReprType :: [[Type]] -> VM Type
-mkPReprType [] = return unitTy
-mkPReprType tys
+mkPRepr :: [[Type]] -> VM Type
+mkPRepr [] = return unitTy
+mkPRepr tys
= do
embed <- builtin embedTyCon
cross <- builtin crossTyCon
. map (mk_tup . map mk_embed)
$ tys
-mkPReprAlts :: [[CoreExpr]] -> VM ([CoreExpr], Type)
-mkPReprAlts ess
+mkToPRepr :: [[CoreExpr]] -> VM ([CoreExpr], Type)
+mkToPRepr ess
= do
embed_tc <- builtin embedTyCon
embed_dc <- builtin embedDataCon
left_dc <- builtin leftDataCon
right_dc <- builtin rightDataCon
- let mk_embed (expr, ty, pa)
- = (mkConApp embed_dc [Type ty, pa, expr],
+ let mk_embed expr
+ = (mkConApp embed_dc [Type ty, expr],
mkTyConApp embed_tc [ty])
+ where ty = exprType expr
mk_cross (expr1, ty1) (expr2, ty2)
= (mkConApp cross_dc [Type ty1, Type ty2, expr1, expr2],
(mkConApp left_dc [Type lty, Type rty, expr]
: [mkConApp right_dc [Type lty, Type rty, alt] | alt <- alts],
mkTyConApp plus_tc [lty, rty])
-
- liftM (mk_sum . map (mk_tup . map mk_embed))
- (mapM (mapM init) ess)
- where
- init expr = let ty = exprType expr
- in do
- pa <- paDictOfType ty
- return (expr, ty, pa)
+
+ return . mk_sum $ map (mk_tup . map mk_embed) ess
+
+mkFromPRepr :: CoreExpr -> Type -> [([Var], CoreExpr)] -> VM CoreExpr
+mkFromPRepr scrut res_ty alts
+ = do
+ embed_dc <- builtin embedDataCon
+ cross_dc <- builtin crossDataCon
+ left_dc <- builtin leftDataCon
+ right_dc <- builtin rightDataCon
+ pa_tc <- builtin paTyCon
+
+ let un_embed expr ty var res
+ = Case expr (mkWildId ty) res_ty
+ [(DataAlt embed_dc, [var], res)]
+
+ un_cross expr ty var1 var2 res
+ = Case expr (mkWildId ty) res_ty
+ [(DataAlt cross_dc, [var1, var2], res)]
+
+ un_tup expr ty [] res = return res
+ un_tup expr ty [var] res = return $ un_embed expr ty var res
+ un_tup expr ty (var : vars) res
+ = do
+ lv <- newLocalVar FSLIT("x") lty
+ rv <- newLocalVar FSLIT("y") rty
+ liftM (un_cross expr ty lv rv
+ . un_embed (Var lv) lty var)
+ (un_tup (Var rv) rty vars res)
+ where
+ (lty, rty) = splitCrossTy ty
+
+ un_plus expr ty var1 var2 res1 res2
+ = Case expr (mkWildId ty) res_ty
+ [(DataAlt left_dc, [var1], res1),
+ (DataAlt right_dc, [var2], res2)]
+
+ un_sum expr ty [(vars, res)] = un_tup expr ty vars res
+ un_sum expr ty ((vars, res) : alts)
+ = do
+ lv <- newLocalVar FSLIT("l") lty
+ rv <- newLocalVar FSLIT("r") rty
+ liftM2 (un_plus expr ty lv rv)
+ (un_tup (Var lv) lty vars res)
+ (un_sum (Var rv) rty alts)
+ where
+ (lty, rty) = splitPlusTy ty
+
+ un_sum scrut (exprType scrut) alts
mkClosureType :: Type -> Type -> VM Type
mkClosureType arg_ty res_ty = mkBuiltinTyConApp closureTyCon [arg_ty, res_ty]
mkClosureTypes :: [Type] -> Type -> VM Type
mkClosureTypes = mkBuiltinTyConApps closureTyCon
+mkPReprType :: Type -> VM Type
+mkPReprType ty = mkBuiltinTyConApp preprTyCon [ty]
+
mkPADictType :: Type -> VM Type
mkPADictType ty = mkBuiltinTyConApp paTyCon [ty]
(tc, arg_tys) <- parrayReprTyCon (exprType ve)
return ((ve, unwrapFamInstScrut tc arg_tys le), tc, arg_tys)
+prDictOfType :: Type -> VM CoreExpr
+prDictOfType orig_ty
+ | Just (tycon, ty_args) <- splitTyConApp_maybe orig_ty
+ = do
+ dfun <- traceMaybeV "prDictOfType" (ppr tycon) (lookupTyConPR tycon)
+ prDFunApply (Var dfun) ty_args
+
+prDFunApply :: CoreExpr -> [Type] -> VM CoreExpr
+prDFunApply dfun tys
+ = do
+ args <- mapM mkDFunArg arg_tys
+ return $ mkApps mono_dfun args
+ where
+ mono_dfun = mkTyApps dfun tys
+ (arg_tys, _) = splitFunTys (exprType mono_dfun)
+
+mkDFunArg :: Type -> VM CoreExpr
+mkDFunArg ty
+ | Just (tycon, [arg]) <- splitTyConApp_maybe ty
+
+ = let name = tyConName tycon
+
+ get_dict | name == paTyConName = paDictOfType
+ | name == prTyConName = prDictOfType
+ | otherwise = pprPanic "mkDFunArg" (ppr ty)
+
+ in get_dict arg
+
+mkDFunArg ty = pprPanic "mkDFunArg" (ppr ty)
+
+prCoerce :: TyCon -> [Type] -> CoreExpr -> VM CoreExpr
+prCoerce repr_tc args expr
+ | Just arg_co <- tyConFamilyCoercion_maybe repr_tc
+ = do
+ pr_tc <- builtin prTyCon
+
+ let co = mkAppCoercion (mkTyConApp pr_tc [])
+ (mkSymCoercion (mkTyConApp arg_co args))
+
+ return $ mkCoerce co expr
+
paDictArgType :: TyVar -> VM (Maybe Type)
paDictArgType tv = go (TyVarTy tv) (tyVarKind tv)
where