diff options
| author | Leo Liu | 2015-02-09 10:05:44 +0800 |
|---|---|---|
| committer | Leo Liu | 2015-02-09 10:05:44 +0800 |
| commit | 751adc4b9631cedcf9bec475afe40da4db7d74a1 (patch) | |
| tree | db7eaca97d1312b5b0592b67e6b134fda51502ea | |
| parent | fd6f7d1449c8496ab5c019d2aad7ca5e2980713a (diff) | |
| download | emacs-751adc4b9631cedcf9bec475afe40da4db7d74a1.tar.gz emacs-751adc4b9631cedcf9bec475afe40da4db7d74a1.zip | |
Add macro pcase-lambda
Fixes: debbugs:19814
* emacs-lisp/lisp-mode.el (el-kws-re): Include `pcase-lambda'.
* emacs-lisp/macroexp.el (macroexp-parse-body): New function.
* emacs-lisp/pcase.el (pcase-lambda): New Macro.
| -rw-r--r-- | lisp/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/emacs-lisp/lisp-mode.el | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/macroexp.el | 10 | ||||
| -rw-r--r-- | lisp/emacs-lisp/pcase.el | 20 |
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 @@ | |||
| 1 | 2015-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 | |||
| 1 | 2015-02-08 Paul Eggert <eggert@cs.ucla.edu> | 9 | 2015-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)) |