module UHC.Light.Compiler.Generics
( Proj (..)
, projFrom
, projTo )
where
import UHC.Light.Compiler.Base.HsName.Builtin
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.Opts
import UHC.Light.Compiler.Ty
import UHC.Light.Compiler.AbstractCore
import UHC.Light.Compiler.AbstractCore.Utils
import UHC.Light.Compiler.Core
import UHC.Light.Compiler.Core.Utils
import UHC.Light.Compiler.Gam.DataGam
import UHC.Util.Utils
data Proj
=
Proj_U1
| Proj_Void
| Proj_Rec1
{ projTyL :: !TyL
, projN :: !Int
}
| Proj_Par1
{ projTyL :: !TyL
, projN :: !Int
}
| Proj_K1
{ projTyL :: !TyL
}
| Proj_Comp1
{ projTyL :: !TyL
, projF1Ty :: !Ty
, projF2Proj :: !Proj
}
| Proj_L1
{ projProj :: !Proj
}
| Proj_R1
{ projProj :: !Proj
}
| Proj_M1
{ projProj :: !Proj
}
| Proj_M1_S1
{ projProj :: !Proj
}
| Proj_Con
{ projCTag :: !CTag
, projProj :: !Proj
}
| Proj_Prod
{ proj1Proj :: !Proj
, proj2Proj :: !Proj
}
| Proj_Sum
{ proj1Proj :: !Proj
, proj2Proj :: !Proj
}
| Proj
{ projProjL :: !Proj
}
deriving (Show)
projCon :: Proj -> Proj
projCon (Proj_L1 p) = projCon p
projCon (Proj_R1 p) = projCon p
projCon (Proj_M1 p) = projCon p
projCon p = p
projSumAlts :: Proj -> [Proj]
projSumAlts (Proj_Sum l r) = projSumAlts l ++ projSumAlts r
projSumAlts (Proj_L1 p ) = map Proj_L1 $ projSumAlts p
projSumAlts (Proj_R1 p ) = map Proj_R1 $ projSumAlts p
projSumAlts (Proj_M1 p ) = map Proj_M1 $ projSumAlts p
projSumAlts Proj_Void = []
projSumAlts p = [p]
projBuiltinNm :: EHCOpts -> Proj -> HsName
projBuiltinNm opts proj
= case proj of
Proj_U1 -> v ehbnGenerDataUnit1AltU1
Proj_Void -> v ehbnUndefined
Proj_Rec1 _ _ -> v ehbnGenerDataRec1AltRec1
Proj_Par1 _ _ -> v ehbnGenerDataPar1AltPar1
Proj_K1 _ -> v ehbnGenerDataKonst1AltK1
Proj_L1 _ -> v ehbnGenerDataSumAltLeft
Proj_R1 _ -> v ehbnGenerDataSumAltRight
Proj_M1 _ -> v ehbnGenerDataMeta1AltM1
Proj_M1_S1 _ -> v ehbnGenerDataMeta1AltM1
Proj_Comp1 _ _ _ -> v ehbnGenerDataComp1AltComp1
Proj_Prod _ _ -> v ehbnGenerDataProdAltProd
_ -> panic ("projBuiltinNm: " ++ show proj)
where v f = ehcOptBuiltin opts f
projBuiltinVar :: (AbstractCore e m b bound boundmeta bcat mbind t p pr pf a) => EHCOpts -> Proj -> e
projBuiltinVar opts proj
= acoreVar $ projBuiltinNm opts proj
nmLForCase nL = zipWith (\n o -> (n,acoreTyErr $ "nmLForCase: " ++ show n,o)) nL [(0::Int) ..]
projFrom
:: (AbstractCore e m b bound boundmeta bcat mbind t p pr pf a, Eq bcat)
=> EHCOpts
-> RCEEnv' e m b ba t
-> Proj
-> e
projFrom
opts rceEnv
(Proj sum)
= acoreLamTy (acoreTyErrLift "Generics.projFrom.argNm" [argNm])
$ acoreSatSelsCasesTy
rceEnv (Just (hsnUniqifyEval argNm,acoreTyErr "Generics.projFrom.sel")) (acoreVar argNm)
[ (tg, nmLForCase nL, Nothing, fst $ mkExp proj nL)
| proj <- projSumAlts sum
, let con = projCon proj
tg = projCTag con
nL = tgNms tg
]
where
argNm = mkHNm "x"
tgNms tg = take (ctagArity tg) $ hsnLclSupply
mkExp proj nL@(~(n:nL'))
= case proj of
Proj_Prod l r -> (acoreApp (projBuiltinVar opts proj) [l',r'], nrL)
where (l',nlL) = mkExp l nL
(r',nrL) = mkExp r nlL
Proj_K1 _ -> var
Proj_Rec1 _ _ -> var
Proj_Par1 _ _ -> var
Proj_M1 _ -> wrap
Proj_M1_S1 _ -> wrap
Proj_L1 _ -> wrap
Proj_R1 _ -> wrap
Proj_Void -> unit
Proj_U1 -> unit
Proj_Comp1 _ _ _ -> var
Proj_Con _ _ -> skip
_ -> panic ("projFrom.mkExp: " ++ show proj)
where wrap = (acore1App (projBuiltinVar opts proj) x, nL')
where (x,nL') = mkExp (projProj proj) nL
unit = (projBuiltinVar opts proj, nL)
skip = mkExp (projProj proj) nL
var = (acore1App (projBuiltinVar opts proj) (acoreVar n), nL')
projTo
:: (AbstractCore e m b bound boundmeta bcat mbind t p pr pf a, Eq bcat)
=> EHCOpts
-> RCEEnv' e m b ba t
-> Proj
-> e
projTo
opts rceEnv
(Proj sum)
= acoreLamTy (acoreTyErrLift "Generics.projTo.scrut" [scrut])
$ mke (acoreVar scrut)
where (mke,(scrut,_,_)) = mkExp sum [] (hsnLclSupplyWith $ mkHNm "proj")
dataGam = rceDataGam rceEnv
mkExp proj nL@(~(n:nL')) scrutL@(~(scrut:scrutL'))
= case proj of
Proj_Prod l r -> ( \e -> acoreSatSelsCasesTy rceEnv (Just (hsnUniqifyEval scrut,acoreTyErr "Generics.projTo.Prod.scrut")) (acoreVar scrut)
[ (prodTg ehbnGenerDataProdAltProd,nmLForCase [sl,sr],Nothing,l' $ r' e) ]
, (scrut, nr, ssr)
)
where (l',(sl,nl,ssl)) = mkExp l nL scrutL'
(r',(sr,nr,ssr)) = mkExp r nl ssl
Proj_K1 _ -> var ehbnGenerDataKonst1 ehbnGenerDataKonst1AltK1
Proj_Rec1 _ _ -> var ehbnGenerDataRec1 ehbnGenerDataRec1AltRec1
Proj_Par1 _ _ -> var ehbnGenerDataPar1 ehbnGenerDataPar1AltPar1
Proj_Comp1 _ _ _ -> var ehbnGenerDataComp1 ehbnGenerDataComp1AltComp1
Proj_U1 -> unit ehbnGenerDataUnit1 ehbnGenerDataUnit1AltU1
Proj_M1_S1 _ -> wrap ehbnGenerDataMeta1 ehbnGenerDataMeta1AltM1
Proj_Sum l r -> ( \e -> acoreSatSelsCasesTy rceEnv (Just (hsnUniqifyEval scrut,acoreTyErr "Generics.projTo.Sum.scrut")) (acoreVar scrut)
[ (sumTg ehbnGenerDataSumAltLeft ,nmLForCase [sl],Nothing,l' e)
, (sumTg ehbnGenerDataSumAltRight,nmLForCase [sr],Nothing,r' e)
]
, (scrut, nr, ssr)
)
where (l',(sl,nl,ssl)) = mkExp l nL scrutL'
(r',(sr,nr,ssr)) = mkExp r nl ssl
Proj_M1 _ -> wrap ehbnGenerDataMeta1 ehbnGenerDataMeta1AltM1
Proj_L1 _ -> skip
Proj_R1 _ -> skip
Proj_Void -> (const $ projBuiltinVar opts proj, (scrut, nL, scrutL'))
Proj_Con tg p -> ( const $ p' $ acoreApp (acoreVar $ ctagNm tg) (map acoreVar nL)
, info
)
where (p',info) = mkExp p nL scrutL
nL = take (ctagArity tg) $ hsnLclSupply
_ -> panic ("projTo.mkExp: " ++ show proj)
where wrap ty con = mkC scrut [sp] np ssp p' ty con
where (p',(sp,np,ssp)) = mkExp (projProj proj) nL scrutL'
var = mkC scrut [n] nL' scrutL' id
unit = mkC scrut [] nL scrutL' id
mkC s nL nL' sL' mke ty con
= ( \e -> acoreSatSelsCasesTy rceEnv (Just (hsnUniqifyEval s,acoreTyErr "Generics.projTo.mkC.s")) (acoreVar s)
[ (tgOf ty con,nmLForCase nL,Nothing,mke e) ]
, (s, nL', sL')
)
skip = mkExp (projProj proj) nL scrutL
tgOf t c = panicJust ("projTo.tgOf: " ++ show c') $ dataGamLookupTag (ehcOptBuiltin opts t) c' dataGam
where c' = ehcOptBuiltin opts c
prodTg = tgOf ehbnGenerDataProd
sumTg = tgOf ehbnGenerDataSum