PostScript执行嵌套过程

时间:2013-05-08 10:20:21

标签: stack interpreter execution procedure postscript

(我又回来了另一个问题:-))

给出以下PostScript代码:

/riverside { 5 pop } def
/star { 6 pop 2 {riverside} repeat } def
star

我想知道应该如何处理嵌套程序。 (我正在创建自己的翻译)。 当我执行星形程序时,它会找到一个名称Obc(河边)并将其替换为包含河边程序中的值的可执行数组并执行它们。 如果我执行重复操作符,则解释器崩溃,因为堆栈中只剩下一个项目。

当我已经在可执行数组(= prodecure)中时,我是否应该直接执行可执行数组(= procedure),或者是否应该在(操作数?/执行?)上推送可执行数组(=过程)堆?或者只能由其他运营商执行? 这条河边应该执行多少次? (2或3次?)我猜2?

供您参考:这是我在第3行执行 star 时的情况(参见错误):

% begin execute 3rd line (star)
% OP = operand stack
% EX = execution stack    

% handle 6
OP: 6
EX: star

% handle pop (removes 6 from OP)
OP: -
EX: star

% handle 2
OP: 2
EX: star

% set the riverside executable array on the EX, execute the values
OP: 2
EX: star riverside

% repeat operator:
CRASH, only one item on the OP left, but repeat operator requires 2 operands.
OP: 5
EX: 

% end

请在这件事上发光,因为它有点复杂/令人困惑: - )

更新 另一个代码示例可能就是这个:

/starside
{ 72 0 lineto
currentpoint translate
-144 rotate } def

/star
{ moveto
currentpoint translate
4 {starside} repeat
closepath
gsave
.5 setgray fill
grestore
stroke } def

200 200 star

showpage

当解释器将 / star {moveto ... 标记为遇到嵌套的 {starside} 时,如何对待它? (+如果有 {starside 5 2 mul pop} 而不仅仅是 {starside} 会怎么样?)

1 个答案:

答案 0 :(得分:3)

我认为您需要查看PLRM的第3.5.3节。虽然这涉及一个简单的可执行数组,但概念是相同的。当令牌扫描器遇到'{'时,它开始构建可执行阵列。在它达到匹配的'}'标记之前,扫描程序只是将它遇到的内容存储在操作数堆栈中。遇到匹配的'{'然后将对象转换为可执行数组(并存储在操作数堆栈中)

如果扫描程序遇到可执行文件名,则会将名称存储在操作数堆栈中。它不执行名称,也不执行查找以检索关联的对象。

因此,在您的示例中执行'}'之前,操作数堆栈将包含twp对象,'{'开放数组和可执行名称riverside。遇到'}'时,扫描程序会创建实际的可执行数组并将其存储在操作数堆栈中。 (注意,实施细节在这里有所不同)

因此,在执行'repeat'之前,您将在堆栈上有两个对象,计数器和一个包含单个可执行文件名的可执行数组。

在执行包含该名称的可执行数组之前,您不会查找该名称。

这可能会更清楚:

%!
/test {(This is my initial string\n) print} def
2 {test} repeat
2 {test} /test {(This is my second string\n) print} def repeat

请注意,在创建包含可执行文件名“test”的可执行数组之后,我重新定义了'test',但执行使用了后面的test定义。正如你所看到的,不要过早地进行名称查找至关重要!