Commit | Line | Data |
---|---|---|
c1009b56 TL |
1 | ;--- file : complrc.l |
2 | (include "compmacs.l") | |
3 | ||
4 | (declare (special w-vars w-labs w-ret w-name w-bv w-atmt cm-alv v-cnt)) | |
5 | (def $pr$ (macro (x) `(patom ,(cadr x) compout))) | |
6 | ||
7 | (def put | |
8 | (macro (x) | |
9 | ((lambda (atm prp arg) | |
10 | `(progn (putprop ,atm ,arg ,prp) ,atm)) | |
11 | (cadr x) (caddr x) (cadddr x)))) | |
12 | ||
13 | (def f-if | |
14 | (lambda (v-l v-r v-j v-t) | |
15 | (cond ((eq (caar v-l) 't) | |
16 | (cond ((null (cdar v-l)) (f-exp t v-r v-t)) | |
17 | (t (f-seq (cdar v-l) v-r v-t)))) | |
18 | (t (prog (v-tr v-i v-dv) | |
19 | (setq v-tr (f-reg nil)) | |
20 | (setq v-dv 'amb) | |
21 | (cond ((null (cdr v-l)) | |
22 | (setq v-tr v-r) | |
23 | (cond ((null (cdar v-l)) (go loop2))) | |
24 | (setq v-dv nil) | |
25 | (setq v-i (cadr v-j))) | |
26 | ((null (cdar v-l)) | |
27 | (setq v-tr v-r) | |
28 | (setq v-t (f-if (cdr v-l) v-r v-j v-t)) | |
29 | (setq v-t (f-addi (list 'true (cadr v-j) t) | |
30 | v-t)) | |
31 | (go loop1)) | |
32 | (t (setq v-t (f-leap (f-if (cdr v-l) | |
33 | v-r | |
34 | v-j | |
35 | v-t))) | |
36 | (setq v-t (f-addi v-j v-t)) | |
37 | (setq v-i (cadr s-inst)))) | |
38 | (setq v-t (f-seq (cdar v-l) v-r v-t)) | |
39 | (setq v-t (f-addi (list 'false v-i v-dv) v-t)) | |
40 | loop1 | |
41 | (setq v-t (f-addi (list 'minus (f-use v-tr) nil) v-t)) | |
42 | loop2 | |
43 | (return (f-exp (caar v-l) v-tr v-t))))))) | |
44 | ;--- f-seqp - v-l : sequence of s-expressions and labels to evaluate | |
45 | ; - v-r : psreg in which to store the final result | |
46 | ; - v-t : tail. | |
47 | ; This will do the top level of prog bodies | |
48 | ; | |
49 | (def f-seqp | |
50 | (lambda (v-l v-r v-t) | |
51 | (do ((l (reverse v-l) (cdr l)) | |
52 | (newreg v-r) | |
53 | (reg v-r newreg)) | |
54 | ((null l) v-t) | |
55 | (cond ((symbolp (car l)) | |
56 | (setq v-t (f-labl v-t (car l)))) | |
57 | (t (setq v-t (f-exp (car l) reg v-t)) | |
58 | (setq newreg (Gensym nil))))))) | |
59 | ||
60 | ;--- f-seq - v-l : sequence of s-expressions to evaluate | |
61 | ; - v-r : psreg in which to store the final result | |
62 | ; - v-t : tail | |
63 | ; | |
64 | ; This generates intermediate codes to calculate the s-expressions | |
65 | ; in v-l. This does not look for labels. | |
66 | ; | |
67 | (def f-seq | |
68 | (lambda (v-l v-r v-t) | |
69 | (do ((l (reverse v-l) (cdr l)) | |
70 | (reg v-r (Gensym nil))) | |
71 | ((null l) v-t) | |
72 | (setq v-t (f-exp (car l) reg v-t))))) | |
73 | \f | |
74 | ;--- f-pusha - v-l : list of forms to evaluate and push on stack | |
75 | ; - v-r : register to place result of last expr in | |
76 | ; - v-t : tail | |
77 | ; emits code to to evaluate and push forms on the stack. | |
78 | (def f-pusha | |
79 | (lambda (v-l v-r v-t) | |
80 | (cond ((null v-l) v-t) | |
81 | (t (do ((ll (reverse v-l) (cdr ll)) | |
82 | (reg v-r (Gensym nil)) | |
83 | (res v-t | |
84 | (f-exp (car ll) | |
85 | reg | |
86 | (f-addi `(push ,(f-use reg)) res)))) | |
87 | ((null ll) res)))))) | |
88 | ||
89 | ;--- f-iter - v-e : list of expression to evaluate | |
90 | ; - v-v : list of variables those expressions will be bound to | |
91 | ; This checks of the given expressions can be bound to the given | |
92 | ; variables with no conflicts. This is determining if tail | |
93 | ; merging is possible were we replace recursion by iteration. | |
94 | ; | |
95 | (def f-iter | |
96 | (lambda (v-e v-v) | |
97 | (prog (v-y w-vars) | |
98 | ||
99 | loop | |
100 | (cond ((null v-e) (return t)) | |
101 | ((null v-v) (go bad)) | |
102 | ((ifflag (setq v-y (car v-v)) x-spec) (go bad)) | |
103 | ((equal (car v-e) v-y) (go usable)) | |
104 | (t (go check))) | |
105 | next | |
106 | (setq w-vars (cons v-y w-vars)) | |
107 | usable | |
108 | (setq v-e (cdr v-e)) | |
109 | (setq v-v (cdr v-v)) | |
110 | (go loop) | |
111 | check | |
112 | (cond ((f-nice (car v-e)) (go next))) | |
113 | bad | |
114 | (return nil)))) | |
115 | ||
116 | (def f-nice | |
117 | (lambda (v-e) | |
118 | (cond ((atom v-e) (not (member v-e w-vars))) | |
119 | ((atom (car v-e)) | |
120 | (cond ((eq (car v-e) 'quote) t) | |
121 | ((ifflag (car v-e) x-dont) nil) | |
122 | (t (f-all v-e 'f-nice)))) | |
123 | (t (f-all v-e 'f-nice))))) | |
124 | ||
125 | ;--- f-all - v-l : list | |
126 | ; - v-f : function | |
127 | ; mapc function v-f over v-l as long as the result is non nil | |
128 | ; | |
129 | (def f-all | |
130 | (lambda (v-l v-f) | |
131 | (cond ((null v-l) t) | |
132 | ((funcall v-f (car v-l)) (f-all (cdr v-l) v-f)) | |
133 | (t nil)))) | |
134 | ||
135 | (def f-make | |
136 | (lambda (v-r v-v) | |
137 | (put v-r x-reg v-v))) | |
138 | \f | |
139 | ;--- f-leap - v-t : tail | |
140 | ; We generate and place in global variable s-inst an itermediate | |
141 | ; instructin which will jump to the current top location in v-t. | |
142 | ; If there is not a label on top of v-t, one is added. | |
143 | ; | |
144 | (def f-leap | |
145 | (lambda (v-t) | |
146 | (cond ((not (setq s-inst (get (caar v-t) x-leap))) | |
147 | (setq v-t (f-labl v-t nil)) | |
148 | (setq s-inst 'go))) | |
149 | (setq s-inst (list s-inst (cadar v-t))) | |
150 | v-t)) | |
151 | ||
152 | ;--- f-labl - v-t : tail | |
153 | ; - v-l : real label or nil | |
154 | ; We insure that there is a label on top of v-t. If not we | |
155 | ; create one. If we are given a label, we associate it with | |
156 | ; a created label. | |
157 | ; Labels in v-t are all gensymed and the association is all | |
158 | ; on the property list of the value of w-labs. | |
159 | ; Errors: duplicate labels | |
160 | ; | |
161 | (def f-labl | |
162 | (lambda (v-t v-l) | |
163 | (prog (v-i) | |
164 | (cond ((eq (caar v-t) 'label) | |
165 | (cond (v-l (cond ((setq v-i (get w-labs v-l))) | |
166 | (t (put w-labs v-l (cadar v-t)) | |
167 | (return v-t)))) | |
168 | (t (return v-t)))) | |
169 | ||
170 | ((null v-l) (setq v-i (Gensym nil))) | |
171 | ((setq v-i (get w-labs v-l))) | |
172 | (t (put w-labs v-l (setq v-i (Gensym nil))))) | |
173 | (return (f-addi (list 'label v-i) v-t))))) | |
174 | ||
175 | (def f-test | |
176 | (lambda (v-t) | |
177 | (and (eq (caar v-t) 'minus) | |
178 | (null (caddar v-t))))) | |
179 | ||
180 | (def f-vble | |
181 | (lambda (v-v v-r) | |
182 | (f-use v-r) | |
183 | (cond ((not (symbolp v-v)) v-v) | |
184 | ((null v-v) nil) | |
185 | ((f-con v-v) v-v) | |
186 | ((ifflag v-v x-spec) v-v) | |
187 | ((member v-v w-vars) v-v) | |
188 | (t (setq k-free (cons v-v k-free)) | |
189 | (flag v-v x-spec))))) | |
190 | ||
191 | (def f-addi | |
192 | (lambda (v-i v-t) | |
193 | (prog (v-o) | |
194 | (cond ((not (setq v-o (get (car v-i) x-opt))) (go normal)) | |
195 | ((setq v-o (funcall v-o v-i v-t)) (return v-o))) | |
196 | normal | |
197 | (return (cons v-i v-t))))) | |
198 | ||
199 | (def f-reg | |
200 | (lambda (v-f) | |
201 | (cond ((numberp v-f) (put (Gensym nil) x-reg v-f)) | |
202 | (v-f (flag (Gensym nil) v-f)) | |
203 | (t (Gensym nil))))) | |
204 | ||
205 | (def f-con | |
206 | (lambda (v-v) | |
207 | (cond ((ifflag v-v x-spec) nil) | |
208 | (t (ifflag v-v x-con))))) | |
209 | ||
210 | (def f-one | |
211 | (lambda (v-e) | |
212 | (or (atom v-e) | |
213 | (eq (car v-e) 'quote)))) | |
214 | ||
215 | (def f-swap | |
216 | (lambda (v-t) | |
217 | (cond ((eq (caar v-t) 'get) (f-swap (cdr v-t))) | |
218 | (t (rplaca (car v-t) | |
219 | (cond ((eq (caar v-t) 'true) 'false) | |
220 | (t 'true))))) | |
221 | v-t)) | |
222 | ||
223 | (def f-xval | |
224 | (lambda (v-t v-r) | |
225 | (cond ((or (eq (caar v-t) 'get) | |
226 | (eq (caddar v-t) 'amb)) v-t) | |
227 | (t (f-addi (list 'get (f-use v-r) (caddar v-t)) v-t))))) | |
228 | \f | |
229 | ;--- f-use - v-r : psreg whose value is being used | |
230 | ; we keep track of the number of times the value of a register is | |
231 | ; used, the count is kept under the indicator x-count in the | |
232 | ; psreg's property list. the count starts at nil, goes to `used' | |
233 | ; and then to `force'. Once the count goes to `force' all gets | |
234 | ; must be done. when the count is used get should look to see | |
235 | ; if the following intermediate code instruction is the one | |
236 | ; using the register and in that case it can merge with that | |
237 | ; instruction | |
238 | ; | |
239 | (def f-use | |
240 | (lambda (v-r) | |
241 | ((lambda (curv) | |
242 | (cond (curv (cond ((not (eq curv 'force)) | |
243 | (putprop v-r 'force 'x-count)))) | |
244 | (t (putprop v-r 'used 'x-count))) | |
245 | v-r) | |
246 | (get v-r 'x-count)))) | |
247 | ||
248 | ||
249 | (def f-chop | |
250 | (lambda (v-t) | |
251 | (cond ((or (eq (caar v-t) 'label) | |
252 | (eq (caar v-t) 'end)) v-t) | |
253 | (t (f-chop (cdr v-t)))))) | |
254 | ||
255 | (def f-tfo | |
256 | (lambda (v-i v-t) | |
257 | (cond ((not (f-like v-t '(go label))) nil) | |
258 | ((not (equal (cadr v-i) (cadadr v-t))) nil) | |
259 | (t (rplaca (cdr v-i) (cadar v-t)) | |
260 | (f-swap (rplaca v-t v-i)))))) | |
261 | ||
262 | (def f-like | |
263 | (lambda (v-t v-p) | |
264 | (cond ((null v-p) t) | |
265 | ((null v-t) nil) | |
266 | ((equal (caar v-t) (car v-p)) (f-like (cdr v-t) (cdr v-p))) | |
267 | (t nil)))) | |
268 | ||
269 | (def f-aor | |
270 | (lambda (v-l v-e v-r v-t) | |
271 | (cond ((null v-l) | |
272 | (f-addi (list 'get (f-use v-r) (eq v-e 'and)) v-t)) | |
273 | (t (prog (v-j v-dv v-tr v-tr2) | |
274 | (setq v-dv (eq v-e 'or)) | |
275 | (setq v-tr v-r) | |
276 | (setq v-tr2 v-r) | |
277 | (setq v-e | |
278 | (cond ((eq v-e 'and) 'false) | |
279 | (t 'true))) | |
280 | (setq v-l (reverse v-l)) | |
281 | (cond ((null (cdr v-l)) (go loop)) | |
282 | ((and (f-test v-t) | |
283 | (not (eq (caadr v-t) 'get))) | |
284 | (cond ((eq (caddadr v-t) 'amb) | |
285 | (setq v-dv 'amb) | |
286 | (setq v-tr2 (f-reg nil))) | |
287 | ((not (equal (caddadr v-t) v-dv)) | |
288 | (setq v-dv 'amb))) | |
289 | (cond ((equal (caadr v-t) v-e) | |
290 | (setq v-j (cadadr v-t)) | |
291 | (go loop))) | |
292 | (rplacd (cdr v-t) (f-leap (cddr v-t)))) | |
293 | (t (setq v-t (f-leap v-t)))) | |
294 | (setq v-j (cadr s-inst)) | |
295 | loop | |
296 | (setq v-t (f-exp (car v-l) v-tr v-t)) | |
297 | (setq v-tr v-tr2) | |
298 | (cond ((null (setq v-l (cdr v-l))) (return v-t))) | |
299 | (setq v-t (f-addi (list v-e v-j v-dv) v-t)) | |
300 | (setq v-t (f-addi (list 'minus (f-use v-tr) nil) v-t)) | |
301 | (go loop)))))) | |
302 | ||
303 | (def f-repl | |
304 | (lambda (v-e) | |
305 | (cons (ucar (car v-e)) (cdr v-e)))) | |
306 | ||
307 | ;this seems out of date, must change to mapconvert | |
308 | (def f-domap | |
309 | (lambda (v-e) | |
310 | (prog (v-x) | |
311 | (cond ((setq v-x (f-chkf (cadr v-e) 4)) | |
312 | (return (list (car v-e) | |
313 | (list 'quote v-x) | |
314 | (caddr v-e)))) | |
315 | (t (return v-e)))))) | |
316 | ||
317 | \f | |
318 | ;--- mapconvert - access : function to access parts of lists | |
319 | ; - join : function to join results | |
320 | ; - resu : function to apply to result | |
321 | ; - form : mapping form | |
322 | ; This function converts maps to an equivalent do form. | |
323 | ; | |
324 | (def mapconvert | |
325 | (lambda (access join resu form ) | |
326 | (prog (vrbls finvar acc accform compform tmp) | |
327 | ||
328 | (setq finvar (Gensym 'X) ; holds result | |
329 | ||
330 | vrbls (maplist '(lambda (arg) | |
331 | ((lambda (temp) | |
332 | (cond ((or resu (cdr arg)) | |
333 | `(,temp ,(car arg) | |
334 | (cdr ,temp))) | |
335 | (t `(,temp | |
336 | (setq ,finvar ,(car arg)) | |
337 | (cdr ,temp))))) | |
338 | (Gensym 'X))) | |
339 | (cdr form)) | |
340 | ||
341 | ||
342 | acc (mapcar '(lambda (tem) | |
343 | (cond (access `(,access ,(car tem))) | |
344 | (t (car tem)))) | |
345 | vrbls) | |
346 | ||
347 | accform (cond ((or (atom (setq tmp (car form))) | |
348 | (null (setq tmp (cmacroexpand tmp))) | |
349 | (not (member (car tmp) '(quote function)))) | |
350 | `(funcall ,tmp ,@acc)) | |
351 | (t `(,(cadr tmp) ,@acc)))) | |
352 | (return | |
353 | `((lambda (,finvar) | |
354 | (do ( ,@vrbls) | |
355 | ((null ,(caar vrbls))) | |
356 | ,(cond (join `(setq ,finvar (,join ,accform ,finvar))) | |
357 | (t accform))) | |
358 | ,(cond (resu `(,resu ,finvar)) | |
359 | (t finvar))) | |
360 | nil ))))) | |
361 | (putprop 'mapc 'f-mapc 'x-spfm) | |
362 | (def f-mapc | |
363 | (lambda (v-e) | |
364 | (mapconvert 'car nil nil (cdr v-e)))) | |
365 | ||
366 | (putprop 'mapcar 'f-mapcar 'x-spfm) | |
367 | (def f-mapcar | |
368 | (lambda (v-e) | |
369 | (mapconvert 'car 'cons 'reverse (cdr v-e)))) | |
370 | ||
371 | (putprop 'map 'f-map 'x-spfm) | |
372 | (def f-map | |
373 | (lambda (v-e) | |
374 | (mapconvert nil nil nil (cdr v-e)))) | |
375 | ||
376 | ||
377 | (putprop 'maplist 'f-maplist 'x-spfm) | |
378 | (def f-maplist | |
379 | (lambda (v-e) | |
380 | (mapconvert nil 'cons 'reverse (cdr v-e)))) | |
381 | ||
382 | ||
383 | ||
384 | ||
385 | (def f-initv | |
386 | (lambda (v-l) | |
387 | (mapcar 'car (car v-l)))) | |
388 | ||
389 | (def f-inits | |
390 | (lambda (v-l) | |
391 | (mapcar 'cadr (car v-l)))) | |
392 | ||
393 | (def f-repv | |
394 | (lambda (v-l) | |
395 | (prog (v-x) | |
396 | (setq v-l (car v-l)) | |
397 | lp | |
398 | (cond ((null v-l) (return (reverse v-x)))) | |
399 | (cond ((cddar v-l) (setq v-x (cons (caar v-l) v-x)))) | |
400 | (setq v-l (cdr v-l)) | |
401 | (go lp)))) | |
402 | ||
403 | (def f-reps | |
404 | (lambda (v-l) | |
405 | (prog (v-x v-y) | |
406 | (setq v-l (car v-l)) | |
407 | lp | |
408 | (cond ((null v-l) (return (reverse v-x)))) | |
409 | (cond ((cddar v-l) | |
410 | (setq v-y (caddar v-l)) (setq v-x (cons v-y v-x)))) | |
411 | (setq v-l (cdr v-l)) | |
412 | (go lp)))) | |
413 | ||
414 | (def f-endtest | |
415 | (lambda (v-l) | |
416 | (caadr v-l))) | |
417 | ||
418 | (def f-endbody | |
419 | (lambda (v-l) | |
420 | (cdadr v-l))) | |
421 | ||
422 | (def f-dobody | |
423 | (lambda (v-l) | |
424 | (cddr v-l))) | |
425 | ||
426 | ||
427 | (putprop 'do 'f-do 'x-spf) | |
428 | ||
429 | (def f-do | |
430 | (lambda (v-l v-r v-t) | |
431 | (prog (v-init v-initv v-rep v-repv v-loop v-outl v-retl) | |
432 | (cond ((and (car v-l) (atom (car v-l))) ; look for old do | |
433 | (setq v-l (olddo-to-newdo v-l)))) | |
434 | (setq v-initv (f-initv v-l) | |
435 | v-init (f-inits v-l) | |
436 | v-repv (f-repv v-l) | |
437 | v-rep (f-reps v-l) | |
438 | v-retl (Gensym nil) | |
439 | v-loop (Gensym nil) | |
440 | v-outl (Gensym nil)) | |
441 | (w-save) | |
442 | (return | |
443 | (f-pusha v-init v-r | |
444 | (prog (w-ret w-labs tmp) | |
445 | (setq w-ret `(,v-r . (go ,v-retl))) | |
446 | (setq w-labs (Gensym nil)) | |
447 | (setq tmp | |
448 | `((begin ,(length v-initv)) | |
449 | ,@(mapcar '(lambda (arg) (setq w-locs | |
450 | (cons arg w-locs)) | |
451 | `(bind ,arg)) | |
452 | v-initv) | |
453 | (label ,v-loop) | |
454 | ,@(f-exp (f-endtest v-l) v-r | |
455 | `((minus ,v-r nil) | |
456 | (true ,v-outl nil) | |
457 | ,@(f-seqp (f-dobody v-l) v-r | |
458 | (f-pusha v-rep v-r | |
459 | `((dopop ,v-repv) | |
460 | (go ,v-loop) | |
461 | (label ,v-outl) | |
462 | ,@(f-seq (f-endbody v-l) v-r | |
463 | `((end ,v-retl) | |
464 | ,@v-t))))))))) | |
465 | (w-unsave) | |
466 | (return tmp))))))) | |
467 | ||
468 | (def olddo-to-newdo | |
469 | (lambda (v-l) | |
470 | `(((,(car v-l) ,(cadr v-l) ,(caddr v-l))) | |
471 | (,(cadddr v-l) nil) | |
472 | ,@(cddddr v-l)))) | |
473 | \f | |
474 | (putprop 'cond 'f-cond 'x-spf) | |
475 | ||
476 | (def f-cond | |
477 | (lambda (v-l v-r v-t) | |
478 | (setq v-t (f-leap v-t)) | |
479 | (f-if v-l v-r s-inst v-t))) | |
480 | ||
481 | (putprop 'quote 'f-quote 'x-spf) | |
482 | ||
483 | (def f-quote | |
484 | (lambda (v-l v-r v-t) | |
485 | (f-addi (list 'get v-r (cons 'quote v-l)) v-t))) | |
486 | ||
487 | (putprop 'prog 'f-prog 'x-spf) | |
488 | ||
489 | ||
490 | ||
491 | ||
492 | (putprop 'setq 'f-setq 'x-spf) | |
493 | ||
494 | (def f-setq | |
495 | (lambda (v-l v-r v-t) | |
496 | (cond ((null (car v-l)) v-t)) | |
497 | (do ((ll (reverse v-l) (cddr ll)) | |
498 | (reg v-r (Gensym nil))) | |
499 | ((null ll) v-t) | |
500 | (setq v-t (f-exp (car ll) | |
501 | reg | |
502 | `((set ,(f-use reg) ,(g-specialchk (cadr ll))) | |
503 | ,@v-t)))))) | |
504 | ||
505 | ||
506 | (putprop 'rplaca 'f-rplaca 'x-spf) | |
507 | ||
508 | ||
509 | (def f-rplaca | |
510 | (lambda (v-l v-r v-t) | |
511 | (cond ((f-one (cadr v-l)) | |
512 | (f-exp (car v-l) | |
513 | v-r | |
514 | (f-exp (cadr v-l) | |
515 | (setq v-l (Gensym nil)) | |
516 | (f-addi (list 'seta (f-use v-r) (f-use v-l)) | |
517 | v-t)))) | |
518 | (t (f-pusha v-l | |
519 | (Gensym nil) | |
520 | (f-addi (list 'setas v-r) v-t)))))) | |
521 | ||
522 | (putprop 'rplacd 'f-rplacd 'x-spf) | |
523 | ||
524 | ||
525 | (def f-rplacd | |
526 | (lambda (v-l v-r v-t) | |
527 | (cond ((f-one (cadr v-l)) | |
528 | (f-exp (car v-l) | |
529 | v-r | |
530 | (f-exp (cadr v-l) | |
531 | (setq v-l (Gensym nil)) | |
532 | (f-addi (list 'setd (f-use v-r) (f-use v-l)) v-t)))) | |
533 | (t (f-pusha v-l | |
534 | (Gensym nil) | |
535 | (f-addi (list 'setds (f-use v-r)) v-t)))))) | |
536 | \f | |
537 | (putprop 'go 'f-go 'x-spf) | |
538 | ||
539 | ;--- f-go - v-l : label to go to | |
540 | ; - v-r : not used | |
541 | ; - v-t : tail | |
542 | ; We allow non local go to's, however the goto must go no further than the | |
543 | ; first inclosing prog. | |
544 | ; f-go works by finding the w-labs associated with the first enclosing prog, | |
545 | ; and keeping track of the number of binding levels which must be traversed | |
546 | ; to get to that prog.o | |
547 | ; when it finds the correct w-labs, it checks if this label has been seen yet, | |
548 | ; if not iit assigns it a gensymed symbol. | |
549 | ; if a binding level must be traversed, we eimit | |
550 | ; (unbind n) n is number of binding levels to traverse, | |
551 | ; 0 means current level only. | |
552 | ; (go gensymedlabl) | |
553 | ; | |
554 | ; if this is a local goto only the (go gensymedlabl) will be emitted. | |
555 | ; | |
556 | (def f-go | |
557 | (lambda (v-l v-r v-t) | |
558 | (prog (use-labs levels) | |
559 | (setq v-l (car v-l)) | |
560 | (setq use-labs | |
561 | (cond (w-ret w-labs) | |
562 | (t (do ((ll w-save (cdr ll)) | |
563 | (count 0 (add1 count))) | |
564 | ((null ll) | |
565 | (comp-err " go not within prog")) | |
566 | (cond ((caar ll) | |
567 | (setq levels count) | |
568 | (comp-warn " non-local go used") | |
569 | (return (cadar ll)))))))) | |
570 | ||
571 | (cond ((not (setq v-r (get use-labs v-l))) | |
572 | (put use-labs v-l (setq v-r (Gensym nil))))) | |
573 | (setq v-t (f-addi (list 'go v-r) v-t)) | |
574 | (cond (levels (setq v-t (f-addi `(unbind ,levels) v-t)))) | |
575 | (return v-t)))) | |
576 | ||
577 | (putprop 'lambda 'f-lambda 'x-spf) | |
578 | ||
579 | ;--- f-lambda - ?? how is this routine called, certainly this isnt the | |
580 | ; same as ((lambda (n) form) arg) | |
581 | ; | |
582 | ||
583 | (putprop 'and 'f-and 'x-spf) | |
584 | ||
585 | (def f-and | |
586 | (lambda (v-l v-r v-t) | |
587 | (f-aor v-l 'and v-r v-t))) | |
588 | ||
589 | (putprop 'or 'f-or 'x-spf) | |
590 | ||
591 | (def f-or | |
592 | (lambda (v-l v-r v-t) | |
593 | (f-aor v-l 'or v-r v-t))) | |
594 | ||
595 | ||
596 | ||
597 | (putprop 'prog2 'prog2toprog 'x-spfm) | |
598 | ||
599 | ||
600 | ;--- prog2toprog - v-e : prog2 expression | |
601 | ; we convert this (prog2 a b c d e f) to | |
602 | ; (progn a ((lambda (newsim) c d e f newsim) b)) | |
603 | ; simple enough. | |
604 | ; | |
605 | (def prog2toprog | |
606 | (lambda (v-e) | |
607 | ((lambda (newsim) | |
608 | `(progn ,(cadr v-e) | |
609 | ((lambda (,newsim) | |
610 | ,@(cdddr v-e) | |
611 | ,newsim) | |
612 | ,(caddr v-e)))) | |
613 | (Gensym nil)))) | |
614 | ||
615 | ||
616 | (putprop 'progn 'f-seq 'x-spf) | |
617 | ||
618 | (putprop 'return 'f-return 'x-spfn) | |
619 | \f | |
620 | ;--- f-return - v-l : arg to return, may be nil meaning return nil | |
621 | ; - v-r : psreg in which to store result | |
622 | ; - v-t : tail | |
623 | ; this handles the return statement. While returns should | |
624 | ; occur in progs, this allows for a return inside a context | |
625 | ; which is inside a prog (or do). If this is a simple return | |
626 | ; from prog or do, we have: | |
627 | ; ... code to place to be returned val in v-r | |
628 | ; (go retlb) jump to label at end of prog body | |
629 | ; but before special unbinding | |
630 | ; for non local cases we have | |
631 | ; ... code to place value to be returned into v-r | |
632 | ; (unwind levels) where is levels is the number of enclosing | |
633 | ; contexts (which begin with a (begin xx)) to return | |
634 | ; from. | |
635 | ; (go retlb) then go to the return spot. | |
636 | ; | |
637 | (def f-return | |
638 | (lambda (v-l v-r v-t) | |
639 | (prog (use-ret levels) | |
640 | (setq use-ret | |
641 | (cond (w-ret) | |
642 | (t (do ((ll w-save (cdr ll)) | |
643 | (count 0 (add1 count))) | |
644 | ((null ll) | |
645 | (comp-err " return not within a prog")) | |
646 | (cond ((caar ll) | |
647 | (setq levels count) | |
648 | (comp-warn " non local return used") | |
649 | (return (caar ll)))))))) | |
650 | ||
651 | (setq v-t (f-addi (cdr use-ret) v-t)) | |
652 | (cond (levels (setq v-t (f-addi `(unbind ,levels) v-t)))) | |
653 | (return (f-exp (and v-l (car v-l)) (f-use (car use-ret)) v-t))))) | |
654 | ||
655 | (putprop 'null 'f-null 'x-spfn) | |
656 | ||
657 | (def f-null | |
658 | (lambda (v-l v-r v-t) | |
659 | (cond ((f-test v-t) | |
660 | (rplaca (cdar (rplacd v-t (f-xval (f-swap (cdr v-t)) v-r))) | |
661 | (f-use (setq v-r (Gensym nil)))) | |
662 | (f-exp (car v-l) v-r v-t))))) | |
663 | ||
664 | (putprop 'not 'f-null 'x-spfn) | |
665 | ||
666 | ||
667 | (def f-type | |
668 | (lambda (v-l v-r v-t v-bits) | |
669 | (cond ((f-test v-t) | |
670 | (setq v-t (f-xval (cdr v-t) v-r)) | |
671 | (f-exp (car v-l) | |
672 | (setq v-r (Gensym nil)) | |
673 | (f-addi (list 'getype (f-use v-r) v-bits) v-t)))))) | |
674 | ||
675 | (putprop 'atom 'f-atom 'x-spfn) | |
676 | ||
677 | (def f-atom | |
678 | (lambda (v-l v-r v-t) | |
679 | (f-type v-l v-r v-t '(0 1 2 4 5 6 7 9 10)))) | |
680 | ||
681 | (putprop 'numberp 'f-numberp 'x-spfn) | |
682 | ||
683 | (def f-numberp | |
684 | (lambda (v-l v-r v-t) | |
685 | (f-type v-l v-r v-t '(2 4 9)))) | |
686 | ||
687 | (putprop 'symbolp 'f-symbolp 'x-spfn) | |
688 | ||
689 | (def f-symbolp | |
690 | (lambda (v-l v-r v-t) | |
691 | (f-type v-l v-r v-t 1))) | |
692 | ||
693 | (putprop 'dtpr 'f-dtpr 'x-spfn) | |
694 | ||
695 | (def f-dtpr | |
696 | (lambda (v-l v-r v-t) | |
697 | (f-type v-l v-r v-t 3))) | |
698 | ||
699 | (putprop 'bcdp 'f-bcdp 'x-spfn) | |
700 | ||
701 | (def f-bcdp | |
702 | (lambda (v-l v-r v-t) | |
703 | (f-type v-l v-r v-t 5))) | |
704 | ||
705 | (putprop 'stringp 'f-stringp 'x-spfn) | |
706 | ||
707 | (def f-stringp | |
708 | (lambda (v-l v-r v-t) | |
709 | (f-type v-l v-r v-t 0))) | |
710 | ||
711 | (putprop 'type 'f-ty 'x-spfn) | |
712 | ||
713 | (def f-ty | |
714 | (lambda (v-l v-r v-t) | |
715 | (f-exp (car v-l) | |
716 | (setq v-r (Gensym nil)) | |
717 | (f-addi (list 'getype (f-use v-r) 'name) v-t)))) | |
718 | ||
719 | (putprop 'eq 'f-eq 'x-spfn) | |
720 | ||
721 | (def f-eq | |
722 | (lambda (v-l v-r v-t) | |
723 | (prog (v-r1) | |
724 | (cond ((f-test v-t) | |
725 | (setq v-t (f-xval (cdr v-t) v-r)) | |
726 | (cond ((and (f-one (car v-l)) (f-one (cadr v-l))) | |
727 | (return (f-addi (list 'eqv (car v-l) (cadr v-l)) | |
728 | v-t)))) | |
729 | (return (f-pusha v-l | |
730 | (Gensym nil) | |
731 | (f-addi '(eqs) v-t)))))))) | |
732 | ||
733 | (putprop 'cons 'f-repl 'x-spfh) | |
734 | ||
735 | '(putprop 'map 'f-domap 'x-spfh) | |
736 | ||
737 | '(putprop 'mapc 'f-domap 'x-spfh) | |
738 | ||
739 | '(putprop 'mapcar 'f-domap 'x-spfh) | |
740 | ||
741 | '(putprop 'maplist 'f-domap 'x-spfh) | |
742 | ||
743 | (putprop 'zerop 'f-zerop 'x-spfm) | |
744 | ||
745 | (def f-zerop | |
746 | (lambda (v-e) | |
747 | (list 'equal 0 (cadr v-e)))) | |
748 | ||
749 | (putprop 'plist 'f-plist 'x-spfm) | |
750 | ||
751 | (def f-plist | |
752 | (lambda (v-e) | |
753 | (list 'car (cadr v-e)))) | |
754 | ||
755 | (putprop 'go 'f-xgo 'x-opt) | |
756 | ||
757 | (def f-xgo | |
758 | (lambda (v-i v-t) | |
759 | (setq v-t (f-chop v-t)) | |
760 | (cond ((equal (cadr v-i) (cadar v-t)) v-t) | |
761 | (t (cons v-i v-t))))) | |
762 | ||
763 | (putprop 'return 'f-xreturn 'x-opt) | |
764 | ||
765 | (def f-xreturn | |
766 | (lambda (v-i v-t) | |
767 | (cons v-i (f-chop v-t)))) | |
768 | ||
769 | (putprop 'repeat 'f-xreturn 'x-opt) | |
770 | ||
771 | (putprop 'false 'f-tfo 'x-opt) | |
772 | ||
773 | (putprop 'true 'f-tfo 'x-opt) | |
774 | ||
775 | \f | |
776 | (putprop '*catch 'f-*catch 'x-spf) | |
777 | ||
778 | ||
779 | ;--- f-*catch - v-l : list of (tag exp) , tag is evaled, exp is to be run | |
780 | ; - v-r : result register | |
781 | ; - v-t : tail | |
782 | ; This compiles a catch by emiting these intermediate codes: | |
783 | ; ..calculate tag.. | |
784 | ; (catchent <gensym> <tag> nil) | |
785 | ; .. code to eval (car v-l) .. | |
786 | ; (catchexit) | |
787 | ; (label <gensym>) | |
788 | ; | |
789 | ; The catchent sets up a catch frame on the c-runtime stack. | |
790 | ; The (car v-l) is evaluated and the result placed in r0 (it must | |
791 | ; be since that is where the value would be thrown). If no throw | |
792 | ; is done, it enters the catchexit which pops our catchframe off | |
793 | ; the stack. If a throw is done it ends up at the label <gensym> | |
794 | ; with the catch frame already popped off. | |
795 | ; | |
796 | (def f-*catch | |
797 | (lambda (v-l v-r v-t) | |
798 | (prog (v-loop v-tag x y z v-nr) | |
799 | (setq v-tag (car v-l)) | |
800 | ; we check to make sure we can force v-r to be r0, else | |
801 | ; we must give up. | |
802 | (cond ((and (get v-r 'x-reg) | |
803 | (not (equal (get v-r 'x-reg) 0))) | |
804 | (err '"Can't compile catch correctly")) | |
805 | (t (f-make v-r 0))) | |
806 | ||
807 | (return | |
808 | (f-exp v-tag | |
809 | (setq v-nr (Gensym nil)) | |
810 | (f-addi `(catchent ,(setq v-loop (Gensym nil)) | |
811 | ,(f-use v-nr) | |
812 | nil) | |
813 | (f-exp (cadr v-l) (f-use v-r) | |
814 | (f-addi `(catchexit) | |
815 | (f-addi `(label ,v-loop) v-t))))))))) | |
816 | ||
817 | (putprop 'errset 'f-errset 'x-spf) | |
818 | ;--- f-errset - v-l : list of (errset form [flag]) | |
819 | ; - v-r : place to put result. | |
820 | ; - v-t : tail | |
821 | ; | |
822 | ; This sets up an errset frame. It is different than a catch in | |
823 | ; that the tag is always (ER%all) and the result returned upon | |
824 | ; a regular exit is listified. | |
825 | ; again, we must insure that v-r can be forced to be r0 since | |
826 | ; an err or error will place the result there. | |
827 | ; | |
828 | (def f-errset | |
829 | (lambda (v-l v-r v-t) | |
830 | (prog (v-loop v-tag v-flag v-nr) | |
831 | (cond ((and (get v-r 'x-reg) (not (equal (get v-r 'x-reg) 0))) | |
832 | (err '"Can't compile errset correctly")) | |
833 | (t (f-make v-r 0))) | |
834 | ||
835 | ; flag tells if error message will be reported, t if so. | |
836 | ; t is the default | |
837 | (cond ((cdr v-l) (setq v-flag (cadr v-l))) | |
838 | (t (setq v-flag t))) | |
839 | ||
840 | (return | |
841 | (f-exp v-flag | |
842 | (setq v-nr (Gensym nil)) | |
843 | (f-addi `(catchent ,(setq v-loop (Gensym nil)) | |
844 | '(ER%all) | |
845 | ,(f-use v-nr)) | |
846 | (f-exp (car v-l) | |
847 | v-r | |
848 | `((catchexit) | |
849 | (push ,v-r) | |
850 | (call ,v-r _Lncons 1) | |
851 | (label ,v-loop) | |
852 | ,@v-t)))))))) | |
853 | ||
854 | ||
855 | ||
856 | ||
857 | (putprop '*throw 'f-*throw 'x-spf) | |
858 | ||
859 | ;--- f-*throw - v-l : list of (tag exp) | |
860 | ; - v-r : loc to eval exp to | |
861 | ; - v-t : tail | |
862 | ; | |
863 | (def f-*throw | |
864 | (lambda (v-l v-r v-t) | |
865 | (let ((v-nr (Gensym nil))) | |
866 | (f-exp (car v-l) | |
867 | v-nr | |
868 | (f-exp (cadr v-l) v-r | |
869 | (f-addi `(*throw ,(f-use v-r) ,(f-use v-nr)) v-t)))))) | |
870 | ||
871 | ||
872 | (putprop 'arg 'f-arg 'x-spf) | |
873 | ||
874 | ;--- f-arg - v-l : list of arg to evaluate | |
875 | ; - v-r : place to store value | |
876 | ; - v-t : tail | |
877 | (def f-arg | |
878 | (lambda (v-l v-r v-t) | |
879 | (f-exp (car v-l) v-r | |
880 | (f-addi `(arg ,(f-use v-r)) | |
881 | v-t)))) |