BSD 3 development
[unix-history] / usr / src / cmd / liszt / complrc.l
CommitLineData
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))))