blob: 244405904e5cc4b2be673ee209726be7e2031164 (
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
(include "prelude/primitives.scm")
;;; env
(define (enclosing-env environ) (cdr environ))
(define (first-frame environ) (car environ))
(define the-empty-env '())
(define (empty-env? environ) (eq? environ the-empty-env))
;; frames
(define (make-frame variables values)
(cons variables values))
(define frame-variables car)
(define frame-values cdr)
(define (add-binding-to-frame! var val frame)
(begin
(set-car! frame (cons var (frame-variables frame)))
(set-cdr! frame (cons val (frame-values frame)))))
(define (extend-env vars vals base-env)
(if (= (length vars) (length vals))
(cons (make-frame vars vals) base-env)
(error "Too few or too many arguments supplied" vars vals)))
;;; variable lookup
(define (lookup-variable-value var env)
(cond
[(empty-env? env) (error "Unbound variable" var)]
[else
(let ([f (first-frame env)])
(let scan ([variables (frame-variables f)]
[values (frame-values f)])
(cond
[(null? variables)
(lookup-variable-value var
(enclosing-env env))]
[(eq? var (car variables)) (car values)]
[else (scan (cdr variables) (cdr values))])))]))
;;; environment modification
(define (set-variable-value! var val env)
(cond
[(empty-env? env) (error "Unbound variable" var)]
[else
(let ([f (first-frame env)])
(let scan ([variables (frame-variables f)]
[values (frame-values f)])
(cond
[(null? variables) (set-variable-value!
var
val
(enclosing-env env))]
[(eq? var (car variables)) (set-car! values val)]
[else (scan (cdr variables) (cdr values))])))]))
(define (define-variable! var val env)
(let ([f (first-frame env)])
(define (scan vars vals)
(cond
[(null? vars) (add-binding-to-frame! var val f)]
[(eq? var (car vars)) (set-car! vals val)]
[else (scan (cdr vars) (cdr vals))]))
(scan (frame-variables f)
(frame-values f))))
(define (setup-environment)
(let ([initial-env (extend-env
(primitive-names)
(primitive-objs)
the-empty-env)])
(define-variable! 'true #t initial-env)
(define-variable! 'false #f initial-env)
initial-env))
|