DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / rpython / env.py
CommitLineData
9be6d5a6 1from mal_types import MalType, MalSym, MalList, throw_str
e6cfacb4
JM
2
3# Environment
4class Env():
5 def __init__(self, outer=None, binds=None, exprs=None):
6 self.data = {}
7 self.outer = outer or None
8
9 if binds:
b0a9121d 10 assert isinstance(binds, MalList) and isinstance(exprs, MalList)
e6cfacb4 11 for i in range(len(binds)):
b0a9121d 12 bind = binds[i]
23fa1b11
JM
13 if not isinstance(bind, MalSym):
14 throw_str("env bind value is not a symbol")
b0a9121d
JM
15 if bind.value == u"&":
16 bind = binds[i+1]
23fa1b11
JM
17 if not isinstance(bind, MalSym):
18 throw_str("env bind value is not a symbol")
b0a9121d 19 self.data[bind.value] = exprs.slice(i)
e6cfacb4
JM
20 break
21 else:
b0a9121d 22 self.data[bind.value] = exprs[i]
e6cfacb4
JM
23
24 def find(self, key):
25 assert isinstance(key, MalSym)
26 if key.value in self.data: return self
27 elif self.outer: return self.outer.find(key)
28 else: return None
29
30 def set(self, key, value):
31 assert isinstance(key, MalSym)
32 assert isinstance(value, MalType)
33 self.data[key.value] = value
34 return value
35
36 def get(self, key):
37 assert isinstance(key, MalSym)
38 env = self.find(key)
9be6d5a6 39 if not env: throw_str("'" + str(key.value) + "' not found")
e6cfacb4 40 return env.data[key.value]