diff options
| -rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 1 | ||||
| -rw-r--r-- | lisp/emacs-lisp/eieio.el | 1 | ||||
| -rw-r--r-- | lisp/emacs-lisp/pcase.el | 38 |
3 files changed, 29 insertions, 11 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 69f2792f4bd..41435b8b7b1 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -2780,6 +2780,7 @@ non-nil value, that slot cannot be set via `setf'. | |||
| 2780 | Elements of FIELDS can be of the form (NAME UPAT) in which case the contents of | 2780 | Elements of FIELDS can be of the form (NAME UPAT) in which case the contents of |
| 2781 | field NAME is matched against UPAT, or they can be of the form NAME which | 2781 | field NAME is matched against UPAT, or they can be of the form NAME which |
| 2782 | is a shorthand for (NAME NAME)." | 2782 | is a shorthand for (NAME NAME)." |
| 2783 | (declare (debug (sexp &rest [&or (sexp pcase-UPAT) sexp]))) | ||
| 2783 | `(and (pred (pcase--flip cl-typep ',type)) | 2784 | `(and (pred (pcase--flip cl-typep ',type)) |
| 2784 | ,@(mapcar | 2785 | ,@(mapcar |
| 2785 | (lambda (field) | 2786 | (lambda (field) |
diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index bca53c0c892..111459509bc 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el | |||
| @@ -348,6 +348,7 @@ variable name of the same name as the slot." | |||
| 348 | Elements of FIELDS can be of the form (NAME UPAT) in which case the contents of | 348 | Elements of FIELDS can be of the form (NAME UPAT) in which case the contents of |
| 349 | field NAME is matched against UPAT, or they can be of the form NAME which | 349 | field NAME is matched against UPAT, or they can be of the form NAME which |
| 350 | is a shorthand for (NAME NAME)." | 350 | is a shorthand for (NAME NAME)." |
| 351 | (declare (debug (&rest [&or (sexp pcase-UPAT) sexp]))) | ||
| 351 | (let ((is (make-symbol "table"))) | 352 | (let ((is (make-symbol "table"))) |
| 352 | ;; FIXME: This generates a horrendous mess of redundant let bindings. | 353 | ;; FIXME: This generates a horrendous mess of redundant let bindings. |
| 353 | ;; `pcase' needs to be improved somehow to introduce let-bindings more | 354 | ;; `pcase' needs to be improved somehow to introduce let-bindings more |
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index bbb278c863e..49603036ead 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el | |||
| @@ -75,18 +75,11 @@ | |||
| 75 | (&or symbolp | 75 | (&or symbolp |
| 76 | ("or" &rest pcase-UPAT) | 76 | ("or" &rest pcase-UPAT) |
| 77 | ("and" &rest pcase-UPAT) | 77 | ("and" &rest pcase-UPAT) |
| 78 | ("`" pcase-QPAT) | ||
| 79 | ("guard" form) | 78 | ("guard" form) |
| 80 | ("let" pcase-UPAT form) | 79 | ("let" pcase-UPAT form) |
| 81 | ("pred" pcase-FUN) | 80 | ("pred" pcase-FUN) |
| 82 | ("app" pcase-FUN pcase-UPAT) | 81 | ("app" pcase-FUN pcase-UPAT) |
| 83 | sexp)) | 82 | pcase-MACRO |
| 84 | |||
| 85 | (def-edebug-spec | ||
| 86 | pcase-QPAT | ||
| 87 | (&or ("," pcase-UPAT) | ||
| 88 | (pcase-QPAT . pcase-QPAT) | ||
| 89 | (vector &rest pcase-QPAT) | ||
| 90 | sexp)) | 83 | sexp)) |
| 91 | 84 | ||
| 92 | (def-edebug-spec | 85 | (def-edebug-spec |
| @@ -96,6 +89,18 @@ | |||
| 96 | (functionp &rest form) | 89 | (functionp &rest form) |
| 97 | sexp)) | 90 | sexp)) |
| 98 | 91 | ||
| 92 | (def-edebug-spec pcase-MACRO pcase--edebug-match-macro) | ||
| 93 | |||
| 94 | (defun pcase--edebug-match-macro (cursor) | ||
| 95 | (let (specs) | ||
| 96 | (mapatoms | ||
| 97 | (lambda (s) | ||
| 98 | (let ((m (get s 'pcase-macroexpander))) | ||
| 99 | (when (and m (get-edebug-spec m)) | ||
| 100 | (push (cons (symbol-name s) (get-edebug-spec m)) | ||
| 101 | specs))))) | ||
| 102 | (edebug-match cursor (cons '&or specs)))) | ||
| 103 | |||
| 99 | ;;;###autoload | 104 | ;;;###autoload |
| 100 | (defmacro pcase (exp &rest cases) | 105 | (defmacro pcase (exp &rest cases) |
| 101 | "Perform ML-style pattern matching on EXP. | 106 | "Perform ML-style pattern matching on EXP. |
| @@ -367,11 +372,14 @@ of the form (UPAT EXP)." | |||
| 367 | (defmacro pcase-defmacro (name args &rest body) | 372 | (defmacro pcase-defmacro (name args &rest body) |
| 368 | "Define a pcase UPattern macro." | 373 | "Define a pcase UPattern macro." |
| 369 | (declare (indent 2) (debug defun) (doc-string 3)) | 374 | (declare (indent 2) (debug defun) (doc-string 3)) |
| 370 | (let ((fsym (intern (format "%s--pcase-macroexpander" name)))) | 375 | ;; Add the function via `fsym', so that an autoload cookie placed |
| 371 | ;; Add the function via `fsym', so that an autoload cookie placed | 376 | ;; on a pcase-defmacro will cause the macro to be loaded on demand. |
| 372 | ;; on a pcase-defmacro will cause the macro to be loaded on demand. | 377 | (let ((fsym (intern (format "%s--pcase-macroexpander" name))) |
| 378 | (decl (assq 'declare body))) | ||
| 379 | (when decl (setq body (remove decl body))) | ||
| 373 | `(progn | 380 | `(progn |
| 374 | (defun ,fsym ,args ,@body) | 381 | (defun ,fsym ,args ,@body) |
| 382 | (put ',fsym 'edebug-form-spec ',(cadr (assq 'debug decl))) | ||
| 375 | (put ',name 'pcase-macroexpander #',fsym)))) | 383 | (put ',name 'pcase-macroexpander #',fsym)))) |
| 376 | 384 | ||
| 377 | (defun pcase--match (val upat) | 385 | (defun pcase--match (val upat) |
| @@ -833,6 +841,13 @@ Otherwise, it defers to REST which is a list of branches of the form | |||
| 833 | (t (error "Unknown internal pattern `%S'" upat))))) | 841 | (t (error "Unknown internal pattern `%S'" upat))))) |
| 834 | (t (error "Incorrect MATCH %S" (car matches))))) | 842 | (t (error "Incorrect MATCH %S" (car matches))))) |
| 835 | 843 | ||
| 844 | (def-edebug-spec | ||
| 845 | pcase-QPAT | ||
| 846 | (&or ("," pcase-UPAT) | ||
| 847 | (pcase-QPAT . pcase-QPAT) | ||
| 848 | (vector &rest pcase-QPAT) | ||
| 849 | sexp)) | ||
| 850 | |||
| 836 | (pcase-defmacro \` (qpat) | 851 | (pcase-defmacro \` (qpat) |
| 837 | "Backquote-style pcase patterns. | 852 | "Backquote-style pcase patterns. |
| 838 | QPAT can take the following forms: | 853 | QPAT can take the following forms: |
| @@ -842,6 +857,7 @@ QPAT can take the following forms: | |||
| 842 | ,UPAT matches if the UPattern UPAT matches. | 857 | ,UPAT matches if the UPattern UPAT matches. |
| 843 | STRING matches if the object is `equal' to STRING. | 858 | STRING matches if the object is `equal' to STRING. |
| 844 | ATOM matches if the object is `eq' to ATOM." | 859 | ATOM matches if the object is `eq' to ATOM." |
| 860 | (declare (debug (pcase-QPAT))) | ||
| 845 | (cond | 861 | (cond |
| 846 | ((eq (car-safe qpat) '\,) (cadr qpat)) | 862 | ((eq (car-safe qpat) '\,) (cadr qpat)) |
| 847 | ((vectorp qpat) | 863 | ((vectorp qpat) |