aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2015-02-22 23:50:03 -0500
committerStefan Monnier2015-02-22 23:50:03 -0500
commite846bbf360d1bcee3a35dd05a57bc76cbb22a6f0 (patch)
tree6405207140152b44c5f4a862ce427e2912383ad7
parent3f006e1d47c25a8282fd41fb0df01fd80f486b9e (diff)
downloademacs-e846bbf360d1bcee3a35dd05a57bc76cbb22a6f0.tar.gz
emacs-e846bbf360d1bcee3a35dd05a57bc76cbb22a6f0.zip
* lisp/emacs-lisp/macroexp.el (macroexp-parse-body): Handle cl-declare
and :documentation. Change return value format accordingly. * lisp/emacs-lisp/cl-generic.el (cl--generic-lambda): * lisp/emacs-lisp/pcase.el (pcase-lambda): Adjust accordingly. * lisp/emacs-lisp/cl-macs.el (cl--transform-lambda): Use macroexp-parse-body.
-rw-r--r--lisp/ChangeLog8
-rw-r--r--lisp/emacs-lisp/cl-generic.el2
-rw-r--r--lisp/emacs-lisp/cl-macs.el35
-rw-r--r--lisp/emacs-lisp/macroexp.el19
-rw-r--r--lisp/emacs-lisp/pcase.el2
5 files changed, 36 insertions, 30 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index ced342baeb9..6352d77ca3a 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,11 @@
12015-02-23 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * emacs-lisp/macroexp.el (macroexp-parse-body): Handle cl-declare
4 and :documentation. Change return value format accordingly.
5 * emacs-lisp/cl-generic.el (cl--generic-lambda):
6 * emacs-lisp/pcase.el (pcase-lambda): Adjust accordingly.
7 * emacs-lisp/cl-macs.el (cl--transform-lambda): Use macroexp-parse-body.
8
12015-02-23 Dmitry Gutov <dgutov@yandex.ru> 92015-02-23 Dmitry Gutov <dgutov@yandex.ru>
2 10
3 Introduce `xref-etags-mode'. 11 Introduce `xref-etags-mode'.
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index ccd5bec5685..99924ba288f 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -278,7 +278,7 @@ This macro can only be used within the lexical scope of a cl-generic method."
278 (uses-cnm (cl--generic-fgrep (list cnm nmp) nbody))) 278 (uses-cnm (cl--generic-fgrep (list cnm nmp) nbody)))
279 (cons (not (not uses-cnm)) 279 (cons (not (not uses-cnm))
280 `#'(lambda (,@(if uses-cnm (list cnm)) ,@args) 280 `#'(lambda (,@(if uses-cnm (list cnm)) ,@args)
281 ,@(delq nil (car parsed-body)) 281 ,@(car parsed-body)
282 ,(if (not (memq nmp uses-cnm)) 282 ,(if (not (memq nmp uses-cnm))
283 nbody 283 nbody
284 `(let ((,nmp (lambda () 284 `(let ((,nmp (lambda ()
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index c5f49b0ed91..c3da091fb00 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -234,10 +234,9 @@ FORM is of the form (ARGS . BODY)."
234 (let* ((args (car form)) (body (cdr form)) (orig-args args) 234 (let* ((args (car form)) (body (cdr form)) (orig-args args)
235 (cl--bind-block bind-block) (cl--bind-defs nil) (cl--bind-enquote nil) 235 (cl--bind-block bind-block) (cl--bind-defs nil) (cl--bind-enquote nil)
236 (cl--bind-lets nil) (cl--bind-forms nil) 236 (cl--bind-lets nil) (cl--bind-forms nil)
237 (header nil) (simple-args nil)) 237 (parsed-body (macroexp-parse-body body))
238 (while (or (stringp (car body)) 238 (header (car parsed-body)) (simple-args nil))
239 (memq (car-safe (car body)) '(interactive declare cl-declare))) 239 (setq body (cdr parsed-body))
240 (push (pop body) header))
241 (setq args (if (listp args) (cl-copy-list args) (list '&rest args))) 240 (setq args (if (listp args) (cl-copy-list args) (list '&rest args)))
242 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p))))) 241 (let ((p (last args))) (if (cdr p) (setcdr p (list '&rest (cdr p)))))
243 (if (setq cl--bind-defs (cadr (memq '&cl-defs args))) 242 (if (setq cl--bind-defs (cadr (memq '&cl-defs args)))
@@ -258,7 +257,7 @@ FORM is of the form (ARGS . BODY)."
258 (or (eq cl--bind-block 'cl-none) 257 (or (eq cl--bind-block 'cl-none)
259 (setq body (list `(cl-block ,cl--bind-block ,@body)))) 258 (setq body (list `(cl-block ,cl--bind-block ,@body))))
260 (if (null args) 259 (if (null args)
261 (cl-list* nil (nreverse simple-args) (nconc (nreverse header) body)) 260 (cl-list* nil (nreverse simple-args) (nconc header body))
262 (if (memq '&optional simple-args) (push '&optional args)) 261 (if (memq '&optional simple-args) (push '&optional args))
263 (cl--do-arglist args nil (- (length simple-args) 262 (cl--do-arglist args nil (- (length simple-args)
264 (if (memq '&optional simple-args) 1 0))) 263 (if (memq '&optional simple-args) 1 0)))
@@ -266,20 +265,18 @@ FORM is of the form (ARGS . BODY)."
266 (cl-list* nil 265 (cl-list* nil
267 (nconc (nreverse simple-args) 266 (nconc (nreverse simple-args)
268 (list '&rest (car (pop cl--bind-lets)))) 267 (list '&rest (car (pop cl--bind-lets))))
269 (nconc (let ((hdr (nreverse header))) 268 (nconc (save-match-data ;; Macro expansion can take place in the
270 ;; Macro expansion can take place in the middle of 269 ;; middle of apparently harmless computation, so it
271 ;; apparently harmless computation, so it should not 270 ;; should not touch the match-data.
272 ;; touch the match-data. 271 (require 'help-fns)
273 (save-match-data 272 (cons (help-add-fundoc-usage
274 (require 'help-fns) 273 (if (stringp (car header)) (pop header))
275 (cons (help-add-fundoc-usage 274 ;; Be careful with make-symbol and (back)quote,
276 (if (stringp (car hdr)) (pop hdr)) 275 ;; see bug#12884.
277 ;; Be careful with make-symbol and (back)quote, 276 (let ((print-gensym nil) (print-quoted t))
278 ;; see bug#12884. 277 (format "%S" (cons 'fn (cl--make-usage-args
279 (let ((print-gensym nil) (print-quoted t)) 278 orig-args)))))
280 (format "%S" (cons 'fn (cl--make-usage-args 279 header))
281 orig-args)))))
282 hdr)))
283 (list `(let* ,cl--bind-lets 280 (list `(let* ,cl--bind-lets
284 ,@(nreverse cl--bind-forms) 281 ,@(nreverse cl--bind-forms)
285 ,@body))))))) 282 ,@body)))))))
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index b75c8cc50a7..68bf4f62c34 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -297,15 +297,16 @@ definitions to shadow the loaded ones for use in file byte-compilation."
297 297
298;;; Handy functions to use in macros. 298;;; Handy functions to use in macros.
299 299
300(defun macroexp-parse-body (exps) 300(defun macroexp-parse-body (body)
301 "Parse EXPS into ((DOC DECLARE-FORM INTERACTIVE-FORM) . BODY)." 301 "Parse a function BODY into (DECLARATIONS . EXPS)."
302 `((,(and (stringp (car exps)) 302 (let ((decls ()))
303 (pop exps)) 303 (while (and (cdr body)
304 ,(and (eq (car-safe (car exps)) 'declare) 304 (let ((e (car body)))
305 (pop exps)) 305 (or (stringp e)
306 ,(and (eq (car-safe (car exps)) 'interactive) 306 (memq (car-safe e)
307 (pop exps))) 307 '(:documentation declare interactive cl-declare)))))
308 ,@exps)) 308 (push (pop body) decls))
309 (cons (nreverse decls) body)))
309 310
310(defun macroexp-progn (exps) 311(defun macroexp-progn (exps)
311 "Return an expression equivalent to `(progn ,@EXPS)." 312 "Return an expression equivalent to `(progn ,@EXPS)."
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 057b12894f9..4706be5e57c 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -180,7 +180,7 @@ like `(,a . ,(pred (< a))) or, with more checks:
180 (when (eq nil (car (last pats 2))) 180 (when (eq nil (car (last pats 2)))
181 (setq pats (append (butlast pats 2) (car (last pats))))) 181 (setq pats (append (butlast pats 2) (car (last pats)))))
182 `(lambda (&rest ,args) 182 `(lambda (&rest ,args)
183 ,@(remq nil (car body)) 183 ,@(car body)
184 (pcase ,args 184 (pcase ,args
185 (,(list '\` pats) . ,(cdr body)))))) 185 (,(list '\` pats) . ,(cdr body))))))
186 186