diff options
Diffstat (limited to 'lisp/emacs-lisp/pcase.el')
-rw-r--r-- | lisp/emacs-lisp/pcase.el | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index 0b46eb2a301..b922e0b0233 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el @@ -76,8 +76,8 @@ BODY should be an expression, and BINDINGS should be a list of bindings of the form (UPAT EXP)." (if (null bindings) body `(pcase ,(cadr (car bindings)) - (,(caar bindings) (plet* ,(cdr bindings) ,body)) - (t (error "Pattern match failure in `plet'"))))) + (,(caar bindings) (pcase-let* ,(cdr bindings) ,body)) + (t (error "Pattern match failure in `pcase-let'"))))) ;;;###autoload (defmacro pcase-let (bindings body) @@ -85,13 +85,14 @@ of the form (UPAT EXP)." BODY should be an expression, and BINDINGS should be a list of bindings of the form (UPAT EXP)." (if (null (cdr bindings)) - `(plet* ,bindings ,body) + `(pcase-let* ,bindings ,body) (setq bindings (mapcar (lambda (x) (cons (make-symbol "x") x)) bindings)) `(let ,(mapcar (lambda (binding) (list (nth 0 binding) (nth 2 binding))) bindings) - (plet* ,(mapcar (lambda (binding) (list (nth 1 binding) (nth 0 binding))) - bindings) - ,body)))) + (pcase-let* + ,(mapcar (lambda (binding) (list (nth 1 binding) (nth 0 binding))) + bindings) + ,body)))) (defun pcase-expand (exp cases) (let* ((defs (if (symbolp exp) '() @@ -290,9 +291,13 @@ MATCH is the pattern that needs to be matched, of the form: (defun pcase-split-memq (elems pat) ;; Based on pcase-split-eq. (cond - ;; The same match will give the same result. + ;; The same match will give the same result, but we don't know how + ;; to check it. + ;; (??? + ;; (cons :pcase-succeed nil)) + ;; A match for one of the elements may succeed or fail. ((and (eq (car-safe pat) '\`) (member (cadr pat) elems)) - (cons :pcase-succeed nil)) + nil) ;; A different match will fail if this one succeeds. ((and (eq (car-safe pat) '\`) ;; (or (integerp (cadr pat)) (symbolp (cadr pat)) @@ -383,18 +388,20 @@ and otherwise defers to REST which is a list of branches of the form `(,(cadr upat) ,sym) (let* ((exp (cadr upat)) ;; `vs' is an upper bound on the vars we need. - (vs (pcase-fgrep (mapcar #'car vars) exp))) - (if vs - ;; Let's not replace `vars' in `exp' since it's - ;; too difficult to do it right, instead just - ;; let-bind `vars' around `exp'. - `(let ,(mapcar (lambda (var) - (list var (cdr (assq var vars)))) - vs) - ;; FIXME: `vars' can capture `sym'. E.g. - ;; (pcase x ((and `(,x . ,y) (pred (fun x))))) - (,@exp ,sym)) - `(,@exp ,sym)))) + (vs (pcase-fgrep (mapcar #'car vars) exp)) + (call (if (functionp exp) + `(,exp ,sym) `(,@exp ,sym)))) + (if (null vs) + call + ;; Let's not replace `vars' in `exp' since it's + ;; too difficult to do it right, instead just + ;; let-bind `vars' around `exp'. + `(let ,(mapcar (lambda (var) + (list var (cdr (assq var vars)))) + vs) + ;; FIXME: `vars' can capture `sym'. E.g. + ;; (pcase x ((and `(,x . ,y) (pred (fun x))))) + ,call)))) (pcase-u1 matches code vars then-rest) (pcase-u else-rest)))) ((symbolp upat) |