|
|
1.1 root 1: (include-if (null (get 'chead 'version)) "../chead.l")
2: (Liszt-file funb
3: "$Header: funb.l,v 1.13 87/12/15 17:02:17 sklower Exp $")
4:
5: ;;; ---- f u n b function compilation
6: ;;;
7: ;;; -[Wed Aug 24 17:14:56 1983 by layer]-
8:
9: ;--- c-declare :: handle the "declare" form
10: ; if a declare is seen inside a function definition, we just
11: ; ignore it. We probably should see what it is declareing, as it
12: ; might be declaring a special.
13: ;
14: (defun c-declare nil nil)
15:
16: ;--- c-do :: compile a "do" expression
17: ;
18: ; a do has this form:
19: ; (do vrbls tst . body)
20: ; we note the special case of tst being nil, in which case the loop
21: ; is evaluated only once, and thus acts like a let with labels allowed.
22: ; The do statement is a cross between a prog and a lambda. It is like
23: ; a prog in that labels are allowed. It is like a lambda in that
24: ; we stack the values of all init forms then bind to the variables, just
25: ; like a lambda expression (that is the initial values of even specials
26: ; are stored on the stack, and then copied into the value cell of the
27: ; atom during the binding phase. From then on the stack location is
28: ; not used).
29: ;
30: (defun c-do nil
31: (let (b-vrbls b-tst b-body chklab bodylab x-repeat x-vrbs x-fst
32: g-loc g-cc oldreguse (g-decls g-decls))
33: (forcecomment '(beginning do))
34: (setq g-loc 'reg chklab (d-genlab) bodylab (d-genlab))
35:
36: (if (and (cadr v-form) (atom (cadr v-form)))
37: then (setq v-form (d-olddo-to-newdo (cdr v-form))))
38:
39: (push (cons 'do 0) g-locs) ; begin our frame
40:
41: (setq b-vrbls (cadr v-form)
42: b-tst (caddr v-form)
43: b-body (cdddr v-form))
44:
45: (d-scanfordecls b-body)
46:
47: ; push value of init forms on stack
48: (d-pushargs (mapcar '(lambda (x)
49: (if (atom x)
50: then nil ; no init form => nil
51: else (cadr x)))
52: b-vrbls))
53:
54: ; now bind to the variables in the vrbls form
55: (d-bindlamb (mapcar '(lambda (x)
56: (if (atom x) then x
57: else (car x)))
58: b-vrbls))
59:
60: ; search through body for all labels and assign them gensymed labels
61: (push (cons (d-genlab)
62: (do ((ll b-body (cdr ll))
63: (res))
64: ((null ll) res)
65: (if (and (car ll) (symbolp (car ll)))
66: then (Push res
67: (cons (car ll) (d-genlab))))))
68: g-labs)
69:
70: ; if the test is non nil, we do the test
71: ; another strange thing, a test form of (pred) will not return
72: ; the value of pred if it is not nil! it will return nil -- in this
73: ; way, it is not like a cond clause
74: (d-clearreg)
75: (if b-tst then (e-label chklab)
76: (let ((g-cc (cons nil bodylab)) g-loc g-ret)
77: (d-exp (car b-tst))) ; eval test
78: ; if false, do body
79: (if (cdr b-tst)
80: then (setq oldreguse (copy g-reguse))
81: (d-exps (cdr b-tst))
82: (setq g-reguse oldreguse)
83: else (d-move 'Nil 'reg))
84: (e-goto (caar g-labs)) ; leave do
85: (e-label bodylab)) ; begin body
86:
87: ; process body
88: (do ((ll b-body (cdr ll))
89: (g-cc) (g-loc)(g-ret))
90: ((null ll))
91: (if (or (null (car ll)) (not (symbolp (car ll))))
92: then (d-exp (car ll))
93: else (e-label (cdr (assoc (car ll) (cdar g-labs))))
94: (d-clearreg)))
95:
96: (if b-tst
97: then ; determine all repeat forms which must be
98: ; evaluated, and all the variables affected.
99: ; store the results in x-repeat and x-vrbs
100: ; if there is just one repeat form, we calculate
101: ; its value directly into where it is stored,
102: ; if there is more than one, we stack them
103: ; and then store them back at once.
104: (do ((ll b-vrbls (cdr ll)))
105: ((null ll))
106: (if (and (dtpr (car ll)) (cddar ll))
107: then (Push x-repeat (caddar ll))
108: (Push x-vrbs (caar ll))))
109: (if x-vrbs
110: then (if (null (cdr x-vrbs)) ; if just one repeat
111: then (let ((g-loc (d-locv (car x-vrbs)))
112: (g-cc nil))
113: (d-exp (car x-repeat)))
114: else (setq x-fst (car x-repeat))
115: (d-pushargs (nreverse
116: (cdr x-repeat)))
117: (let ((g-loc (d-locv (car x-vrbs)))
118: (g-cc)
119: (g-ret))
120: (d-exp x-fst))
121: (do ((ll (cdr x-vrbs) (cdr ll)))
122: ((null ll))
123: (d-move 'unstack
124: (d-locv (car ll)))
125: (setq g-locs (cdr g-locs))
126: (decr g-loccnt))))
127: (e-goto chklab))
128:
129: (e-label (caar g-labs)) ; end of do label
130: (d-clearreg)
131: (d-unbind)
132: (setq g-labs (cdr g-labs))))
133:
134: ;--- d-olddo-to-newdo :: map old do to new do
135: ;
136: ; form of old do is (do var tst . body)
137: ; where var is a symbol, not nil
138: ;
139: (defun d-olddo-to-newdo (v-l)
140: `(do ((,(car v-l) ,(cadr v-l) ,(caddr v-l)))
141: (,(cadddr v-l))
142: ,@(cddddr v-l)))
143:
144: ;--- cc-dtpr :: check for dtprness
145: ;
146: (defun cc-dtpr nil
147: (d-typesimp (cadr v-form) #.(immed-const 3)))
148:
149: ;--- cc-eq :: compile an "eq" expression
150: ;
151: (defun cc-eq nil
152: (let ((arg1 (cadr v-form))
153: (arg2 (caddr v-form))
154: arg1loc
155: arg2loc)
156: (if (setq arg2loc (d-simple arg2))
157: then (if (setq arg1loc (d-simple arg1))
158: then ; eq <simple> <simple>
159: (d-cmp arg1loc arg2loc)
160: else ; eq <nonsimple> <simple>
161: (let ((g-loc 'reg) ; put <nonsimple> in reg
162: ; must rebind because
163: ; cc->& may have modified
164: (g-trueop #+(or for-vax for-tahoe) 'jneq
165: #+for-68k 'jne)
166: (g-falseop #+(or for-vax for-tahoe) 'jeql
167: #+for-68k 'jeq)
168: g-cc
169: g-ret)
170: (d-exp arg1))
171: (d-cmp 'reg arg2loc))
172: else ; since second is nonsimple, must stack first
173: ; arg out of harms way
174: (let ((g-loc 'stack)
175: (g-trueop #+(or for-vax for-tahoe) 'jneq #+for-68k 'jne)
176: (g-falseop #+(or for-vax for-tahoe) 'jeql #+for-68k 'jeq)
177: g-cc
178: g-ret)
179: (d-exp arg1)
180: (push nil g-locs)
181: (incr g-loccnt)
182: (setq g-loc 'reg) ; second arg to reg
183: (d-exp arg2))
184: (d-cmp 'unstack 'reg)
185: (setq g-locs (cdr g-locs))
186: (decr g-loccnt)))
187: (d-invert))
188:
189: ;--- cc-equal :: compile `equal'
190: ;
191: (defun cc-equal nil
192: (let ((lab1 (d-genlab))
193: (lab11 (d-genlab))
194: lab2)
195: (d-pushargs (cdr v-form))
196: (e-cmp '(-8 #.np-reg) '(-4 #.np-reg))
197: (e-gotonil lab1)
198: (d-calltran 'equal '2) ; not eq, try equal.
199: (d-clearreg)
200: #+(or for-vax for-tahoe) (e-tst (e-cvt 'reg))
201: #+for-68k (e-cmpnil (e-cvt 'reg))
202: (e-gotot lab11)
203: (if g-loc then (d-move 'Nil g-loc))
204: (if (cdr g-cc) then (e-goto (cdr g-cc))
205: else (e-goto (setq lab2 (d-genlab))))
206: (e-writel lab1)
207: (e-dropnp 2)
208: (e-writel lab11)
209: (if g-loc then (d-move 'T g-loc))
210: (if (car g-cc) then (e-goto (car g-cc)))
211: (if lab2 then (e-writel lab2))
212: (setq g-locs (cddr g-locs))
213: (setq g-loccnt (- g-loccnt 2))))
214:
215: ;--- c-errset :: compile an errset expression
216: ;
217: ; the errset has this form: (errset 'value ['tag])
218: ; where tag defaults to t.
219: ;
220: (defun c-errset nil
221: (let ((g-loc 'reg)
222: (g-cc nil)
223: (g-ret nil)
224: (finlab (d-genlab))
225: (beglab (d-genlab)))
226: (d-exp (if (cddr v-form) then (caddr v-form) else t))
227: (d-pushframe #.F_CATCH (d-loclit 'ER%all nil) 'reg)
228: (push nil g-labs) ; disallow labels
229: ; If retval is non zero then an error has throw us here so we
230: ; must recover the value thrown (from _lispretval) and leave
231: ; If retval is zero then we shoud calculate the expression
232: ; into r0 and put a cons cell around it
233: (e-tst '_retval)
234: (e-write2 #+(or for-vax for-tahoe) 'jeql #+for-68k 'jeq beglab)
235: (e-move '_lispretval (e-cvt 'reg))
236: (e-write2 #+(or for-vax for-tahoe) 'jbr #+for-68k 'jra finlab)
237: (e-label beglab)
238: (let ((g-loc 'stack)
239: (g-cc nil))
240: (d-exp (cadr v-form)))
241: (d-move 'Nil 'stack) ; haven't updated g-loc, g-loccnt but it
242: ; shouldn't hurt (famous last words)
243: (e-quick-call '_qcons)
244: (e-label finlab)
245: (d-popframe)
246: (unpush g-locs) ; remove (catcherrset . 0)
247: (unpush g-labs) ; remove nil
248: (d-clearreg)))
249:
250: ;--- cm-fixnum-cxr :: open code a fixnum-cxr expression.
251: ;
252: ; fixnum-cxr is a compile only hacky function which accesses an element
253: ; of a fixnum space and boxes the resulting fixnum. It can be used
254: ; for rapid access to user defined structures.
255: ;
256: (defun cm-fixnum-cxr ()
257: `(internal-fixnum-box (cxr ,@(cdr v-form))))
258:
259: (defun c-internal-fixnum-box ()
260: (let ((g-cc nil)
261: (g-ret nil)
262: (g-loc '#.fixnum-reg))
263: #+for-68k (d-regused '#.fixnum-reg)
264: (d-exp (cadr v-form))
265: (e-call-qnewint)))
266:
267: ;--- cc-offset-cxr
268: ; return a pointer to the address of the object instead of the object.
269: ;
270: (defun cc-offset-cxr nil
271: (d-supercxr nil t))
272:
273: ;--- cc-fixp :: check for a fixnum or bignum
274: ;
275: (defun cc-fixp nil
276: (d-typecmplx (cadr v-form)
277: '#.(immed-const (plus 1_2 1_9))))
278:
279: ;--- cc-floatp :: check for a flonum
280: ;
281: (defun cc-floatp nil
282: (d-typesimp (cadr v-form) #.(immed-const 4)))
283:
284: ;--- c-funcall :: compile a funcall
285: ;
286: ; we open code a funcall the resulting object is a compiled lambda.
287: ; We don't open code nlambda and macro funcalls since they are
288: ; rarely used and it would waste space to check for them
289: (defun c-funcall nil
290: (if (null (cdr v-form))
291: then (comp-err "funcall requires at least one argument " v-form))
292: (let ((g-locs g-locs)
293: (g-loccnt g-loccnt)
294: (args (length (cdr v-form)))
295: (g-loc nil)
296: (g-ret nil)
297: (g-cc nil))
298: (d-pushargs (cdr v-form))
299: (rplaca (nthcdr (1- args) g-locs) 'funcallfcn)
300:
301: (d-exp '(cond ((and (symbolp funcallfcn)
302: (getd funcallfcn))
303: (setq funcallfcn (getd funcallfcn)))))
304:
305: (d-exp `(cond ((and (bcdp funcallfcn) (eq 'lambda (getdisc funcallfcn)))
306: (Internal-bcdcall ,args t))
307: (t (Internal-bcdcall ,args nil))))))
308:
309: ;--- c-Internal-bcdcall
310: ; this is a compiler internal function call. when this occurs, there
311: ; are argnum objects stacked, the first of which is a function name
312: ; or bcd object. If dobcdcall is t then we want to do a bcdcall of
313: ; the first object stacked. If it is not true then we want to
314: ; call the interpreter funcall function to handle it.
315: ;
316: (defun c-Internal-bcdcall nil
317: (let ((argnum (cadr v-form))
318: (dobcdcall (caddr v-form)))
319: (cond (dobcdcall (d-bcdcall argnum))
320: (t (d-calltran 'funcall argnum)))))
321:
322: ;--- cc-function :: compile a function function
323: ;
324: ; function is an nlambda, which the interpreter treats as 'quote'
325: ; If the argument is a lambda expression, then Liszt will generate
326: ; a new function and generate code to return the name of
327: ; that function. If the argument is a symbol, then 'symbol
328: ; is compiled. It would probably be better to return the function
329: ; cell of the symbol, but Maclisp returns the symbol and it
330: ; would cause compatibility problems.
331: ;
332: (defun cc-function nil
333: (if (or (null (cdr v-form))
334: (cddr v-form))
335: then (comp-err "Wrong number of arguments to 'function': " v-form))
336: (let ((arg (cadr v-form)))
337: (if (symbolp arg)
338: then (d-exp `',arg)
339: elseif (and (dtpr arg)
340: (memq (car arg) '(lambda nlambda lexpr)))
341: then (let ((newname (concat "in-line-lambda:"
342: (setq in-line-lambda-number
343: (add1 in-line-lambda-number)))))
344: (Push liszt-process-forms
345: `(def ,newname ,arg))
346: (d-exp `',newname))
347: else (comp-err "Illegal argument to 'function': " v-form))))
348:
349: ;--- c-get :: do a get from the prop list
350: ;
351: (defun c-get nil
352: (if (not (eq 2 (length (cdr v-form))))
353: then (comp-err "Wrong number of args to get " v-form))
354: (d-pushargs (cdr v-form)) ; there better be 2 args
355: (e-quick-call '_qget)
356: (d-clearreg)
357: (setq g-locs (cddr g-locs))
358: (setq g-loccnt (- g-loccnt 2)))
359:
360: ;--- cm-getaccess :: compile a getaccess instruction
361: ;
362: (defun cm-getaccess nil `(cdr ,(cadr v-form)))
363:
364: ;--- cm-getaux :: compile a getaux instruction
365: ;
366: (defun cm-getaux nil `(car ,(cadr v-form)))
367:
368: ;--- cm-getd :: compile a getd instruction
369: ;
370: ; the getd function is open coded to look in the third part of a symbol
371: ; cell
372: ;
373: (defun cm-getd nil `(cxr 2 ,(cadr v-form)))
374:
375: ;--- cm-getdata :: compile a getdata instruction
376: ;
377: ; the getdata function is open coded to look in the third part of an
378: ; array header.
379: (defun cm-getdata nil `(cxr 2 ,(cadr v-form)))
380:
381: ;--- cm-getdisc :: compile a getdisc expression
382: ; getdisc accessed the discipline field of a binary object.
383: ;
384: (defun cm-getdisc nil `(cxr 1 ,(cadr v-form)))
385:
386: ;--- c-go :: compile a "go" expression
387: ;
388: ; we only compile the (go symbol)type expression, we do not
389: ; allow symbol to be anything by a non null symbol.
390: ;
391: (defun c-go nil
392: ; find number of frames we have to go down to get to the label
393: (do ((labs g-labs (cdr labs))
394: (locs g-locs)
395: (locals 0)
396: (specials 0)
397: (catcherrset 0)
398: (label))
399: ((null labs)
400: (comp-err "go label not found for expression: " (or v-form)))
401:
402: (if (car labs) ; if we have a set of labels to look at...
403: then (if (setq label
404: (do ((lbs (cdar labs) (cdr lbs)))
405: ((null lbs))
406: (if (eq (caar lbs) (cadr v-form))
407: then (return (cdar lbs)))))
408: then (if (not (eq labs g-labs))
409: then (comp-note g-fname ": non local go used : "
410: (or v-form)))
411: ; three stack to pop: namestack, bindstack
412: ; and execution stack
413: (e-pop locals)
414: (if (greaterp specials 0)
415: then (e-unshallowbind specials))
416: (if (greaterp catcherrset 0)
417: then (comp-note g-fname
418: ": Go through a catch or errset "
419: v-form)
420: (do ((i 0 (1+ i)))
421: ((=& catcherrset i))
422: (d-popframe)))
423: (e-goto label)
424: (return)))
425: ; tally all locals, specials and catcherrsets used in this frame
426: (do ()
427: ((dtpr (car locs))
428: (if (eq 'catcherrset (caar locs))
429: then (incr catcherrset)
430: elseif (eq 'progv (caar locs))
431: then (comp-err "Attempt to 'go' through a progv"))
432: (setq specials (+ specials (cdar locs))
433: locs (cdr locs)))
434: (setq locs (cdr locs))
435: (incr locals))))
436:
437: ;--- cc-ignore :: just ignore this code
438: ;
439: (defun cc-ignore nil
440: nil)
441:
442: ;--- c-lambexp :: compile a lambda expression
443: ;
444: (defun c-lambexp nil
445: (let ((g-loc (if (or g-loc g-cc) then 'reg))
446: (g-cc nil)
447: (g-locs (cons (cons 'lambda 0) g-locs))
448: (g-labs (cons nil g-labs)))
449: (d-pushargs (cdr v-form)) ; then push vals
450: (d-lambbody (car v-form))
451: (d-clearreg)))
452:
453: ;--- d-lambbody :: do a lambda body
454: ; - body : body of lambda expression, eg (lambda () dld)
455: ;
456: (defun d-lambbody (body)
457: (let ((g-decls g-decls))
458: (d-scanfordecls (cddr body)) ; look for declarations
459: (d-bindlamb (cadr body)) ; bind locals
460: (d-clearreg)
461: (d-exp (do ((ll (cddr body) (cdr ll))
462: (g-loc)
463: (g-cc)
464: (g-ret))
465: ((null (cdr ll)) (car ll))
466: (d-exp (car ll))))
467:
468: (d-unbind))) ; unbind this frame
469:
470: ;--- d-bindlamb :: bind variables in lambda list
471: ; - vrbs : list of lambda variables, may include nil meaning ignore
472: ;
473: (defun d-bindlamb (vrbs)
474: (let ((res (d-bindlrec (reverse vrbs) g-locs 0 g-loccnt)))
475: (if res then (e-setupbind)
476: (mapc '(lambda (vrb) (e-shallowbind (car vrb) (cdr vrb)))
477: res)
478: (e-unsetupbind))))
479:
480: ;--- d-bindlrec :: recusive routine to bind lambda variables
481: ; - vrb : list of variables yet to bind
482: ; - locs : current location in g-loc
483: ; - specs : number of specials seen so far
484: ; - lev : how far up from the bottom of stack we are.
485: ; returns: list of elements, one for each special, of this form:
486: ; (<specialvrbname> stack <n>)
487: ; where specialvrbname is the name of the special variable, and n is
488: ; the distance from the top of the stack where its initial value is
489: ; located
490: ; also: puts the names of the local variables in the g-locs list, as well
491: ; as placing the number of special variables in the lambda header.
492: ;
493: (defun d-bindlrec (vrb locs specs lev)
494: (if vrb
495: then (let ((spcflg (d-specialp (car vrb)))
496: retv)
497: (if spcflg then (setq specs (1+ specs)))
498:
499: (if (cdr vrb) ; if more vrbls to go ...
500: then (setq retv (d-bindlrec (cdr vrb)
501: (cdr locs)
502: specs
503: (1- lev)))
504: else (rplacd (cadr locs)
505: specs)) ; else fix up lambda hdr
506:
507: (if (not spcflg) then (rplaca locs (car vrb))
508: else (Push retv `(,(car vrb) stack ,lev)))
509:
510: retv)))
511:
512: ;--- d-scanfordecls
513: ; forms - the body of a lambda, prog or do.
514: ; we look down the form for 'declare' forms. They should be at the
515: ; beginning, but there are macros which may unintentionally put forms
516: ; in front of user written forms. Thus we check a little further than
517: ; the first form.
518: (defun d-scanfordecls (forms)
519: ; look for declarations in the first few forms
520: (do ((count 3 (1- count)))
521: ((= 0 count))
522: (cond ((and (dtpr (car forms))
523: (eq 'declare (caar forms))
524: (apply 'liszt-declare (cdar forms)))))
525: (setq forms (cdr forms))))
526:
527: ;--- c-list :: compile a list expression
528: ;
529: ; this is compiled as a bunch of conses with a nil pushed on the
530: ; top for good measure
531: ;
532: (defun c-list nil
533: (prog (nargs)
534: (setq nargs (length (cdr v-form)))
535: (makecomment '(list expression))
536: (if (zerop nargs)
537: then (d-move 'Nil 'reg) ; (list) ==> nil
538: (return))
539: (d-pushargs (cdr v-form))
540: #+(or for-vax for-tahoe) (e-write2 'clrl '#.np-plus) ; stack one nil
541: #+for-68k (L-push (e-cvt 'Nil))
542:
543: ; now do the consing
544: (do ((i (max 1 nargs) (1- i)))
545: ((zerop i))
546: (e-quick-call '_qcons)
547: (d-clearreg)
548: (if (> i 1) then (L-push (e-cvt 'reg))))
549:
550: (setq g-locs (nthcdr nargs g-locs)
551: g-loccnt (- g-loccnt nargs))))
552:
553: ;--- d-mapconvert - access : function to access parts of lists
554: ; - join : function to join results
555: ; - resu : function to apply to result
556: ; - form : mapping form
557: ; This function converts maps to an equivalent do form.
558: ;
559: ; in this function, the variable vrbls contains a list of forms, one form
560: ; per list we are mapping over. The form of the form is
561: ; (dummyvariable realarg (cdr dummyvariable))
562: ; realarg may be surrounded by (setq <variable which holds result> realarg)
563: ; in the case that the result is the list to be mapped over (this only occurs
564: ; with the function mapc).
565: ;
566: (defun d-mapconvert (access join resu form )
567: (prog (vrbls finvar acc accform compform
568: tmp testform tempvar lastvar)
569:
570: (setq finvar (gensym 'X) ; holds result
571:
572: vrbls
573: (reverse
574: (maplist '(lambda (arg)
575: ((lambda (temp)
576: (cond ((or resu (cdr arg))
577: `(,temp ,(car arg)
578: (cdr ,temp)))
579: (t `(,temp
580: (setq ,finvar
581: ,(car arg))
582: (cdr ,temp)))))
583: (gensym 'X)))
584: (reverse (cdr form))))
585:
586: ; the access form will either be nil or car. If it is
587: ; nil, then we are doing something like a maplist,
588: ; if the access form is car, then we are doing something
589: ; like a mapcar.
590: acc (mapcar '(lambda (tem)
591: (cond (access `(,access ,(car tem)))
592: (t (car tem))))
593: vrbls)
594:
595: accform (cond ((or (atom (setq tmp (car form)))
596: (null (setq tmp (d-macroexpand tmp)))
597: (not (member (car tmp) '(quote function))))
598: `(funcall ,tmp ,@acc))
599: (t `(,(cadr tmp) ,@acc)))
600:
601: ; the testform checks if any of the lists we are mapping
602: ; over is nil, in which case we quit.
603: testform (cond ((null (cdr vrbls)) `(null ,(caar vrbls)))
604: (t `(or ,@(mapcar '(lambda (x)
605: `(null ,(car x)))
606: vrbls)))))
607:
608: ; in the case of mapcans and mapcons, you need two
609: ; extra variables to simulate the nconc.
610: ; testvar gets intermediate results and lastvar
611: ; points to then end of the list
612: (if (eq join 'nconc)
613: then (setq tempvar (gensym 'X)
614: lastvar (gensym 'X)
615: vrbls `((,tempvar) (,lastvar) ,@vrbls)))
616:
617: (return
618: `((lambda
619: (,finvar)
620: (liszt-internal-do
621: ( ,@vrbls)
622: (,testform)
623: ,(cond ((eq join 'nconc)
624: `(cond ((setq ,tempvar ,accform)
625: (cond (,lastvar
626: (liszt-internal-do
627: ()
628: ((null (cdr ,lastvar)))
629: (setq ,lastvar
630: (cdr ,lastvar)))
631: (rplacd ,lastvar ,tempvar))
632: (t (setq ,finvar
633: (setq ,lastvar
634: ,tempvar)))))))
635: (join `(setq ,finvar (,join ,accform ,finvar)))
636: (t accform)))
637: ,(cond ((eq resu 'identity) finvar)
638: (resu `(,resu ,finvar))
639: (t finvar)))
640: nil ))))
641:
642: ; apply to successive elements, return second arg
643: (defun cm-mapc nil
644: (d-mapconvert 'car nil nil (cdr v-form)))
645:
646: ; apply to successive elements, return list of results
647: (defun cm-mapcar nil
648: (d-mapconvert 'car 'cons 'nreverse (cdr v-form)))
649:
650: ; apply to successive elements, returned nconc of results
651: (defun cm-mapcan nil
652: (d-mapconvert 'car 'nconc 'identity (cdr v-form)))
653:
654: ; apply to successive sublists, return second arg
655: (defun cm-map nil
656: (d-mapconvert nil nil nil (cdr v-form)))
657:
658: ; apply to successive sublists, return list of results
659: (defun cm-maplist nil
660: (d-mapconvert nil 'cons 'reverse (cdr v-form)))
661:
662: ; apply to successive sublists, return nconc of results
663: (defun cm-mapcon nil
664: (d-mapconvert nil 'nconc 'identity (cdr v-form)))
665:
666: ;--- cc-memq :: compile a memq expression
667: ;
668: #+(or for-vax for-tahoe)
669: (defun cc-memq nil
670: (let ((loc1 (d-simple (cadr v-form)))
671: (loc2 (d-simple (caddr v-form)))
672: looploc finlab)
673: (if loc2
674: then (d-clearreg 'r1)
675: (if loc1
676: then (d-move loc1 'r1)
677: else (let ((g-loc 'r1)
678: g-cc
679: g-ret)
680: (d-exp (cadr v-form))))
681: (d-move loc2 'reg)
682: else (let ((g-loc 'stack)
683: g-cc
684: g-ret)
685: (d-exp (cadr v-form)))
686: (push nil g-locs)
687: (incr g-loccnt)
688: (let ((g-loc 'reg)
689: g-cc
690: g-ret)
691: (d-exp (caddr v-form)))
692: (L-pop 'r1)
693: (d-clearreg 'r1)
694: (unpush g-locs)
695: (decr g-loccnt))
696: ; now set up the jump addresses
697: (if (null g-loc)
698: then (setq loc1 (if (car g-cc) thenret else (d-genlab))
699: loc2 (if (cdr g-cc) thenret else (d-genlab)))
700: else (setq loc1 (d-genlab)
701: loc2 (d-genlab)))
702:
703: (setq looploc (d-genlab))
704: (e-tst 'r0)
705: (e-write2 'jeql loc2)
706: (e-label looploc)
707: (e-cmp 'r1 '(4 r0))
708: (e-write2 'jeql loc1)
709: (e-move '(0 r0) 'r0)
710: (e-write2 'jneq looploc)
711: (if g-loc
712: then (e-label loc2) ; nil result
713: (d-move 'reg g-loc)
714: (if (cdr g-cc)
715: then (e-goto (cdr g-cc))
716: else (e-goto (setq finlab (d-genlab))))
717: else (if (cdr g-cc)
718: then (e-goto (cdr g-cc))
719: else (e-label loc2)))
720: (if g-loc
721: then (e-label loc1) ; non nil result
722: (d-move 'reg g-loc)
723: (if (car g-cc) then (e-goto (car g-cc)))
724: else (if (null (car g-cc)) then (e-label loc1)))
725: (if finlab then (e-label finlab))))
726:
727: #+for-68k
728: (defun cc-memq nil
729: (let ((loc1 (d-simple (cadr v-form)))
730: (loc2 (d-simple (caddr v-form)))
731: looploc finlab
732: (tmp-data-reg (d-alloc-register 'd nil)))
733: (d-clearreg tmp-data-reg)
734: (d-clearreg 'a0)
735: (if loc2
736: then (if loc1
737: then (d-move loc1 tmp-data-reg)
738: else (let ((g-loc tmp-data-reg)
739: g-cc
740: g-ret)
741: (d-exp (cadr v-form))))
742: (d-move loc2 'reg)
743: else (let ((g-loc 'stack)
744: g-cc
745: g-ret)
746: (d-exp (cadr v-form)))
747: (push nil g-locs)
748: (incr g-loccnt)
749: (let ((g-loc 'reg)
750: g-cc
751: g-ret)
752: (d-exp (caddr v-form)))
753: (L-pop tmp-data-reg)
754: (unpush g-locs)
755: (decr g-loccnt))
756: ; now set up the jump addresses
757: (if (null g-loc)
758: then (setq loc1 (if (car g-cc) thenret else (d-genlab))
759: loc2 (if (cdr g-cc) thenret else (d-genlab)))
760: else (setq loc1 (d-genlab)
761: loc2 (d-genlab)))
762: (setq looploc (d-genlab))
763: (e-cmpnil 'd0)
764: (e-write2 'jeq loc2)
765: (e-move 'd0 'a0)
766: (e-label looploc)
767: (e-cmp tmp-data-reg '(4 a0))
768: (e-write2 'jeq loc1)
769: (e-move '(0 a0) 'a0)
770: (e-cmpnil 'a0)
771: (e-write2 'jne looploc)
772: (e-move 'a0 'd0)
773: (if g-loc
774: then (e-label loc2) ; nil result
775: (d-move 'reg g-loc)
776: (if (cdr g-cc)
777: then (e-goto (cdr g-cc))
778: else (e-goto (setq finlab (d-genlab))))
779: else (if (cdr g-cc)
780: then (e-goto (cdr g-cc))
781: else (e-label loc2)))
782: (if g-loc
783: then (e-label loc1) ; non nil result
784: (d-move 'a0 g-loc) ;a0 was cdr of non-nil result
785: (if (car g-cc) then (e-goto (car g-cc)))
786: else (if (null (car g-cc)) then (e-label loc1)))
787: (if finlab then (e-label finlab))))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.