mdw-base: Update-in-place macros.
authorMark Wooding <mdw@distorted.org.uk>
Thu, 20 Apr 2006 11:00:25 +0000 (12:00 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 20 Apr 2006 11:06:08 +0000 (12:06 +0100)
These are largely here because the infix reader stuff wants them, but
it's handy enough, probably.

mdw-base.lisp

index edebebb..21948fa 100644 (file)
@@ -31,7 +31,9 @@
           #:whitespace-char-p
           #:slot-uninitialized
           #:with-gensyms #:let*/gensyms #:with-places
-          #:locp #:locf #:ref #:with-locatives))
+          #:locp #:locf #:ref #:with-locatives
+          #:update-place #:update-place-after
+          #:incf-after #:decf-after))
 (in-package #:mdw.base)
 
 (defmacro compile-time-defun (name args &body body)
@@ -173,6 +175,25 @@ reading or setting the value of the corresponding PLACE."
                                          body))))))))))
           (car (more (mapcar #'pairify (listify places))))))))
 
+(defmacro update-place (op place arg &environment env)
+  "Update PLACE with the value of OP PLACE ARG, returning the new value."
+  (with-places (:environment env) (place)
+    `(setf ,place (,op ,place ,arg))))
+(defmacro update-place-after (op place arg &environment env)
+  "Update PLACE with the value of OP PLACE ARG, returning the old value."
+  (with-places (:environment env) (place)
+    (with-gensyms (x)
+      `(let ((,x ,place))
+         (setf ,place (,op ,x ,arg))
+         ,x))))
+(defmacro incf-after (place &optional (by 1))
+  "Increment PLACE by BY, returning the old value."
+  `(update-place-after + ,place ,by))
+(defmacro decf-after (place &optional (by 1))
+  "Decrement PLACE by BY, returning the old value."
+  `(update-place-after - ,place ,by))
+
+
 (defstruct (loc (:predicate locp) (:constructor make-loc (reader writer)))
   "Locative data type.  See `locf' and `ref'."
   (reader (slot-uninitialized) :type function)