2016-09-26 7 views
2

ed의 입력 형식을 모방하는 텍스트 편집기를 작성하려고합니다. ed에서 한 번에 한 줄씩 입력하고 한 줄에 하나의 .을 입력하면 완성됩니다. 여기에 내가 무엇을 최대 온의 :루프에 대한 입력 견적이 예상 효과와 일치하지 않습니다.

0 [ 
    [ readln [ "." = not ] keep swap ] dip 1 + swap 
] loop 
nip 1 - narray 

이 조각은 한 번에 사용자 한 줄에서 입력을 취득, 그것은 하나의 점에 도달 할 때 중지하고 문자열의 배열을 반환합니다.

나는 최대한 빨리 단어에 넣어 시도로 자체에 때 오류를 얻을 수 있지만하지 않습니다

: getinput (-- input) 
    0 [ 
     [ readln [ "." = not ] keep swap ] dip 1 + swap 
    ] loop 
    nip 1 - 
    narray 
; 

내가받을 다음과 같은 오류 :

The input quotation to “loop” doesn't match its expected effect 
Input       Expected   Got 
[ ~quotation~ dip 1 + swap ] (... -- ... ?) (x -- x x x) 
(U) Quotation: [ c-to-factor -> ] 
... 

컴파일러가 스택 선언을 신경 쓰지 않는 것과 관련이 있다고 생각합니다. 루프 밑의 스택을 수정하는 것에 불만이 있습니까? 내가 call()에 대해 알고 있지만, 내가 그것을 여기에서 사용해야한다면, 어떻게?


편집 : 나는 또한 바로 다음 시도 :

:: getinput (-- input) 
    0 :> count! 
    [ [ "." = not ] keep swap ] 
    [ readln count 1 + count! ] do while 
    drop count 1 - narray 
; 

내가 유사한 오류 그러나 스택 효과는 약간 다릅니다 :

The input quotations to “while” don't match their expected effects 
Input                Expected   Got 
[ ~quotation~ keep swap ]           (..a -- ..b ?) (x -- x x) 
[ _ 1 load-locals readln 0 get-local local-value 1 + 0 get-local... (..b -- ..a) (-- x) 
(U) Quotation: [ c-to-factor -> ] 
... 

다시 자체에 잘 ,하지만 한마디로 컴파일되지 않습니다.

답변

1

적은 로터리과 지역 주민을 사용하지 않고, 만세 삼창

! get input as array of lines 
: getinput (-- input) 
    { } [ 
     readln 
     ! stop on . 
     [ "." = ] keep swap 
     [ 
      drop f 
     ] [ 
      1array append 
      t 
     ] if 
    ] loop 
; 

나는 오류도 간단한 분기에, 요소는 꽤 엄격한 스택 효과 물건을 가지고 있다는 사실과했다 생각합니다.

+1

니스, 단지 스택이 아닌 임의의 데이터 구조와 지역 바르와 함수 인수, 같은 목적으로 사용하고 있다고 생각. 나는이 작은 조정을 제안 할 것이다. 1)'dup '. " ='대신에'[ "." =] 스왑을 유지하십시오. 2)'1array append' 대신'{}'와'suffix! '대신'V {} clone'을 사용합니다. 결과로 배열이 필요한 경우 끝에'> array'를 할 수 있습니다. 이렇게하면 추가 할 때마다 새 것을 할당하지 않습니다. (접미사와 추가 사이의 차이점은 돌연변이 유무와 상관없이 적용 가능합니다.) –

1

리스너에서 코드를 작성할 때 오류가 발생하지 않는 이유는 코드를 최적화하지 않고 스택 효과를 확인하지 않는 순진 컴파일러로 컴파일되기 때문입니다.

예를 들어 수신기에서 clear을 실행할 수 있지만 단어에 어떤 스택 효과가 있습니까? 데이터 저장소에있는 항목의 수에 따라 다릅니다. 세 가지 효과가있는 경우 (x x x --), 두 개는 (x x --) 또는 두 개는 (x --)입니다. 시도하고 단어로 clear 넣고 컴파일하십시오. 최적화 컴파일러는 스택 효과가 무엇인지 모르기 때문에 그렇게 할 수 없습니다.

0 [ 
    [ readln [ "." = not ] keep swap ] dip 1 + swap 
] loop 

그것은 사용자가 기간 전에 입력 얼마나 많은 라인에 따라 스택 효과입니다 :

코드는 같은 문제가 있습니다. 따라서 (-- x x x), (--) (제로 라인), (-- x) 등이 될 수 있습니다. 표시되는 오류 메시지는 아마도 명확하지 않지만이 문제가 원인입니다.

당신은 루프를 다시 한 방법, 요인 정적의 스택 효과를 확인하고 코드를 컴파일 할 수 있습니다 또한

[ readln [ "." = ] keep swap [ drop f ] [ 1array append t ] if ] infer. 
(x -- x x) 

참고 loop 것은 반복을 구현하기위한 낮은 수준의 단어이고 당신은 필요가 없습니다 거의 안 그것을 사용하십시오. 예를 들어, produce 콤비 사용할 수 있습니다

[ readln dup "." = not ] [ ] produce 
+0

최적화에 대한 설명과 스택 효과를 확인하는 데 도움이되어 주셔서 감사합니다. – user1610406