Level 1, lesson 9

# 1.9 Slicing strings

Slicing strings is just like copying strings. We just don't copy all of it and we don't always start copying at the beginning of a string. We'll show you what we mean:

         32 string one                   \ define string one
         " Hans Bezemer" one copy        \ initialize string one
         dup count type cr               \ duplicate and print it
         char+                           \ move one character forward
         dup count type cr               \ duplicate and print it again
         char+                           \ move one character forward
         dup count type cr               \ duplicate and print it again
         char+                           \ move one character forward
         count type cr                   \ print it for the last time

First it will print "Hans Bezemer", then "ans Bezemer", then "ns Bezemer" and finally "s Bezemer". The word 'CHAR+' is functionally equivalent to '1+', but a more portable way to do manipulations on strings. If we want to discard the first name at all we could even write:

         32 string one                   \ define string one
         " Hans Bezemer" one copy        \ initialize string one
         5 chars + count type cr         \ print sliced string

The five characters we want to skip are the first name (which is four characters) and a space (which adds up to five). There is no special word for slicing strings. There is a smarter way to handle strings in 4tH, which we will discuss later on. But if you desperately need slicing you might want to use a word like this. It works just like 'CMOVE' with an extra parameter:

         : slice$
               over over                 \ copy the dest and #chars
               >r >r >r >r               \ store on the return stack
               chars +                   \ make address to the source
               r> r>                     \ restore dest and #chars
               cmove                     \ copy the string
               0                         \ throw NULL char. on stack
               r> r>                     \ restore dest and #chars
               chars +                   \ make index to slice
               c!                        \ terminate string
         ;

This is another example of "you're not supposed to understand this". You call it with:

         source index-to-source destination #chars

The index-to-source starts counting at zero. So this will copy the first name to string "two" and print it:

         : slice$
               over over                 \ copy the dest and #chars
               >r >r >r >r               \ store on the return stack
               chars +                   \ make address to the source
               r> r>                     \ restore dest and #chars
               cmove                     \ copy the string
               0                         \ throw NULL char. on stack
               r> r>                     \ restore dest and #chars
               chars +                   \ make index to slice
               c!                        \ terminate string
         ;

         32 string one                   \ declare string one
         32 string two                   \ declare string two
         " Hans Bezemer" one copy        \ initialize string one
         0 two 4 slice$                  \ slice the first name
         two count type cr               \ print string two

This will slice the last name off and store it in string "two":

         : slice$
               over over                 \ copy the dest and #chars
               >r >r >r >r               \ store on the return stack
               chars +                   \ make address to the source
               r> r>                     \ restore dest and #chars
               cmove                     \ copy the string
               0                         \ throw NULL char. on stack
               r> r>                     \ restore dest and #chars
               chars +                   \ make index to slice
               c!                        \ terminate string
         ;

         32 string one                   \ declare string one
         32 string two                   \ declare string two
         " Hans Bezemer" one copy        \ initialize string one
         5 two 7 slice$                  \ slice the first name
         two count type cr               \ print string two

Since the last name is seven characters long and starts at position five (start counting with zero!). Although this is very "Basic" way to slice strings, we can do this kind of string processing the 4tH way. It will probably require less stack manipulations.