DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / haskell / Env.hs
1 module Env
2 ( Env, env_new, env_bind, env_get, env_set )
3 where
4
5 import Data.IORef (modifyIORef, newIORef, readIORef)
6 import qualified Data.Map as Map
7
8 import Types
9
10 -- The Env type si defined in Types module to avoid dep cycle.
11
12 env_new :: Env -> IO Env
13 env_new outer = (: outer) <$> newIORef (Map.fromList [])
14
15 -- True means that the actual arguments match the signature.
16 env_bind :: Env -> [String] -> [MalVal] -> IO Bool
17 env_bind env (k : ks) (v : vs) | k /= "&" = do
18 env_set env k v
19 env_bind env ks vs
20 env_bind env ["&", k] vs = do
21 env_set env k $ toList vs
22 return True
23 env_bind _ [] [] = return True
24 env_bind _ _ _ = return False
25
26 env_get :: Env -> String -> IO (Maybe MalVal)
27 env_get [] _ = return Nothing
28 env_get (ref : outer) key = do
29 hm <- readIORef ref
30 case Map.lookup key hm of
31 Nothing -> env_get outer key
32 justVal -> return justVal
33
34 env_set :: Env -> String -> MalVal -> IO ()
35 env_set (ref : _) key val = modifyIORef ref $ Map.insert key val
36 env_set [] _ _ = error "assertion failed in env_set"