(       Title:  Dynamic-Strings Examples
         File:  trydstrings.fs
      Version:  0.6.24
       Author:  david.n.williams@umich.edu
      License:  public domain
Last revision:  May 29, 2002

This file provides examples that use words from our
Dynamic-Strings word list--pfe module version.  The words
$FRAME-DEPTH $GARBAGE? used in .$STAT is post pfe-0.32.75.  The
phrases containing them can be omitted to make the code work
with earlier versions of pfe.
)

loadm dstrings

: .$stat  ( -- )
  cr ." string buffer size: " /$space . ." bytes"
    ."    max #frames: " #frames .
 cr ." $unused:  " $unused . ." bytes   "
    ." $depth: " $depth .
    ."    frame depth: " $frame-depth .
   base @ hex
  cr ." $buffer:  0x" $buffer .
  cr ." $break:   0x" $break .
    4 spaces ." $frame-break:  0x" $fbreak .
  cr ." $sp:      0x" $sp .
    4 spaces ." $frame-sp:     0x" $fsp .
  cr ." $sp0:     0x" $sp0 .
    4 spaces ." $frame-sp0:    0x" $fsp0 .
  base !
  cr $garbage? IF ." There is some string garbage. "
    ELSE ." There is no string garbage. " THEN ;

: dump-strings  ( -- )
  dstrings @ ( addr)
  /$space /$space-header + /frame-stack + cell+ ( #bytes)
  dump .$stat ;

s" This is Bill's string." s, 2constant bill
s" This is Marie's string." s, 2constant marie
s" This is a string called George." s, 2constant george

variable sys-strings dstrings @ sys-strings !

108 4  make-$space dstrings !
cr .( The system default string space pointer is in SYS-STRINGS.)
cr .( To follow what's happening, it's important to look at the)
cr .( source file, trydstrings.fs.)

\ store dynamic string
bill >$s-copy
cr
cr .( We've just copied the Forth string BILL into string space)
cr .( and pushed it onto the string stack.  Note that the backward)
cr .( link points to the string stack:)
dump-strings
$variable bill$  bill$ $!

\ store external string
marie >$s $variable marie$  marie$ $!

bill$ $@ marie$ $@ george >$s 3 $frame
cr
cr .( We've made the following into a string frame [remove "]:)
cr .(   ") george type .( ")
cr .(   ") marie$ $@ $. .( ")
cr .(   ") bill$ $@ $. .( ")
cr .( Note that the first two strings are external to string space.)
cr .( The last is the same dynamic string as before, still on the)
cr .( string stack, but now the back link points outside of string)
cr .( space to BILL$, where it is also stored:)
dump-strings

cr
cr .( Using [address count] FIND-ARG gives the following string frame)
cr .( indices:)
\ $PICK works here because the frame is at the top of the stack.
george find-arg ( true) drop ( index) dup
  cr .(   index ) 1 .r .( :  ) ( index) $pick $. 
marie find-arg ( true) drop ( index) dup
  cr .(   index ) 1 .r .( :  ) ( index) $pick $. 
bill find-arg ( true) drop ( index) dup
  cr .(   index ) 1 .r .( :  ) ( index) $pick $. 
cr .( The topmost element has frame index 0.)

drop-$frame
cr
cr .( Now we've executed DROP-$FRAME, and the string and string)
cr .( frame stacks are both empty, while Bill's string remains)
cr .( stored in a string variable:)
dump-strings

cr
cr .( We're freeing the )
  /$space . .( byte string space, and creating a larger)
cr .( one for the next test with nested arguments:)

\ This makes BILL$ invalid!
dstrings @ free
204 4  make-$space dstrings !

: \n+  ( -- )  \n$ cat ;

\ test args with nesting

: reverse  args{ arg1 arg2 }
  cat" Here are the args in reverse order: " arg2 arg1 ;

: tryargs  args{ arg1 arg2 }
  cat" This is arg1: " arg1 \n+
  cat" This is arg2: " arg2 \n+
  $over ($: arg1 arg2 arg1) $over ($: arg1 arg2 arg1 arg2)
  reverse ;

$" Hello " $" world!" tryargs endcat cr $.

cr
cr .( Execute CR DUMP-STRINGS COLLECT-$GARBAGE CR DUMP-STRINGS to see)
cr .( the effect of garbage collection with no strings bound to)
cr .( variables and nothing on the string stack. )
