aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier2015-10-28 13:59:42 -0400
committerStefan Monnier2015-10-28 13:59:42 -0400
commitd5ee655c1710a62e01513fd20256a7cf35d52167 (patch)
tree9d53dd575f27624e44ec3851b3012f621e50f44b /lisp
parent1f02cbea8b489ed7676110431aa36ad5abc47d9b (diff)
downloademacs-d5ee655c1710a62e01513fd20256a7cf35d52167.tar.gz
emacs-d5ee655c1710a62e01513fd20256a7cf35d52167.zip
* lisp/emacs-lisp/macroexp.el: Tweak macroexp-if optimizations
(macroexp-unprogn): Make sure we never return an empty list. (macroexp-if): Remove unused (and unsafe) optimization. Optimize (if A T (if B T E)) into (if (or A B) T E) instead, which does occur occasionally.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/emacs-lisp/macroexp.el38
1 files changed, 25 insertions, 13 deletions
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index 8bf49b01689..8983454d318 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -322,8 +322,9 @@ definitions to shadow the loaded ones for use in file byte-compilation."
322 (if (cdr exps) `(progn ,@exps) (car exps))) 322 (if (cdr exps) `(progn ,@exps) (car exps)))
323 323
324(defun macroexp-unprogn (exp) 324(defun macroexp-unprogn (exp)
325 "Turn EXP into a list of expressions to execute in sequence." 325 "Turn EXP into a list of expressions to execute in sequence.
326 (if (eq (car-safe exp) 'progn) (cdr exp) (list exp))) 326Never returns an empty list."
327 (if (eq (car-safe exp) 'progn) (or (cdr exp) '(nil)) (list exp)))
327 328
328(defun macroexp-let* (bindings exp) 329(defun macroexp-let* (bindings exp)
329 "Return an expression equivalent to `(let* ,bindings ,exp)." 330 "Return an expression equivalent to `(let* ,bindings ,exp)."
@@ -333,22 +334,33 @@ definitions to shadow the loaded ones for use in file byte-compilation."
333 (t `(let* ,bindings ,exp)))) 334 (t `(let* ,bindings ,exp))))
334 335
335(defun macroexp-if (test then else) 336(defun macroexp-if (test then else)
336 "Return an expression equivalent to `(if ,test ,then ,else)." 337 "Return an expression equivalent to `(if ,TEST ,THEN ,ELSE)."
337 (cond 338 (cond
338 ((eq (car-safe else) 'if) 339 ((eq (car-safe else) 'if)
339 (if (equal test (nth 1 else)) 340 (cond
340 ;; Doing a test a second time: get rid of the redundancy. 341 ;; Drop this optimization: It's unsafe (it assumes that `test' is
341 `(if ,test ,then ,@(nthcdr 3 else)) 342 ;; pure, or at least idempotent), and it's not used even a single
342 `(cond (,test ,then) 343 ;; time while compiling Emacs's sources.
343 (,(nth 1 else) ,(nth 2 else)) 344 ;;((equal test (nth 1 else))
344 (t ,@(nthcdr 3 else))))) 345 ;; ;; Doing a test a second time: get rid of the redundancy.
346 ;; (message "macroexp-if: sharing 'test' %S" test)
347 ;; `(if ,test ,then ,@(nthcdr 3 else)))
348 ((equal then (nth 2 else))
349 ;; (message "macroexp-if: sharing 'then' %S" then)
350 `(if (or ,test ,(nth 1 else)) ,then ,@(nthcdr 3 else)))
351 ((equal (macroexp-unprogn then) (nthcdr 3 else))
352 ;; (message "macroexp-if: sharing 'then' with not %S" then)
353 `(if (or ,test (not ,(nth 1 else)))
354 ,then ,@(macroexp-unprogn (nth 2 else))))
355 (t
356 `(cond (,test ,@(macroexp-unprogn then))
357 (,(nth 1 else) ,@(macroexp-unprogn (nth 2 else)))
358 (t ,@(nthcdr 3 else))))))
345 ((eq (car-safe else) 'cond) 359 ((eq (car-safe else) 'cond)
346 `(cond (,test ,then) 360 `(cond (,test ,@(macroexp-unprogn then)) ,@(cdr else)))
347 ;; Doing a test a second time: get rid of the redundancy, as above.
348 ,@(remove (assoc test else) (cdr else))))
349 ;; Invert the test if that lets us reduce the depth of the tree. 361 ;; Invert the test if that lets us reduce the depth of the tree.
350 ((memq (car-safe then) '(if cond)) (macroexp-if `(not ,test) else then)) 362 ((memq (car-safe then) '(if cond)) (macroexp-if `(not ,test) else then))
351 (t `(if ,test ,then ,else)))) 363 (t `(if ,test ,then ,@(macroexp-unprogn else)))))
352 364
353(defmacro macroexp-let2 (test sym exp &rest body) 365(defmacro macroexp-let2 (test sym exp &rest body)
354 "Evaluate BODY with SYM bound to an expression for EXP's value. 366 "Evaluate BODY with SYM bound to an expression for EXP's value.