]> code.delx.au - gnu-emacs/commitdiff
Add macro pcase-lambda
authorLeo Liu <sdl.web@gmail.com>
Mon, 9 Feb 2015 02:05:44 +0000 (10:05 +0800)
committerLeo Liu <sdl.web@gmail.com>
Mon, 9 Feb 2015 02:05:44 +0000 (10:05 +0800)
Fixes: debbugs:19814
* emacs-lisp/lisp-mode.el (el-kws-re): Include `pcase-lambda'.

* emacs-lisp/macroexp.el (macroexp-parse-body): New function.

* emacs-lisp/pcase.el (pcase-lambda): New Macro.

lisp/ChangeLog
lisp/emacs-lisp/lisp-mode.el
lisp/emacs-lisp/macroexp.el
lisp/emacs-lisp/pcase.el

index ce381315b40c00d4cfd5f3412c2036bd71a9200b..cd40ac7a259756436e384aacc5ccdf2ffe6858b9 100644 (file)
@@ -1,3 +1,11 @@
+2015-02-09  Leo Liu  <sdl.web@gmail.com>
+
+       * emacs-lisp/pcase.el (pcase-lambda): New Macro.  (Bug#19814)
+
+       * emacs-lisp/lisp-mode.el (el-kws-re): Include `pcase-lambda'.
+
+       * emacs-lisp/macroexp.el (macroexp-parse-body): New function.
+
 2015-02-08  Paul Eggert  <eggert@cs.ucla.edu>
 
        Port to platforms lacking test -a and -o
index 868a9578b0d8a19a51fe726e17ddc08daca776f4..5d912097838e79b094a38cd836f531cf752a3f30 100644 (file)
                           "defface"))
               (el-tdefs '("defgroup" "deftheme"))
               (el-kw '("while-no-input" "letrec" "pcase" "pcase-exhaustive"
-                       "pcase-let" "pcase-let*" "save-restriction"
+                       "pcase-lambda" "pcase-let" "pcase-let*" "save-restriction"
                        "save-excursion" "save-selected-window"
                        ;; "eval-after-load" "eval-next-after-load"
                        "save-window-excursion" "save-current-buffer"
index 797de9abb5bb7edb56a7b22b8d08a44610156897..b75c8cc50a74ef7986339301d1b575399c180004 100644 (file)
@@ -297,6 +297,16 @@ definitions to shadow the loaded ones for use in file byte-compilation."
 
 ;;; Handy functions to use in macros.
 
+(defun macroexp-parse-body (exps)
+  "Parse EXPS into ((DOC DECLARE-FORM INTERACTIVE-FORM) . BODY)."
+  `((,(and (stringp (car exps))
+           (pop exps))
+     ,(and (eq (car-safe (car exps)) 'declare)
+           (pop exps))
+     ,(and (eq (car-safe (car exps)) 'interactive)
+           (pop exps)))
+    ,@exps))
+
 (defun macroexp-progn (exps)
   "Return an expression equivalent to `(progn ,@EXPS)."
   (if (cdr exps) `(progn ,@exps) (car exps)))
index b495793bee02dad7540dfef1bf3294bc50e8ae83..057b12894f9fa49f04b74d59d13a06961dd5deae 100644 (file)
@@ -164,6 +164,26 @@ like `(,a . ,(pred (< a))) or, with more checks:
      ;; FIXME: Could we add the FILE:LINE data in the error message?
      exp (append cases `((,x (error "No clause matching `%S'" ,x)))))))
 
+;;;###autoload
+(defmacro pcase-lambda (lambda-list &rest body)
+  "Like `lambda' but allow each argument to be a pattern.
+`&rest' argument is supported."
+  (declare (doc-string 2) (indent defun)
+           (debug ((&rest pcase-UPAT &optional ["&rest" pcase-UPAT]) body)))
+  (let ((args (make-symbol "args"))
+        (pats (mapcar (lambda (u)
+                        (unless (eq u '&rest)
+                          (if (eq (car-safe u) '\`) (cadr u) (list '\, u))))
+                      lambda-list))
+        (body (macroexp-parse-body body)))
+    ;; Handle &rest
+    (when (eq nil (car (last pats 2)))
+      (setq pats (append (butlast pats 2) (car (last pats)))))
+    `(lambda (&rest ,args)
+       ,@(remq nil (car body))
+       (pcase ,args
+         (,(list '\` pats) . ,(cdr body))))))
+
 (defun pcase--let* (bindings body)
   (cond
    ((null bindings) (macroexp-progn body))