aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/emacs-lisp/cl-macs.el1
-rw-r--r--lisp/emacs-lisp/eieio.el1
-rw-r--r--lisp/emacs-lisp/pcase.el38
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'.
2780Elements of FIELDS can be of the form (NAME UPAT) in which case the contents of 2780Elements of FIELDS can be of the form (NAME UPAT) in which case the contents of
2781field NAME is matched against UPAT, or they can be of the form NAME which 2781field NAME is matched against UPAT, or they can be of the form NAME which
2782is a shorthand for (NAME NAME)." 2782is 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."
348Elements of FIELDS can be of the form (NAME UPAT) in which case the contents of 348Elements of FIELDS can be of the form (NAME UPAT) in which case the contents of
349field NAME is matched against UPAT, or they can be of the form NAME which 349field NAME is matched against UPAT, or they can be of the form NAME which
350is a shorthand for (NAME NAME)." 350is 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.
838QPAT can take the following forms: 853QPAT 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)