emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 37c41c6: * lisp/emacs-lisp/cl-macs.el (cl--sm-macro


From: Stefan Monnier
Subject: [Emacs-diffs] master 37c41c6: * lisp/emacs-lisp/cl-macs.el (cl--sm-macroexpand) <setq>: Rewrite
Date: Thu, 16 May 2019 15:29:43 -0400 (EDT)

branch: master
commit 37c41c6ef01de5bf16948eb67c4a9da6c7158b34
Author: Stefan Monnier <address@hidden>
Commit: Stefan Monnier <address@hidden>

    * lisp/emacs-lisp/cl-macs.el (cl--sm-macroexpand) <setq>: Rewrite
    
    The previous code had 2 problems:
    - It converted `setq` to `setf` in unrelated cases such as
      (cl-symbol-macrolet ((x 1)) (setq (car foo) bar))
    - It macroexpanded places before `setf` had a chance to see if they
      have a gv-expander.
---
 lisp/emacs-lisp/cl-macs.el | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 16e9bd6..23c4351 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -2145,16 +2145,26 @@ of `cl-symbol-macrolet' to additionally expand symbol 
macros."
              (let ((symval (assq exp venv)))
                (when symval
                  (setq exp (cadr symval)))))
-            (`(setq . ,_)
+            (`(setq . ,args)
              ;; Convert setq to setf if required by symbol-macro expansion.
-             (let* ((args (mapcar (lambda (f) (macroexpand f env))
-                                  (cdr exp)))
-                    (p args))
-               (while (and p (symbolp (car p))) (setq p (cddr p)))
-               (if p (setq exp (cons 'setf args))
-                 (setq exp (cons 'setq args))
-                 ;; Don't loop further.
-                 nil)))
+             (let ((convert nil)
+                   (rargs nil))
+               (while args
+                 (let ((place (pop args)))
+                   ;; Here, we know `place' should be a symbol.
+                   (while
+                       (let ((symval (assq place venv)))
+                         (when symval
+                           (setq place (cadr symval))
+                           (if (symbolp place)
+                               t        ;Repeat.
+                             (setq convert t)
+                             nil))))
+                   (push place rargs)
+                   (push (pop args) rargs)))
+               (setq exp (cons (if convert 'setf 'setq)
+                               (nreverse rargs)))
+               convert))
             ;; CL's symbol-macrolet used to treat re-bindings as candidates for
             ;; expansion (turning the let into a letf if needed), contrary to
             ;; Common-Lisp where such re-bindings hide the symbol-macro.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]