Merge pull request #400 from asarhaddon/improve-mal-impl-macro-no-meta
[jackhill/mal.git] / yorick / env.i
CommitLineData
21986733
DM
1require, "hash.i"
2require, "types.i"
3
4struct Env {
5 pointer outer
6 Hash data
7}
8
9func env_new(outer_ptr, binds=, exprs=)
10{
11 env = Env(outer=outer_ptr, data=hash_new())
12 for (i = 1; i <= numberof(binds); ++i) {
13 if (binds(i)->val == "&") {
14 rest_args = numberof(exprs) >= i ? exprs(i:) : []
15 env_set, env, binds(i + 1)->val, MalList(val=&rest_args)
16 break
17 } else {
18 env_set, env, binds(i)->val, *exprs(i)
19 }
20 }
21 return env
22}
23
24func env_find(env, key)
25{
26 if (hash_has_key(env.data, key)) return env
27 if (is_void(*env.outer)) return nil
28 return env_find(*env.outer, key)
29}
30
31func env_get(env, key)
32{
33 found_env = env_find(env, key)
34 if (is_void(found_env)) return MalError(message=("'" + key + "' not found"))
35 return hash_get(found_env.data, key)
36}
37
38func env_set(&env, key, val)
39{
40 d = env.data
41 hash_set, d, key, val
42 env.data = d
43 return val
44}