## LOOP and +LOOP

forth

### Next

• 1. Ambiguous SEARCH
What should SEARCH return in the following instance? S" fred" HERE 0 SEARCH In Gforth and Win32Forth it returns a match while in CHForth it fails. Other forths ??? Personally I've found the match result to be more useful. Ed
• 2. What about COMPARE? (was Ambiguous SEARCH
Alex McDonald wrote: > As for COMPARE (a test of equality will suffice to make the point, > rather than less than, equal, greater than): A null string is equal to > itself (true of any string). A null string is equal to another null > string (because they are indistinguishable; the address is not part of > the comparison). A null string is not equal to any non-null string > (because the lengths differ). I agree that SEARCHing for a null string should succeed, but what should be the result of COMPAREing a null string and a non-null string?

### LOOP and +LOOP

```With LOOP, since the index (I) increases by 1 with each loop
iteration, we can test for equality as a means to determine if it's
time to exit the loop or not:

: TEST 10 0 DO I . LOOP ;
TEST
0 1 2 3 4 5 6 7 8 9

Here, when I gets to 10, the loop exits.

It's not so easy with +LOOP, since the index can be changed by any
arbitrary value on each iteration:

: TEST 100 0 DO I . RANDOM +LOOP ;

Here, we cannot test for equality. We have to test for crossing a
boundary instead, at least as far as I can see.

With that in mind, are these following results correct:

: TEST 10 0 DO I . 1 +LOOP ;
TEST 0 1 2 3 4 5 6 7 8 9 10 (11 iterations)

: TEST 10 0 DO I . 3 +LOOP ;
TEST 0 3 6 9 (4 iterations)

: TEST -30 -7 DO I . -3 +LOOP ;
TEST -7 -10 -13 -16 -19 -22 -25 -28 (8 iterations)

Regards

Mark
```

### Re: LOOP and +LOOP

```

There's something wrong with your +LOOP test in the case of 1 +LOOP;
it should be the equivalent of LOOP.

: test 10 0 do i . 1 +loop ;  ok
test 0 1 2 3 4 5 6 7 8 9  ok
: TEST -30 -7 DO I . -3 +LOOP ;
^
Warning(-4100): test is redefined  ok
test -7 -10 -13 -16 -19 -22 -25 -28  ok
: TEST 10 0 DO I . 3 +LOOP ;
^
Warning(-4100): test is redefined  ok
test 0 3 6 9  ok
```

### Re: LOOP and +LOOP

```On 2010-11-25 22:34:55 +0000, MarkWills said:

Don't think you should see the 10. You should get 0 - 9, 10 iterations.

Chris

```

### Re: LOOP and +LOOP

```

No.

Yes.

Yes.

We had a thread discussing test cases for DO .. LOOP a while back.

Assuming you have a two's-complement system (!) try these:

hex

0 invert 8 rshift 1+ constant step
step negate constant -step

: gd7 do 1+ step +loop ;
0 0 0 gd7 . 100  ok

: gd8 do 1+ -step +loop ;
0 0 -1 gd8 . 100  ok
0 0 -1 gd8 . 100  ok

There's some more dicussion in that thread, althugh it bacame rather
random after the first few postings.

Grab the Hayes tester and see what happens.

http://www.**--****.com/

All these tests should pass too:

MAX-UINT 8 RSHIFT 1+ CONSTANT STEP
STEP NEGATE CONSTANT -STEP

T{ : GD7 DO 1+ STEP +LOOP ; -> }T
T{ 0 0 0 GD7 -> 100 }T
T{ : GD8 DO 1+ -STEP +LOOP ; -> }T
T{ 0 0 -1 GD8 -> 100 }T
T{ 0 0 0 GD8 -> 1 }T

T{ : GD7 DO 1+ STEP +LOOP ; -> }T
T{ 0 MAX-UINT 0 GD7 -> 100 }T
T{ 0 1 0 GD7 -> 1 }T
T{ 0 MIN-INT MAX-INT GD7 -> 1 }T
T{ 0 MAX-INT MIN-INT GD7 -> 100 }T
T{ : GD8 DO 1+ -STEP +LOOP ; -> }T
T{ 0 0 MAX-UINT GD8 -> 100 }T
T{ 0 MIN-INT MAX-INT GD8 -> 100 }T
T{ 0 MAX-INT MIN-INT GD8 -> 1 }T

Andrew.
```

### Re: LOOP and +LOOP

```
Ah, so (as mentioned above) 1 +loop behaves like LOOP.

Ok, a simple addition JEQ will sort that. I'll check the other thread.

Thanks

Mark
```

### Re: LOOP and +LOOP

```Op Thu, 25 Nov 2010 14:34:55 -0800 (PST) schreef MarkWills:

<snip> because of the other answers.

Ok, but try these
: TEST -31 -7 DO I . -3 +LOOP ;
TEST -7 -10 -13 -16 -19 -22 -25 -28 -31
: TEST -1 1 DO I . -1 +LOOP ;
TEST 1 0 -1

--
Coos

CHForth, 16 bit DOS applications
http://www.**--****.com/
```

### Re: LOOP and +LOOP

```> Ok, but try these

Hi Coos - thanks for the reply... This is a pain in the ass!

It seems, from what you have shown, +LOOP does not does not do a
simple greater than or equal test to terminate the loop.

It seems, if the increment is exactly 1 or -1, +LOOP will behave like
LOOP and terminate when the index exactly equals the termination
value:

: TEST 10 0 DO I . 1 +LOOP ; ok
TEST 0 1 2 3 4 5 6 7 8 9

However, if the increment is bigger, +LOOP *only* terminates when the
index is greater than the terminator:

: TEST -31 -7 DO I . -3 +LOOP ; ok
TEST -7 -10 -13 -16 -19 -22 -25 -28 -31 <---

Note that -31 *is displayed* which means the loop actually terminated
when index = -34

Does that make sense?

My code behaves differently:

: TEST -31 -7 DO I . -3 +LOOP ; ok
TEST -7 -10 -13 -16 -19 -22 -25 -28 <---

That is because the next value after -28 is -31, which is exactly
equal to the termination value, so it exits. In other words, my code
does a 'is greater than OR equal to' for all increment values.
However, there seems to be something else going on.

I'd appreciate some help to nail this.

Thanks

Mark
```

### Re: LOOP and +LOOP

```Op Tue, 30 Nov 2010 13:46:14 -0800 (PST) schreef MarkWills:

Mark,
I would suggest consulting the standard. Look up the word +LOOP (or any
word of your interrest) in  http://www.**--****.com/
Click the link and look at the description of +LOOP in particular 'if the
loop index did not cross..'
+LOOP is one of the more intricate Forth constructs and hardly intuitive
for the unaware spectator ;-(
I add the limit and the index, flip the high bit and add the increment. On
overflow, leave the loop.

--
Coos

CHForth, 16 bit DOS applications
http://www.**--****.com/
```

### Re: LOOP and +LOOP

```

If my Forth pseudo-code is any good, it's

: do ( start lim -- ) over \$80000000 + - 2>r begin ;
: i  ( -- index )     2r@ + ;
: loop ( -- )         r> 1+ dup >r 0= until 2r> ;

```

### Re: LOOP and +LOOP

```

> : loop ( -- ) > r> >+ dup >r 0= u>til 2r> ;

Pardon; 0= should be OVERFLOW? or somesuch overflow test.
```

### Re: LOOP and +LOOP

```Op Tue, 30 Nov 2010 14:54:40 -0800 (PST) schreef Alex McDonald:

<snip>

That's wat I used to do. At present I is the same as R@ and I' is the
second item on the return stack, the limit. But yours is faster.

--
Coos

CHForth, 16 bit DOS applications
http://www.**--****.com/
```

### Re: LOOP and +LOOP

```

As Coos has already pointed out the reliant part of the standard says:

The Hayes test suite includes the following:

0 INVERT 1 RSHIFT        CONSTANT MID-UINT
0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+1

T{ : GD1 DO I LOOP ; -> }T
T{                 4 1 GD1 -> 1 2 3    }T
T{                2 -1 GD1 -> -1 0 1   }T
T{ MID-UINT+1 MID-UINT GD1 -> MID-UINT }T

T{ : GD2 DO I -1 +LOOP ; -> }T
T{                 1 4 GD2 -> 4 3 2 1             }T
T{                -1 2 GD2 -> 2 1 0 -1            }T
T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T

--
Peter Knaggs
```

### Re: LOOP and +LOOP

```

> 0 INVERT 1 RSHIFT INVERT CONSTANT MID-UINT+>
> T{ : GD1 DO I LOOP > -> }>
> T{ > 4 1 GD1 -> 1>2 3 T
> T{ gt; -1>GD1 -> -1 0 1 }T
> T{ MID->INT+1 MID-UINT>GD> -> MID-UINT }T
>
> T{ : >D2 DO>I -1 +LOOP ; -> }T
>>T{ > 4 GD2 -> 4 3 2 1 gt;}T
> T{ gt;1 2 GD2 -> 2 1 0 >1 T
> T{ MID>UI>T MID>UINT+1 GD2 -> MID-UINT+1 MID-UINT }T
>
> --
> Peter Knaggs

I guess it is important to point out that by "between the loop limit
minus one and the loop limit" this means the loop count reaching the
loop limit for a positive index case will exit without executing the
body of the loop while for the case of a negative index will execute
the body of the loop and exit on the next iteration.  I think the OP
the loop count and limit.

Rick
```

### Re: LOOP and +LOOP

```

> > T{ gt; -1>G>1 -> -1 0 1 }T
> > T{ MID->INT+1 MID-UINT>GD> >> MID-UINT }T
>
> > T{ : >D2 DO>I>-1 +LOOP ; -> }T
> >>T{ > > GD2 -> 4 3 2 1 gt;}T
> > T{ gt;gt;1 2 GD2 -> 2 1 0 -1>T
> > T{ MID>UI>T>MID-U>N>+1 GD2 -> MID-U>NT>1 MID-UINT }T
>
> > --
> > Peter Knaggs
>
> I guess it is importan> to point out that by "between the loop limit
> minus one and the loop>limit" this means the loop count reaching the
> loop limit for a posit>ve index case will exit without executing the
> body of the loop while>for the case of a negative index will execute
> the body of the loop a>d exit on the next iteration.  think the OP
> the loop count and limit.
>
> Rick

Rick,

That's exactly right. The question is how to code that behaviour
efficiently. I'm coding in assembler.

Mark
```

### Re: LOOP and +LOOP

```

> > > T{ gt; -1>G>1>-> -1 0 1 }T
> > > T{ MID->INT+1 MID-UINT>GD> >>>MID-UINT }T
>
> > > T{ : >D2 DO>I>-> +LOOP ; -> }T
> > >>T{ > > >D2 -> 4 3 2 1 gt;}T
> > > T{ gt;gt;gt;1 2 GD2 -> 2 1 0 -1 gt;T
> > > T{ MID>UI>T>M>D-UIN>+> >D2 -> MID-UINT+> M>D>UINT }T
>
> > > --
> > > Peter Knaggs
>
> > I guess it is importan> >o point out that by "between the loop limit
> > minus one and the loop>l>mit" this means the loop count reaching the
> > loop limit for a posit>v> index case will exit without executing the
> > body of the loop while>f>r the case of a negative index will execute
> > the body of the loop a>d>exit on the next iteration.  think the OP
>> > the >oo> count and limit.
>
> > Rick
>
> Rick,
>
> That's exactly rig>t. The question is how to code that beha>io>r
> efficiently. I'm coding in assembler.
>
> Mark

hmmmm.... which behavior exactly?  I described two, the one I think
the standard refers to and the one I am thinking you are referring
to...

Rick
```

```Hi again everyone,

Here is my rather clunky code (and I know it is rather inefficient):

------------------------------------------------------------------------------------------------------------------------------
while e_t lt 2 do begin
for x=4e003, 20e003, 4e003 do begin
for c=0.006, 0.01, 0.004 do begin
for o=(50*!pi/180), (70*!pi/180), (10*!pi/180) do begin
v= (a*x)
ind_small = where(file[1,*] lt 2*x,count)
if count eq 0 then te_small=0
if count gt 0 then begin
ext_small = file[*,ind_small]
le_small= ext_small[1,*]
te_small = total(le_small^3)
endif

ind_large = where(file[1,*] ge 2*x,count)
if count eq 0 then te_large=0
if count gt 0 then begin
ext_large = file[*,ind_large]
le_large= ext_large[1,*]
te_large = total(le_large)
endif

kns=(sin(o)*cos(o)/v)
knl=(c*cos(o)*x/a/sin(o))

ens= (kns*c/u)*te_small
enl=  knl*te_large
e_t= ens+enl
print,x,c,o,e_t
if e_t ge 0.45 && e_t le 0.9 then openw,1,'g:\Mars_tectonics
\IDL_programs\paper_m_data\alba_eflank.txt',
printf,1,x,c,o,e_t,format='(3f9.3)'
close, 1
endfor
endfor
endfor
endwhile
------------------------------------------------------------------------------------------------------------------------------
I have a few issues here that i could use some advice for:

1.) I'm not sure how to start and more importantly, end this loop. I
chose: while e_t lt 2 do begin to start it. The problem is that this
loop will never be greater than 2 so it will never end and it just
keeps repeating values ad nauseum in the output file.

I don't want it repeating but I'm not certain how to start it and stop
it to allow for no repeated values.

2.) for for c=0.006, 0.01, 0.004 do begin, I watch the output, but I
don't see it change.

3.) i must of screwed something up in this segment:
if e_t ge 0.45 && e_t le 0.9 then openw,1,'g:\Mars_tectonics
\IDL_programs\paper_m_data\alba_eflank.txt',
printf,1,x,c,o,e_t,format='(3f9.3)'

because it worked before, but know I keep getting an error about
unable to close 1, or somesuch thing (just switched to compilation
error).

As always, I appreciate any help that you may provide. After all I
wouldn't be asking this question if it weren't for all your help :)

Thanks,
~Matt
```

```With LOOP, since the index (I) increases by 1 with each loop
iteration, we can test for equality as a means to determine if it's
time to exit the loop or not:

: TEST 10 0 DO I . LOOP ;
TEST
0 1 2 3 4 5 6 7 8 9

Here, when I gets to 10, the loop exits.

It's not so easy with +LOOP, since the index can be changed by any
arbitrary value on each iteration:

: TEST 100 0 DO I . RANDOM +LOOP ;

Here, we cannot test for equality. We have to test for crossing a
boundary instead, at least as far as I can see.

With that in mind, are these following results correct:

: TEST 10 0 DO I . 1 +LOOP ;
TEST 0 1 2 3 4 5 6 7 8 9 10 (11 iterations)

: TEST 10 0 DO I . 3 +LOOP ;
TEST 0 3 6 9 (4 iterations)

: TEST -30 -7 DO I . -3 +LOOP ;
TEST -7 -10 -13 -16 -19 -22 -25 -28 (8 iterations)

Regards

Mark
```

```Is it allowed to have one do loop completely within another
do loop in Fortran?

```

```Heya,

I'm running a py script that simply grabs an image, creates a
thumbnail and uploads it to s3. I'm simply logging into ssh and
running the script through Terminal. It works fine, but gives me an
IOError every now and then.

I was wondering if I can catch this error and just get the script to
start again?
I mean, in Terminal it dies anyway, so I have to start it again by
hand, which is a pain as it dies so sporadically. Can I automate this
error, catch it and just get it to restart the loop?

Thanks for your time and energy,

Danny
```