Merge branch 'master' into elisp
[jackhill/mal.git] / elisp / env.el
1 (defun mal-env (&optional outer binds exprs)
2 (let ((env (vector 'env (vector (make-hash-table :test 'eq) outer))))
3 (while binds
4 (let ((key (pop binds)))
5 (if (eq key '&)
6 (let ((key (pop binds))
7 (value (mal-list exprs)))
8 (mal-env-set env key value)
9 (setq binds nil
10 exprs nil))
11 (let ((value (pop exprs)))
12 (mal-env-set env key value)))))
13 env))
14
15 (defun mal-env-set (env key value)
16 (let ((data (aref (aref env 1) 0)))
17 (puthash key value data)))
18
19 (defun mal-env-find (env key)
20 (let* ((data (aref (aref env 1) 0))
21 (value (gethash key data)))
22 (if (not value)
23 (let ((outer (aref (aref env 1) 1)))
24 (when outer
25 (mal-env-find outer key)))
26 value)))
27
28 (defun mal-env-get (env key)
29 (let ((value (mal-env-find env key)))
30 (if (not value)
31 (error "'%s' not found" key)
32 value)))