module Data.Array.Repa.Plugin.ToGHC.Type
( convertType
, convertType_boxed
, convertType_unboxed
, convertBoxed
, convertUnboxed
, Env(..)
, bindVarT
, bindVarX)
where
import Data.Array.Repa.Plugin.ToGHC.Var
import Data.Array.Repa.Plugin.Primitives
import Data.Array.Repa.Plugin.FatName
import Data.Map (Map)
import qualified BasicTypes as G
import qualified HscTypes as G
import qualified Type as G
import qualified TypeRep as G
import qualified TysPrim as G
import qualified TysWiredIn as G
import qualified TyCon as G
import qualified UniqSupply as G
import qualified DDC.Core.Exp as D
import qualified DDC.Core.Compounds as D
import qualified DDC.Core.Flow as D
import qualified DDC.Core.Flow.Compounds as D
import qualified DDC.Core.Flow.Prim as D
import qualified DDC.Base.Pretty as D
import qualified Data.Map as Map
convertType_boxed
:: Env
-> D.Type D.Name
-> G.UniqSM G.Type
convertType_boxed env tt
= case convertBoxed tt of
Just t' -> return t'
_ -> convertType env tt
convertType_unboxed
:: Env
-> D.Type D.Name
-> G.UniqSM G.Type
convertType_unboxed env tt
= case convertUnboxed tt of
Just t' -> return t'
_ -> convertType env tt
convertType
:: Env
-> D.Type D.Name
-> G.UniqSM G.Type
convertType kenv tt
= case tt of
D.TCon (D.TyConBound (D.UPrim (D.NameTyConFlow D.TyConFlowWorld) _) _)
-> return $ G.mkTyConApp G.statePrimTyCon [G.realWorldTy]
D.TApp{}
| Just (D.NameTyConFlow D.TyConFlowVector, [tElem])
<- D.takePrimTyConApps tt
, Just tElem' <- convertBoxed tElem
-> do return $ G.applyTy (prim_Vector (envPrimitives kenv))
tElem'
D.TApp{}
| Just (D.NameTyConFlow D.TyConFlowRef, [tElem])
<- D.takePrimTyConApps tt
, Just tElem' <- convertBoxed tElem
-> do return $ G.applyTy (prim_Ref (envPrimitives kenv))
tElem'
D.TApp{}
| Just (D.NameTyConFlow D.TyConFlowSeries, [tK, tElem])
<- D.takePrimTyConApps tt
, Just tElem' <- convertBoxed tElem
-> do tK' <- convertType kenv tK
return $ G.applyTys (prim_Series (envPrimitives kenv))
[tK', tElem']
D.TCon (D.TyConKind D.KiConData)
-> return $ G.liftedTypeKind
D.TCon (D.TyConBound (D.UPrim (D.NameKiConFlow D.KiConFlowRate) _) _)
-> return $ G.liftedTypeKind
D.TForall b t
-> do (kenv', gv) <- bindVarT kenv b
t' <- convertType kenv' t
return $ G.mkForAllTy gv t'
D.TApp{}
| Just (t1, t2) <- D.takeTFun tt
-> do t1' <- convertType kenv t1
t2' <- convertType kenv t2
return $ G.mkFunTy t1' t2'
D.TApp{}
| Just (tc, tsArgs) <- D.takeTyConApps tt
-> do tsArgs' <- mapM (convertType kenv) tsArgs
tsArgs_b' <- mapM (convertType_boxed kenv) tsArgs
return $ convertTyConApp
(envPrimitives kenv) (envNames kenv)
tc tsArgs' tsArgs_b'
D.TCon tc
-> return $ convertTyConApp
(envPrimitives kenv) (envNames kenv)
tc [] []
D.TVar (D.UName n)
-> case lookup n (envVars kenv) of
Nothing
-> error $ unlines
[ "repa-plugin.ToGHC.convertType: variable "
++ show n ++ " not in scope"
, "env = " ++ show (map fst $ envVars kenv) ]
Just gv
-> return $ G.TyVarTy gv
_ -> error $ "repa-plugin.convertType: no match for " ++ show tt
convertTyConApp
:: Primitives
-> Map D.Name GhcName
-> D.TyCon D.Name
-> [G.Type]
-> [G.Type]
-> G.Type
convertTyConApp _prims names tc tsArgs' tsArgs_b'
= case tc of
D.TyConSpec D.TcConFun
| [t1, t2] <- tsArgs'
-> G.FunTy t1 t2
D.TyConSpec D.TcConUnit
| [] <- tsArgs'
-> G.unitTy
D.TyConBound (D.UPrim (D.NameTyConFlow (D.TyConFlowTuple n)) _) _
| length tsArgs' == n
-> G.mkTyConApp (G.tupleTyCon G.UnboxedTuple n) tsArgs'
D.TyConBound (D.UPrim n _) _
| [] <- tsArgs'
, Just tc' <- convertTyConPrimName n
-> G.mkTyConApp tc' tsArgs'
D.TyConBound (D.UName n) _
| Just (GhcNameTyCon tc') <- Map.lookup n names
-> G.mkTyConApp tc' tsArgs_b'
_ -> error $ "repa-plugin.convertTyConApp: no match for "
++ show tc
convertTyConPrimName :: D.Name -> Maybe G.TyCon
convertTyConPrimName n
= case n of
D.NamePrimTyCon D.PrimTyConBool -> Just G.boolTyCon
D.NamePrimTyCon D.PrimTyConNat -> Just G.intPrimTyCon
D.NamePrimTyCon D.PrimTyConInt -> Just G.intPrimTyCon
_ -> Nothing
convertBoxed :: D.Type D.Name -> Maybe G.Type
convertBoxed t
| t == D.tNat = Just G.intTy
| t == D.tInt = Just G.intTy
| Just (tc,args) <- D.takeTyConApps t
, D.TyConBound (D.UPrim (D.NameTyConFlow (D.TyConFlowTuple n)) _) _
<- tc
, Just args' <- mapM convertBoxed args
= Just $ G.mkTyConApp (G.tupleTyCon G.BoxedTuple n) args'
| otherwise = Nothing
convertUnboxed :: D.Type D.Name -> Maybe G.Type
convertUnboxed t
| t == D.tNat = Just G.intPrimTy
| t == D.tInt = Just G.intPrimTy
| otherwise = Nothing
data Env
= Env
{
envGuts :: G.ModGuts
, envPrimitives :: Primitives
, envNames :: Map D.Name GhcName
, envVars :: [(D.Name, G.Var)]
}
bindVarX :: Env -> Env -> D.Bind D.Name -> G.UniqSM (Env, G.Var)
bindVarX kenv tenv (D.BName n t)
= do gt <- convertType kenv t
let str = D.renderPlain (D.ppr n)
gv <- newDummyVar str gt
let tenv' = tenv { envVars = (n, gv) : envVars tenv }
return (tenv', gv)
bindVarX kenv tenv (D.BNone t)
= do gt <- convertType kenv t
gv <- newDummyVar "x" gt
return (tenv, gv)
bindVarX _ _ b
= error $ "repa-plugin.ToGHC.bindVarX: can't bind " ++ show b
bindVarT :: Env -> D.Bind D.Name -> G.UniqSM (Env, G.Var)
bindVarT kenv (D.BName n _)
= do let str = D.renderPlain (D.ppr n)
gv <- newDummyTyVar str
let kenv' = kenv { envVars = (n, gv) : envVars kenv }
return (kenv', gv)
bindVarT _ b
= error $ "repa-plugin.ToGHC.bindVarT: can't bind " ++ show b