-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenvironment.scm
143 lines (126 loc) · 4.73 KB
/
environment.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
;: Keep reverse for the underlying "apply" procedure.
(define apply-in-underlying-scheme apply)
;: Environments
(define (enclosing-environment env) (cdr env))
(define (first-frame env) (car env))
(define the-empty-environment '())
(define (make-frame variables values)
(cons variables values))
(define (frame-variables frame) (car frame))
(define (frame-values frame) (cdr frame))
(define (add-binding-to-frame! var val frame)
(set-car! frame (cons var (car frame)))
(set-cdr! frame (cons val (cdr frame))))
(define (extend-environment vars vals base-env)
(display-debug "extend-environment: ")
(display-debug vars)
(display-debug " ")
(user-print-objects vals)
(newline-debug)
(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))))
;: This constraint way of our environment is simple but inefficient.
(define (lookup-variable-value var env)
(display-debug "lookup-variable-value: ")
(display-debug var)
(display-debug " => ")
(define (env-loop env)
(define (scan vars vals)
(cond ((null? vars)
(env-loop (enclosing-environment env)))
((eq? var (car vars))
(if (eq? (car vals) '*unassigned*) ;:
(error-report "LOOKUP-VARIABLE-VALUE have found unassigned variable" var)
(car vals)))
(else (scan (cdr vars) (cdr vals)))))
(if (eq? env the-empty-environment)
(error-report "Unbound variable" var)
(let ((frame (first-frame env)))
(scan (frame-variables frame)
(frame-values frame)))))
(let ((return-val (env-loop env)))
(user-print return-val)
(newline-debug)
return-val))
(define (set-variable-value! var val env)
(display-debug "set-variable-value!: ")
(display-debug var)
(display-debug " ")
(user-print val)
(newline-debug)
(define (env-loop env)
(define (scan vars vals)
(cond ((null? vars)
(env-loop (enclosing-environment env)))
((eq? var (car vars))
(set-car! vals val))
(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 (define-variable! var val env)
(display-debug "define-variable!: ")
(display-debug var)
(display-debug " ")
(user-print val)
(newline-debug)
(let ((frame (first-frame env)))
(define (scan vars vals)
(cond ((null? vars)
(add-binding-to-frame! var val frame))
((eq? var (car vars))
(set-car! vals val))
(else (scan (cdr vars) (cdr vals)))))
(scan (frame-variables frame)
(frame-values frame))))
(define primitive-procedures
(list (list 'car car)
(list 'cdr cdr)
(list 'cons cons)
(list 'null? null?)
(list '+ +)
(list '= =)
(list '- -)
(list '* *)
(list '/ /)
(list '> >)
(list 'square square)
(list 'quit quit)
(list 'list list)
(list 'map map)
;; more primitives
))
;: Setup Environments
(define (setup-environment)
(let ((initial-env
(extend-environment (primitive-procedure-names)
(primitive-procedure-objects)
the-empty-environment)))
(define-variable! 'true true initial-env)
(define-variable! 'false false initial-env)
initial-env))
;: if we input: (map car (list (list 1 2) (list 2 3)))
;: the map object of system: #[compiled-procedure 14 (list #x6f)]
;: the car object of system: #[compiled-procedure 15 (list #x1)]
;: then we apply: (apply-in-underlying-scheme #[compiled-procedure 14 (list #6xf)]
;: ('primitive #[compiled-procedure 15 (list #x1)])
;: ((1 2) (3 4)))
;: the system's map can't identify the ('primitive #[compiled-procedure 15 (list #x1)])
;: because it's the defination of ourself.
;: so we have to define our own map procedure.
(define (primitive-procedure-names) (map car primitive-procedures))
(define (primitive-procedure-objects) (map (lambda (proc) (list 'primitive (cadr proc)))
primitive-procedures))
(define (apply-primitive-procedure proc args)
(display-debug "apply-primitive-procedure: ")
(display-debug proc)
(display-debug " ")
(user-print-objects args)
(newline-debug)
(apply-in-underlying-scheme (primitive-implementation proc) args))