35 lines
813 B
Plaintext
35 lines
813 B
Plaintext
|
(def! bind-env (fn* [env b e]
|
||
|
(if (empty? b)
|
||
|
env
|
||
|
(let* [b0 (first b)]
|
||
|
(if (= '& b0)
|
||
|
(assoc env (str (nth b 1)) e)
|
||
|
(bind-env (assoc env (str b0) (first e)) (rest b) (rest e)))))))
|
||
|
|
||
|
(def! new-env (fn* [& args]
|
||
|
(if (<= (count args) 1)
|
||
|
(atom {:outer (first args)})
|
||
|
(atom (apply bind-env {:outer (first args)} (rest args))))))
|
||
|
|
||
|
(def! env-find (fn* [env k]
|
||
|
(env-find-str env (str k))))
|
||
|
|
||
|
(def! env-find-str (fn* [env ks]
|
||
|
(if env
|
||
|
(let* [data @env]
|
||
|
(if (contains? data ks)
|
||
|
env
|
||
|
(env-find-str (get data :outer) ks))))))
|
||
|
|
||
|
(def! env-get (fn* [env k]
|
||
|
(let* [ks (str k)
|
||
|
e (env-find-str env ks)]
|
||
|
(if e
|
||
|
(get @e ks)
|
||
|
(throw (str "'" ks "' not found"))))))
|
||
|
|
||
|
(def! env-set (fn* [env k v]
|
||
|
(do
|
||
|
(swap! env assoc (str k) v)
|
||
|
v)))
|