diff options
| author | Stefan Monnier | 2010-04-08 15:59:46 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2010-04-08 15:59:46 -0400 |
| commit | e754e83b6555fccf9676b10ff6e6253d75f2bba1 (patch) | |
| tree | 772f0b3e61adbc51afb8c7e36d7c70085c1e6676 | |
| parent | 0269ef77309827f774779a2df95aca858fd96146 (diff) | |
| download | emacs-e754e83b6555fccf9676b10ff6e6253d75f2bba1.tar.gz emacs-e754e83b6555fccf9676b10ff6e6253d75f2bba1.zip | |
Fix some of the problems in defsubst* (bug#5728).
* emacs-lisp/cl-macs.el (defsubst*): Don't substitute non-trivial args.
(cl-defsubst-expand): Do the substitutions simultaneously (bug#5728).
| -rw-r--r-- | lisp/ChangeLog | 10 | ||||
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 39 |
2 files changed, 38 insertions, 11 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6cdaaf2255b..ba042245fd6 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,7 +1,13 @@ | |||
| 1 | 2010-04-08 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | Fix some of the problems in defsubst* (bug#5728). | ||
| 4 | * emacs-lisp/cl-macs.el (defsubst*): Don't substitute non-trivial args. | ||
| 5 | (cl-defsubst-expand): Do the substitutions simultaneously (bug#5728). | ||
| 6 | |||
| 1 | 2010-04-07 Sam Steingold <sds@gnu.org> | 7 | 2010-04-07 Sam Steingold <sds@gnu.org> |
| 2 | 8 | ||
| 3 | * progmodes/compile.el (compilation-save-buffers-predicate): New | 9 | * progmodes/compile.el (compilation-save-buffers-predicate): |
| 4 | custom variable. | 10 | New custom variable. |
| 5 | (compile, recompile): Pass it to `save-some-buffers'. | 11 | (compile, recompile): Pass it to `save-some-buffers'. |
| 6 | 12 | ||
| 7 | 2010-04-07 Jan Djärv <jan.h.d@swipnet.se> | 13 | 2010-04-07 Jan Djärv <jan.h.d@swipnet.se> |
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 8a60ffdf1fe..7d8108bcd87 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -128,6 +128,12 @@ | |||
| 128 | (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x))) | 128 | (and (eq (cl-const-expr-p x) t) (if (consp x) (nth 1 x) x))) |
| 129 | 129 | ||
| 130 | (defun cl-expr-access-order (x v) | 130 | (defun cl-expr-access-order (x v) |
| 131 | ;; This apparently tries to return nil iff the expression X evaluates | ||
| 132 | ;; the variables V in the same order as they appear in V (so as to | ||
| 133 | ;; be able to replace those vars with the expressions they're bound | ||
| 134 | ;; to). | ||
| 135 | ;; FIXME: This is very naive, it doesn't even check to see if those | ||
| 136 | ;; variables appear more than once. | ||
| 131 | (if (cl-const-expr-p x) v | 137 | (if (cl-const-expr-p x) v |
| 132 | (if (consp x) | 138 | (if (consp x) |
| 133 | (progn | 139 | (progn |
| @@ -2616,21 +2622,36 @@ surrounded by (block NAME ...). | |||
| 2616 | (cons '&cl-quote args)) | 2622 | (cons '&cl-quote args)) |
| 2617 | (list* 'cl-defsubst-expand (list 'quote argns) | 2623 | (list* 'cl-defsubst-expand (list 'quote argns) |
| 2618 | (list 'quote (list* 'block name body)) | 2624 | (list 'quote (list* 'block name body)) |
| 2619 | (not (or unsafe (cl-expr-access-order pbody argns))) | 2625 | ;; We used to pass `simple' as |
| 2626 | ;; (not (or unsafe (cl-expr-access-order pbody argns))) | ||
| 2627 | ;; But this is much too simplistic since it | ||
| 2628 | ;; does not pay attention to the argvs (and | ||
| 2629 | ;; cl-expr-access-order itself is also too naive). | ||
| 2630 | nil | ||
| 2620 | (and (memq '&key args) 'cl-whole) unsafe argns))) | 2631 | (and (memq '&key args) 'cl-whole) unsafe argns))) |
| 2621 | (list* 'defun* name args body)))) | 2632 | (list* 'defun* name args body)))) |
| 2622 | 2633 | ||
| 2623 | (defun cl-defsubst-expand (argns body simple whole unsafe &rest argvs) | 2634 | (defun cl-defsubst-expand (argns body simple whole unsafe &rest argvs) |
| 2624 | (if (and whole (not (cl-safe-expr-p (cons 'progn argvs)))) whole | 2635 | (if (and whole (not (cl-safe-expr-p (cons 'progn argvs)))) whole |
| 2625 | (if (cl-simple-exprs-p argvs) (setq simple t)) | 2636 | (if (cl-simple-exprs-p argvs) (setq simple t)) |
| 2626 | (let ((lets (delq nil | 2637 | (let* ((substs ()) |
| 2627 | (mapcar* (function | 2638 | (lets (delq nil |
| 2628 | (lambda (argn argv) | 2639 | (mapcar* (function |
| 2629 | (if (or simple (cl-const-expr-p argv)) | 2640 | (lambda (argn argv) |
| 2630 | (progn (setq body (subst argv argn body)) | 2641 | (if (or simple (cl-const-expr-p argv)) |
| 2631 | (and unsafe (list argn argv))) | 2642 | (progn (push (cons argn argv) substs) |
| 2632 | (list argn argv)))) | 2643 | (and unsafe (list argn argv))) |
| 2633 | argns argvs)))) | 2644 | (list argn argv)))) |
| 2645 | argns argvs)))) | ||
| 2646 | ;; FIXME: `sublis/subst' will happily substitute the symbol | ||
| 2647 | ;; `argn' in places where it's not used as a reference | ||
| 2648 | ;; to a variable. | ||
| 2649 | ;; FIXME: `sublis/subst' will happily copy `argv' to a different | ||
| 2650 | ;; scope, leading to name capture. | ||
| 2651 | (setq body (cond ((null substs) body) | ||
| 2652 | ((null (cdr substs)) | ||
| 2653 | (subst (cdar substs) (caar substs) body)) | ||
| 2654 | (t (sublis substs body)))) | ||
| 2634 | (if lets (list 'let lets body) body)))) | 2655 | (if lets (list 'let lets body) body)))) |
| 2635 | 2656 | ||
| 2636 | 2657 | ||