{-
%
% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%
-}

-- | FastStringEnv: FastString environments
module GHC.Data.FastString.Env (
        -- * FastString environments (maps)
        FastStringEnv,

        -- ** Manipulating these environments
        mkFsEnv,
        emptyFsEnv, unitFsEnv,
        extendFsEnv_C, extendFsEnv_Acc, extendFsEnv,
        extendFsEnvList, extendFsEnvList_C,
        filterFsEnv,
        plusFsEnv, plusFsEnv_C, alterFsEnv,
        lookupFsEnv, lookupFsEnv_NF, delFromFsEnv, delListFromFsEnv,
        elemFsEnv, mapFsEnv, strictMapFsEnv, mapMaybeFsEnv,
        nonDetFoldFsEnv,

        -- * Deterministic FastString environments (maps)
        DFastStringEnv,

        -- ** Manipulating these environments
        mkDFsEnv, emptyDFsEnv, dFsEnvElts, lookupDFsEnv
    ) where

import GHC.Prelude

import GHC.Types.Unique.FM
import GHC.Types.Unique.DFM
import GHC.Data.Maybe
import GHC.Data.FastString


-- | A non-deterministic set of FastStrings.
-- See Note [Deterministic UniqFM] in "GHC.Types.Unique.DFM" for explanation why it's not
-- deterministic and why it matters. Use DFastStringEnv if the set eventually
-- gets converted into a list or folded over in a way where the order
-- changes the generated code.
type FastStringEnv a = UniqFM FastString a  -- Domain is FastString

emptyFsEnv         :: FastStringEnv a
mkFsEnv            :: [(FastString,a)] -> FastStringEnv a
alterFsEnv         :: (Maybe a-> Maybe a) -> FastStringEnv a -> FastString -> FastStringEnv a
extendFsEnv_C      :: (a->a->a) -> FastStringEnv a -> FastString -> a -> FastStringEnv a
extendFsEnv_Acc    :: (a->b->b) -> (a->b) -> FastStringEnv b -> FastString -> a -> FastStringEnv b
extendFsEnv        :: FastStringEnv a -> FastString -> a -> FastStringEnv a
plusFsEnv          :: FastStringEnv a -> FastStringEnv a -> FastStringEnv a
plusFsEnv_C        :: (a->a->a) -> FastStringEnv a -> FastStringEnv a -> FastStringEnv a
extendFsEnvList    :: FastStringEnv a -> [(FastString,a)] -> FastStringEnv a
extendFsEnvList_C  :: (a->a->a) -> FastStringEnv a -> [(FastString,a)] -> FastStringEnv a
delFromFsEnv       :: FastStringEnv a -> FastString -> FastStringEnv a
delListFromFsEnv   :: FastStringEnv a -> [FastString] -> FastStringEnv a
elemFsEnv          :: FastString -> FastStringEnv a -> Bool
unitFsEnv          :: FastString -> a -> FastStringEnv a
lookupFsEnv        :: FastStringEnv a -> FastString -> Maybe a
lookupFsEnv_NF     :: FastStringEnv a -> FastString -> a
filterFsEnv        :: (elt -> Bool) -> FastStringEnv elt -> FastStringEnv elt
mapFsEnv           :: (elt1 -> elt2) -> FastStringEnv elt1 -> FastStringEnv elt2
mapMaybeFsEnv      :: (elt1 -> Maybe elt2) -> FastStringEnv elt1 -> FastStringEnv elt2

