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 |