ps 文件在程序上调用 'length'

ps file calling 'length' on a procedure

我有一个包含这一行的 ps 文件:

^ab {@st0 setfont}^ap

此处定义^ab时:

/^ab{1000 array 0 1000}bind def

^ap定义在这里:

/^ap{
    dup length 3 index add dup 3 index lt{
        4 index exch 6 2 roll exch
        4 1 roll putinterval
    }{
        3 -1 roll 1000 add dup
        {array}stopped{
            pop pop pop
            3 1 roll 0 exch getinterval
            cvx bind
            1000 array dup 0 4 -1 roll put
            dup 1 /exec load put
            2 1000 4 -1 roll ^ap
        }{
            dup 0 8 -1 roll putinterval
            dup 6 -2 roll putinterval
            3 1 roll
        }ifelse
    }ifelse
}bind def`

因此,如果我没看错的话,^ab 在堆栈上创建了一个大小为 1000 和 2 个整数的数组:0 和 1000。 然后过程 {@st0 setfont} 被保存在堆栈中,所以堆栈看起来像这样:

[array, 0, 1000, {@st0 setfont}]

然后用 dup 调用 ^ap,它在堆栈上复制过程,然后调用 length,它应该得到堆栈上最顶部项目的长度,即重复的程序,但对我来说没有意义。 length 只能在字符串、数组或字典上调用。那么这是怎么回事? 还是我理解错了?

一个过程一个数组。通常是一个压缩数组,但这无关紧要。这里发生的是它得到数组 {@st0 setfont} 的长度,即 2.

尝试将 pstackdup == 粘贴到 /^ap 过程的定义中,在长度之后。

Ken 已经回答了基本问题,但我希望我的评论有助于 OP 理解这段代码。

我有根据的猜测是缩写是 ab="array begin" 和 ap="append".

它似乎将三个对象一起维护,几乎像一个元组,但所有三个都在堆栈上。数组本身,"write head" 位置,容量。然后它填充数组直到位置>容量。然后它变得有趣。它会尝试分配一个更大的数组并继续前进,但如果由于某种原因它不能分配一个更大的数组,它会将其包含在 { ... } exec 中的内容包装起来并创建一个仅包含该数组的新小数组。

相当聪明。此代码来自哪里?