branch: elpa/loopy
commit b876d0f431d14a5d716220a41428287a5f50aed1
Author: okamsn <[email protected]>
Commit: GitHub <[email protected]>
Remove, clean-up, and implement some old TODOs. (#261)
- In `lisp/loopy-commands.el`:
- Remove TODO comment for `set-prev` command, stating to support
when `back` is not know at compile time, as described in
issue #194. This was implemented.
- Turn `loopy--distribute-list-elements`,
`loopy--distribute-sequence-elements`,
and `loopy--distribute-array-elements` into functions
instead of macros. Call using `apply` in their corresponding
commands.
- Remove old comments for `append` command.
- Remove comment asking if there is a faster way to append.
- For `loopy--parse-loop-command`, remove comment for allowing commands to
return single instruction. Always returning a list of instructions is
more predictable.
- In `lisp/loopy-destructure.el`:
- Remove mention of old implementation of streams for
`loopy--seq-length=` and `loopy--seq-length>`.
- In `lisp/loopy-iter.el`:
- In `loopy-iter--def-special-processor`, only check whether the form
starts with an `loopy-iter-keyword` once
---
lisp/loopy-commands.el | 31 +++++++++----------------------
lisp/loopy-destructure.el | 15 ++++++---------
lisp/loopy-iter.el | 8 ++++----
3 files changed, 19 insertions(+), 35 deletions(-)
diff --git a/lisp/loopy-commands.el b/lisp/loopy-commands.el
index b249781ab84..7bdf1a95981 100644
--- a/lisp/loopy-commands.el
+++ b/lisp/loopy-commands.el
@@ -191,9 +191,6 @@ handled by `loopy-iter'."
(setq ,value-selector (1+ ,value-selector)))))))))
;;;;;; Prev Expr
-;; TODO: Use body of when with-bound and destructuring to allow for `back' not
-;; being known at compile time (but still only being evaluated once.)
-;; (#194)
(cl-defun loopy--parse-set-prev-command
((_ var val &key (back 1)))
"Parse the `set-prev' command as (set-prev VAR VAL &key back).
@@ -626,7 +623,7 @@ CMD is the command usage for error reporting."
:inclusive ,inclusive))))
;;;;;; Array
-(defmacro loopy--distribute-array-elements (&rest arrays)
+(defun loopy--distribute-array-elements (&rest arrays)
"Distribute the elements of the ARRAYS into an array of lists.
For example, [1 2] and [3 4] gives [(1 3) (1 4) (2 3) (2 4)]."
@@ -676,8 +673,8 @@ using the function `loopy--distribute-array-elements'."
(loopy--find-start-by-end-dir-vals opts)
(loopy--instr-let-const* ((value-holder (if (null other-vals)
val
-
`(loopy--distribute-array-elements
- ,val ,@other-vals)))
+ (apply
#'loopy--distribute-array-elements
+ val other-vals)))
(end-holder (or key-end
(if decreasing
0
@@ -821,8 +818,7 @@ and is a value."
(iter-close ,obj-holder))))))))))))
;;;;;; List
-;; TODO: Make this a normal function.
-(defmacro loopy--distribute-list-elements (&rest lists)
+(defun loopy--distribute-list-elements (&rest lists)
"Distribute the elements of LISTS into a list of lists.
For example, (1 2) and (3 4) would give ((1 3) (1 4) (2 3) (2 4))."
@@ -857,8 +853,8 @@ using the function `loopy--distribute-list-elements'."
loopy--iteration-vars
(loopy--instr-let-var* ((list-val (if (null other-vals)
val
- `(loopy--distribute-list-elements
- ,val ,@other-vals))))
+ (apply
#'loopy--distribute-list-elements
+ val other-vals))))
loopy--iteration-vars
`(;; NOTE: The benchmarks show that `consp' is faster than no `consp',
;; at least for some commands.
@@ -1176,8 +1172,7 @@ distributed using the function
`loopy--distribute-seq-elements'."
,seq-index ,by))))))))
;;;;;; Sequence
-;; TODO: Turn this into a function.
-(defmacro loopy--distribute-sequence-elements (&rest sequences)
+(defun loopy--distribute-sequence-elements (&rest sequences)
"Distribute the elements of SEQUENCES into a vector of lists.
For example, [1 2] and (3 4) give [(1 3) (1 4) (2 3) (2 4)]."
@@ -1241,8 +1236,8 @@ distributed using the function
`loopy--distribute-sequence-elements'."
(test test))
loopy--iteration-vars
(loopy--instr-let-var* ((temp-val (if other-vals
-
`(loopy--distribute-sequence-elements
- ,val ,@other-vals)
+ (apply
#'loopy--distribute-sequence-elements
+ val other-vals)
val))
(is-list (if optimize
`(consp ,temp-val)
@@ -2081,9 +2076,6 @@ you can use in the instructions:
(progn
(loopy--check-accumulation-compatibility loop var 'list cmd)
`(,@(if (eq pos 'start)
- ;; TODO: Is there a better way of appending to the
beginning
- ;; of a list?
- ;; `append' doesn't copy the last argument.
`((loopy--main-body (setq ,var (append ,val ,var))))
(loopy--produce-multi-item-end-tracking var val))
(loopy--vars-final-updates (,var . nil))))
@@ -2115,9 +2107,6 @@ you can use in the instructions:
(loopy--check-accumulation-compatibility loopy--loop-name var 'list cmd)
`((loopy--accumulation-vars (,var nil))
,@(pcase pos
- ;; TODO: Is there a better way of appending to the beginning
- ;; of a list?
- ;; `append' doesn't copy the last argument.
('start `((loopy--main-body (setq ,var (append ,val ,var)))))
('end (loopy--produce-multi-item-end-tracking var val))
(_ (signal 'loopy-bad-position-command-argument (list pos cmd))))
@@ -3046,8 +3035,6 @@ This function gets the parser, and passes the command to
that parser."
(signal 'loopy-parser-instructions-missing
(list command parser)))))
-;; TODO: Allow for commands to return single instructions, instead of requiring
-;; list of instructions.
(defun loopy--parse-loop-commands (command-list)
"Parse commands in COMMAND-LIST via `loopy--parse-loop-command'.
Return a single list of instructions in the same order as
diff --git a/lisp/loopy-destructure.el b/lisp/loopy-destructure.el
index 6d211fecb06..77586df8fe5 100644
--- a/lisp/loopy-destructure.el
+++ b/lisp/loopy-destructure.el
@@ -542,28 +542,25 @@ MAP-OR-KEY-VARS is whether there are map or key
variables."
(defun loopy--seq-length= (seq n)
"Check whether the length of SEQ is equal to N."
- ;; TODO: Simplify when `stream.el' is updated and streams are no longer
- ;; implemented as lists. See also `loopy--seq-length>'.
(cond
+ ((sequencep seq)
+ (length= seq n))
((streamp seq)
;; Avoid traversing long streams.
(let ((s (seq-drop seq (1- n))))
(and (not (stream-empty-p s))
(stream-empty-p (stream-rest s)))))
- ((listp seq)
- (compat-call length= seq n))
(t
(= (seq-length seq) n))))
(defun loopy--seq-length> (seq n)
"Check whether the length of SEQ is greater than to N."
(cond
- ;; Test streams first, because version 2.3.0 of `stream.el' implements
- ;; streams as lists. Take advantage of lazy evaluation of streams.
- ((streamp seq) (not (stream-empty-p (seq-drop seq n))))
+ ((sequencep seq) (length> seq n))
+ ;; Take advantage of lazy evaluation of streams.
+ ((streamp seq) (not (stream-empty-p (seq-drop seq n))))
;; `length>' only seems to matter for lists, based on its definition.
- ((listp seq) (compat-call length> seq n))
- (t (> (seq-length seq) n))))
+ (t (> (seq-length seq) n))))
(defun loopy--pcase-pat-positional-&seq-pattern (pos-vars opt-vars rest-var
map-or-key-vars)
"Build a pattern for the positional, `&optional', and `&rest' variables.
diff --git a/lisp/loopy-iter.el b/lisp/loopy-iter.el
index f62ce79b413..15ee1eb83a2 100644
--- a/lisp/loopy-iter.el
+++ b/lisp/loopy-iter.el
@@ -321,11 +321,13 @@ Returns BODY without the `%s' argument."
name name)
(loopy
(accum-opt matching-args new-body)
+ (with (first-is-keyword nil))
(listing expr body)
(if (and (consp expr)
(let ((first (cl-first expr)))
(or (and (memq first loopy-iter--keywords-internal)
- (eq ,fn-sym (loopy--get-command-parser (cl-second
expr) :error nil)))
+ (eq ,fn-sym (loopy--get-command-parser (cl-second
expr) :error nil))
+ (setq first-is-keyword t))
(and (memq first loopy-iter--bare-names-internal)
(eq ,fn-sym (loopy--get-command-parser first
:error nil))))))
(collecting matching-args expr)
@@ -336,9 +338,7 @@ Returns BODY without the `%s' argument."
(let ((arg (car matching-args))
(arg-name)
(arg-value))
- ;; TODO: Probably a better way to do this that
doesn't
- ;; involve checking twice.
- (if (memq (cl-first arg) loopy-iter-keywords)
+ (if first-is-keyword
(loopy-setq (_ arg-name . arg-value) arg)
(loopy-setq (arg-name . arg-value) arg))
(ignore arg-name)