-vectTyConDecls :: [TyCon] -> VM [TyCon]
-vectTyConDecls tcs = fixV $ \tcs' ->
- do
- mapM_ (uncurry defTyCon) (lazy_zip tcs tcs')
- mapM vectTyConDecl tcs
- where
- lazy_zip [] _ = []
- lazy_zip (x:xs) ~(y:ys) = (x,y) : lazy_zip xs ys
-
-vectTyConDecl :: TyCon -> VM TyCon
-vectTyConDecl tc
- = do
- name' <- cloneName mkVectTyConOcc name
- rhs' <- vectAlgTyConRhs (algTyConRhs tc)
-
- liftDs $ buildAlgTyCon name'
- tyvars
- [] -- no stupid theta
- rhs'
- rec_flag -- FIXME: is this ok?
- False -- FIXME: no generics
- False -- not GADT syntax
- Nothing -- not a family instance
- where
- name = tyConName tc
- tyvars = tyConTyVars tc
- rec_flag = boolToRecFlag (isRecursiveTyCon tc)
-
-vectAlgTyConRhs :: AlgTyConRhs -> VM AlgTyConRhs
-vectAlgTyConRhs (DataTyCon { data_cons = data_cons
- , is_enum = is_enum
- })
- = do
- data_cons' <- mapM vectDataCon data_cons
- zipWithM_ defDataCon data_cons data_cons'
- return $ DataTyCon { data_cons = data_cons'
- , is_enum = is_enum
- }
-
-vectDataCon :: DataCon -> VM DataCon
-vectDataCon dc
- | not . null $ dataConExTyVars dc = pprPanic "vectDataCon: existentials" (ppr dc)
- | not . null $ dataConEqSpec dc = pprPanic "vectDataCon: eq spec" (ppr dc)
- | otherwise
- = do
- name' <- cloneName mkVectDataConOcc name
- tycon' <- vectTyCon tycon
- arg_tys <- mapM vectType rep_arg_tys
-
- liftDs $ buildDataCon name'
- False -- not infix
- (map (const NotMarkedStrict) arg_tys)
- [] -- no labelled fields
- univ_tvs
- [] -- no existential tvs for now
- [] -- no eq spec for now
- [] -- no context
- arg_tys
- tycon'
- where
- name = dataConName dc
- univ_tvs = dataConUnivTyVars dc
- rep_arg_tys = dataConRepArgTys dc
- tycon = dataConTyCon dc
-
-mk_fam_inst :: TyCon -> TyCon -> (TyCon, [Type])
-mk_fam_inst fam_tc arg_tc
- = (fam_tc, [mkTyConApp arg_tc . mkTyVarTys $ tyConTyVars arg_tc])
-
-mkSumOfProdRepr :: [[Type]] -> VM Type
-mkSumOfProdRepr [] = panic "mkSumOfProdRepr"
-mkSumOfProdRepr tys
- = do
- embed <- builtin embedTyCon
- plus <- builtin plusTyCon
- cross <- builtin crossTyCon
-
- return . foldr1 (mk_bin plus)
- . map (mkprod cross)
- . map (map (mk_un embed))
- $ tys
- where
- mkprod cross [] = unitTy
- mkprod cross tys = foldr1 (mk_bin cross) tys
-
- mk_un tc ty = mkTyConApp tc [ty]
- mk_bin tc ty1 ty2 = mkTyConApp tc [ty1,ty2]
-
-buildPReprTyCon :: TyCon -> TyCon -> VM TyCon
-buildPReprTyCon orig_tc vect_tc
- = do
- name <- cloneName mkPReprTyConOcc (tyConName orig_tc)
- rhs_ty <- buildPReprRhsTy vect_tc
- repr_tc <- builtin reprTyCon
- liftDs $ buildSynTyCon name
- tyvars
- (SynonymTyCon rhs_ty)
- (Just $ mk_fam_inst repr_tc vect_tc)
- where
- tyvars = tyConTyVars vect_tc
-
-buildPReprRhsTy :: TyCon -> VM Type
-buildPReprRhsTy = mkSumOfProdRepr . map dataConRepArgTys . tyConDataCons
-
-buildPArrayTyCon :: TyCon -> TyCon -> VM TyCon
-buildPArrayTyCon orig_tc vect_tc = fixV $ \repr_tc ->
- do
- name' <- cloneName mkPArrayTyConOcc orig_name
- rhs <- buildPArrayTyConRhs orig_name vect_tc repr_tc
- parray <- builtin parrayTyCon
-
- liftDs $ buildAlgTyCon name'
- tyvars
- [] -- no stupid theta
- rhs
- rec_flag -- FIXME: is this ok?
- False -- FIXME: no generics
- False -- not GADT syntax
- (Just $ mk_fam_inst parray vect_tc)
- where
- orig_name = tyConName orig_tc
- tyvars = tyConTyVars vect_tc
- rec_flag = boolToRecFlag (isRecursiveTyCon vect_tc)
-
-
-buildPArrayTyConRhs :: Name -> TyCon -> TyCon -> VM AlgTyConRhs
-buildPArrayTyConRhs orig_name vect_tc repr_tc
- = do
- data_con <- buildPArrayDataCon orig_name vect_tc repr_tc
- return $ DataTyCon { data_cons = [data_con], is_enum = False }
-
-buildPArrayDataCon :: Name -> TyCon -> TyCon -> VM DataCon
-buildPArrayDataCon orig_name vect_tc repr_tc
- = do
- dc_name <- cloneName mkPArrayDataConOcc orig_name
- shape <- tyConShape vect_tc
- repr_tys <- mapM mkPArrayType types
-
- liftDs $ buildDataCon dc_name
- False -- not infix
- (shapeStrictness shape ++ map (const NotMarkedStrict) repr_tys)
- [] -- no field labels
- (tyConTyVars vect_tc)
- [] -- no existentials
- [] -- no eq spec
- [] -- no context
- (shapeReprTys shape ++ repr_tys)
- repr_tc
- where
- types = [ty | dc <- tyConDataCons vect_tc
- , ty <- dataConRepArgTys dc]
-
-mkPADFun :: TyCon -> VM Var
-mkPADFun vect_tc
- = newExportedVar (mkPADFunOcc $ getOccName vect_tc) =<< paDFunType vect_tc
-
-data Shape = Shape {
- shapeReprTys :: [Type]
- , shapeStrictness :: [StrictnessMark]
- , shapeLength :: [CoreExpr] -> VM CoreExpr
- , shapeReplicate :: CoreExpr -> CoreExpr -> VM [CoreExpr]
- }
-
-tyConShape :: TyCon -> VM Shape
-tyConShape vect_tc
- | isProductTyCon vect_tc
- = return $ Shape {
- shapeReprTys = [intPrimTy]
- , shapeStrictness = [NotMarkedStrict]
- , shapeLength = \[len] -> return len
- , shapeReplicate = \len _ -> return [len]
- }
-
- | otherwise
- = do
- repr_ty <- mkPArrayType intTy -- FIXME: we want to unbox this
- return $ Shape {
- shapeReprTys = [repr_ty]
- , shapeStrictness = [MarkedStrict]
- , shapeLength = \[sel] -> lengthPA sel
- , shapeReplicate = \len n -> do
- e <- replicatePA len n
- return [e]
- }
-
-buildTyConBindings :: TyCon -> TyCon -> TyCon -> Var -> VM [(Var, CoreExpr)]
-buildTyConBindings orig_tc vect_tc arr_tc dfun
- = do
- shape <- tyConShape vect_tc
- sequence_ (zipWith4 (vectDataConWorker shape vect_tc arr_tc arr_dc)
- orig_dcs
- vect_dcs
- (inits repr_tys)
- (tails repr_tys))
- dict <- buildPADict shape vect_tc arr_tc dfun
- binds <- takeHoisted
- return $ (dfun, dict) : binds
- where
- orig_dcs = tyConDataCons orig_tc
- vect_dcs = tyConDataCons vect_tc
- [arr_dc] = tyConDataCons arr_tc