-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenvironment_2.scm
105 lines (95 loc) · 3.4 KB
/
environment_2.scm
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
;:
;: the frame is a table of cons
;: instead of a cons of two tables.
;:
(define (enclosing-environment env) (cdr env))
(define (first-frame env) (car env))
(define the-empty-environment '())
(define (make-frame variables values)
(if (or (null? variables) (null? values))
'()
(cons (cons (car variables) (car values))
(make-frame (cdr variables) (cdr values)))))
(define (frame-first-variable frame) (caar frame))
(define (frame-first-value frame) (cdar frame))
(define (add-binding-to-frame! var val frame)
(set! frame (cons (cons var val) frame)))
(define (extend-environment vars vals base-env)
(if (= (length vars) (length vals))
(cons (make-frame vars vals) base-env)
(if (< (length vars) (length vals))
(error-report "Too many arguments supplied" vars vals)
(error-report "Too few arguments supplied" vars vals))))
(define (lookup-variable-value var env)
(define (env-loop env)
(define (scan f)
(cond ((null? f)
(env-loop (enclosing-environment env)))
((eq? var (caar f))
(cdar f))
(else (scan (cdr f)))))
(if (eq? env the-empty-environment)
(error-report "Unbound variable" var)
(let ((frame (first-frame env)))
(scan frame))))
(env-loop env))
(define (set-variable-value! var val env)
(define (env-loop env)
(define (scan f)
(cond ((null? f)
(env-loop (enclosing-environment env)))
((eq? var (caar f))
(set-cdr! (car f) val))
(else (scan (cdr f)))))
(if (eq? env the-empty-environment)
(error-report "Unbound variable -- SET!" var)
(let ((frame (first-frame env)))
(scan frame))))
(env-loop env))
(define (define-variable! var val env)
(let ((frame (first-frame env)))
(define (scan f)
(cond ((null? f)
(add-binding-to-frame! var val frame))
((eq? var (caar f))
(set-cdr! (car f) val))
(else (scan (cdr f)))))
(scan frame)))
;:
;: High-Order Function.
(define (lookup-operate-env-variable var val env f-not-founded f-founded)
(define (env-loop env)
(define (scan vars vals)
(cond ((null? vars) ; not-founded
(f-not-founded (enclosing-environment env)
(lambda (var val) (add-binding-to-frame! var val frame))))
((eq? var (car vars))
(set-car! vals val)
(car vals))
(else (scan (cdr vars) (cdr vals)))))
(if (eq? env the-empty-environment)
(error-report "Unbound variable -- SET!" var)
(let ((frame (first-frame env)))
(scan (frame-variables frame) (frame-values frame)))))
(env-loop env))
(define (set-variable-value! var val env)
(lookup-operate-env-variable
var
val
env
(lambda (e f) (set-variable-value! var val e))
(lambda (pair) (set-cdr! pair val))))
(define (define-variable! var val env)
(lookup-operate-env-variable
var
val
env
(lambda (e f) (f var val))
(lambda (pair) (set-cdr! pair val))))
(define (lookup-variable-value var env)
(lookup-operate-env-variable
var
0
env
(lambda (e f) (lookup-variable-value var e))
(lambda (pair) (cdr pair))))