6.1.2380 UNLOOP CORE

Interpretation:

Interpretation semantics for this word are undefined.

Execution:

( -- ) ( R: loop-sys -- )

Discard the loop-control parameters for the current nesting level. An UNLOOP is required for each nesting level before the definition may be EXITed. An ambiguous condition exists if the loop-control parameters are unavailable.

See:

Rationale:

Typical use:
: X ...
   limit first DO
   ... test IF ... UNLOOP EXIT THEN ...
   LOOP ...
;

UNLOOP allows the use of EXIT within the context of DO ... LOOP and related do-loop constructs. UNLOOP as a function has been called UNDO. UNLOOP is more indicative of the action: nothing gets undone — we simply stop doing it.

Testing:

T{ : GD6 ( PAT: {0 0},{0 0}{1 0}{1 1},{0 0}{1 0}{1 1}{2 0}{2 1}{2 2} ) 
      0 SWAP 0 DO 
         I 1+ 0 DO 
           I J + 3 = IF I UNLOOP I UNLOOP EXIT THEN 1+ 
         LOOP 
      LOOP ; -> }T

T{ 1 GD6 -> 1 }T
T{ 2 GD6 -> 3 }T
T{ 3 GD6 -> 4 1 2 }T

ContributeContributions

AtHavatar of AtH [18] Another use of UNLOOPSuggested Testcase2016-05-16 21:55:15

Old standard concentrates on UNLOOP EXIT

I suggest to legalize in the new standard UNLOOP LEAVE for breaking the outer loop.

AntonErtlavatar of AntonErtl

A common implementation of UNLOOP is as just a run-time word, while a common implementation of LEAVE is a compile word that generates a branch to the end of the loop. Your suggestion would cause quite a bit of additional implementation complexity with such a LEAVE. If we need to leave two DO LOOPs, a word LEAVE2 would be simpler to implement (although word counters won't like it). Or, with the current standard, put the nested loop in an extra colon definition, and leave it with UNLOOP UNLOOP EXIT.

AtHavatar of AtH

There are two ways to implement LEAVE

  1. As you said, compile UNLOOP with direct BRANCH to the first word after first LOOP

  2. When end of loop address is part of discarded loop-control parameters, fetch this exit point and indirect branch to it.

First implementation is slightly faster, the second allows to use UNLOOPs for leaving any number of nested loops. I use the second way, LEAVE is just a regular primitive without IMMEDIATE and DO always knows, where it's LOOP

UNLOOP could be more powerful, without extra words in the standard like LEAVE2 LEAVE3 etc.

AntonErtlavatar of AntonErtl

Do we want to limit the Forth implementations to those that are implemented in the way you describe? I don't.

Anyway, don't let my objections stop you. If you think it is worth it, make a proposal.

Reply New Version