Liste des Groupes | Revenir à cl forth |
On 15-05-2025 02:51, dxf wrote:On 14/05/2025 7:17 pm, Hans Bezemer wrote:On 14-05-2025 09:07, ahmed wrote:>On Wed, 14 May 2025 5:51:35 +0000, anthk wrote:>
>On 2024-07-11, ahmed <melahi_ahmed@yahoo.fr> wrote:>Thanks for the explanation.>
How can I get FOR and NEXT with MinForth? I have MF384.
>
Ahmed
In pforth (pfe), that's why I use to test code made for eforth:
>
: >MARK ( --A ) HERE 0 , ;
: AHEAD ( --A ) COMPILE branch >MARK ; IMMEDIATE
: AFT ( a --a A ) DROP [COMPILE] AHEAD [COMPILE] BEGIN SWAP ; IMMEDIATE
>
: FOR ( RUNTIME: N -- )
COMPILE ABS \ NO NEGATIVES
COMPILE LIT 0 , COMPILE SWAP
[COMPILE] ?DO ; IMMEDIATE
>
: NEXT
COMPILE LIT -1 ,
[COMPILE] +LOOP ; IMMEDIATE
Thanks.
>
I've already defined for and next in MinForth like this:
>
: (0) 0 ;
: (-1) -1 ;
: for_ postpone (0) postpone swap postpone ?do ; immediate
: _next postpone (-1) postpone +loop ; immediate
>
and here is an example of use:
>
: go_ 10 for_ i . _next ;
>
go_ 10 9 8 7 6 5 4 3 2 1 0 ok
Well, it isn't standardized - so you can make it anything you want to. I got two variants, the one I think it should be, and the one from eForth:
>
:macro for >r begin r@ 0> while ;
:macro next r> 1- >r repeat rdrop ;
>
eForth:
:macro for >r begin ;
:macro next r@ 0> while r> 1- >r repeat rdrop ;
>
They *SEEM* almost identical, but they aren't. The eForth one performs "the action" before the condition is tested, mine *AFTER* the condition is tested.
>
Now - what do I expect when I issue a "10"? I expect a thing to be performed ten times. No more, no less. And that's what mine gets. The eForth one does not ten things, but eleven (including the zero). Also note my version fixes another DO..LOOP problem - it bombs out when the count is zero or less.
>
Finally, we all agree DO..LOOP is deeply flawed (it is) but we still prefer to use it - preferably with loops with negative subscripts, or garnishing it with horrors like UNLOOP and LEAVE (Hello! - it's a *counted* loop. It should do as many times as I asked it to do initially - not halfway change my mind saying "Oops - now I want you to quit anyway").
...
Except eForth's FOR NEXT had AFT WHILE etc to effect such things. Never say never?
I would say we "prefer to use" DO LOOP because when all said and done it hasn't been
bettered. Immediate LEAVE ?DO UNLOOP full range loops were incremental improvements
that led to DO LOOP's ubiquitous status in Forth. That said I can appreciate
restrictive environments where the decision was made to implement FOR NEXT instead.
>
Ooooh! I find it almost as beautiful as UNLOOP and LEAVE. If you want to do a thing before doing another thing then do it - and then enter the loop. Ok, it may violate your sense of elegance (depending on your taste) but it is much more understandable:
[char] ; PARSE TYPE
BEGIN
[char] ; PARSE DUP
WHILE
[char] , EMIT TYPE
REPEAT 2DROP CR
Moore's rule: "AFT is *not* a word!" (https://sourceforge.net/p/forth-4th/wiki/What%27s%20in%20a%20name%3F/)
It's constructs like this that give Forth a bad name as "a write only language".
Often, I'd rather construct a DO..LOOP myself by putting one or more of the loop items on the return stack (like an "end address", resulting in constructs like "DUP R@ < WHILE") than use a DO..LOOP. I mean - if you got R'@, what's the problem?
Add to that I can use as many WHILEs as I want in 4tH without those mind boggling and utterly ugly THEN resolves. It also means I don't have to cram all conditions in a single WHILE to avoid them.
Gee, I never wanted to become one of those grumpy old Forth guys - and all of a sudden you realize you just became one.. ;-)
Les messages affichés proviennent d'usenet.