aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2010-04-08 15:59:46 -0400
committerStefan Monnier2010-04-08 15:59:46 -0400
commite754e83b6555fccf9676b10ff6e6253d75f2bba1 (patch)
tree772f0b3e61adbc51afb8c7e36d7c70085c1e6676
parent0269ef77309827f774779a2df95aca858fd96146 (diff)
downloademacs-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/ChangeLog10
-rw-r--r--lisp/emacs-lisp/cl-macs.el39
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 @@
12010-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
12010-04-07 Sam Steingold <sds@gnu.org> 72010-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
72010-04-07 Jan Djärv <jan.h.d@swipnet.se> 132010-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