emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Question on pcase


From: Johan Bockgård
Subject: Re: Question on pcase
Date: Wed, 28 Oct 2015 00:50:44 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

Michael Heerdegen <address@hidden> writes:

> The only thing that makes sense to me would be to make `edebug' let you
> step into a pattern.  AFAICT that would be a very hard work.

Edebug already understands most of pcase's patterns, but it doesn't step
"into" the SYMBOL bindings.

Try this:

    pcase.el: Support edebug stepping of SYMBOL patterns

    * lisp/emacs-lisp/pcase.el (pcase-SYMBOL) New edebug spec.
    (pcase-PAT): Use it.
    (pcase--edebug-match-symbol): New function.
    (pcase-QPAT): Improve handling of cons patterns.

diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 8bcb447..3ea519c 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -70,31 +70,20 @@ (defconst pcase--dontcare-upats '(t _ pcase--dontcare))
 
 (defvar pcase--dontwarn-upats '(pcase--dontcare))
 
-(def-edebug-spec
-  pcase-PAT
-  (&or symbolp
-       ("or" &rest pcase-PAT)
-       ("and" &rest pcase-PAT)
-       ("guard" form)
-       ("let" pcase-PAT form)
-       ("pred" pcase-FUN)
-       ("app" pcase-FUN pcase-PAT)
-       pcase-MACRO
-       sexp))
-
-(def-edebug-spec
-  pcase-FUN
-  (&or lambda-expr
-       ;; Punt on macros/special forms.
-       (functionp &rest form)
-       sexp))
-
-(def-edebug-spec pcase-MACRO pcase--edebug-match-macro)
-
 ;; Only called from edebug.
 (declare-function get-edebug-spec "edebug" (symbol))
 (declare-function edebug-match "edebug" (cursor specs))
+(declare-function edebug-no-match "edebug" (cursor &rest args))
+(declare-function edebug-top-element-required "edebug" (cursor &rest error))
 
+(def-edebug-spec pcase-SYMBOL pcase--edebug-match-symbol)
+(defun pcase--edebug-match-symbol (cursor)
+  (let ((sexp (edebug-top-element-required cursor "Expected" '(symbolp))))
+    (if (or (not (symbolp sexp)) (keywordp sexp))
+       (edebug-no-match cursor "Expected" '(symbolp))
+      (list `(and ,sexp (let _ ,(car (edebug-match cursor '(form)))))))))
+
+(def-edebug-spec pcase-MACRO pcase--edebug-match-macro)
 (defun pcase--edebug-match-macro (cursor)
   (let (specs)
     (mapatoms
@@ -105,6 +94,26 @@ (defun pcase--edebug-match-macro (cursor)
                 specs)))))
     (edebug-match cursor (cons '&or specs))))
 
+(def-edebug-spec
+  pcase-FUN
+  (&or lambda-expr
+       ;; Punt on macros/special forms.
+       (functionp &rest form)
+       sexp))
+
+(def-edebug-spec
+  pcase-PAT
+  (&or "_"
+       pcase-SYMBOL
+       ("or" &rest pcase-PAT)
+       ("and" &rest pcase-PAT)
+       ("guard" form)
+       ("let" pcase-PAT form)
+       ("pred" pcase-FUN)
+       ("app" pcase-FUN pcase-PAT)
+       pcase-MACRO
+       sexp))
+
 ;;;###autoload
 (defmacro pcase (exp &rest cases)
   "Perform ML-style pattern matching on EXP.
@@ -865,8 +874,10 @@ (defun pcase--u1 (matches code vars rest)
 
 (def-edebug-spec
   pcase-QPAT
+  ;; Cf. edebug spec for `backquote-form' in edebug.el.
   (&or ("," pcase-PAT)
-       (pcase-QPAT . pcase-QPAT)
+       (pcase-QPAT [&rest [&not ","] pcase-QPAT]
+                  . [&or nil pcase-QPAT])
        (vector &rest pcase-QPAT)
        sexp))
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]