X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fearly-setf.lisp;h=b09d1f0c91b5cee4187ac6ded3de1d9306cd9a7c;hb=d2241edb01a6dad8a7bc1107d28d0873f5f8d83e;hp=d9d808174532475e23dc96e748aa920879a455c7;hpb=a26fc2e03904bd0dac626a43e169e2e3514344d4;p=sbcl.git diff --git a/src/code/early-setf.lisp b/src/code/early-setf.lisp index d9d8081..b09d1f0 100644 --- a/src/code/early-setf.lisp +++ b/src/code/early-setf.lisp @@ -32,7 +32,7 @@ (declaim (ftype (function (t &optional (or null sb!c::lexenv))) sb!xc:get-setf-expansion)) (defun sb!xc:get-setf-expansion (form &optional environment) #!+sb-doc - "Returns five values needed by the SETF machinery: a list of temporary + "Return five values needed by the SETF machinery: a list of temporary variables, a list of values with which to fill them, a list of temporaries for the new values, the setting function, and the accessing function." (let (temp) @@ -47,9 +47,9 @@ ;; Local functions inhibit global SETF methods. ((and environment (let ((name (car form))) - (dolist (x (sb!c::lexenv-functions environment)) + (dolist (x (sb!c::lexenv-funs environment)) (when (and (eq (car x) name) - (not (sb!c::defined-function-p (cdr x)))) + (not (sb!c::defined-fun-p (cdr x)))) (return t))))) (expand-or-get-setf-inverse form environment)) ((setq temp (info :setf :inverse (car form))) @@ -61,11 +61,12 @@ ;; for macroexpansion in general. -- WHN 19991128 (funcall temp form - ;; As near as I can tell from the ANSI spec, macroexpanders - ;; have a right to expect an actual lexical environment, - ;; not just a NIL which is to be interpreted as a null - ;; lexical environment. -- WHN 19991128 - (or environment (make-null-lexenv)))) + ;; As near as I can tell from the ANSI spec, + ;; macroexpanders have a right to expect an actual + ;; lexical environment, not just a NIL which is to + ;; be interpreted as a null lexical environment. + ;; -- WHN 19991128 + (coerce-to-lexenv environment))) (t (expand-or-get-setf-inverse form environment))))) @@ -100,7 +101,7 @@ GET-SETF-EXPANSION directly." `(funcall #'(setf ,(car form))) t)))) -(defun get-setf-method-inverse (form inverse setf-function) +(defun get-setf-method-inverse (form inverse setf-fun) (let ((new-var (gensym)) (vars nil) (vals nil)) @@ -109,18 +110,19 @@ GET-SETF-EXPANSION directly." (push x vals)) (setq vals (nreverse vals)) (values vars vals (list new-var) - (if setf-function + (if setf-fun `(,@inverse ,new-var ,@vars) `(,@inverse ,@vars ,new-var)) `(,(car form) ,@vars)))) ;;;; SETF itself -;;; Except for atoms, we always call GET-SETF-EXPANSION, since it has some -;;; non-trivial semantics. But when there is a setf inverse, and G-S-E uses -;;; it, then we return a call to the inverse, rather than returning a hairy let -;;; form. This is probably important mainly as a convenience in allowing the -;;; use of SETF inverses without the full interpreter. +;;; Except for atoms, we always call GET-SETF-EXPANSION, since it has +;;; some non-trivial semantics. But when there is a setf inverse, and +;;; G-S-E uses it, then we return a call to the inverse, rather than +;;; returning a hairy LET form. This is probably important mainly as a +;;; convenience in allowing the use of SETF inverses without the full +;;; interpreter. (defmacro-mundanely setf (&rest args &environment env) #!+sb-doc "Takes pairs of arguments like SETQ. The first is a place and the second @@ -172,8 +174,8 @@ GET-SETF-EXPANSION directly." `(let* ,(nreverse bindlist) ,@(nreverse storelist) ,resultvar)) (multiple-value-bind (sm1 sm2 sm3 sm4 sm5) (get-setf-method (first arglist) env) - (mapc #'(lambda (var val) - (push `(,var ,val) bindlist)) + (mapc (lambda (var val) + (push `(,var ,val) bindlist)) sm1 sm2) (push `(,lastvar ,sm5) bindlist) @@ -184,54 +186,43 @@ GET-SETF-EXPANSION directly." #!+sb-doc "Takes an object and a location holding a list. Conses the object onto the list, returning the modified list. OBJ is evaluated before PLACE." - (if (symbolp place) - `(setq ,place (cons ,obj ,place)) - (multiple-value-bind - (dummies vals newval setter getter) - (get-setf-method place env) - (let ((g (gensym))) - `(let* ((,g ,obj) - ,@(mapcar #'list dummies vals) - (,(car newval) (cons ,g ,getter))) - ,setter))))) + (multiple-value-bind (dummies vals newval setter getter) + (get-setf-method place env) + (let ((g (gensym))) + `(let* ((,g ,obj) + ,@(mapcar #'list dummies vals) + (,(car newval) (cons ,g ,getter))) + ,setter)))) (defmacro-mundanely pushnew (obj place &rest keys &environment env) #!+sb-doc "Takes an object and a location holding a list. If the object is already in the list, does nothing. Else, conses the object onto the list. Returns NIL. If there is a :TEST keyword, this is used for the comparison." - (if (symbolp place) - `(setq ,place (adjoin ,obj ,place ,@keys)) - (multiple-value-bind (dummies vals newval setter getter) - (get-setf-method place env) - (do* ((d dummies (cdr d)) - (v vals (cdr v)) - (let-list nil)) - ((null d) - (push (list (car newval) `(adjoin ,obj ,getter ,@keys)) - let-list) - `(let* ,(nreverse let-list) - ,setter)) - (push (list (car d) (car v)) let-list))))) + (multiple-value-bind (dummies vals newval setter getter) + (get-setf-method place env) + (let ((g (gensym))) + `(let* ((,g ,obj) + ,@(mapcar #'list dummies vals) + (,(car newval) (adjoin ,g ,getter ,@keys))) + ,setter)))) (defmacro-mundanely pop (place &environment env) #!+sb-doc "The argument is a location holding a list. Pops one item off the front of the list and returns it." - (if (symbolp place) - `(prog1 (car ,place) (setq ,place (cdr ,place))) - (multiple-value-bind (dummies vals newval setter getter) - (get-setf-method place env) - (do* ((d dummies (cdr d)) - (v vals (cdr v)) - (let-list nil)) - ((null d) - (push (list (car newval) getter) let-list) - `(let* ,(nreverse let-list) - (prog1 (car ,(car newval)) - (setq ,(car newval) (cdr ,(car newval))) - ,setter))) - (push (list (car d) (car v)) let-list))))) + (multiple-value-bind (dummies vals newval setter getter) + (get-setf-method place env) + (do* ((d dummies (cdr d)) + (v vals (cdr v)) + (let-list nil)) + ((null d) + (push (list (car newval) getter) let-list) + `(let* ,(nreverse let-list) + (prog1 (car ,(car newval)) + (setq ,(car newval) (cdr ,(car newval))) + ,setter))) + (push (list (car d) (car v)) let-list)))) (defmacro-mundanely remf (place indicator &environment env) #!+sb-doc @@ -326,7 +317,7 @@ GET-SETF-EXPANSION directly." ;;;; DEFSETF (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute) - ;;; Assign setf macro information for NAME, making all appropriate checks. + ;;; Assign SETF macro information for NAME, making all appropriate checks. (defun assign-setf-macro (name expander inverse doc) (cond ((gethash name sb!c:*setf-assumed-fboundp*) (warn @@ -337,11 +328,6 @@ GET-SETF-EXPANSION directly." ((not (fboundp `(setf ,name))) ;; All is well, we don't need any warnings. (values)) - ((info :function :accessor-for name) - (warn "defining SETF macro for DEFSTRUCT slot ~ - accessor; redefining as a normal function: ~S" - name) - (sb!c::proclaim-as-function-name name)) ((not (eq (symbol-package name) (symbol-package 'aref))) (style-warn "defining setf macro for ~S when ~S is fbound" name `(setf ,name)))) @@ -381,19 +367,20 @@ GET-SETF-EXPANSION directly." `(eval-when (:compile-toplevel :load-toplevel :execute) (assign-setf-macro ',access-fn - #'(lambda (,access-form-var ,env-var) - (declare (ignore ,env-var)) - (%defsetf ,access-form-var ,(length store-variables) - #'(lambda (,arglist-var) - ,@local-decs - (block ,access-fn - ,body)))) + (lambda (,access-form-var ,env-var) + (declare (ignore ,env-var)) + (%defsetf ,access-form-var ,(length store-variables) + (lambda (,arglist-var) + ,@local-decs + (block ,access-fn + ,body)))) nil ',doc)))))) (t (error "ill-formed DEFSETF for ~S" access-fn)))) (defun %defsetf (orig-access-form num-store-vars expander) + (declare (type function expander)) (let (subforms subform-vars subform-exprs @@ -435,9 +422,9 @@ GET-SETF-EXPANSION directly." :environment environment) `(eval-when (:compile-toplevel :load-toplevel :execute) (assign-setf-macro ',access-fn - #'(lambda (,whole ,environment) - ,@local-decs - (block ,access-fn ,body)) + (lambda (,whole ,environment) + ,@local-decs + (block ,access-fn ,body)) nil ',doc))))) @@ -524,7 +511,7 @@ GET-SETF-EXPANSION directly." (sb!xc:define-setf-expander ldb (bytespec place &environment env) #!+sb-doc "The first argument is a byte specifier. The second is any place form - acceptable to SETF. Replaces the specified byte of the number in this + acceptable to SETF. Replace the specified byte of the number in this place with bits from the low-order end of the new value." (declare (type sb!c::lexenv env)) (multiple-value-bind (dummies vals newval setter getter)