wmb@MITCH.ENG.SUN.COM (Mitch Bradley) (12/03/90)
I don't remember where I first saw this technique; if you invented it,
I apologize for not being able to give credit where it is due.
Anyway, the goal is to extend Eaker's CASE statement to match a range
of consecutive numbers, in addition to individual numbers. The solution
is the word RANGE , used like:
: CARD-CLASS ( card# -- )
CASE
1 OF ." Ace" ENDOF
2 10 RANGE OF ." Number Card" ENDOF
11 13 RANGE OF ." Face Card" ENDOF
ENDCASE
;
The trick is to perform the range test, then construct some artifical
arguments to OF that will make it do the right thing based on the
outcome of the previous test. Here is an implementation of RANGE :
: RANGE ( selector low high -- selector selector | selector selector+1 )
ROT DUP 2SWAP ( selector selector low high )
BETWEEN IF ( selector )
DUP ( selector selector ) \ Following OF will match
ELSE ( selector )
DUP 1+ ( selector selector+1 ) \ Following OF will not match
THEN
;
A similar technique could be used for other kinds of tests, in addition
to the "BETWEEN" test shown here. For an arbitrary test "X", the code
would be:
DUP X IF DUP ELSE DUP 1+ THEN
This suggests the following factor:
: whatever ( selector flag -- selector selector | selector selector+1 )
IF DUP ELSE DUP 1+ THEN
;
Can somebody thing of a good name for "whatever"?
By the way, BETWEEN ( n1 n2 n3 -- flag ) returns true iff n2 <= n1 <= n3 .
BETWEEN is in ANS Basis. I first encountered it in L&P F83 .
Mitcheaker@sunbelt.crd.ge.com (Charles E Eaker) (12/05/90)
In article <9012031443.AA22305@ucbvax.Berkeley.EDU> Mitch Bradley <wmb%MITCH.ENG.SUN.COM@SCFVM.GSFC.NASA.GOV> writes: >I don't remember where I first saw this technique; if you invented it, >I apologize for not being able to give credit where it is due. The first RANGE proposal I remember was Alfred J. Monroe's in Forth Dimensions Vol III, p. 187. It is quite different in detail from yours, but the spirit is the same. -- Chuck Eaker / P.O. Box 8, K-1 3C12 / Schenectady, NY 12301 USA eaker@crd.ge.com eaker@crdgw1.UUCP (518) 387-5964