summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/generator.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/generator.el')
-rw-r--r--lisp/emacs-lisp/generator.el33
1 files changed, 17 insertions, 16 deletions
diff --git a/lisp/emacs-lisp/generator.el b/lisp/emacs-lisp/generator.el
index 4ae20ba4205..ac1412704b0 100644
--- a/lisp/emacs-lisp/generator.el
+++ b/lisp/emacs-lisp/generator.el
@@ -143,8 +143,7 @@ the CPS state machinery."
(setf ,static-var ,dynamic-var)))))
(defmacro cps--with-dynamic-binding (dynamic-var static-var &rest body)
- "Evaluate BODY such that generated atomic evaluations run with
-DYNAMIC-VAR bound to STATIC-VAR."
+ "Run BODY's atomic evaluations run with DYNAMIC-VAR bound to STATIC-VAR."
(declare (indent 2))
`(cps--with-value-wrapper
(cps--make-dynamic-binding-wrapper ,dynamic-var ,static-var)
@@ -291,22 +290,28 @@ DYNAMIC-VAR bound to STATIC-VAR."
(cps--transform-1 `(progn ,@rest)
next-state)))
- ;; Process `let' in a helper function that transforms it into a
- ;; let* with temporaries.
+ (`(,(or 'let 'let*) () . ,body)
+ (cps--transform-1 `(progn ,@body) next-state))
+
+ ;; Transform multi-variable `let' into `let*':
+ ;; (let ((v1 e1) ... (vN eN)) BODY)
+ ;; -> (let* ((t1 e1) ... (tN-1 eN-1) (vN eN) (v1 t1) (vN-1 tN-1)) BODY)
(`(let ,bindings . ,body)
(let* ((bindings (cl-loop for binding in bindings
collect (if (symbolp binding)
(list binding nil)
binding)))
- (temps (cl-loop for (var _value-form) in bindings
+ (butlast-bindings (butlast bindings))
+ (temps (cl-loop for (var _value-form) in butlast-bindings
collect (cps--add-binding var))))
(cps--transform-1
`(let* ,(append
- (cl-loop for (_var value-form) in bindings
+ (cl-loop for (_var value-form) in butlast-bindings
for temp in temps
collect (list temp value-form))
- (cl-loop for (var _binding) in bindings
+ (last bindings)
+ (cl-loop for (var _binding) in butlast-bindings
for temp in temps
collect (list var temp)))
,@body)
@@ -315,9 +320,6 @@ DYNAMIC-VAR bound to STATIC-VAR."
;; Process `let*' binding: process one binding at a time. Flatten
;; lexical bindings.
- (`(let* () . ,body)
- (cps--transform-1 `(progn ,@body) next-state))
-
(`(let* (,binding . ,more-bindings) . ,body)
(let* ((var (if (symbolp binding) binding (car binding)))
(value-form (car (cdr-safe binding)))
@@ -467,7 +469,7 @@ DYNAMIC-VAR bound to STATIC-VAR."
(guard (cps--special-form-p name))
(guard (not (memq name cps-standard-special-forms))))
name ; Shut up byte compiler
- (error "special form %S incorrect or not supported" form))
+ (error "Special form %S incorrect or not supported" form))
;; Process regular function applications with nontrivial
;; parameters, converting them to applications of trivial
@@ -633,7 +635,7 @@ modified copy."
;; If we're exiting non-locally (error, quit,
;; etc.) close the iterator.
,(cps--make-close-iterator-form terminal-state)))))
- (t (error "unknown iterator operation %S" op))))))
+ (t (error "Unknown iterator operation %S" op))))))
,(when finalizer-symbol
'(funcall iterator
:stash-finalizer
@@ -642,12 +644,11 @@ modified copy."
(iter-close iterator)))))
iterator))))
-(defun iter-yield (value)
+(defun iter-yield (_value)
"When used inside a generator, yield control to caller.
The caller of `iter-next' receives VALUE, and the next call to
`iter-next' resumes execution with the form immediately following this
`iter-yield' call."
- (identity value)
(error "`iter-yield' used outside a generator"))
(defmacro iter-yield-from (value)
@@ -668,7 +669,7 @@ sub-iterator function returns via `iter-end-of-sequence'."
(iter-close ,valsym)))))
(defmacro iter-defun (name arglist &rest body)
- "Creates a generator NAME.
+ "Create a generator NAME that accepts ARGLIST as its arguments.
When called as a function, NAME returns an iterator value that
encapsulates the state of a computation that produces a sequence
of values. Callers can retrieve each value using `iter-next'."
@@ -711,7 +712,7 @@ iterator cannot supply more values."
(defun iter-close (iterator)
"Terminate an iterator early.
-Run any unwind-protect handlers in scope at the point ITERATOR
+Run any `unwind-protect' handlers in scope at the point ITERATOR
is blocked."
(funcall iterator :close nil))