emptyFsEnv :: forall a. FastStringEnv a
emptyFsEnv                = UniqFM FastString a
forall key elt. UniqFM key elt
emptyUFM
unitFsEnv :: forall a. FastString -> a -> FastStringEnv a
unitFsEnv FastString
x a
y             = FastString -> a -> UniqFM FastString a
forall key elt. Uniquable key => key -> elt -> UniqFM key elt
unitUFM FastString
x a
y
extendFsEnv :: forall a. FastStringEnv a -> FastString -> a -> FastStringEnv a
extendFsEnv FastStringEnv a
x FastString
y a
z         = FastStringEnv a -> FastString -> a -> FastStringEnv a
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM FastStringEnv a
x FastString
y a
z
extendFsEnvList :: forall a. FastStringEnv a -> [(FastString, a)] -> FastStringEnv a
extendFsEnvList FastStringEnv a
x [(FastString, a)]
l       = FastStringEnv a -> [(FastString, a)] -> FastStringEnv a
forall key elt.
Uniquable key =>
UniqFM key elt -> [(key, elt)] -> UniqFM key elt
addListToUFM FastStringEnv a
x [(FastString, a)]
l
lookupFsEnv :: forall a. FastStringEnv a -> FastString -> Maybe a
lookupFsEnv FastStringEnv a
x FastString
y           = FastStringEnv a -> FastString -> Maybe a
forall key elt. Uniquable key => UniqFM key elt -> key -> Maybe elt
lookupUFM FastStringEnv a
x FastString
y
alterFsEnv :: forall a.
(Maybe a -> Maybe a)
-> FastStringEnv a -> FastString -> FastStringEnv a
alterFsEnv                = (Maybe a -> Maybe a)
-> UniqFM FastString a -> FastString -> UniqFM FastString a
forall key elt.
Uniquable key =>
(Maybe elt -> Maybe elt) -> UniqFM key elt -> key -> UniqFM key elt
alterUFM
mkFsEnv :: forall a. [(FastString, a)] -> FastStringEnv a
mkFsEnv     [(FastString, a)]
l             = [(FastString, a)] -> UniqFM FastString a
forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
listToUFM [(FastString, a)]
l
elemFsEnv :: forall a. FastString -> FastStringEnv a -> Bool
elemFsEnv FastString
x FastStringEnv a
y             = FastString -> FastStringEnv a -> Bool
forall key elt. Uniquable key => key -> UniqFM key elt -> Bool
elemUFM FastString
x FastStringEnv a
y
plusFsEnv :: forall a. FastStringEnv a -> FastStringEnv a -> FastStringEnv a
plusFsEnv FastStringEnv a
x FastStringEnv a
y             = FastStringEnv a -> FastStringEnv a -> FastStringEnv a
forall key elt. UniqFM key elt -> UniqFM key elt -> UniqFM key elt
plusUFM FastStringEnv a
x FastStringEnv a
y
plusFsEnv_C :: forall a.
(a -> a -> a)
-> FastStringEnv a -> FastStringEnv a -> FastStringEnv a
plusFsEnv_C a -> a -> a
f FastStringEnv a
x FastStringEnv a
y         = (a -> a -> a)
-> FastStringEnv a -> FastStringEnv a -> FastStringEnv a
forall elt key.
(elt -> elt -> elt)
-> UniqFM key elt -> UniqFM key elt -> UniqFM key elt
plusUFM_C a -> a -> a
f FastStringEnv a
x FastStringEnv a
y
extendFsEnv_C :: forall a.
(a -> a -> a)
-> FastStringEnv a -> FastString -> a -> FastStringEnv a
extendFsEnv_C a -> a -> a
f FastStringEnv a
x FastString
y a
z     = (a -> a -> a)
-> FastStringEnv a -> FastString -> a -> FastStringEnv a
forall key elt.
Uniquable key =>
(elt -> elt -> elt)
-> UniqFM key elt -> key -> elt -> UniqFM key elt
addToUFM_C a -> a -> a
f FastStringEnv a
x FastString
y a
z
mapFsEnv :: forall elt1 elt2.
(elt1 -> elt2) -> FastStringEnv elt1 -> FastStringEnv elt2
mapFsEnv elt1 -> elt2
f FastStringEnv elt1
x              = (elt1 -> elt2) -> FastStringEnv elt1 -> UniqFM FastString elt2
forall elt1 elt2 key.
(elt1 -> elt2) -> UniqFM key elt1 -> UniqFM key elt2
mapUFM elt1 -> elt2
f FastStringEnv elt1
x
extendFsEnv_Acc :: forall a b.
(a -> b -> b)
-> (a -> b)
-> FastStringEnv b
-> FastString
-> a
-> FastStringEnv b
extendFsEnv_Acc a -> b -> b
x a -> b
y FastStringEnv b
z FastString
a a
b = (a -> b -> b)
-> (a -> b)
-> FastStringEnv b
-> FastString
-> a
-> FastStringEnv b
forall key elt elts.
Uniquable key =>
(elt -> elts -> elts)
-> (elt -> elts)
-> UniqFM key elts
-> key
-> elt
-> UniqFM key elts
addToUFM_Acc a -> b -> b
x a -> b
y FastStringEnv b
z FastString
a a
b
extendFsEnvList_C :: forall a.
(a -> a -> a)
-> FastStringEnv a -> [(FastString, a)] -> FastStringEnv a
extendFsEnvList_C a -> a -> a
x FastStringEnv a
y [(FastString, a)]
z   = (a -> a -> a)
-> FastStringEnv a -> [(FastString, a)] -> FastStringEnv a
forall key elt.
Uniquable key =>
(elt -> elt -> elt)
-> UniqFM key elt -> [(key, elt)] -> UniqFM key elt
addListToUFM_C a -> a -> a
x FastStringEnv a
y [(FastString, a)]
z
delFromFsEnv :: forall a. FastStringEnv a -> FastString -> FastStringEnv a
delFromFsEnv FastStringEnv a
x FastString
y          = FastStringEnv a -> FastString -> FastStringEnv a
forall key elt.
Uniquable key =>
UniqFM key elt -> key -> UniqFM key elt
delFromUFM FastStringEnv a
x FastString
y
delListFromFsEnv :: forall a. FastStringEnv a -> [FastString] -> FastStringEnv a
delListFromFsEnv FastStringEnv a
x [FastString]
y      = FastStringEnv a -> [FastString] -> FastStringEnv a
forall key elt.
Uniquable key =>
UniqFM key elt -> [key] -> UniqFM key elt
delListFromUFM FastStringEnv a
x [FastString]
y
filterFsEnv :: forall elt. (elt -> Bool) -> FastStringEnv elt -> FastStringEnv elt
filterFsEnv elt -> Bool
x FastStringEnv elt
y           = (elt -> Bool) -> FastStringEnv elt -> FastStringEnv elt
forall elt key. (elt -> Bool) -> UniqFM key elt -> UniqFM key elt
filterUFM elt -> Bool
x FastStringEnv elt
y
mapMaybeFsEnv :: forall elt1 elt2.
(elt1 -> Maybe elt2) -> FastStringEnv elt1 -> FastStringEnv elt2
mapMaybeFsEnv elt1 -> Maybe elt2
f FastStringEnv elt1
x         = (elt1 -> Maybe elt2)
-> FastStringEnv elt1 -> UniqFM FastString elt2
forall elt1 elt2 key.
(elt1 -> Maybe elt2) -> UniqFM key elt1 -> UniqFM key elt2
mapMaybeUFM elt1 -> Maybe elt2
f FastStringEnv elt1
x

