Move implementations into impls/ dir
[jackhill/mal.git] / impls / skew / env.sk
diff --git a/impls/skew/env.sk b/impls/skew/env.sk
new file mode 100644 (file)
index 0000000..2f4afb9
--- /dev/null
@@ -0,0 +1,38 @@
+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
+  }
+}