duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 867e92969725196fcc2e1858297a4ac1c88346db
parent c711a0228a96415139eba8e5cdbf9883606f32a6
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sat, 21 Jan 2023 10:09:38 -0500

doc: flesh out an idea about iteration and coroutines

I did try implementing it but took a wrong turn. I still think the idea is good,
but I will try again later.

Diffstat:
Afs/doc/lib/iter.txt | 43+++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+), 0 deletions(-)

diff --git a/fs/doc/lib/iter.txt b/fs/doc/lib/iter.txt @@ -0,0 +1,43 @@ +# Iterators + +TODO: this isn't implemented yet, only broadly specced out. + +Iterators are generic and convenient ways to iterate over arbitrary elements in +a loop-like syntax. Iterators are coroutines. + +Coroutines are two routines that intertwine at the top of RS. Generally, +routines are called upon, pushing a return address on RS, and then the routine +finishes, pops return address of RS and jump to that. With coroutine, we don't +push and pop, we *swap* return addresses on RS until iteration is completed. + +An iterator is a word that uses the special "yield" word to perform coroutine +swapping. Here's an example implementation of the core "begin .. next" loop as +an iterator: + + 0 value i + :iter for ( n -- ) + to@! i >r begin yield -1 to+ i i not until r> to i ; + + : hello 5 for i . spc> inext ; + hello \ prints "5 4 3 2 1 " + +Iterators are expected to keep PS and RS balanced between yields. For this +reason, iteration should be passed through global variables such as "i" in the +example. To allow iterators to be nested, it's the iterator's responsibility to +save/restore those variables to RS at iteration intialization/cleanup. + +Further examples: + + 0 value i + 0 value j + :iter for2 ( n max -- ) + to@! j >r to@! i >r begin yield 1 to+ i i j = until r> to i r> to j ; + + : hello 2 6 for i . spc> inext ; + hello \ prints "2 3 4 5 " + + \ "iterinfo" is a structbind to FSInfo + : ls p" /" Path :iter iterinfo name stype nl> inext ; + + \ returns size in bytes + : totsz 0 p" /" Path :iter iterinfo size + inext ;