aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2013-01-08 17:26:21 -0500
committerStefan Monnier2013-01-08 17:26:21 -0500
commit4bdc352611db6d7e9a11e75693e94dce61377d2e (patch)
treeae53445dba1cb58811897565e23e0e35ad8786fe
parenta464813702e6c0af49d148ef3bc77e3727e148a1 (diff)
downloademacs-4bdc352611db6d7e9a11e75693e94dce61377d2e.tar.gz
emacs-4bdc352611db6d7e9a11e75693e94dce61377d2e.zip
* lisp/emacs-lisp/pcase.el (pcase--split-equal): Also take advantage if
the predicate returns nil.
-rw-r--r--lisp/ChangeLog3
-rw-r--r--lisp/emacs-lisp/pcase.el29
2 files changed, 18 insertions, 14 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 58dec6e41ec..92c071e1776 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,8 @@
12013-01-08 Stefan Monnier <monnier@iro.umontreal.ca> 12013-01-08 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * emacs-lisp/pcase.el (pcase--split-equal): Also take advantage if
4 the predicate returns nil.
5
3 * simple.el: Use lexical-binding. 6 * simple.el: Use lexical-binding.
4 (primitive-undo): Use pcase. 7 (primitive-undo): Use pcase.
5 (minibuffer-history-isearch-push-state): Use a closure. 8 (minibuffer-history-isearch-push-state): Use a closure.
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 69834810d11..e000c343721 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -431,30 +431,31 @@ MATCH is the pattern that needs to be matched, of the form:
431 (match ,symd . ,(pcase--upat (cdr qpat)))) 431 (match ,symd . ,(pcase--upat (cdr qpat))))
432 :pcase--fail))) 432 :pcase--fail)))
433 ;; A QPattern but not for a cons, can only go to the `else' side. 433 ;; A QPattern but not for a cons, can only go to the `else' side.
434 ((eq (car-safe pat) '\`) (cons :pcase--fail nil)) 434 ((eq (car-safe pat) '\`) '(:pcase--fail . nil))
435 ((and (eq (car-safe pat) 'pred) 435 ((and (eq (car-safe pat) 'pred)
436 (or (member (cons 'consp (cadr pat)) 436 (or (member (cons 'consp (cadr pat))
437 pcase-mutually-exclusive-predicates) 437 pcase-mutually-exclusive-predicates)
438 (member (cons (cadr pat) 'consp) 438 (member (cons (cadr pat) 'consp)
439 pcase-mutually-exclusive-predicates))) 439 pcase-mutually-exclusive-predicates)))
440 (cons :pcase--fail nil)))) 440 '(:pcase--fail . nil))))
441 441
442(defun pcase--split-equal (elem pat) 442(defun pcase--split-equal (elem pat)
443 (cond 443 (cond
444 ;; The same match will give the same result. 444 ;; The same match will give the same result.
445 ((and (eq (car-safe pat) '\`) (equal (cadr pat) elem)) 445 ((and (eq (car-safe pat) '\`) (equal (cadr pat) elem))
446 (cons :pcase--succeed :pcase--fail)) 446 '(:pcase--succeed . :pcase--fail))
447 ;; A different match will fail if this one succeeds. 447 ;; A different match will fail if this one succeeds.
448 ((and (eq (car-safe pat) '\`) 448 ((and (eq (car-safe pat) '\`)
449 ;; (or (integerp (cadr pat)) (symbolp (cadr pat)) 449 ;; (or (integerp (cadr pat)) (symbolp (cadr pat))
450 ;; (consp (cadr pat))) 450 ;; (consp (cadr pat)))
451 ) 451 )
452 (cons :pcase--fail nil)) 452 '(:pcase--fail . nil))
453 ((and (eq (car-safe pat) 'pred) 453 ((and (eq (car-safe pat) 'pred)
454 (symbolp (cadr pat)) 454 (symbolp (cadr pat))
455 (get (cadr pat) 'side-effect-free) 455 (get (cadr pat) 'side-effect-free))
456 (funcall (cadr pat) elem)) 456 (if (funcall (cadr pat) elem)
457 (cons :pcase--succeed nil)))) 457 '(:pcase--succeed . nil)
458 '(:pcase--fail . nil)))))
458 459
459(defun pcase--split-member (elems pat) 460(defun pcase--split-member (elems pat)
460 ;; Based on pcase--split-equal. 461 ;; Based on pcase--split-equal.
@@ -462,7 +463,7 @@ MATCH is the pattern that needs to be matched, of the form:
462 ;; The same match (or a match of membership in a superset) will 463 ;; The same match (or a match of membership in a superset) will
463 ;; give the same result, but we don't know how to check it. 464 ;; give the same result, but we don't know how to check it.
464 ;; (??? 465 ;; (???
465 ;; (cons :pcase--succeed nil)) 466 ;; '(:pcase--succeed . nil))
466 ;; A match for one of the elements may succeed or fail. 467 ;; A match for one of the elements may succeed or fail.
467 ((and (eq (car-safe pat) '\`) (member (cadr pat) elems)) 468 ((and (eq (car-safe pat) '\`) (member (cadr pat) elems))
468 nil) 469 nil)
@@ -471,7 +472,7 @@ MATCH is the pattern that needs to be matched, of the form:
471 ;; (or (integerp (cadr pat)) (symbolp (cadr pat)) 472 ;; (or (integerp (cadr pat)) (symbolp (cadr pat))
472 ;; (consp (cadr pat))) 473 ;; (consp (cadr pat)))
473 ) 474 )
474 (cons :pcase--fail nil)) 475 '(:pcase--fail . nil))
475 ((and (eq (car-safe pat) 'pred) 476 ((and (eq (car-safe pat) 'pred)
476 (symbolp (cadr pat)) 477 (symbolp (cadr pat))
477 (get (cadr pat) 'side-effect-free) 478 (get (cadr pat) 'side-effect-free)
@@ -479,21 +480,21 @@ MATCH is the pattern that needs to be matched, of the form:
479 (dolist (elem elems) 480 (dolist (elem elems)
480 (unless (funcall p elem) (setq all nil))) 481 (unless (funcall p elem) (setq all nil)))
481 all)) 482 all))
482 (cons :pcase--succeed nil)))) 483 '(:pcase--succeed . nil))))
483 484
484(defun pcase--split-pred (upat pat) 485(defun pcase--split-pred (upat pat)
485 ;; FIXME: For predicates like (pred (> a)), two such predicates may 486 ;; FIXME: For predicates like (pred (> a)), two such predicates may
486 ;; actually refer to different variables `a'. 487 ;; actually refer to different variables `a'.
487 (let (test) 488 (let (test)
488 (cond 489 (cond
489 ((equal upat pat) (cons :pcase--succeed :pcase--fail)) 490 ((equal upat pat) '(:pcase--succeed . :pcase--fail))
490 ((and (eq 'pred (car upat)) 491 ((and (eq 'pred (car upat))
491 (eq 'pred (car-safe pat)) 492 (eq 'pred (car-safe pat))
492 (or (member (cons (cadr upat) (cadr pat)) 493 (or (member (cons (cadr upat) (cadr pat))
493 pcase-mutually-exclusive-predicates) 494 pcase-mutually-exclusive-predicates)
494 (member (cons (cadr pat) (cadr upat)) 495 (member (cons (cadr pat) (cadr upat))
495 pcase-mutually-exclusive-predicates))) 496 pcase-mutually-exclusive-predicates)))
496 (cons :pcase--fail nil)) 497 '(:pcase--fail . nil))
497 ((and (eq 'pred (car upat)) 498 ((and (eq 'pred (car upat))
498 (eq '\` (car-safe pat)) 499 (eq '\` (car-safe pat))
499 (symbolp (cadr upat)) 500 (symbolp (cadr upat))
@@ -502,8 +503,8 @@ MATCH is the pattern that needs to be matched, of the form:
502 (ignore-errors 503 (ignore-errors
503 (setq test (list (funcall (cadr upat) (cadr pat)))))) 504 (setq test (list (funcall (cadr upat) (cadr pat))))))
504 (if (car test) 505 (if (car test)
505 (cons nil :pcase--fail) 506 '(nil . :pcase--fail)
506 (cons :pcase--fail nil)))))) 507 '(:pcase--fail . nil))))))
507 508
508(defun pcase--fgrep (vars sexp) 509(defun pcase--fgrep (vars sexp)
509 "Check which of the symbols VARS appear in SEXP." 510 "Check which of the symbols VARS appear in SEXP."