summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorMattias EngdegÄrd <mattiase@acm.org>2021-03-18 13:33:09 +0100
committerMattias EngdegÄrd <mattiase@acm.org>2021-03-18 13:35:55 +0100
commit52270aa0dc3313f42986a07413bf5b600d9fecbe (patch)
tree08446978f2b72d4a3a04448707dcccfeba2dfa58 /lisp
parentce1b4acd71e962b6a72a779ee04cb5aeb6ceb6f2 (diff)
downloademacs-52270aa0dc3313f42986a07413bf5b600d9fecbe.tar.gz
emacs-52270aa0dc3313f42986a07413bf5b600d9fecbe.tar.bz2
emacs-52270aa0dc3313f42986a07413bf5b600d9fecbe.zip
Optimise tail calls in `and` and `or` forms in `cl-labels` functions
* lisp/emacs-lisp/cl-macs.el (cl--self-tco): Handle `and` and `or`. * test/lisp/emacs-lisp/cl-macs-tests.el (cl-macs--labels): Add test cases.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/emacs-lisp/cl-macs.el6
1 files changed, 6 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index c38dc44ff60..73ff4e6fd09 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -2100,6 +2100,12 @@ Like `cl-flet' but the definitions can refer to previous ones.
(`(progn . ,exps) `(progn . ,(funcall opt-exps exps)))
(`(if ,cond ,then . ,else)
`(if ,cond ,(funcall opt then) . ,(funcall opt-exps else)))
+ (`(and . ,exps) `(and . ,(funcall opt-exps exps)))
+ (`(or ,arg) (funcall opt arg))
+ (`(or ,arg . ,args)
+ (let ((val (make-symbol "val")))
+ `(let ((,val ,arg))
+ (if ,val ,(funcall opt val) ,(funcall opt `(or . ,args))))))
(`(cond . ,conds)
(let ((cs '()))
(while conds