lookupFsEnv_NF :: forall a. FastStringEnv a -> FastString -> a
lookupFsEnv_NF FastStringEnv a
env FastString
n = String -> Maybe a -> a
forall a. HasCallStack => String -> Maybe a -> a
expectJust String
"lookupFsEnv_NF" (FastStringEnv a -> FastString -> Maybe a
forall a. FastStringEnv a -> FastString -> Maybe a
lookupFsEnv FastStringEnv a
env FastString
n)

strictMapFsEnv :: (a -> b) -> FastStringEnv a -> FastStringEnv b
strictMapFsEnv :: forall elt1 elt2.
(elt1 -> elt2) -> FastStringEnv elt1 -> FastStringEnv elt2
strictMapFsEnv = (a -> b) -> UniqFM FastString a -> UniqFM FastString b
forall elt1 elt2 key.
(elt1 -> elt2) -> UniqFM key elt1 -> UniqFM key elt2
strictMapUFM

-- | Fold over a 'FastStringEnv'.
--
-- Non-deterministic, unless the folding function is commutative
-- (i.e. @a1 `f` ( a2 `f` b ) == a2 `f` ( a1 `f` b )@ for all @a1@, @a2@, @b@).
nonDetFoldFsEnv :: (a -> b -> b) -> b -> FastStringEnv a -> b
nonDetFoldFsEnv :: forall a b. (a -> b -> b) -> b -> FastStringEnv a -> b
nonDetFoldFsEnv = (a -> b -> b) -> b -> UniqFM FastString a -> b
forall elt a key. (elt -> a -> a) -> a -> UniqFM key elt -> a
nonDetFoldUFM

-- Deterministic FastStringEnv
-- See Note [Deterministic UniqFM] in GHC.Types.Unique.DFM for explanation why we need
-- DFastStringEnv.

type DFastStringEnv a = UniqDFM FastString a  -- Domain is FastString

emptyDFsEnv :: DFastStringEnv a
emptyDFsEnv :: forall a. DFastStringEnv a
emptyDFsEnv = UniqDFM FastString a
forall key elt. UniqDFM key elt
emptyUDFM

dFsEnvElts :: DFastStringEnv a -> [a]
dFsEnvElts :: forall a. DFastStringEnv a -> [a]
dFsEnvElts = UniqDFM FastString a -> [a]
forall key elt. UniqDFM key elt -> [elt]
eltsUDFM

mkDFsEnv :: [(FastString,a)] -> DFastStringEnv a
mkDFsEnv :: forall a. [(FastString, a)] -> DFastStringEnv a
mkDFsEnv [(FastString, a)]
l = [(FastString, a)] -> UniqDFM FastString a
forall key elt. Uniquable key => [(key, elt)] -> UniqDFM key elt
listToUDFM [(FastString, a)]
l

lookupDFsEnv :: DFastStringEnv a -> FastString -> Maybe a
lookupDFsEnv :: forall a. DFastStringEnv a -> FastString -> Maybe a
lookupDFsEnv = UniqDFM FastString a -> FastString -> Maybe a
forall key elt.
Uniquable key =>
UniqDFM key elt -> key -> Maybe elt
lookupUDFM