2017-06-01 133 views
4

我正试图围绕立即执行和延期执行。 从我的理解是,解释器维护一个标志,知道它是否在延期执行或不。PostScript立即执行或延期执行

推迟执行过程可能是因为名称查找返回了一个过程。

现在我试图找出哪些类型,操作或操作控制这个解释器标志。

例如,下面这段代码在最后有一个立即评估的名称,它返回一个过程。但这个过程是推,虽然它是可执行文件(xcheck):

/setdata 
{ 
    /a 1 def 
    /b 0 def 

/foo 
    a 0 ne 
    b 0 ne 
    and 
def 

{ foo false and } 
} def 

//setdata 

我知道有一个特殊的规则:直接出现

程序(无论是作为计划的一部分,正在读 从一个文件或作为内存中一些较大过程的一部分)通常是定义或构造的一部分,例如条件, 明确地对该过程进行操作。但是间接获得的程序(例如,作为查找名称的结果)通常是 意图被执行。 PostScript程序可以在必要时覆盖这些语义。

我明白,如果您直接遇到需要推送它的过程(即使它是可执行的)。 (立即评估的名称返回一个直接遇到的过程,所以它应该被推送到操作系统。)

现在,如果我在代码中思考在解释器中实现此逻辑,我可以想到类似这样的事情:

如果我有一个文字名查找,请设置解释器的DeferredFlag = true; 现在我怎么知道延迟执行何时结束?如果我遇到“def”名字,我可以硬编码,但也可能有其他名称。

(+什么的情况下,程序嵌套在正在执行的程序。等...)

我无法找到一个方法来控制在解释器DeferredFlag知道当前的执行模式。

希望问题清楚。

更新:

一些额外的代码示例我尝试没有成功调试。

代码1:

/foo { 2 3 add } def 
foo 
% result: 5 

代码2:

/foo { 2 3 add } def 
//foo 
% result: { 2 3 add } 

代码3:

/foo { 2 3 add } def 
/bar { foo } def 
bar 
% result: 5 

代码4:

/foo { 2 3 add } def 
/bar { //foo } def 
bar 
% result: { 2 3 add } 

回答

3

在试图理解口译员时,我有许多相同的问题和困惑。国际海事组织术语延期执行不是很有用。另外,我觉得这个词马上评价也不是很有用。你不需要一个DeferredFlag。

这里涉及到两个独立但相关的部分:解释器循环和运算符token

token处理“延迟执行”的一部分,它将可执行数组的所有令牌收集到单个对象中。所以如果一个文件或字符串以过程体开头,那么调用token就会产生整个过程体。

{ execution is deferred until the closing } 

它看起来像一个评论,但毕竟是PostScript代码行其不需要即使没有的话推迟关闭等被定义的错误运行。但是,如果您打电话给exec,或者将其定义为名称,那么它将执行,并且最好定义内容。

解释器循环总是从exec堆中抓取顶层对象,并且语义上可执行数组,文件和字符串的行为都是相同的。口译员将其视为来源并获得第一个要素。名称案例有点不同,因为它本身不是来源。 (我介绍我自己的概念,希望它有助于/工作)。在C-ISH伪代码:

main_loop(){ 
    while(! quit){ 
     eval(); 
    } 
} 

eval(){ 
    object = pop(exec_stack); 
    if(!executable_flag(object)) push(op_stack, object); 
    else switch(type_of(object)){ 
     case array: array_handler(object); break; 
     case string: string_handler(object); break; 
     case file: file_handler(object); break; 
     case name: name_handler(object); break; 
     default: push(op_stack, object); 
    } 
} 

在名称的情况下,查找名称,如果可执行文件执行。

name_handler(object) { 
    object = load(object); 
    push(executable_flag(object) ? exec_stack : op_stack, object); 
} 

在其他三个,你还必须检查它是否是一个数组。

array_handler(object){ 
    switch(length(object){ 
    default: 
     push(exec_stack, getinterval(object, 1, length(object) - 1)); 
     /* fall-thru */ 
    case 1: 
     object = get(object, 0); 
     push(executable_flag(object) && type_of(object) != array ? 
       exec_stack : op_stack, object); 
    case 0: 
     /* do nothing */ 
    } 

} 

只有executable_flag(object) && type_of(object) != array然后你推到exec堆栈。

对于另一个问题,立即评估的名称,我更喜欢称它们为立即加载的名称。在返回之前,token运营商在其上呼叫load。容易处理,如果在正确的地方完成。它与“延期执行”部分没有真正的互动。

编辑:

我通过我的debugger与跟踪跑你的样品。这显示每个令牌执行后op_stack的运行图片。左边的元素是由token返回的对象。请注意,token已经消耗了所有的//

$ cat test.ps 
(db5.ps) run currentfile cvx traceon debug 

/foo { 2 3 add } def 
foo 
% result: 5 

/foo { 2 3 add } def 
//foo 
% result: { 2 3 add } 

/foo { 2 3 add } def 
/bar { foo } def 
bar 
% result: 5 

/foo { 2 3 add } def 
/bar { //foo } def 
bar 
% result: { 2 3 add } 

$ gsnd -DNOSAFER test.ps 
GPL Ghostscript 9.19 (2016-03-23) 
Copyright (C) 2016 Artifex Software, Inc. All rights reserved. 
This software comes with NO WARRANTY: see the file PUBLIC for details. 
%|- 
/foo %|- /foo 
{2 3 add} %|- /foo {2 3 add} 
def %|- 
foo %|- 5 
/foo %|- 5 /foo 
{2 3 add} %|- 5 /foo {2 3 add} 
def %|- 5 
{2 3 add} %|- 5 {2 3 add} 
/foo %|- 5 {2 3 add} /foo 
{2 3 add} %|- 5 {2 3 add} /foo {2 3 add} 
def %|- 5 {2 3 add} 
/bar %|- 5 {2 3 add} /bar 
{foo} %|- 5 {2 3 add} /bar {foo} 
def %|- 5 {2 3 add} 
bar %|- 5 {2 3 add} 5 
/foo %|- 5 {2 3 add} 5 /foo 
{2 3 add} %|- 5 {2 3 add} 5 /foo {2 3 add} 
def %|- 5 {2 3 add} 5 
/bar %|- 5 {2 3 add} 5 /bar 
{{2 3 add}} %|- 5 {2 3 add} 5 /bar {{2 3 add}} 
def %|- 5 {2 3 add} 5 
bar GS<4> 
GS<4>pstack 
{2 3 add} 
5 
{2 3 add} 
5 
GS<4> 
+0

关于立即评估的名称。例如在应该返回的程序的情况下(作为imm评估名称的结果)。 这会返回1个过程对象,例如{2 3 add}还是会返回5个表示过程的标记:标记{,标记2,标记3,标记添加,标记}? – juFo

+0

它返回1个过程对象。有两种方法可以考虑这一点。 'def'总是为该值接受一个单一对象,并且立即评估的名称总是从早期的“def”生成值,因此立即评估的名称只能返回单个对象。 OTOH的所有程序结构通过'token'运算符进入解释器,'token'总是消耗最多}并返回一个对象。如果没有右大括号,'token'指示/语法错误。所以,没有像“令牌{”这样的东西。在postscript中它本身永远不会存在。 –