]> git.eshelyaron.com Git - emacs.git/commitdiff
Flatten nested `concat` calls
authorMattias Engdegård <mattiase@acm.org>
Wed, 8 Feb 2023 12:45:57 +0000 (13:45 +0100)
committerMattias Engdegård <mattiase@acm.org>
Wed, 8 Feb 2023 12:45:57 +0000 (13:45 +0100)
* lisp/emacs-lisp/byte-opt.el (byte-optimize-concat):
Flatten nested forms; concat is associative.  This reduces the number
of calls and may coalesce adjacent constant strings.

lisp/emacs-lisp/byte-opt.el

index b7e21db688ff460e5bdd57229637f2b9ed41aadf..3eef8f385b5f8a4c42fac1c1e1e809391c5cb8a8 100644 (file)
@@ -1132,21 +1132,31 @@ See Info node `(elisp) Integer Basics'."
     form))
 
 (defun byte-optimize-concat (form)
-  "Merge adjacent constant arguments to `concat'."
+  "Merge adjacent constant arguments to `concat' and flatten nested forms."
   (let ((args (cdr form))
         (newargs nil))
     (while args
-      (let ((strings nil)
-            val)
-        (while (and args (macroexp-const-p (car args))
-                    (progn
-                      (setq val (byteopt--eval-const (car args)))
-                      (and (or (stringp val)
-                               (and (or (listp val) (vectorp val))
-                                    (not (memq nil
-                                               (mapcar #'characterp val))))))))
-          (push val strings)
-          (setq args (cdr args)))
+      (let ((strings nil))
+        (while
+            (and args
+                 (let ((arg (car args)))
+                   (pcase arg
+                     ;; Merge consecutive constant arguments.
+                     ((pred macroexp-const-p)
+                      (let ((val (byteopt--eval-const arg)))
+                        (and (or (stringp val)
+                                 (and (or (listp val) (vectorp val))
+                                      (not (memq nil
+                                                 (mapcar #'characterp val)))))
+                             (progn
+                               (push val strings)
+                               (setq args (cdr args))
+                               t))))
+                     ;; Flatten nested `concat' form.
+                     (`(concat . ,nested-args)
+                      (setq args (append nested-args (cdr args)))
+                      t)))))
+
         (when strings
           (let ((s (apply #'concat (nreverse strings))))
             (when (not (zerop (length s)))