Question

I was following an example, trying to explain to myself what it does:

: place                                   \ ptr len ptr2
    2dup                                  \ ptr len ptr2 len ptr2
    >r >r                                 \ ptr len ptr2
    char+                                 \ ptr len (ptr2 + 1)
    swap                                  \ ptr (ptr2 + 1) len
    chars                                 \ ptr (ptr2 + 1) (len * char)
    cmove                                 \ --
                                          \ from to        how-many 
    r> r>                                 \ ptr2 len
    c! ;                                  \ len = ptr2 ???
\ s" Hello! " name place

It all made sense, until the last instruction... where did I go wrong?

EDIT:

I've added some tracing:

: place                    \ ptr len ptr2                |
    2dup    cr .s          \ ptr len ptr2 len ptr2       | <5> 16490736 5 2126333248 5 2126333248  
    >r >r   cr .s          \ ptr len ptr2                | <3> 16490736 5 2126333248               
    char+   cr .s          \ ptr len (ptr2 + 1)          | <3> 16490736 5 2126333249               
    swap    cr .s          \ ptr (ptr2 + 1) len          | <3> 16490736 2126333249 5               
    chars   cr .s          \ ptr (ptr2 + 1) (len * char) | <3> 16490736 2126333249 5               
    cmove   cr .s          \ --                          | <0>                                     
                           \ from to        how-many     |
    r> r>   cr .s          \ ptr2 len                    | <2> 5 2126333248  ok
    c! ;                   \ ptr2 = len ???              |
\ s" Hello! " name place
Was it helpful?

Solution

I think the first part of Will Hartung's answer is correct.

The string representation that is being used is as he described, namely a character count and then the actual string.

So in your example c! is storing the length of the string in the the first cell of the memory that starts with ptr2.

So if you wanted to retrieve your string you would only need to know the address, you could then fetch from that address to get the length n, and the fetch n chars starting at the address + 1.

OTHER TIPS

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top