root/lang/scheme/3imp/4.4.scm @ 29891

Revision 29870, 7.0 kB (checked in by mokehehe, 4 years ago)

古い compile-refer が残っていた

Line 
1
2(load "./util.scm")
3
4(define extend
5  (lambda (e r)
6    (cons r e)))
7
8(define compile
9  (lambda (x e next)
10    (cond
11     ((symbol? x) (compile-refer x e next))
12     ((pair? x)
13      (record-case x
14                   (quote (obj) (list 'constant obj next))
15                   (lambda (vars body)
16                     (let ((free (find-free body vars)))
17                       (collect-free free e
18                                     (list 'close
19                                           (length free)
20                                           (compile body
21                                                    (cons vars free)
22                                                    (list 'return
23                                                          (length vars)))
24                                           next))))
25                   (if (test then else)
26                       (let ((thenc (compile then e next))
27                             (elsec (compile else e next)))
28                         (compile test e (list 'test thenc elsec))))
29                   (call/cc (x)
30                            (list 'frame
31                                  next
32                                  (list 'conti
33                                        (list 'argument
34                                              (compile x e '(apply))))))
35                   (else
36                    (recur loop ((args (cdr x))
37                                 (c (compile (car x) e '(apply))))
38                           (if (null? args)
39                               (list 'frame next c)
40                             (loop (cdr args)
41                               (compile (car args)
42                                        e
43                                        (list 'argument c))))))))
44     (else
45      (list 'constant x next)))))
46
47(define find-free
48  (lambda (x b)
49    (cond
50     ((symbol? x) (if (set-member? x b) '() (list x)))
51     ((pair? x)
52      (record-case x
53                   (quote (obj) '())
54                   (lambda (vars body)
55                     (find-free body (set-union vars b)))
56                   (if (test then else)
57                       (set-union (find-free test b)
58                                  (set-union (find-free then b)
59                                             (find-free else b))))
60                   (call/cc (exp) (find-free exp b))
61                   (else
62                    (recur next ((x x))
63                           '()
64                           (set-union (find-free (car x) b)
65                                      (next (cdr x)))))))
66     (else '()))))
67
68(define collect-free
69  (lambda (vars e next)
70    (if (null? vars)
71        next
72      (collect-free (cdr vars) e
73                   (compile-refer (car vars) e
74                                  (list 'argument next))))))
75
76(define compile-refer
77  (lambda (x e next)
78    (compile-lookup x e
79                    (lambda (n) (list 'refer-local n next))
80                    (lambda (n) (list 'refer-free n next)))))
81
82(define compile-lookup
83  (lambda (x e return-local return-free)
84    (recur nxtlocal ((locals (car e)) (n 0))
85           (if (null? locals)
86               (recur nxtfree ((free (cdr e)) (n 0))
87                      (if (eq? (car free) x)
88                          (return-free n)
89                        (nxtfree (cdr free) (+ n 1))))
90             (if (eq? (car locals) x)
91                 (return-local n)
92               (nxtlocal (cdr locals) (+ n 1)))))))
93
94(define set-member?
95  (lambda (x s)
96    (cond
97     ((null? s) #f)
98     ((eq? x (car s)) #t)
99     (else (set-member? x (cdr s))))))
100
101(define set-cons
102  (lambda (x s)
103    (if (set-member? x s)
104        s
105      (cons x s))))
106
107(define set-union
108  (lambda (s1 s2)
109    (if (null? s1)
110        s2
111      (set-union (cdr s1) (set-cons (car s1) s2)))))
112
113(define set-minus
114  (lambda (s1 s2)
115    (if (null? s1)
116        '()
117      (if (set-member? (car s1) s2)
118          (set-minus (cdr s1) s2)
119        (cons (car s1) (set-minus (cdr s1) s2))))))
120
121(define set-intersect
122  (lambda (s1 s2)
123    (if (null? s1)
124        '()
125      (if (set-member? (car s1) s2)
126          (cons (car s1) (set-intersect (cdr s1) s2))
127        (set-intersect (cdr s1) s2)))))
128
129
130;;;; runtime
131
132(define functional
133  (lambda (body e)
134    (list body e)))
135
136(define stack (make-vector 1000))
137
138(define push
139  (lambda (x s)
140    (vector-set! stack s x)
141    (+ s 1)))
142
143(define index
144  (lambda (s i)
145    (vector-ref stack (- (- s i) 1))))
146
147(define index-set!
148  (lambda (s i v)
149    (vector-set! stack (- (- s i) 1) v)))
150
151
152;;;; VM
153
154(define VM
155  (lambda (a x f c s)
156    (record-case x
157                 (halt () a)
158                 (refer-local (n x)
159                              (VM (index f n) x f c s))
160                 (refer-free (n x)
161                             (VM (index-closure c n) x f c s))
162                 (constant (obj x)
163                           (VM obj x f c s))
164                 (close (n body x)
165                        (VM (closure body n s) x f c (- s n)))
166                 (test (then else)
167                       (VM a (if a then else) f c s))
168                 (conti (x)
169                        (VM (continuation s) x f c s))
170                 (nuate (stack x)
171                        (VM a x f c (restore-stack stack)))
172                 (frame (ret x)
173                        (VM a x f c (push ret (push f (push c s)))))
174                 (argument (x)
175                           (VM a x f c (push a s)))
176                 (apply ()
177                        (VM a (closure-body a) s a s))
178                 (return (n)
179                         (let ((s (- s n)))
180                           (VM a (index s 0) (index s 1) (index s 2) (- s 3)))))))
181
182(define continuation
183  (lambda (s)
184    (closure
185     (list 'refer 0 0 (list 'nuate (save-stack s) '(return 0)))
186     '())))
187
188(define closure
189  (lambda (body n s)
190    (let ((v (make-vector (+ n 1))))
191      (vector-set! v 0 body)
192      (recur f ((i 0))
193             (unless (= i n)
194               (vector-set! v (+ i 1) (index s i))
195               (f (+ i 1))))
196      v)))
197
198(define closure-body
199  (lambda (c)
200    (vector-ref c 0)))
201
202(define index-closure
203  (lambda (c n)
204    (vector-ref c (+ n 1))))
205
206(define save-stack
207  (lambda (s)
208    (let ((v (make-vector s)))
209      (recur copy ((i 0))
210             (unless (= i s)
211               (vector-set! v i (vector-ref stack i))
212               (copy (+ i 1))))
213      v)))
214
215(define restore-stack
216  (lambda (v)
217    (let ((s (vector-length v)))
218      (recur copy ((i 0))
219             (unless (= i s)
220               (vector-set! stack i (vector-ref v i))
221               (copy (+ i 1))))
222      s)))
223
224(define lookup
225  (lambda (n m e)
226    (recur nxtrib ((e e) (rib n))
227           (if (= rib 0)
228               (recur nxtelt ((r (car e)) (elt m))
229                      (if (= elt 0)
230                          r
231                        (nxtelt (cdr r) (- elt 1))))
232             (nxtrib (cdr e) (- rib 1))))))
233
234(define find-link
235  (lambda (n e)
236    (if (= n 0)
237        e
238      (find-link (- n 1) (index e -1)))))
239
240
241(define evaluate
242  (lambda (x)
243    (let1 code (compile x '() '(halt))
244      (VM '() code 0 '() 0))))
245
Note: See TracBrowser for help on using the browser.