%
% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1998
%
\begin{code}
module NameSet (
NameSet,
emptyNameSet, unitNameSet, mkNameSet, unionNameSets, unionManyNameSets,
minusNameSet, elemNameSet, nameSetToList, addOneToNameSet, addListToNameSet,
delFromNameSet, delListFromNameSet, isEmptyNameSet, foldNameSet, filterNameSet,
intersectsNameSet, intersectNameSet,
FreeVars,
isEmptyFVs, emptyFVs, plusFVs, plusFV,
mkFVs, addOneFV, unitFV, delFV, delFVs,
Defs, Uses, DefUse, DefUses,
emptyDUs, usesOnly, mkDUs, plusDU,
findUses, duDefs, duUses, allUses
) where
#include "HsVersions.h"
#include "Typeable.h"
import Name
import UniqSet
\end{code}
%************************************************************************
%* *
\subsection[Sets of names}
%* *
%************************************************************************
\begin{code}
type NameSet = UniqSet Name
emptyNameSet :: NameSet
unitNameSet :: Name -> NameSet
addListToNameSet :: NameSet -> [Name] -> NameSet
addOneToNameSet :: NameSet -> Name -> NameSet
mkNameSet :: [Name] -> NameSet
unionNameSets :: NameSet -> NameSet -> NameSet
unionManyNameSets :: [NameSet] -> NameSet
minusNameSet :: NameSet -> NameSet -> NameSet
elemNameSet :: Name -> NameSet -> Bool
nameSetToList :: NameSet -> [Name]
isEmptyNameSet :: NameSet -> Bool
delFromNameSet :: NameSet -> Name -> NameSet
delListFromNameSet :: NameSet -> [Name] -> NameSet
foldNameSet :: (Name -> b -> b) -> b -> NameSet -> b
filterNameSet :: (Name -> Bool) -> NameSet -> NameSet
intersectNameSet :: NameSet -> NameSet -> NameSet
intersectsNameSet :: NameSet -> NameSet -> Bool
isEmptyNameSet = isEmptyUniqSet
emptyNameSet = emptyUniqSet
unitNameSet = unitUniqSet
mkNameSet = mkUniqSet
addListToNameSet = addListToUniqSet
addOneToNameSet = addOneToUniqSet
unionNameSets = unionUniqSets
unionManyNameSets = unionManyUniqSets
minusNameSet = minusUniqSet
elemNameSet = elementOfUniqSet
nameSetToList = uniqSetToList
delFromNameSet = delOneFromUniqSet
foldNameSet = foldUniqSet
filterNameSet = filterUniqSet
intersectNameSet = intersectUniqSets
delListFromNameSet set ns = foldl delFromNameSet set ns
intersectsNameSet s1 s2 = not (isEmptyNameSet (s1 `intersectNameSet` s2))
\end{code}
%************************************************************************
%* *
\subsection{Free variables}
%* *
%************************************************************************
These synonyms are useful when we are thinking of free variables
\begin{code}
type FreeVars = NameSet
plusFV :: FreeVars -> FreeVars -> FreeVars
addOneFV :: FreeVars -> Name -> FreeVars
unitFV :: Name -> FreeVars
emptyFVs :: FreeVars
plusFVs :: [FreeVars] -> FreeVars
mkFVs :: [Name] -> FreeVars
delFV :: Name -> FreeVars -> FreeVars
delFVs :: [Name] -> FreeVars -> FreeVars
isEmptyFVs :: NameSet -> Bool
isEmptyFVs = isEmptyNameSet
emptyFVs = emptyNameSet
plusFVs = unionManyNameSets
plusFV = unionNameSets
mkFVs = mkNameSet
addOneFV = addOneToNameSet
unitFV = unitNameSet
delFV n s = delFromNameSet s n
delFVs ns s = delListFromNameSet s ns
\end{code}
%************************************************************************
%* *
Defs and uses
%* *
%************************************************************************
\begin{code}
type Defs = NameSet
type Uses = NameSet
type DefUse = (Maybe Defs, Uses)
type DefUses = [DefUse]
emptyDUs :: DefUses
emptyDUs = []
usesOnly :: Uses -> DefUses
usesOnly uses = [(Nothing, uses)]
mkDUs :: [(Defs,Uses)] -> DefUses
mkDUs pairs = [(Just defs, uses) | (defs,uses) <- pairs]
plusDU :: DefUses -> DefUses -> DefUses
plusDU = (++)
duDefs :: DefUses -> Defs
duDefs dus = foldr get emptyNameSet dus
where
get (Nothing, _u1) d2 = d2
get (Just d1, _u1) d2 = d1 `unionNameSets` d2
allUses :: DefUses -> Uses
allUses dus = foldr get emptyNameSet dus
where
get (_d1, u1) u2 = u1 `unionNameSets` u2
duUses :: DefUses -> Uses
duUses dus = foldr get emptyNameSet dus
where
get (Nothing, rhs_uses) uses = rhs_uses `unionNameSets` uses
get (Just defs, rhs_uses) uses = (rhs_uses `unionNameSets` uses)
`minusNameSet` defs
findUses :: DefUses -> Uses -> Uses
findUses dus uses
= foldr get uses dus
where
get (Nothing, rhs_uses) uses
= rhs_uses `unionNameSets` uses
get (Just defs, rhs_uses) uses
| defs `intersectsNameSet` uses
|| any (startsWithUnderscore . nameOccName) (nameSetToList defs)
= rhs_uses `unionNameSets` uses
| otherwise
= uses
\end{code}