aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/ChangeLog8
-rw-r--r--lisp/emacs-lisp/lisp-mode.el2
-rw-r--r--lisp/emacs-lisp/macroexp.el10
-rw-r--r--lisp/emacs-lisp/pcase.el20
4 files changed, 39 insertions, 1 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index ce381315b40..cd40ac7a259 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,11 @@
12015-02-09 Leo Liu <sdl.web@gmail.com>
2
3 * emacs-lisp/pcase.el (pcase-lambda): New Macro. (Bug#19814)
4
5 * emacs-lisp/lisp-mode.el (el-kws-re): Include `pcase-lambda'.
6
7 * emacs-lisp/macroexp.el (macroexp-parse-body): New function.
8
12015-02-08 Paul Eggert <eggert@cs.ucla.edu> 92015-02-08 Paul Eggert <eggert@cs.ucla.edu>
2 10
3 Port to platforms lacking test -a and -o 11 Port to platforms lacking test -a and -o
diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el
index 868a9578b0d..5d912097838 100644
--- a/lisp/emacs-lisp/lisp-mode.el
+++ b/lisp/emacs-lisp/lisp-mode.el
@@ -204,7 +204,7 @@
204 "defface")) 204 "defface"))
205 (el-tdefs '("defgroup" "deftheme")) 205 (el-tdefs '("defgroup" "deftheme"))
206 (el-kw '("while-no-input" "letrec" "pcase" "pcase-exhaustive" 206 (el-kw '("while-no-input" "letrec" "pcase" "pcase-exhaustive"
207 "pcase-let" "pcase-let*" "save-restriction" 207 "pcase-lambda" "pcase-let" "pcase-let*" "save-restriction"
208 "save-excursion" "save-selected-window" 208 "save-excursion" "save-selected-window"
209 ;; "eval-after-load" "eval-next-after-load" 209 ;; "eval-after-load" "eval-next-after-load"
210 "save-window-excursion" "save-current-buffer" 210 "save-window-excursion" "save-current-buffer"
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 797de9abb5b..b75c8cc50a7 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -297,6 +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)
301 "Parse EXPS into ((DOC DECLARE-FORM INTERACTIVE-FORM) . BODY)."
302 `((,(and (stringp (car exps))
303 (pop exps))
304 ,(and (eq (car-safe (car exps)) 'declare)
305 (pop exps))
306 ,(and (eq (car-safe (car exps)) 'interactive)
307 (pop exps)))
308 ,@exps))
309
300(defun macroexp-progn (exps) 310(defun macroexp-progn (exps)
301 "Return an expression equivalent to `(progn ,@EXPS)." 311 "Return an expression equivalent to `(progn ,@EXPS)."
302 (if (cdr exps) `(progn ,@exps) (car exps))) 312 (if (cdr exps) `(progn ,@exps) (car exps)))
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index b495793bee0..057b12894f9 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -164,6 +164,26 @@ like `(,a . ,(pred (< a))) or, with more checks:
164 ;; FIXME: Could we add the FILE:LINE data in the error message? 164 ;; FIXME: Could we add the FILE:LINE data in the error message?
165 exp (append cases `((,x (error "No clause matching `%S'" ,x))))))) 165 exp (append cases `((,x (error "No clause matching `%S'" ,x)))))))
166 166
167;;;###autoload
168(defmacro pcase-lambda (lambda-list &rest body)
169 "Like `lambda' but allow each argument to be a pattern.
170`&rest' argument is supported."
171 (declare (doc-string 2) (indent defun)
172 (debug ((&rest pcase-UPAT &optional ["&rest" pcase-UPAT]) body)))
173 (let ((args (make-symbol "args"))
174 (pats (mapcar (lambda (u)
175 (unless (eq u '&rest)
176 (if (eq (car-safe u) '\`) (cadr u) (list '\, u))))
177 lambda-list))
178 (body (macroexp-parse-body body)))
179 ;; Handle &rest
180 (when (eq nil (car (last pats 2)))
181 (setq pats (append (butlast pats 2) (car (last pats)))))
182 `(lambda (&rest ,args)
183 ,@(remq nil (car body))
184 (pcase ,args
185 (,(list '\` pats) . ,(cdr body))))))
186
167(defun pcase--let* (bindings body) 187(defun pcase--let* (bindings body)
168 (cond 188 (cond
169 ((null bindings) (macroexp-progn body)) 189 ((null bindings) (macroexp-progn body))