gamber@cosmo.UUCP (Johannes Teich) (05/08/90)
Forthers, I'm glad to have them both running: +--------+ +--------+ FOR | For | ?DO | ?Do | +--------+ +--------+ | offs |--. | offs |--. +--------+ | +--------+ | | |<-|-. | |<-|-. | | | | | | | | LEAVE | Leave ---|-|-. LEAVE | Leave ---|-|-. | | | | | | | | | | LEAVE | Leave ---|-|-. LEAVE | Leave ---|-|-. | | | | | | | | | | +--------+ | | | +--------+ | | | NEXT | Next |<-' | | LOOP | Loop | | | | +--------+ | | +--------+ | | | | offs |----' | | offs |--|-' | +--------+ | +--------+ | | | |<-----' | |<-' <-' FOR ... I ... LEAVE ... LEAVE ... NEXT ?DO ... I ... LEAVE ... LEAVE ... LOOP ( or DO and/or +LOOP ) There are 3 values on the return stack: jump-addr reference loop-index. The jump-addr is for LEAVE . The reference is for FORTH-83 & speed. The word I does a subtraction: R> DUP R@ - SWAP >R (it could be an addition like in Zen as well). The reference is always zero for FOR...NEXT , but must be present because of LEAVE , I and J . R@ is the same as I , then, but quicker. Now I think of something like n +FOR which sets the reference to n. 10 4 +FOR ... NEXT --> 9 8 7 6 5 4 doing the same as: 4 9 DO ... -1 +LOOP ( FORTH-83 ) The reference value would no longer be waisted. What do others think about +FOR or whatever it should be called? I prefer offsets over absolut addresses (as used in Pygmy), for I plan to shift the code in memory, and metacompiling becomes a little simpler, too. Btw, my 0 FOR...NEXT loops zero times. (In addition, cmFOR is available.) cheers, --Hannes | gamber@cosmo.uucp | | fido 2:507/414.20 |
gamber@cosmo.UUCP (Johannes Teich) (05/09/90)
In article <5628@balu.UUCP>, gamber@cosmo.UUCP (Johannes Teich) writes: > Now I think of something like n +FOR which sets the reference to n. > > 10 4 +FOR ... NEXT --> 9 8 7 6 5 4 > doing the same as: 4 9 DO ... -1 +LOOP ( FORTH-83 ) Maybe there is little need for that type of a loop. It's just simple to implement. It would be more useful if the index went forward... but why not take the DO ... LOOP construct, then? The FORTH-83 Standard says: "If the new index was incremented across the boundary between limit-1 and limit then the loop is terminated". That is, 3 0 DO I . LOOP --> 0 1 2 0 -3 DO I . LOOP --> -2 -1 0 0 3 DO I . -1 +LOOP --> 3 2 1 0 -3 0 DO I . -1 +LOOP --> 0 -1 -2 -3 This leads to the solution with the CPU overflow flag in several Forths: 3 0 DO ... R@ . ... LOOP 32765 32766 32767 (overflow) reference (2nd on Rstack) 32765 32765 32765 3 0 DO ... I . ... LOOP 0 1 2 0 3 DO ... R@ . ... -1 +LOOP -32775 -32776 -32767 -32768 (overflow) reference (2nd on Rstack) -32768 -32768 -32768 -32768 0 3 DO ... I . ... -1 +LOOP 3 2 1 0 This unsymmetric behavior looks less plausible than floored division. (In fact, I dislike it.) On the other hand, I do not intend to use standard words or controlled words other than described in the standard paper. (I even hesitate to use FOR and cmFOR instead of ?FOR and FOR . But CM doesn't care of any standards, does he?) When Rstack holds only one value, how can the loop index increment? 3 FOR ... R@ . ... NEXT 2 1 0 3 DUP 1- SWAP FOR ... R@ - . ... NEXT 0 1 2 3 cmFOR ... R@ . ... NEXT 3 2 1 0 3 DUP cmFOR ... R@ - . ... NEXT 0 1 2 3 Now I see why CM choose his version... :-) Alternatively, we may have the loop index on Dstack: 0 3 FOR ... DUP . 1+ ... NEXT DROP 0 1 2 0 3 cmFOR ... DUP . 1+ ... NEXT DROP 0 1 2 3 Heretical question: why not have an incrementing negative index? 3 -FOR ... R@ . ... NEXT -2 -1 0 3 -FOR ... R@ ABS . ... NEXT 2 1 0 3 DUP -FOR ... R@ + . ... NEXT 0 1 2 3 DUP 5 + SWAP -FOR ... R@ + . ... NEXT 5 6 7 This could be considered a special case of >FOR . :-) (Now we have to have more than one value on Rstack.) 0 3 >FOR ... R@ . ... NEXT -2 -1 0 reference (2nd on Rstack) -2 -2 -2 0 3 >FOR ... I . ... NEXT 0 1 2 5 8 >FOR ... R@ . ... NEXT -2 -1 0 reference (2nd on Rstack) -7 -7 -7 5 8 >FOR ... I . ... NEXT 5 6 7 5 8 <FOR ... R@ . ... NEXT 2 1 0 reference (2nd on Rstack) -5 -5 -5 5 8 <FOR ... I . ... NEXT 7 6 5 To conclude this brainstorming, just a look on TYPE : : TYPE ( a n -) ?DUP IF OVER + SWAP DO I C@ EMIT LOOP ELSE DROP THEN ; : TYPE ( a n -) ?DUP IF 1- cmFOR DUP C@ EMIT 1+ NEXT THEN DROP ; : TYPE ( a n -) ?DUP IF FOR DUP C@ EMIT 1+ NEXT THEN DROP ; : TYPE ( a n -) ?DUP IF -FOR DUP I + C@ EMIT NEXT THEN DROP ; : TYPE ( a n -) ?DUP IF OVER + >FOR I C@ EMIT NEXT ELSE DROP THEN ; Maybe FOR ... NEXT is all we need. :-) cheers, --Hannes | gamber@cosmo.uucp | | fido 2:507/414.20 |