2015-01-29 7 views
1

최근에 comp.lang.forth에 나는 이해하기 힘든 쿠아스 하크 (Koos 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>r2r> 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 

이는 w와 D 사이의 변환을 할 수있는 뭔가가 있나요?

답변

2

2>r (및 Forth 200x 워드 n>r)은 반환 스택에 푸시 된 요소의 순서를 유지합니다. 따라서 데이터 스택에 (1 0)이 있고 스택의 맨 위에 0이있는 경우 2>r 다음에 스택 스택 맨 위에 0이 있고 그 아래에 1이 있습니다.

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

그리고 이러한 정의는 동일합니다 : 2>r하지

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

그러나로, 그러므로 정의입니다

: a ]] 0 >r 1 >r [[ ; immediate 
: b ]] 0 1 2>r [[ ; immediate 
쿠스 HAAK는 그 코드에서 무엇을

가 값을 미끄러하는 것입니다 리턴 스택의 맨 아래에 있습니다. 그의 (이 반환 스택의 맨 위로 깊이를 밀기 만하면이 단어를 빠져 나올 때 gforth는 깊이로 주소로 점프하려고 시도합니다. 이 방법으로 자신의 단어를 사용하려고하면 동일한 오류 조건을 볼 수 있습니다 :

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

그 코드는하지만 일하는 것이 (정상 사용이 실패) 반환 스택의 세 번째 요소와 조정 (+) 경우 두 번째 대신에. 말하자면, 리턴 스택의

  1. 정상 거주자 리턴 스택의 하나의 셀을 차지 보장 할 수 없습니다 :

    가이 코드 몇 가지 함정이다.

  2. j의 사용은 j가 가져옵니다 리턴 스택에 정확한 깊이에 대한 지식에 의존
  3. - 즉, 그것은 DO ... LOOP 및 관련 단어가 어떻게 구현되는지에 대한 지식에 의존한다.

이 단어들은 즉석 단어로 이식 될 수 있습니다.이 단어는 반환 스택의 맨 위에 깊이있게 저장되지만 정의 밖에서는 사용할 수 없습니다. 주어진 Forth에서와 같이 작동하도록하는 것은 간단합니다.

+0

그래서 gforth 문서에서 'd'데이터 유형은 두 개의 데이터 요소로 표시되고 'w'는 하나만있는 것으로 추측됩니다. 이제 200x 레퍼런스를 갖게되어 기쁩니다. – beeflobill