--- /dev/null
+class Env {
+ const _outer Env
+ var _data StringMap<MalVal> = {}
+
+ def new(outer Env) {
+ _outer = outer
+ }
+
+ def new(outer Env, binds List<MalVal>, exprs List<MalVal>) {
+ _outer = outer
+ for i in 0..binds.count {
+ const name = (binds[i] as MalSymbol).val
+ if name == "&" {
+ const restName = (binds[i + 1] as MalSymbol).val
+ _data[restName] = MalList.new(exprs.slice(i))
+ break
+ } else {
+ _data[name] = exprs[i]
+ }
+ }
+ }
+
+ def find(key MalSymbol) Env {
+ if key.val in _data { return self }
+ return _outer?.find(key)
+ }
+
+ def get(key MalSymbol) MalVal {
+ const env = find(key)
+ if env == null { throw MalError.new("'" + key.val + "' not found") }
+ return env._data[key.val]
+ }
+
+ def set(key MalSymbol, value MalVal) MalVal {
+ _data[key.val] = value
+ return value
+ }
+}