Commit | Line | Data |
---|---|---|
ea81a808 JM |
1 | #include <stdlib.h> |
2 | #include "types.h" | |
3 | ||
4 | // Env | |
5 | ||
6 | Env *new_env(Env *outer, MalVal* binds, MalVal *exprs) { | |
6b3ecaa7 | 7 | Env *e = MAL_GC_MALLOC(sizeof(Env)); |
ea81a808 JM |
8 | e->table = g_hash_table_new(g_str_hash, g_str_equal); |
9 | e->outer = outer; | |
10 | ||
11 | if (binds && exprs) { | |
12 | assert_type(binds, MAL_LIST|MAL_VECTOR, | |
13 | "new_env called with non-sequential bindings"); | |
14 | assert_type(exprs, MAL_LIST|MAL_VECTOR, | |
15 | "new_env called with non-sequential expressions"); | |
16 | int binds_len = _count(binds), | |
17 | exprs_len = _count(exprs), | |
18 | varargs = 0, i; | |
19 | for (i=0; i<binds_len; i++) { | |
20 | if (i > exprs_len) { break; } | |
21 | if (_nth(binds, i)->val.string[0] == '&') { | |
22 | varargs = 1; | |
b8ee29b2 | 23 | env_set(e, _nth(binds, i+1), _slice(exprs, i, _count(exprs))); |
ea81a808 JM |
24 | break; |
25 | } else { | |
b8ee29b2 | 26 | env_set(e, _nth(binds, i), _nth(exprs, i)); |
ea81a808 JM |
27 | } |
28 | } | |
29 | assert(varargs || (binds_len == exprs_len), | |
30 | "Arity mismatch: %d formal params vs %d actual params", | |
31 | binds_len, exprs_len); | |
32 | ||
33 | } | |
34 | return e; | |
35 | } | |
36 | ||
b8ee29b2 JM |
37 | Env *env_find(Env *env, MalVal *key) { |
38 | void *val = g_hash_table_lookup(env->table, key->val.string); | |
ea81a808 JM |
39 | if (val) { |
40 | return env; | |
41 | } else if (env->outer) { | |
42 | return env_find(env->outer, key); | |
43 | } else { | |
44 | return NULL; | |
45 | } | |
46 | } | |
47 | ||
b8ee29b2 | 48 | MalVal *env_get(Env *env, MalVal *key) { |
ea81a808 | 49 | Env *e = env_find(env, key); |
b8ee29b2 JM |
50 | assert(e, "'%s' not found", key->val.string); |
51 | return g_hash_table_lookup(e->table, key->val.string); | |
ea81a808 JM |
52 | } |
53 | ||
b8ee29b2 JM |
54 | Env *env_set(Env *env, MalVal *key, MalVal *val) { |
55 | g_hash_table_insert(env->table, key->val.string, val); | |
ea81a808 JM |
56 | return env; |
57 | } |