Семь уроков по PostScript

       

Массивы


PostScript работает с одномерными массивами - (векторами), которые определяются как набор объектов ( возможно разного типа), заключенный в квадратные скобки. Так

[ (PC Magazine) 1991 54]

и

[ (Julia) 4 12 78]

массивы, причем первый элемент этих массивов - строка. (Такие структуры в других языках , кроме АПЛ, обычно называют записями). Операции внутри квадратных скобок выполняются по обычным правилам PostScript, так после вычисления

[(add) 10 5 6 mul sub]

получим массив из двух элементов.

Массив может быть также определен с помощью оператора array, который берет из стека число и создает массив такой длины.

8 array

Эта строка оставит в стеке массив из 8 элементов. Его элементы -- NULL-объекты.

Когда массив создается строкой типа

[1 2 3 8 ],

то квадратные скобки, используемые для его записи играют в PostScript большую роль, чем это кажется на первый взгляд. Открывающая (левая) квадратная скобка оставляет в стеке объект, называемый маркером



(mark). После маркера интерпретатор просматривает строку программы дальше и помещает в стек все встречающиеся ему объекты до правой квадратной скобки. Эта скобка является оператором, создающим массив из хранящихся в стеке объектов: от вершины до маркера. При этом маркер удаляется из стека, а массив остаётся.

Массивы, строки и словари -- всё это примеры объектов сложных типов. Их значения хранятся PostScript отдельно от самого объекта (то есть PostScript работает в этом случае не со значением, а с указателем на него). Так операция dup над строкой дублирует объект, но не его значение, которое в этом случае разделяется двумя объектами. Массив в PostScript индексируются с нуля. Для работы с элементами массивов служат операторы put и get.

Оператор put берет из стека три аргумента: массив, индекс элемента в массиве и объект. Он помещает объект в массив в позицию, заданную индексом:

/MyArray 12 array def

MyArray 5 (Jerry) put]

У оператора get два аргумента: массив и индекс. Он возвращает в стеке элемент массива с заданным индексом. После выполнения строки


[0 1 2 3 4 5] 5 get

в вершине стека будет число 4.

Для работы с массивами также необходим оператор length, возвращающий длину массива (то есть число его элементов). Следующая программа распечатывает массив, находящийся в стеке.

/LeftM 60 def

/TmpString 40 string def

/Helvetica findfont 11 scalefont setfont /newln

{currentpoint 15 sub exch pop    % y-15

LeftM exch moveto} def

/printarr    % в стеке массив

{/arr exch def  % поместить массив в переменную 0 1 arr length 1 sub % параметры цикла

{arr exch get    % следующий элемент

 TmpString cvs

 show newln} for

} def

LeftM 400 moveto

[(Julia)         % строка

15    % число

/SimplName   % литерал

[8 3 4]  % массив

{NewLN}  % исполняемый массив

LeftM % переменная

]

printarr

showpage

Перед каждым выполнением цикла оператор for  помещает в стек счетчик, который используется в качестве индекса в строке arr exch get. ( В этой строке берется не сам массив из стека, а ссылка на него по имени переменной, поэтому и делается exch.)

Результат работы программы

Julia

15

SimplName

--nostringval--

--nostringval--

60

Как видно из примера обычные действия над массивом в PostScript достаточно утомительны. Так как наиболее частой операцией над массивом в этом языке является применение некоторой процедуры к каждому его элементу, то для этого есть очень красивый оператор farall, который применяет к массиву-аргументу заданную процедуру. Предыдущий пример можно записать с его помощью более компактно:

arr {30 string cvs show} forall


Содержание раздела