0.9.0.25:
[sbcl.git] / src / code / early-setf.lisp
index 4a9aecb..e829b6a 100644 (file)
@@ -257,8 +257,9 @@ GET-SETF-EXPANSION directly."
          (local1 (gensym))
          (local2 (gensym)))
         ((null d)
-         (push (list (car newval) getter) let-list)
+          ;; See ANSI 5.1.3 for why we do out-of-order evaluation
          (push (list ind-temp indicator) let-list)
+         (push (list (car newval) getter) let-list)
          `(let* ,(nreverse let-list)
             (do ((,local1 ,(car newval) (cddr ,local1))
                  (,local2 nil ,local1))
@@ -273,6 +274,31 @@ GET-SETF-EXPANSION directly."
                               ,setter
                               (return t))))))))
       (push (list (car d) (car v)) let-list))))
+
+;;; we can't use DEFINE-MODIFY-MACRO because of ANSI 5.1.3
+(defmacro-mundanely incf (place &optional (delta 1) &environment env)
+  #!+sb-doc
+  "The first argument is some location holding a number. This number is
+  incremented by the second argument, DELTA, which defaults to 1."
+  (multiple-value-bind (dummies vals newval setter getter)
+      (get-setf-method place env)
+    (let ((d (gensym)))
+      `(let* (,@(mapcar #'list dummies vals)
+              (,d ,delta)
+              (,(car newval) (+ ,getter ,d)))
+         ,setter))))
+
+(defmacro-mundanely decf (place &optional (delta 1) &environment env)
+  #!+sb-doc
+  "The first argument is some location holding a number. This number is
+  decremented by the second argument, DELTA, which defaults to 1."
+  (multiple-value-bind (dummies vals newval setter getter)
+      (get-setf-method place env)
+    (let ((d (gensym)))
+      `(let* (,@(mapcar #'list dummies vals)
+              (,d ,delta)
+              (,(car newval) (- ,getter ,d)))
+         ,setter))))
 \f
 ;;;; DEFINE-MODIFY-MACRO stuff
 
@@ -321,16 +347,6 @@ GET-SETF-EXPANSION directly."
                    let-list)
              `(let* ,(nreverse let-list)
                 ,setter)))))))
-
-(sb!xc:define-modify-macro incf (&optional (delta 1)) +
-  #!+sb-doc
-  "The first argument is some location holding a number. This number is
-  incremented by the second argument, DELTA, which defaults to 1.")
-
-(sb!xc:define-modify-macro decf (&optional (delta 1)) -
-  #!+sb-doc
-  "The first argument is some location holding a number. This number is
-  decremented by the second argument, DELTA, which defaults to 1.")
 \f
 ;;;; DEFSETF
 
@@ -428,11 +444,11 @@ GET-SETF-EXPANSION directly."
 ;;; DEFINE-SETF-EXPANDER is a lot like DEFMACRO.
 (def!macro sb!xc:define-setf-expander (access-fn lambda-list &body body)
   #!+sb-doc
-  "Syntax like DEFMACRO, but creates a Setf-Method generator. The body
-  must be a form that returns the five magical values."
+  "Syntax like DEFMACRO, but creates a setf expander function. The body
+  of the definition must be a form that returns five appropriate values."
   (unless (symbolp access-fn)
-    (error "DEFINE-SETF-EXPANDER access-function name ~S is not a symbol."
-          access-fn))
+    (error "~S access-function name ~S is not a symbol."
+           'sb!xc:define-setf-expander access-fn))
   (with-unique-names (whole environment)
     (multiple-value-bind (body local-decs doc)
        (parse-defmacro lambda-list whole body access-fn
@@ -576,10 +592,10 @@ GET-SETF-EXPANSION directly."
 
 (sb!xc:define-setf-expander the (type place &environment env)
   (declare (type sb!c::lexenv env))
-  (multiple-value-bind (dummies vals newval setter getter)
-      (get-setf-method place env)
-    (values dummies
-             vals
-             newval
-             (subst `(the ,type ,(car newval)) (car newval) setter)
-             `(the ,type ,getter))))
+  (multiple-value-bind (temps subforms store-vars setter getter)
+      (sb!xc:get-setf-expansion place env)
+    (values temps subforms store-vars
+            `(multiple-value-bind ,store-vars
+                 (the ,type (values ,@store-vars))
+               ,setter)
+            `(the ,type ,getter))))