2014-04-02 22:23:37 -05:00
|
|
|
# Environment
|
2024-08-08 16:08:30 +02:00
|
|
|
from mal_types import List
|
2014-04-02 22:23:37 -05:00
|
|
|
|
|
|
|
|
class Env():
|
|
|
|
|
def __init__(self, outer=None, binds=None, exprs=None):
|
2024-08-08 16:08:30 +02:00
|
|
|
"""If binds is not None, exprs must be an iterable.."""
|
2014-04-02 22:23:37 -05:00
|
|
|
self.data = {}
|
2024-08-08 16:08:30 +02:00
|
|
|
self.outer = outer
|
2014-04-02 22:23:37 -05:00
|
|
|
|
|
|
|
|
if binds:
|
2024-08-08 16:08:30 +02:00
|
|
|
exprs_it = iter(exprs)
|
2014-04-02 22:23:37 -05:00
|
|
|
for i in range(len(binds)):
|
|
|
|
|
if binds[i] == "&":
|
2024-08-08 16:08:30 +02:00
|
|
|
# binds may be a non-list iterable
|
|
|
|
|
self.data[binds[i+1]] = List(exprs_it)
|
2014-04-02 22:23:37 -05:00
|
|
|
break
|
|
|
|
|
else:
|
2024-08-08 16:08:30 +02:00
|
|
|
self.data[binds[i]] = next(exprs_it)
|
2014-04-02 22:23:37 -05:00
|
|
|
|
|
|
|
|
def set(self, key, value):
|
|
|
|
|
self.data[key] = value
|
|
|
|
|
return value
|
|
|
|
|
|
2024-08-08 16:08:30 +02:00
|
|
|
def get(self, key, return_nil=False):
|
|
|
|
|
# Python prefers iteration over recursion.
|
|
|
|
|
env = self
|
|
|
|
|
while key not in env.data:
|
|
|
|
|
env = env.outer
|
|
|
|
|
if env is None:
|
|
|
|
|
if return_nil:
|
|
|
|
|
return None
|
|
|
|
|
raise Exception("'" + key + "' not found")
|
2014-04-02 22:23:37 -05:00
|
|
|
return env.data[key]
|