mirror of
https://github.com/janet-lang/janet
synced 2024-12-26 00:10:27 +00:00
Add eachy and repeat to make looping easier.
Like eachk and eachp, use eachy and repeat to bring loop verbs outside of the loop macro. These new macros are very simple and easy to understand, in contrast to the loop macro which is of medium complexity.
This commit is contained in:
parent
08a3687eb5
commit
803f17aa90
@ -433,6 +433,17 @@
|
||||
(def ,binding ,i)
|
||||
,body))))
|
||||
|
||||
(defn- loop-fiber-template
|
||||
[binding expr body]
|
||||
(with-syms [f s]
|
||||
(def ds (if (idempotent? binding) binding (gensym)))
|
||||
~(let [,f ,expr]
|
||||
(while true
|
||||
(def ,ds (,resume ,f))
|
||||
(if (= :dead (,fiber/status ,f)) (break))
|
||||
,;(if (= ds binding) [] [~(def ,binding ,ds)])
|
||||
,;body))))
|
||||
|
||||
(defn- loop1
|
||||
[body head i]
|
||||
|
||||
@ -470,14 +481,7 @@
|
||||
:pairs (keys-template binding object true [rest])
|
||||
:in (each-template binding object [rest])
|
||||
:iterate (iterate-template binding object rest)
|
||||
:generate (with-syms [f s]
|
||||
(def ds (if (idempotent? binding) binding (gensym)))
|
||||
~(let [,f ,object]
|
||||
(while true
|
||||
(def ,ds (,resume ,f))
|
||||
(if (= :dead (,fiber/status ,f)) (break))
|
||||
,;(if (= ds binding) [] [~(def ,binding ,ds)])
|
||||
,rest)))
|
||||
:generate (loop-fiber-template binding object [rest])
|
||||
(error (string "unexpected loop verb " verb)))))
|
||||
|
||||
(defmacro for
|
||||
@ -495,6 +499,18 @@
|
||||
[x ds & body]
|
||||
(keys-template x ds true body))
|
||||
|
||||
(defmacro eachy
|
||||
"Resume a fiber in a loop until it has errored or died. Evaluate the body
|
||||
of the loop with binding set to the yielded value."
|
||||
[x fiber & body]
|
||||
(loop-fiber-template x fiber body))
|
||||
|
||||
(defmacro repeat
|
||||
"Evaluate body n times. If n is negative, body will be evaluated 0 times. Evaluates to nil."
|
||||
[n & body]
|
||||
(with-syms [iter]
|
||||
~(do (var ,iter ,n) (while (> ,iter 0) ,;body (-- ,iter)))))
|
||||
|
||||
(defmacro each
|
||||
"Loop over each value in ds. Returns nil."
|
||||
[x ds & body]
|
||||
@ -544,6 +560,7 @@
|
||||
(put _env 'each-template nil)
|
||||
(put _env 'keys-template nil)
|
||||
(put _env 'range-template nil)
|
||||
(put _env 'loop-fiber-template nil)
|
||||
|
||||
(defmacro seq
|
||||
"Similar to loop, but accumulates the loop body into an array and returns that.
|
||||
|
@ -23,7 +23,6 @@
|
||||
#ifndef JANET_AMALG
|
||||
#include "features.h"
|
||||
#include <janet.h>
|
||||
#include "state.h"
|
||||
#endif
|
||||
|
||||
/* Run a string */
|
||||
|
Loading…
Reference in New Issue
Block a user