diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el index 2ab01404ba..a3462971f8 100644 --- a/lisp/emacs-lisp/generator.el +++ b/lisp/emacs-lisp/generator.el @@ -286,19 +286,25 @@ don't yield.") ;; Process `progn' and `inline': they are identical except for the ;; name, which has some significance to the byte compiler. - (`(inline) (cps--transform-1 nil next-state)) - (`(inline ,form) (cps--transform-1 form next-state)) - (`(inline ,form . ,rest) - (cps--transform-1 form - (cps--transform-1 `(inline ,@rest) - next-state))) - - (`(progn) (cps--transform-1 nil next-state)) - (`(progn ,form) (cps--transform-1 form next-state)) - (`(progn ,form . ,rest) - (cps--transform-1 form - (cps--transform-1 `(progn ,@rest) - next-state))) + (`(,(or 'inline 'progn)) (cps--transform-1 nil next-state)) + (`(,(or 'inline 'progn) ,form) (cps--transform-1 form next-state)) + (`(,(and (or 'inline 'progn) progn-type) ,form . ,rest) + (let (atomic-head) + ;; When there are several atomic (i.e. without `iter-yield') + ;; forms at the beginning, don't create a separate state for + ;; each of them, but rather one for all. + (unless cps-inhibit-atomic-optimization + (when (cps--atomic-p form) + (setf atomic-head (list form)) + (while (and rest (cps--atomic-p (car rest))) + (push (pop rest) atomic-head)))) + (if atomic-head + (cps--make-atomic-state `(,progn-type ,@(nreverse atomic-head)) + (cps--transform-1 `(,progn-type ,@rest) + next-state)) + (cps--transform-1 form + (cps--transform-1 `(,progn-type ,@rest) + next-state))))) ;; Process `let' in a helper function that transforms it into a ;; let* with temporaries.