{-# LANGUAGE PatternGuards #-}
module Development.Ninja.Env(
Env, newEnv, scopeEnv, addEnv, askEnv, fromEnv
) where
import qualified Data.HashMap.Strict as Map
import Data.Hashable
import Data.IORef
data Env k v = Env (IORef (Map.HashMap k v)) (Maybe (Env k v))
instance Show (Env k v) where show :: Env k v -> String
show Env k v
_ = String
"Env"
newEnv :: IO (Env k v)
newEnv :: forall k v. IO (Env k v)
newEnv = do IORef (HashMap k v)
ref <- forall a. a -> IO (IORef a)
newIORef forall k v. HashMap k v
Map.empty; forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall k v. IORef (HashMap k v) -> Maybe (Env k v) -> Env k v
Env IORef (HashMap k v)
ref forall a. Maybe a
Nothing
scopeEnv :: Env k v -> IO (Env k v)
scopeEnv :: forall k v. Env k v -> IO (Env k v)
scopeEnv Env k v
e = do IORef (HashMap k v)
ref <- forall a. a -> IO (IORef a)
newIORef forall k v. HashMap k v
Map.empty; forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall k v. IORef (HashMap k v) -> Maybe (Env k v) -> Env k v
Env IORef (HashMap k v)
ref forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just Env k v
e
addEnv :: (Eq k, Hashable k) => Env k v -> k -> v -> IO ()
addEnv :: forall k v. (Eq k, Hashable k) => Env k v -> k -> v -> IO ()
addEnv (Env IORef (HashMap k v)
ref Maybe (Env k v)
_) k
k v
v = forall a. IORef a -> (a -> a) -> IO ()
modifyIORef IORef (HashMap k v)
ref forall a b. (a -> b) -> a -> b
$ forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
Map.insert k
k v
v
askEnv :: (Eq k, Hashable k) => Env k v -> k -> IO (Maybe v)
askEnv :: forall k v. (Eq k, Hashable k) => Env k v -> k -> IO (Maybe v)
askEnv (Env IORef (HashMap k v)
ref Maybe (Env k v)
e) k
k = do
HashMap k v
mp <- forall a. IORef a -> IO a
readIORef IORef (HashMap k v)
ref
case forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
Map.lookup k
k HashMap k v
mp of
Just v
v -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just v
v
Maybe v
Nothing | Just Env k v
e <- Maybe (Env k v)
e -> forall k v. (Eq k, Hashable k) => Env k v -> k -> IO (Maybe v)
askEnv Env k v
e k
k
Maybe v
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a. Maybe a
Nothing
fromEnv :: Env k v -> IO (Map.HashMap k v)
fromEnv :: forall k v. Env k v -> IO (HashMap k v)
fromEnv (Env IORef (HashMap k v)
ref Maybe (Env k v)
_) = forall a. IORef a -> IO a
readIORef IORef (HashMap k v)
ref