1

私はに従っていて、それが何をするのかを自分自身に説明しようとしました:

: 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

最後の指示まで、それはすべて理にかなっています...どこが間違っていましたか?

編集:

いくつかのトレースを追加しました:

: 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
4

2 に答える 2

1

Forth では、少なくともこの特定のケースでは、文字列の長さはメモリ内の文字列の START で指定されます。たとえば、C では、文字列は 0 で終了する一連のバイトです。Forth や、Pascal などの他の言語では、文字列には関連する長さがあり、通常、この場合のように、長さは文字列の先頭にあります。文字列。

したがって、文字列「HELLO」の場合、バイトは次のようになります

05 H E L L O

文字列の先頭は、5 が含まれるバイトを指します。

あなたのコードは文字列を見つけ、長さ(最初のchar+)をスキップcmoveしてから、作業を行う の準備をします。

最後に、長さを新しい文字列の先頭にコピーします。

placeコピーの長さを指定していないため、使用例は間違っています。これには、スタックの 2 番目の引数として長さが必要です。

したがって、あなたの例は次のようになります。

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

これに関する奇妙な部分は、理論的には長さを単語に渡す必要がないことです。それはすでに文字列に含まれています。サブセットをコピーする場合は、長さを指定します。

このように見ることもできます。そのままplaceでは、簡単な単語を書くことができます:

: copy-string ( string-src dest -- )
    >r                          \ string-src 
    dup                         \ string-src string-src
    c@                          \ string-src length
    <r                          \ string-src length dest
    place ;

そう:

s" Hello! " name copy-string

次に、次のことができます。

: type-string ( string-src ) 
    dup           \ string-src string-src
    c@            \ string-src length
    type ;        \ type out the string, type requires addr and length

そう:

create name 10 allot
s" Hello! " name copy-string
name type-string
于 2013-08-08T22:37:54.520 に答える
1

Will Hartung の答えの最初の部分は正しいと思います。

使用されている文字列表現は、彼が説明したとおりです。つまり、文字数と実際の文字列です。

したがって、あなたの例c!では、で始まるメモリの最初のセルに文字列の長さを格納していますptr2

したがって、文字列を取得したい場合は、アドレスを知るだけでよく、そのアドレスからフェッチして長さ n を取得し、アドレス + 1 から始まる n 文字を取得できます。

于 2013-08-09T10:09:00.843 に答える