Commit | Line | Data |
---|---|---|
179e8eaf ST |
1 | #include "Environment.h" |
2 | #include "Types.h" | |
3 | ||
4 | #include <algorithm> | |
5 | ||
dc9b184b ST |
6 | malEnv::malEnv(malEnvPtr outer) |
7 | : m_outer(outer) | |
8 | { | |
9 | TRACE_ENV("Creating malEnv %p, outer=%p\n", this, m_outer.ptr()); | |
10 | } | |
11 | ||
ad0fc149 ST |
12 | malEnv::malEnv(malEnvPtr outer, const StringVec& bindings, |
13 | malValueIter argsBegin, malValueIter argsEnd) | |
14 | : m_outer(outer) | |
15 | { | |
16 | TRACE_ENV("Creating malEnv %p, outer=%p\n", this, m_outer.ptr()); | |
17 | int n = bindings.size(); | |
18 | auto it = argsBegin; | |
19 | for (int i = 0; i < n; i++) { | |
20 | if (bindings[i] == "&") { | |
0997015d | 21 | MAL_CHECK(i == n - 2, "There must be one parameter after the &"); |
ad0fc149 ST |
22 | |
23 | set(bindings[n-1], mal::list(it, argsEnd)); | |
24 | return; | |
25 | } | |
0997015d | 26 | MAL_CHECK(it != argsEnd, "Not enough parameters"); |
ad0fc149 ST |
27 | set(bindings[i], *it); |
28 | ++it; | |
29 | } | |
0997015d | 30 | MAL_CHECK(it == argsEnd, "Too many parameters"); |
ad0fc149 ST |
31 | } |
32 | ||
dc9b184b ST |
33 | malEnv::~malEnv() |
34 | { | |
35 | TRACE_ENV("Destroying malEnv %p, outer=%p\n", this, m_outer.ptr()); | |
36 | } | |
37 | ||
38 | malEnvPtr malEnv::find(const String& symbol) | |
39 | { | |
40 | for (malEnvPtr env = this; env; env = env->m_outer) { | |
41 | if (env->m_map.find(symbol) != env->m_map.end()) { | |
42 | return env; | |
43 | } | |
44 | } | |
45 | return NULL; | |
46 | } | |
47 | ||
179e8eaf ST |
48 | malValuePtr malEnv::get(const String& symbol) |
49 | { | |
dc9b184b ST |
50 | for (malEnvPtr env = this; env; env = env->m_outer) { |
51 | auto it = env->m_map.find(symbol); | |
52 | if (it != env->m_map.end()) { | |
53 | return it->second; | |
54 | } | |
179e8eaf | 55 | } |
0997015d | 56 | MAL_FAIL("'%s' not found", symbol.c_str()); |
179e8eaf ST |
57 | } |
58 | ||
59 | malValuePtr malEnv::set(const String& symbol, malValuePtr value) | |
60 | { | |
61 | m_map[symbol] = value; | |
62 | return value; | |
63 | } | |
ad50bab2 ST |
64 | |
65 | malEnvPtr malEnv::getRoot() | |
66 | { | |
67 | // Work our way down the the global environment. | |
68 | for (malEnvPtr env = this; ; env = env->m_outer) { | |
69 | if (!env->m_outer) { | |
70 | return env; | |
71 | } | |
72 | } | |
73 | } |