2 ( Env
, env_new
, env_bind
, env_get
, env_set
)
5 import Data
.IORef
(modifyIORef
, newIORef
, readIORef
)
6 import qualified Data
.Map
as Map
10 -- The Env type si defined in Types module to avoid dep cycle.
12 env_new
:: Env
-> IO Env
13 env_new outer
= (: outer
) <$> newIORef
(Map
.fromList
[])
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
20 env_bind env
["&", k
] vs
= do
21 env_set env k
$ toList vs
23 env_bind _
[] [] = return True
24 env_bind _ _ _
= return False
26 env_get
:: Env
-> String -> IO (Maybe MalVal
)
27 env_get
[] _
= return Nothing
28 env_get
(ref
: outer
) key
= do
30 case Map
.lookup key hm
of
31 Nothing
-> env_get outer key
32 justVal
-> return justVal
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"