Массивы
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