2013-08-08 7 views
1

я после example, пытаясь объяснить себе, что он делает:Копировать статически строку в динамически распределяемой один

: 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 

Все это имело смысл, до последней инструкции ... где я ошибся ?

EDIT:

Я добавил некоторые трассировку:

: 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 

ответ

1

Я думаю, что первая часть ответа Уилла Хартунга верно.

Строковое представление, которое используется, как он описал, а именно количество символов, а затем фактическая строка.

Итак, в вашем примере c! хранит длину строки в первой ячейке памяти, которая начинается с ptr2.

Так что если вы хотите, чтобы получить свою строку, которую вы должны знать только адрес, вы могли бы извлечь из этого адреса, чтобы получить длину п, и выборки п символов, начиная с адреса + 1.

+1

Извините, мне потребовалось навсегда ответить. Да, теперь я понял, где моя ошибка. Я думал, что перемещение данных между стеками было fifo, но это lifo, поэтому я понимаю, что произошло сейчас. –

+0

Не волнуйтесь! Я рад, что вы разобрали его. – sheepez

1

в Forth, по крайней мере, в этом конкретном случае, строки имеют длину указано в начале строки в памяти. В C, например, строки - это длины байтов, заканчивающиеся на 0. В Forth, а на других языках, таких как Pascal, строки имеют связанную длину с ними, и обычно, как и в этом случае, длина находится в начале Струна.

Так, для строки «HELLO», байты будут выглядеть

05 H E L L O 

И в начале строки указывает на байт с 5 в нем.

Ваш код находит строку, пропускает ее длину (первая char+), затем пронумерует ее для cmove, что делает работу.

В конце он копирует длину в начало новой строки.

Вы, например, используете place, так как вы не указываете длину копии. Для этого требуется длина в качестве второго аргумента в стеке.

Итак, ваш пример должен быть:

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 
    [email protected]       \ string-src length 
    <r       \ string-src length dest 
    place ; 

Итак:

s" Hello! " name copy-string 

Тогда вы могли бы сделать:

: type-string (string-src) 
    dup   \ string-src string-src 
    [email protected]   \ 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 
+0

You вероятно, захотите снова рассмотреть пример. Это не «мое использование примера», я скопировал его, как и тот, который находится на связанной странице. Я также тестировал его, и он работал как рекламируемый ... Кроме того, возможно, это вас смутило, в комментариях, которые я написал рядом с кодом, верхняя часть стека находится вправо (самый правый элемент берется первым из стек). –

+0

На самом деле, они, как вы его написали, я получаю ошибку «неправильный адрес памяти». –

Смежные вопросы