[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[barmar@Think.COM: MULTIPLE-VALUE-SETQ and SYMBOL-MACROLET interaction]
- To: Gregor.pa@Xerox.COM
- Subject: [barmar@Think.COM: MULTIPLE-VALUE-SETQ and SYMBOL-MACROLET interaction]
- From: Eric Benson <edsel!eb@labrea.stanford.edu>
- Date: Fri, 29 Jul 88 15:08:12 pdt
- Cc: CommonLoops.pa@Xerox.COM
- In-reply-to: Gregor.pa@xerox.com's message of Fri, 29 Jul 88 11:10 PDT <19880729181046.9.GREGOR@PORTNOY.parc.xerox.com>
- Redistributed: CommonLoops.pa
MULTIPLE-VALUE-CALL is the wrong thing to use here, since it forces
the number of values to match the number of variables. The correct
thing is to use MULTIPLE-VALUE-BIND. Here is a modified version of
EXPAND-WITH-SLOTS-INTERNAL:
(defun expand-with-slots-internal (specs form context translate-fn &aux entry)
(cond ((not (eq context :eval)) form)
((symbolp form)
(if (setq entry (assoc form specs))
(funcall translate-fn (cadr entry))
form))
((not (listp form)) form)
((member (car form) '(setq setf))
;; Have to be careful. We must only convert the form to a SETF
;; form when we convert one of the 'logical' variables to a form
;; Otherwise we will get looping in implementations where setf
;; is a macro which expands into setq.
(let ((kind (car form)))
(labels ((scan-setf (tail)
(if (null tail)
nil
(walker::relist*
tail
(if (setq entry (assoc (car tail) specs))
(progn (setq kind 'setf)
(funcall translate-fn (cadr entry)))
(car tail))
(cadr tail)
(scan-setf (cddr tail))))))
(let (new-tail)
(setq new-tail (scan-setf (cdr form)))
(walker::recons form kind new-tail)))))
((eq (car form) 'multiple-value-setq)
(let* ((vars (cadr form))
(gensyms (mapcar #'(lambda (i) (declare (ignore i)) (gensym))
vars)))
`(multiple-value-bind ,gensyms
,(caddr form)
.,(mapcar #'(lambda (v g) `(setf ,v ,g))
vars
gensyms))))
(t form)))