]> git.eshelyaron.com Git - emacs.git/commitdiff
Tighter pcase or-pattern member function selection (bug#36139)
authorMattias Engdegård <mattiase@acm.org>
Tue, 21 May 2019 10:19:38 +0000 (12:19 +0200)
committerMattias Engdegård <mattiase@acm.org>
Wed, 19 Jun 2019 09:20:58 +0000 (11:20 +0200)
* lisp/emacs-lisp/pcase.el (pcase--u1):
Use the most specific of `memq', `memql' and `member' in or-patterns
with constant cases.  This improves performance and may help the byte-code
compiler generate a switch.
* test/lisp/emacs-lisp/pcase-tests.el (pcase-tests-member):
Add mixed-type or-pattern test cases.

lisp/emacs-lisp/pcase.el
test/lisp/emacs-lisp/pcase-tests.el

index a644453a94821a351c4b94afca0a7d54ae4a1c93..ae2cf8eb02fcef0a8e6b51a845272e9dc2263da3 100644 (file)
@@ -785,25 +785,26 @@ Otherwise, it defers to REST which is a list of branches of the form
    ((eq 'or (caar matches))
     (let* ((alts (cdar matches))
            (var (if (eq (caar alts) 'match) (cadr (car alts))))
-           (simples '()) (others '()) (memql-ok t))
+           (simples '()) (others '()) (mem-fun 'memq))
       (when var
         (dolist (alt alts)
           (if (and (eq (car alt) 'match) (eq var (cadr alt))
                    (let ((upat (cddr alt)))
                      (eq (car-safe upat) 'quote)))
               (let ((val (cadr (cddr alt))))
-                (unless (or (integerp val) (symbolp val))
-                  (setq memql-ok nil))
-                (push (cadr (cddr alt)) simples))
+                (cond ((integerp val)
+                       (when (eq mem-fun 'memq)
+                         (setq mem-fun 'memql)))
+                      ((not (symbolp val))
+                       (setq mem-fun 'member)))
+                (push val simples))
             (push alt others))))
       (cond
        ((null alts) (error "Please avoid it") (pcase--u rest))
        ;; Yes, we can use `memql' (or `member')!
        ((> (length simples) 1)
         (pcase--u1 (cons `(match ,var
-                                 . (pred (pcase--flip
-                                          ,(if memql-ok #'memql #'member)
-                                          ',simples)))
+                                 . (pred (pcase--flip ,mem-fun ',simples)))
                          (cdr matches))
                    code vars
                    (if (null others) rest
index af8c9a3f3c39fcbbe851d7fc746462473f548a0d..e8c0b8219c53347d1a038a6ba5dd5e765c3b5ac5 100644 (file)
 
 (ert-deftest pcase-tests-member ()
   (should (pcase-tests-grep
-           'memql (macroexpand-all '(pcase x ((or 1 2 3) body)))))
+           'memq (macroexpand-all '(pcase x ((or 'a 'b 'c) body)))))
   (should (pcase-tests-grep
-           'member (macroexpand-all '(pcase x ((or "a" 2 3) body)))))
+           'memql (macroexpand-all '(pcase x ((or 1 2 3 'a) body)))))
+  (should (pcase-tests-grep
+           'member (macroexpand-all '(pcase x ((or "a" 2 3 'a) body)))))
   (should-not (pcase-tests-grep
                'memq (macroexpand-all '(pcase x ((or "a" 2 3) body)))))
   (should-not (pcase-tests-grep