mirror of
https://github.com/kanaka/mal.git
synced 2024-09-19 09:38:28 +03:00
8a19f60386
- Reorder README to have implementation list after "learning tool" bullet. - This also moves tests/ and libs/ into impls. It would be preferrable to have these directories at the top level. However, this causes difficulties with the wasm implementations which need pre-open directories and have trouble with paths starting with "../../". So in lieu of that, symlink those directories to the top-level. - Move the run_argv_test.sh script into the tests directory for general hygiene.
41 lines
1.4 KiB
Python
41 lines
1.4 KiB
Python
from mal_types import MalType, MalSym, MalList, throw_str
|
|
|
|
# Environment
|
|
class Env():
|
|
def __init__(self, outer=None, binds=None, exprs=None):
|
|
self.data = {}
|
|
self.outer = outer or None
|
|
|
|
if binds:
|
|
assert isinstance(binds, MalList) and isinstance(exprs, MalList)
|
|
for i in range(len(binds)):
|
|
bind = binds[i]
|
|
if not isinstance(bind, MalSym):
|
|
throw_str("env bind value is not a symbol")
|
|
if bind.value == u"&":
|
|
bind = binds[i+1]
|
|
if not isinstance(bind, MalSym):
|
|
throw_str("env bind value is not a symbol")
|
|
self.data[bind.value] = exprs.slice(i)
|
|
break
|
|
else:
|
|
self.data[bind.value] = exprs[i]
|
|
|
|
def find(self, key):
|
|
assert isinstance(key, MalSym)
|
|
if key.value in self.data: return self
|
|
elif self.outer: return self.outer.find(key)
|
|
else: return None
|
|
|
|
def set(self, key, value):
|
|
assert isinstance(key, MalSym)
|
|
assert isinstance(value, MalType)
|
|
self.data[key.value] = value
|
|
return value
|
|
|
|
def get(self, key):
|
|
assert isinstance(key, MalSym)
|
|
env = self.find(key)
|
|
if not env: throw_str("'" + str(key.value) + "' not found")
|
|
return env.data[key.value]
|