Sujet : Re: DO..LOOP and stack shuffling
De : anton (at) *nospam* mips.complang.tuwien.ac.at (Anton Ertl)
Groupes : comp.lang.forthDate : 03. Jul 2025, 08:50:15
Autres entêtes
Organisation : Institut fuer Computersprachen, Technische Universitaet Wien
Message-ID : <2025Jul3.095015@mips.complang.tuwien.ac.at>
References : 1 2 3 4 5 6
User-Agent : xrn 10.11
Hans Bezemer <
the.beez.speaks@gmail.com> writes:
The DO..LOOP advantages - nah, not really. E.g. an "address" loop can be
done like (a n = address count):
>
OVER SWAP /ELEMENT * + >R
BEGIN DUP R@ < WHILE ( ..) /ELEMENT + REPEAT R> DROP DROP
>
No need for BOUNDS DO..LOOP ..
Great. You can write a counted loop without body with BEGIN ... WHILE
... REPEAT. I can write equivalent code shorter, and it will execute
more efficiently:
2DROP
However, things become more interesting when the body does something,
in particular when it needs access to additional data beyond just I,
and maybe even modify some of these stack items. E.g., here's a
definition from Gforth:
: del-included-files ( addr u -- )
included-files $@ cell MEM+DO
I $@ 2over string-prefix? IF I 0 third $del THEN
LOOP 2drop ;
That's a relatively easy case, because the loop body does not modify
addr nor u. You can find documentation on most used words through
<
https://net2o.de/gforth/Word-Index.html>. INCLUDED-FILES is a
variable.
Another one is:
: usage# ( nt -- n ) \ gforth-internal
\G count usage of the word @var{nt}
0 wheres $@ where-struct MEM+DO
over i where-nt @ = -
LOOP nip ;
Here the body reads one additional stack item ( nt ) and modifies
another one (the count). WHERES is a variable, WHERE-STRUCT is the
size of an element of the array that WHERES points to.
So for a lot of applications, I don't really need DO..LOOP and its
deeply flawed implementation.
If your implementation of DO..LOOP is deeply flawed, maybe you should
replace it with a better one.
And since R@ and I are synonyms
They are not, not in the standard, and not on a number of systems.
E.g., consider the following program:
: foo 10 5 do cr i . r@ . loop ; foo
On Gforth and iForth, the result of I and R@ are the same, but on lxf,
sf64, and vfx64, they are not:
lxf sf64 vfx64
I R@ I R@ I R@
5 2147483643 5 0 5 8388608
6 2147483644 6 0 6 8388608
7 2147483645 7 0 7 8388608
8 2147483646 8 0 8 8388608
9 2147483647 9 0 9 8388608
- anton
, I can
even use I if I prefer I! :)
>
Usually, if I think of it I could even do less DO..LOOP - but you know
how it is when a pattern has entered your mind. It's like an ear worm.
>
But anyways - that was the reason I defined R'@ and R"@ a long time ago.
It still feels like cheating if I use them, but they're just synonyms of
I' and J anyways - so they don't take up much space if you want to
support them.
>
As I've shown, in 4tH you can make the code much clearer by
(temporarily) assigning synonyms to them.
>
Now as I was playing with the idea there were a lot of people claiming
"It makes no sense adding R'@ and R"@. Been there done that."
>
But since I'm so easily convinced, I did it anyway. Can't say I
regretted that, since it allows you to better balance the load between
both stacks.
>
Hans Bezemer
>
P.S. If you want to do an equally misconceived FOR..NEXT as eForth has
implemented, place the (..) payload directly behind BEGIN. That will
make it do 11 iterations when you only asked for 10.
>
>
>
-- M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.htmlcomp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html New standard: https://forth-standard.org/EuroForth 2023 proceedings: http://www.euroforth.org/ef23/papers/EuroForth 2024 proceedings:
http://www.euroforth.org/ef24/papers/