aboutsummaryrefslogtreecommitdiff
path: root/clojure/src/env.clj
blob: 7f1f934c6577b54b35922c2f926b95f1bfd1e3ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
(ns env)

(defn env [& [outer binds exprs]]
  ;;(prn "env" binds exprs)
  ;; (when (not= (count binds) (count exprs))
  ;;  (throw (Exception. "Arity mistmatch in env call")))
  (atom
    (loop [env {:outer outer}
           b binds
           e exprs]
      (cond
        (= nil b)
        env
        
        (= '& (first b))
        (assoc env (nth b 1) e)
  
        :else
        (recur (assoc env (first b) (first e)) (next b) (next e))))))

(defn env-find [env k]
  (cond
    (contains? @env k) env
    (:outer @env) (env-find (:outer @env) k)
    :else nil))

(defn env-get [env k]
  (let [e (env-find env k)]
    (when-not e
      (throw (Exception. (str "'" k "' not found"))))
    (get @e k)))

(defn env-set [env k v]
  (swap! env assoc k v)
  v)