2015-01-29 3 views
1

Недавно, на comp.lang.forth Я нашел код, любезно написанный Coos Haak, с которым я с трудом понимаю.Как работают 2> r и 2r> работают?

Предполагается суммировать или умножать цифры между скобками. Например,

(1 2 3 +) ok 
. 6 ok 

Для удобства, я буду воспроизводить его здесь:

: ( 
    depth 1+ r> 2>r 
; 

: cond 
    depth j > 
; 

: done 
    2r> rdrop 2>r 
; 

: +) 
    begin cond 
    while + 
    repeat 
    done 
; 

: *) 
    begin cond 
    while * 
    repeat 
    done 
; 

Я вижу фразы r> 2>r и 2r> rdrop 2>r. Но я довольно смущен тем, что они делают. Я предполагаю, что глубина стека в открытой скобке каким-то образом скрывается в стеке возврата. Но я этого не понимаю.

Что они делают с возвратным стеклом?

В документации Gforth я вижу:

r>  R:w – w  core   “r-from” 
2>r  d – R:d  core-ext  “two-to-r” 
2r>  R:d – d  core-ext  “two-r-from” 
rdrop  R:w –   gforth   “rdrop” 

w Cell, can contain an integer or an address 
d double sized signed integer 

ли это что-то делать с переходом между ш и д?

ответ

2

2>r (и слово «Форт 200x» n>r) сохраняет порядок элементов, перемещаемых в стек возврата. Так что если у вас есть (1 0) в стеке данных, с 0 в верхней части стека, то после 2>r у вас будет 0 в верхней части стека возврата и 1 под ним. 2>r поэтому определим, а не как

: 2>r ]] >r >r [[ ; immediate 

Но, как:

: 2>r ]] swap >r >r [[ ; immediate 

И эти определения эквивалентны:

: a ]] 0 >r 1 >r [[ ; immediate 
: b ]] 0 1 2>r [[ ; immediate 

Что Кус Хаак делает в этом коде тогда проскользнуть значение ниже вершины возвратного стека. Если его ( просто подтолкнул глубину к вершине возвращаемого стека, то при выходе из этого слова gforth попытался бы перейти на глубину в качестве адреса. То же самое состояние ошибки видно, если вы пытаетесь использовать его слова таким образом:

: numbers (1 2 ; 
: sum +) ; 
numbers sum 
\ output: :16: error: Invalid memory address 
\   >>>numbers<<< sum 

Этот код будет работать, однако (и нормальное использование провалится), если ( и +) согласованному с третьим элементом на стеке возвратов а не второй.

Есть несколько подводных камней с этим кодом:

  1. нормальные обитатели стека возвратов, так сказать, не гарантируется занимать только одну ячейку стека возврата.

  2. Использование j опирается на знания о точной глубине в стек возвратов, что j вытягивает из - то есть, он опирается на знания о том, как реализуются DO ... LOOP и связанные с ними слова.

Эти слова могут быть переносимым реализованы как непосредственные слова, где они будут держать глубину в верхней части стека возвратов, но тогда вы не могли бы использовать их за пределами определения. Это достаточно просто, чтобы заставить их работать, как на любом данном Форте.

+0

Итак, я полагаю, что в документах gforth тип данных «d» представлен двумя элементами данных, а «w» - только одним. Я рад, что теперь имею ссылку на 200x. – beeflobill

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