aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2015-01-15 08:58:45 -0500
committerStefan Monnier2015-01-16 17:49:00 -0500
commit69f36afa11c0b754c40f4fc57408ccd85428e2b0 (patch)
treed6bbe2d1b3f7defa437b053ea055fd589da035a3
parent9d940c667ab1dadc9d25a88cc2af1594b6c1bb49 (diff)
downloademacs-69f36afa11c0b754c40f4fc57408ccd85428e2b0.tar.gz
emacs-69f36afa11c0b754c40f4fc57408ccd85428e2b0.zip
* lisp/emacs-lisp/cl-macs.el: Fix last change.
(cl--labels-magic): New constant. (cl--labels-convert): Use it to ask the macro what is its replacement in the #'f case.
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/emacs-lisp/cl-macs.el37
-rw-r--r--test/automated/cl-lib-tests.el3
3 files changed, 29 insertions, 15 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index c6e315e1260..c80f8f7bad4 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -38,6 +38,10 @@
38 38
392015-01-15 Stefan Monnier <monnier@iro.umontreal.ca> 392015-01-15 Stefan Monnier <monnier@iro.umontreal.ca>
40 40
41 * emacs-lisp/cl-macs.el (cl--labels-magic): New constant.
42 (cl--labels-convert): Use it to ask the macro what is its replacement
43 in the #'f case.
44
41 * emacs-lisp/cl-generic.el (cl--generic-build-combined-method): 45 * emacs-lisp/cl-generic.el (cl--generic-build-combined-method):
42 Return the value of the primary rather than the after method. 46 Return the value of the primary rather than the after method.
43 47
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 0070599af6f..38f15b89b0e 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -1807,6 +1807,8 @@ a `let' form, except that the list of symbols can be computed at run-time."
1807 (push (list (pop ,syms) (list 'quote (pop ,vals))) ,binds)) 1807 (push (list (pop ,syms) (list 'quote (pop ,vals))) ,binds))
1808 (eval (list 'let ,binds (list 'funcall (list 'quote ,bodyfun)))))))) 1808 (eval (list 'let ,binds (list 'funcall (list 'quote ,bodyfun))))))))
1809 1809
1810(defconst cl--labels-magic (make-symbol "cl--labels-magic"))
1811
1810(defvar cl--labels-convert-cache nil) 1812(defvar cl--labels-convert-cache nil)
1811 1813
1812(defun cl--labels-convert (f) 1814(defun cl--labels-convert (f)
@@ -1818,10 +1820,12 @@ a `let' form, except that the list of symbols can be computed at run-time."
1818 ;; being expanded even though we don't receive it. 1820 ;; being expanded even though we don't receive it.
1819 ((eq f (car cl--labels-convert-cache)) (cdr cl--labels-convert-cache)) 1821 ((eq f (car cl--labels-convert-cache)) (cdr cl--labels-convert-cache))
1820 (t 1822 (t
1821 (let ((found (assq f macroexpand-all-environment))) 1823 (let* ((found (assq f macroexpand-all-environment))
1822 (if (and found (ignore-errors 1824 (replacement (and found
1823 (eq (cadr (cl-caddr found)) 'cl-labels-args))) 1825 (ignore-errors
1824 (cadr (cl-caddr (cl-cadddr found))) 1826 (funcall (cdr found) cl--labels-magic)))))
1827 (if (and replacement (eq cl--labels-magic (car replacement)))
1828 (nth 1 replacement)
1825 (let ((res `(function ,f))) 1829 (let ((res `(function ,f)))
1826 (setq cl--labels-convert-cache (cons f res)) 1830 (setq cl--labels-convert-cache (cons f res))
1827 res)))))) 1831 res))))))
@@ -1850,17 +1854,18 @@ for (FUNC (lambda ARGLIST BODY)).
1850 `(cl-function (lambda . ,args-and-body)))) 1854 `(cl-function (lambda . ,args-and-body))))
1851 binds)) 1855 binds))
1852 (push (cons (car binding) 1856 (push (cons (car binding)
1853 (lambda (&rest cl-labels-args) 1857 (lambda (&rest args)
1854 (cl-list* 'funcall var cl-labels-args))) 1858 (if (eq (car args) cl--labels-magic)
1859 (list cl--labels-magic var)
1860 `(funcall ,var ,@args))))
1855 newenv))) 1861 newenv)))
1856 ;; FIXME: Eliminate those functions which aren't referenced. 1862 ;; FIXME: Eliminate those functions which aren't referenced.
1857 `(let ,(nreverse binds) 1863 (macroexp-let* (nreverse binds)
1858 ,@(macroexp-unprogn 1864 (macroexpand-all
1859 (macroexpand-all 1865 `(progn ,@body)
1860 `(progn ,@body) 1866 ;; Don't override lexical-let's macro-expander.
1861 ;; Don't override lexical-let's macro-expander. 1867 (if (assq 'function newenv) newenv
1862 (if (assq 'function newenv) newenv 1868 (cons (cons 'function #'cl--labels-convert) newenv))))))
1863 (cons (cons 'function #'cl--labels-convert) newenv)))))))
1864 1869
1865;;;###autoload 1870;;;###autoload
1866(defmacro cl-flet* (bindings &rest body) 1871(defmacro cl-flet* (bindings &rest body)
@@ -1887,8 +1892,10 @@ in closures will only work if `lexical-binding' is in use.
1887 (let ((var (make-symbol (format "--cl-%s--" (car binding))))) 1892 (let ((var (make-symbol (format "--cl-%s--" (car binding)))))
1888 (push (list var `(cl-function (lambda . ,(cdr binding)))) binds) 1893 (push (list var `(cl-function (lambda . ,(cdr binding)))) binds)
1889 (push (cons (car binding) 1894 (push (cons (car binding)
1890 (lambda (&rest cl-labels-args) 1895 (lambda (&rest args)
1891 (cl-list* 'funcall var cl-labels-args))) 1896 (if (eq (car args) cl--labels-magic)
1897 (list cl--labels-magic var)
1898 (cl-list* 'funcall var args))))
1892 newenv))) 1899 newenv)))
1893 (macroexpand-all `(letrec ,(nreverse binds) ,@body) 1900 (macroexpand-all `(letrec ,(nreverse binds) ,@body)
1894 ;; Don't override lexical-let's macro-expander. 1901 ;; Don't override lexical-let's macro-expander.
diff --git a/test/automated/cl-lib-tests.el b/test/automated/cl-lib-tests.el
index bbfb8d1f1da..c83391b1cc5 100644
--- a/test/automated/cl-lib-tests.el
+++ b/test/automated/cl-lib-tests.el
@@ -245,4 +245,7 @@
245(ert-deftest cl-loop-destructuring-with () 245(ert-deftest cl-loop-destructuring-with ()
246 (should (equal (cl-loop with (a b c) = '(1 2 3) return (+ a b c)) 6))) 246 (should (equal (cl-loop with (a b c) = '(1 2 3) return (+ a b c)) 6)))
247 247
248(ert-deftest cl-flet-test ()
249 (should (equal (cl-flet ((f1 (x) x)) (let ((x #'f1)) (funcall x 5))) 5)))
250
248;;; cl-lib.el ends here 251;;; cl-lib.el ends here