+( This word returns the width (in characters) of an unsigned number in the current base )
+: UWIDTH ( u -- width )
+ BASE @ / ( rem quot )
+ ?DUP IF ( if quotient <> 0 then )
+ RECURSE 1+ ( return 1+recursive call )
+ ELSE
+ 1 ( return 1 )
+ THEN
+;
+
+: U.R ( u width -- )
+ SWAP ( width u )
+ DUP ( width u u )
+ UWIDTH ( width u uwidth )
+ ROT ( u uwidth width )
+ SWAP - ( u width-uwidth )
+ ( At this point if the requested width is narrower, we'll have a negative number on the stack.
+ Otherwise the number on the stack is the number of spaces to print. But SPACES won't print
+ a negative number of spaces anyway, so it's now safe to call SPACES ... )
+ SPACES
+ ( ... and then call the underlying implementation of U. )
+ U.
+;
+
+: .R ( n width -- )
+ SWAP ( width n )
+ DUP 0< IF
+ NEGATE ( width u )
+ 1 ( save a flag to remember that it was negative | width n 1 )
+ -ROT ( 1 width u )
+ SWAP ( 1 u width )
+ 1- ( 1 u width-1 )
+ ELSE
+ 0 ( width u 0 )
+ -ROT ( 0 width u )
+ SWAP ( 0 u width )
+ THEN
+ SWAP ( flag width u )
+ DUP ( flag width u u )
+ UWIDTH ( flag width u uwidth )
+ ROT ( flag u uwidth width )
+ SWAP - ( flag u width-uwidth )
+
+ SPACES ( flag u )
+ SWAP ( u flag )
+
+ IF ( was it negative? print the - character )
+ '-' EMIT
+ THEN
+
+ U.
+;
+
+: . 0 .R SPACE ;
+
+: .S ( -- )
+ '<' EMIT DEPTH U. '>' EMIT SPACE
+ PSP0 @ 1+
+ BEGIN
+ DUP PSP@ 2 - <=
+ WHILE
+ DUP @ .
+ 1+
+ REPEAT
+ DROP
+;
+
+: U. U. SPACE ;
+
+( ? fetches the integer at an address and prints it. )
+: ? ( addr -- ) @ . ;
+
+( c a b WITHIN returns true if a <= c and c < b )
+: WITHIN
+ -ROT ( b c a )
+ OVER ( b c a c )
+ <= IF
+ > IF ( b c -- )
+ TRUE
+ ELSE
+ FALSE
+ THEN
+ ELSE
+ 2DROP ( b c -- )
+ FALSE
+ THEN
+;
+
+: ROLL ( x_u x_u-1... x_0 u -- x_u-1 ... x_0 x_u )
+ 1+ DUP PICK SWAP ( x_u x_u-1 ... x_0 x_u u+1 )
+ PSP@ 1- SWAP - PSP@ 2- SWAP
+ DO
+ i 1+ @ i !
+ LOOP
+ SWAP DROP
+;
+