2016-07-08 2 views
2

스택에 두 개의 절차 p1p2이 있다고 가정하고 이들을 소비하고 해당 효과를 결합하는 새로운 절차를 스택에 남기고 싶습니다. 나는 이것을하기위한 절차를 원한다. 내가 항상 사전에 약간의 부기를 기꺼이하고 있다면 충분히 쉽다. 하지만 이름을 알리지 않고 할 수 있습니까? (단지 현재의 스택에 결합 효과를 실행하기 위해, I가 생성 절차하고자합니다.)포인트 프리 프로 시저 구성

예를

/compose {<< /f1 4 2 roll /f2 exch >>begin {f1 f2} end}bind def 

위해 고려 F1 및 F2를 알 수 있기 때문에 이는 당연히 작동하지 end 이후. 하지만이 깨진 코드는 내가 무엇을했는지 설명해야합니다.

답변

1

전적으로 가능하며별로 어렵지 않습니다. 각 프로 시저 개체에 실행 파일 이름 exec이 오는 새 배열을 만듭니다. 그런 다음 해당 배열을 실행 가능하게 만듭니다. 가까이 명명 된 인수하여 원본에 스타일에 대한

/combine { % {a} {b} . {{a} exec {b} exec} 
    /exec cvx exch  % {a} exec {b} 
    /exec cvx   % {a} exec {b} exec 
    4 array astore  % [{a} exec {b} exec] 
    cvx    % {{a} exec {b} exec} 
} def 

는,이처럼 작성합니다

% fun1 fun2 compose proc 
/compose { 2 dict begin  % f1 f2 
    {f2 f1}{exch def} forall % 
    ({ //f1 exec //f2 exec }) % ({ //f1 exec //f2 exec }) 
    cvx exec     % { <f1> exec <f2> exec } 
end } def 

//immediate-name 구문은 매우 강력하다. 여기서는 문자열에 코드 템플릿을 사용합니다. 문자열이 실행되면 cvx exec 내용에 따라 스캐너가 호출되며 자동으로 load의 모든 토큰 앞에 이중 슬래시 //이 붙습니다. 주석 <f1>은 명명 된 변수의 내용을 나타냅니다. 프로그램 스트림의 {executable array}이 실행되지 않고 스택에 proc을 생성하는 것처럼 exec 문자열을 포함하는 문자열도 스택에 proc을 생성합니다.

명명 된 인수 스타일의 경우 몇 가지 특별한 포스트 스크립트 규칙을 사용합니다. 실행 가능 배열이 실행되지 않으므로 변수 이름 배열을 실행 배열로 작성한 다음 추가 번거 로움없이 데이터로 사용할 수 있습니다. 그러나 실행 구문을 사용하면 내용 (이름)을 /없이 쓸 수 있습니다. 따라서 [ /f2 /f1 ] 대신 { f2 f1 }을 쓸 수 있습니다.

인수 부분을 자체 함수로 분해 할 수도 있습니다.

/argsbegin { % a r g s _ {n a m e s} . - 
    dup length dict begin 
    {exch def} forall % currentdict:<</n _ /a s /m g /e r /s a>> 
} def 

/compose { {f2 f1} argsbegin 
    ({//f1 exec //f2 exec}) token pop exch pop %another way to invoke the scanner 
end } def 

실제로 인수를 올바른 방법으로 전달하려면 다음과 같을 수 있습니다. for 루프를 사용하여 뒤로 forall을 시뮬레이트하는 것은 약간 어색합니다.

/argsbegin { % a r g s _ {n a m e s} . - 
    dup length dup dict begin % a r g s _ {} n 
    1 sub -1 0 { % a r g s _ {} i 
     3 2 roll % a r g s {} i _ 
     3 copy % a r g s {} i _ {} i _ 
     pop  % a r g s {} i _ {} i 
     get  % a r g s {} i _ /s 
     exch def % a r g s {} i 
     pop  % a r g s {} 
    } for   % {} 
    pop 
} def 

/compose { {f1 f2} argsbegin 
    ({//f1 exec //f2 exec}) cvx exec 
end } def 
+0

니스. 나는'exec'을 사용하는 방법을 찾아 내려고 노력하고 있었지만 스택에 리터럴 이름을 넣고 실행 가능하게 만들 수 있다는 것을 몰랐습니다. 감사. – Alan

+0

대단히 반갑습니다. 나는 프로그래밍 측면에 실제로 들어가는 포스트 스크립트 질문을 좋아합니다. 필자는 필자의 [문서 형식 엔진] (https://github.com/luser-dr00g/ibis.ps/blob/0c0aa7d5bd683d21d9814b2b697a85028bcddc81/ibis.ps#L750)에서 약 750 ~ 850 줄의 함수를 정의하는보다 복잡한 예제가 있습니다. * morphisms * (change-state/revert-state 함수 쌍)의 합성을 수행하는 'addstyle'이라고 불린다. –

+0

동일한 프로그램의 초안이 [검토 중]입니다. (http://codereview.stackexchange.com/questions/117320/document-formatting-markup-engine-in-postscript) GitHub에서 줄 번호 및 구문 강조 표시. –

관련 문제