summaryrefslogtreecommitdiff
path: root/environment.scm
diff options
context:
space:
mode:
Diffstat (limited to 'environment.scm')
-rw-r--r--environment.scm72
1 files changed, 72 insertions, 0 deletions
diff --git a/environment.scm b/environment.scm
new file mode 100644
index 0000000..2444059
--- /dev/null
+++ b/environment.scm
@@ -0,0 +1,72 @@
1(include "prelude/primitives.scm")
2
3;;; env
4(define (enclosing-env environ) (cdr environ))
5(define (first-frame environ) (car environ))
6(define the-empty-env '())
7(define (empty-env? environ) (eq? environ the-empty-env))
8
9;; frames
10(define (make-frame variables values)
11 (cons variables values))
12(define frame-variables car)
13(define frame-values cdr)
14(define (add-binding-to-frame! var val frame)
15 (begin
16 (set-car! frame (cons var (frame-variables frame)))
17 (set-cdr! frame (cons val (frame-values frame)))))
18(define (extend-env vars vals base-env)
19 (if (= (length vars) (length vals))
20 (cons (make-frame vars vals) base-env)
21 (error "Too few or too many arguments supplied" vars vals)))
22
23;;; variable lookup
24(define (lookup-variable-value var env)
25 (cond
26 [(empty-env? env) (error "Unbound variable" var)]
27 [else
28 (let ([f (first-frame env)])
29 (let scan ([variables (frame-variables f)]
30 [values (frame-values f)])
31 (cond
32 [(null? variables)
33 (lookup-variable-value var
34 (enclosing-env env))]
35 [(eq? var (car variables)) (car values)]
36 [else (scan (cdr variables) (cdr values))])))]))
37
38;;; environment modification
39(define (set-variable-value! var val env)
40 (cond
41 [(empty-env? env) (error "Unbound variable" var)]
42 [else
43 (let ([f (first-frame env)])
44 (let scan ([variables (frame-variables f)]
45 [values (frame-values f)])
46 (cond
47 [(null? variables) (set-variable-value!
48 var
49 val
50 (enclosing-env env))]
51 [(eq? var (car variables)) (set-car! values val)]
52 [else (scan (cdr variables) (cdr values))])))]))
53
54(define (define-variable! var val env)
55 (let ([f (first-frame env)])
56 (define (scan vars vals)
57 (cond
58 [(null? vars) (add-binding-to-frame! var val f)]
59 [(eq? var (car vars)) (set-car! vals val)]
60 [else (scan (cdr vars) (cdr vals))]))
61 (scan (frame-variables f)
62 (frame-values f))))
63
64(define (setup-environment)
65 (let ([initial-env (extend-env
66 (primitive-names)
67 (primitive-objs)
68 the-empty-env)])
69 (define-variable! 'true #t initial-env)
70 (define-variable! 'false #f initial-env)
71 initial-env))
72