in Forth, at least in this specific case, Strings have their length specified at the START of the String in memory. In C, for example, Strings are stretches of bytes terminated by a 0. In Forth, and in other languages such as Pascal, Strings have an associated length with them, and typically, as in this case, the length is at the beginning of the String.
So, for the String "HELLO", the bytes would look like
05 H E L L O
And the start of the string points at the byte with the 5 in it.
Your code locates the string, skips past the length (that first char+
), then primes it for the cmove
, which does the work.
At the end, it copies the length in to the start of the new String.
You example use of place
is wrong, as you do not specify the length of the copy. This needs the length as the second argument on the stack.
So, your example should be:
s" Hello! " 7 name place \ 7 because of the space after the Hello!, the quote is the
\ delimiter, not the space. The leading spaces are ignored
The odd part about this is that in theory there's no need to pass the length to the word, it's already there in the String. You would specify the length if you wanted to copy a subset.
You could look at it this way as well. Given place
as it is, you could write a simple word:
: copy-string ( string-src dest -- )
>r \ string-src
dup \ string-src string-src
c@ \ string-src length
<r \ string-src length dest
place ;
So:
s" Hello! " name copy-string
Then, you could do:
: type-string ( string-src )
dup \ string-src string-src
c@ \ string-src length
type ; \ type out the string, type requires addr and length
So:
create name 10 allot
s" Hello! " name copy-string
name type-string