module UHC.Light.Compiler.Gam
( module UHC.Light.Compiler.Gam.Base
, ppGam, ppGamDup
, IdDefOccGam, IdDefOccAsc
, idDefOccGamUnion
, gamDoTyWithVarMp
, SoGam, SoGamInfo (..)
, initSoGam
, idDefOccGamPartitionByKind
, idDefOccGamByKind
, idDefOccGamStrip
, IdQualGam
, idGam2QualGam, idQualGamReplacement )
where
import UHC.Light.Compiler.Gam.Base
import Data.List
import UHC.Util.Utils
import UHC.Light.Compiler.Base.HsName.Builtin
import UHC.Light.Compiler.Base.Common
import UHC.Light.Compiler.NameAspect
import UHC.Light.Compiler.Error
import UHC.Util.Pretty
import UHC.Light.Compiler.Ty.Pretty
import qualified Data.Set as Set
import UHC.Light.Compiler.VarMp
import UHC.Light.Compiler.Substitutable
import UHC.Light.Compiler.Ty
import UHC.Light.Compiler.Opts.Base
import Data.Maybe
import qualified Data.Set as Set
import qualified Data.Map as Map
import UHC.Light.Compiler.Core
import UHC.Util.ScopeMapGam
import UHC.Light.Compiler.Base.Debug
import UHC.Light.Compiler.Core.Subst
import UHC.Light.Compiler.VarLookup
gamDoTyWithVarMp
:: Ord key =>
(info -> Ty,Ty -> info -> info)
-> (key
-> (Ty,VarMp)
-> VarMp
-> thr
-> (Ty,VarMp,thr))
-> VarMp
-> thr
-> Gam key info
-> (Gam key info,VarMp,thr)
gamDoTyWithVarMp (get,set) f gamVarMp thr gam
= (g,c,thr')
where (g,(thr',c))
= gamMapThr
(\(n,gi) (thr,c)
-> let t = get gi
(t',c',thr') = f n (gamVarMp `varUpdCyc` t) c thr
(tg,cg) = case (tyUnAnn t,tyUnAnn t') of
(Ty_Var v1 _ ,Ty_Var v2 _) | v1 == v2
-> dflt
(Ty_Var v cat,_ ) | not (tvCatIsFixed cat)
-> (t ,v `varmpTyUnit` t')
_ -> dflt
where dflt = (t',emptyVarMp)
in ((n,set ( tg) gi)
,(thr', cg `varmpPlus` c')
)
)
(thr,emptyVarMp) gam
data SoGamInfo
= SoGamInfo
{ sgiSo :: Ty }
deriving Show
type SoGam = Gam HsName SoGamInfo
type IdDefOccGam = Gam IdOcc IdDefOcc
type IdDefOccAsc = AssocL IdOcc [IdDefOcc]
idDefOccGamUnion :: IdDefOccGam -> IdDefOccGam -> IdDefOccGam
idDefOccGamUnion = gamUnionWith idDefOccLCmb
idDefOccGamPartitionByKind :: [IdOccKind] -> IdDefOccGam -> (IdDefOccAsc,IdDefOccAsc)
idDefOccGamPartitionByKind ks
= partition (\(IdOcc n k',_) -> k' `elem` ks) . gamToAssocDupL
idDefOccGamByKind :: IdOccKind -> IdDefOccGam -> AssocL HsName IdDefOcc
idDefOccGamByKind k g = [ (n,head i) | (IdOcc n _,i) <- fst (idDefOccGamPartitionByKind [k] g) ]
idDefOccGamStrip :: IdDefOccGam -> IdDefOccGam
idDefOccGamStrip g = gamMap (\(k,v) -> (k,doccStrip v)) g
type IdQualGam = Gam IdOcc HsName
idGam2QualGam :: IdDefOccGam -> IdQualGam
idGam2QualGam = gamMap (\(iocc,docc) -> (iocc {ioccNm = hsnQualified $ ioccNm iocc},ioccNm $ doccOcc $ docc))
idQualGamReplacement :: IdQualGam -> IdOccKind -> HsName -> HsName
idQualGamReplacement g k n = maybe n id $ gamLookup (IdOcc n k) g
instance (Ord tk,VarUpdatable vv subst) => VarUpdatable (SGam tk vv) subst where
s `varUpd` g = gamMapElts (s `varUpd`) g
s `varUpdCyc` g = (g',varmpUnions $ gamElts gm)
where (g',gm) = sgamUnzip $ gamMapElts (s `varUpdCyc`) g
instance (Ord tk,Ord k,VarExtractable vv k) => VarExtractable (SGam tk vv) k where
varFreeSet g = Set.unions $ map varFreeSet $ gamElts g
ppGam :: (Ord k, PP k, PP v) => Gam k v -> PP_Doc
ppGam g = ppAssocL (gamToAssocL g)
ppGamDup :: (Ord k,PP k, PP v) => Gam k v -> PP_Doc
ppGamDup g = ppAssocL $ map (\(k,v) -> (k,ppBracketsCommas v)) $ gamToAssocDupL $ g
instance (Ord k, PP k, PP v) => PP (SGam k v) where
pp g = ppGam g
initSoGam :: SoGam
initSoGam
= assocLToGam
[ (hsnKindStar, SoGamInfo kiStar)
]