Commit | Line | Data |
---|---|---|
f409e200 VS |
1 | (define-library (lib env) |
2 | ||
3 | (export make-env env-set env-find env-get) | |
4 | ||
5 | (import (scheme base)) | |
6 | ||
7 | (import (lib util)) | |
1d20dc6b | 8 | (import (lib types)) |
f409e200 VS |
9 | |
10 | (begin | |
11 | ||
12 | (define-record-type env | |
13 | (%make-env outer data) | |
14 | env? | |
15 | (outer env-outer) | |
16 | (data env-data env-data-set!)) | |
17 | ||
18 | (define (make-env outer . rest) | |
19 | (let ((env (%make-env outer '()))) | |
20 | (when (pair? rest) | |
1d20dc6b VS |
21 | (let loop ((binds (car rest)) |
22 | (exprs (cadr rest))) | |
23 | (when (pair? binds) | |
24 | (let ((bind (car binds))) | |
25 | (if (eq? bind '&) | |
26 | (env-set env (cadr binds) (mal-list exprs)) | |
27 | (begin | |
28 | (env-set env bind (car exprs)) | |
29 | (loop (cdr binds) (cdr exprs)))))))) | |
f409e200 VS |
30 | env)) |
31 | ||
32 | (define (env-set env key value) | |
33 | (env-data-set! env (cons (cons key value) (env-data env)))) | |
34 | ||
35 | (define (env-find env key) | |
36 | (cond | |
84dee477 | 37 | ((alist-ref key (env-data env)) => identity) |
f409e200 VS |
38 | ((env-outer env) => (lambda (outer) (env-find outer key))) |
39 | (else #f))) | |
40 | ||
41 | (define (env-get env key) | |
84dee477 VS |
42 | (let ((value (env-find env key))) |
43 | (if value | |
44 | value | |
f409e200 VS |
45 | (error (str "'" key "' not found"))))) |
46 | ||
47 | ) | |
48 | ||
49 | ) |