* improvement: reading from a TWO-WAY-STREAM does not touch the output
stream anymore making it thread safe to have a concurrent reader and
a writer, for instance, in a pipe.
+ * improvement: GET-SETF-EXPANDER avoids adding bindings for constant
+ arguments, making compiler-macros for SETF-functions able to inspect
+ their constant arguments.
+
changes in sbcl-1.0.24 relative to 1.0.23:
* new feature: ARRAY-STORAGE-VECTOR provides access to the underlying data
vector of a multidimensional SIMPLE-ARRAY.
(sb!xc:macroexpand-1 form environment)
(if expanded
(sb!xc:get-setf-expansion expansion environment)
- (let ((new-var (gensym)))
+ (let ((new-var (gensym "NEW")))
(values nil nil (list new-var)
`(setq ,form ,new-var) form)))))
;; Local functions inhibit global SETF methods.
(return t)))))
(expand-or-get-setf-inverse form environment))
((setq temp (info :setf :inverse (car form)))
- (get-setf-method-inverse form `(,temp) nil))
+ (get-setf-method-inverse form `(,temp) nil environment))
((setq temp (info :setf :expander (car form)))
;; KLUDGE: It may seem as though this should go through
;; *MACROEXPAND-HOOK*, but the ANSI spec seems fairly explicit
(sb!xc:get-setf-expansion expansion environment)
(get-setf-method-inverse form
`(funcall #'(setf ,(car form)))
- t))))
+ t
+ environment))))
-(defun get-setf-method-inverse (form inverse setf-fun)
- (let ((new-var (gensym))
+(defun get-setf-method-inverse (form inverse setf-fun environment)
+ (let ((new-var (gensym "NEW"))
(vars nil)
- (vals nil))
- (dolist (x (cdr form))
- (push (gensym) vars)
- (push x vals))
- (setq vals (nreverse vals))
- (values vars vals (list new-var)
+ (vals nil)
+ (args nil))
+ (dolist (x (reverse (cdr form)))
+ (cond ((sb!xc:constantp x environment)
+ (push x args))
+ (t
+ (let ((temp (gensym "TMP")))
+ (push temp args)
+ (push temp vars)
+ (push x vals)))))
+ (values vars
+ vals
+ (list new-var)
(if setf-fun
- `(,@inverse ,new-var ,@vars)
- `(,@inverse ,@vars ,new-var))
- `(,(car form) ,@vars))))
+ `(,@inverse ,new-var ,@args)
+ `(,@inverse ,@args ,new-var))
+ `(,(car form) ,@args))))
\f
;;;; SETF itself
(class-precedence-list
accessor-class))
:test #'eq)
- (if early-p
- (not (eq *the-class-standard-method*
- (early-method-class meth)))
- (accessor-method-p meth))
- (if early-p
- (early-accessor-method-slot-name meth)
- (accessor-method-slot-name meth))))))
+ (accessor-method-p meth)
+ (accessor-method-slot-name meth)))))
(slotd (and accessor-class
(if early-p
(dolist (slot (early-class-slotds accessor-class) nil)
(declare (ignore env))
`(set-foo ,foo ,new)))))
+;;; Not required by the spec, but allowes compiler-macros for SETF-functiosn
+;;; to see their constant argument forms.
+(with-test (:name constantp-aware-get-setf-expansion)
+ (multiple-value-bind (temps values stores set get)
+ (get-setf-expansion '(foo 1 2 3))
+ (assert (not temps))
+ (assert (not values))
+ (assert (equal `(funcall #'(setf foo) ,@stores 1 2 3) set))
+ (assert (equal '(foo 1 2 3) get))))
+
;;; success