diff options
| author | Stefan Monnier | 2014-09-22 11:04:12 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2014-09-22 11:04:12 -0400 |
| commit | 536cda1f84f3be1959e5a475e51dbecaa2253bfd (patch) | |
| tree | b6dfd400c6f4b13d5a8ce9442c52f26df948986b | |
| parent | 13b1840d23f1f214bec11a3c6823d675cbd82f28 (diff) | |
| download | emacs-536cda1f84f3be1959e5a475e51dbecaa2253bfd.tar.gz emacs-536cda1f84f3be1959e5a475e51dbecaa2253bfd.zip | |
* lisp/emacs-lisp/pcase.el (pcase-defmacro): New macro.
(pcase--macroexpand): New function.
(pcase--expand): Use it.
| -rw-r--r-- | etc/NEWS | 1 | ||||
| -rw-r--r-- | lisp/ChangeLog | 4 | ||||
| -rw-r--r-- | lisp/emacs-lisp/pcase.el | 27 |
3 files changed, 31 insertions, 1 deletions
| @@ -104,6 +104,7 @@ performance improvements when pasting large amounts of text. | |||
| 104 | 104 | ||
| 105 | ** pcase | 105 | ** pcase |
| 106 | *** New UPatterns `quote' and `app'. | 106 | *** New UPatterns `quote' and `app'. |
| 107 | *** New UPatterns can be defined with `pcase-defmacro'. | ||
| 107 | 108 | ||
| 108 | ** Lisp mode | 109 | ** Lisp mode |
| 109 | *** Strings after `:documentation' are highlighted as docstrings. | 110 | *** Strings after `:documentation' are highlighted as docstrings. |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 1aad2004d6a..32843569eda 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,9 @@ | |||
| 1 | 2014-09-22 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2014-09-22 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * emacs-lisp/pcase.el (pcase-defmacro): New macro. | ||
| 4 | (pcase--macroexpand): New function. | ||
| 5 | (pcase--expand): Use it. | ||
| 6 | |||
| 3 | Add support for `quote' and `app'. | 7 | Add support for `quote' and `app'. |
| 4 | * emacs-lisp/pcase.el (pcase--app-subst-match, pcase--app-subst-rest): | 8 | * emacs-lisp/pcase.el (pcase--app-subst-match, pcase--app-subst-rest): |
| 5 | New optimization functions. | 9 | New optimization functions. |
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index fbe241b6fc8..2d5f19fe5f7 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el | |||
| @@ -284,7 +284,7 @@ of the form (UPAT EXP)." | |||
| 284 | (main | 284 | (main |
| 285 | (pcase--u | 285 | (pcase--u |
| 286 | (mapcar (lambda (case) | 286 | (mapcar (lambda (case) |
| 287 | `((match ,val . ,(car case)) | 287 | `((match ,val . ,(pcase--macroexpand (car case))) |
| 288 | ,(lambda (vars) | 288 | ,(lambda (vars) |
| 289 | (unless (memq case used-cases) | 289 | (unless (memq case used-cases) |
| 290 | ;; Keep track of the cases that are used. | 290 | ;; Keep track of the cases that are used. |
| @@ -303,6 +303,31 @@ of the form (UPAT EXP)." | |||
| 303 | (message "Redundant pcase pattern: %S" (car case)))) | 303 | (message "Redundant pcase pattern: %S" (car case)))) |
| 304 | (macroexp-let* defs main)))) | 304 | (macroexp-let* defs main)))) |
| 305 | 305 | ||
| 306 | (defun pcase--macroexpand (pat) | ||
| 307 | "Expands all macro-patterns in PAT." | ||
| 308 | (let ((head (car-safe pat))) | ||
| 309 | (cond | ||
| 310 | ((memq head '(nil pred guard quote)) pat) | ||
| 311 | ((memq head '(or and)) `(,head ,@(mapcar #'pcase--macroexpand (cdr pat)))) | ||
| 312 | ((eq head 'let) `(let ,(pcase--macroexpand (cadr pat)) ,@(cddr pat))) | ||
| 313 | ((eq head 'app) `(app ,(nth 1 pat) ,(pcase--macroexpand (nth 2 pat)))) | ||
| 314 | (t | ||
| 315 | (let* ((expander (get head 'pcase-macroexpander)) | ||
| 316 | (npat (if expander (apply expander (cdr pat))))) | ||
| 317 | (if (null npat) | ||
| 318 | (error (if expander | ||
| 319 | "Unexpandable %s pattern: %S" | ||
| 320 | "Unknown %s pattern: %S") | ||
| 321 | head pat) | ||
| 322 | (pcase--macroexpand npat))))))) | ||
| 323 | |||
| 324 | ;;;###autoload | ||
| 325 | (defmacro pcase-defmacro (name args &rest body) | ||
| 326 | "Define a pcase UPattern macro." | ||
| 327 | (declare (indent 2) (debug (def-name sexp def-body)) (doc-string 3)) | ||
| 328 | `(put ',name 'pcase-macroexpander | ||
| 329 | (lambda ,args ,@body))) | ||
| 330 | |||
| 306 | (defun pcase-codegen (code vars) | 331 | (defun pcase-codegen (code vars) |
| 307 | ;; Don't use let*, otherwise macroexp-let* may merge it with some surrounding | 332 | ;; Don't use let*, otherwise macroexp-let* may merge it with some surrounding |
| 308 | ;; let* which might prevent the setcar/setcdr in pcase--expand's fancy | 333 | ;; let* which might prevent the setcar/setcdr in pcase--expand's fancy |