ForthHub/forth

-1 +LOOP

Closed this issue · 1 comments

drom commented

The following test:

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

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

Fails:

Error: in line: 704 T{ 1 4 GD2 -> 4 3 2 1 }T  expected [ 4, 3, 2 ] to deeply equal [ 4, 3, 2, 1 ].
Error: in line: 705 T{ -1 2 GD2 -> 2 1 0 -1 }T  expected [ 2, 1, 0 ] to deeply equal [ 2, 1, 0, -1 ].
Error: in line: 706 T{ MID-UINT MID-UINT+1 GD2 -> MID-UINT+1 MID-UINT }T  expected [ -2147483648 ] to deeply equal [ -2147483648, 2147483647 ].

Error: in line: 714 T{ 1 4 GD4 -> 4 3 2 1 }T  expected [ 4, 3, 2 ] to deeply equal [ 4, 3, 2, 1 ].
Error: in line: 715 T{ -1 2 GD4 -> 2 1 0 -1 }T  expected [ 2, 1, 0 ] to deeply equal [ 2, 1, 0, -1 ].
Error: in line: 716 T{ MID-UINT MID-UINT+1 GD4 -> MID-UINT+1 MID-UINT }T  expected [ -2147483648 ] to deeply equal [ -2147483648, 2147483647 ].

Decompiled GD2:

gd2: function () {
    this.rpush(this.dnext());
    this.rpush(this.dpop());
    this.dpop();
    L1:
        do {
            this.dpush(this.rtop());
            this.dpush(-1);
            this.rpush(this.rpop() + this.dpop());
        } while (this.rtop() >>> 0 !== this.rnext() >>> 0);
    this.rpop();
    this.rpop();
}
drom commented

If the loop index did not cross the boundary between the loop limit minus one and the loop limit, continue execution at the beginning of the loop.

Here is the page from the standard:

image

Here is the relevant picture from the Child Forth book 😄

image