diff options
| author | Stefan Monnier | 2013-01-08 17:26:21 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2013-01-08 17:26:21 -0500 |
| commit | 4bdc352611db6d7e9a11e75693e94dce61377d2e (patch) | |
| tree | ae53445dba1cb58811897565e23e0e35ad8786fe | |
| parent | a464813702e6c0af49d148ef3bc77e3727e148a1 (diff) | |
| download | emacs-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/ChangeLog | 3 | ||||
| -rw-r--r-- | lisp/emacs-lisp/pcase.el | 29 |
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 @@ | |||
| 1 | 2013-01-08 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2013-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." |