X-Git-Url: https://git.distorted.org.uk/~mdw/lisp/blobdiff_plain/202c91a3c5682b65cd3681bb5bdb919ae6b13c85..e979e568d0046326c2ce24a449468e4d207d9318:/mdw-base.lisp diff --git a/mdw-base.lisp b/mdw-base.lisp index edebebb..21948fa 100644 --- a/mdw-base.lisp +++ b/mdw-base.lisp @@ -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)