Stack Manipulation

Because the stack is so important, PostScript offers a slew of operators to manipulate the operand stack. In this chapter we are going to explore some of them.

We could show a picture of the stack, but that takes up a lot of space. Instead we will rely on a representation of the operand stack that fits on a line.

\[ a_{n-1}\ a_{n-2}\ \dots\ a_{1}\ a_{0} \]

The above line represents a stack that has \(n\) items. The bottom item is \(a_{n-1}\), the item above that one is \(a_{n-2}\), etc. The top item is \(a_{0}\).

Operators

push

Pushes onto the operand stack are often implicit. For example, it is enough just to list the value for it to be pushed on the operand stack.

37

The program listing above will push the value 37 onto the operand stack.

pop

The opposite of pushing is popping. This can be achieved by the pop operator. This will remove the top most item from the operand stack.

37 51 pop

This leaves the operand stack containing the value 37.

dup

To duplicate the top element on the operand stack use the dup operator.

37 dup

The above program will result in an operand stack containing two values: 37 37.

exch

If there are more than two items on the operand stack, exch allows you to exchange the top two items. If the operand stack contains 1 2 3, the operator exch will exchange the 2 and the 3, resulting in a stack containing 1 3 2. The program below demonstrates that behavior.

1 2 3
exch

copy

The copy operator is like dup on steroids. The dup operator copies the top most item on the operand stack. The copy operator, when provided with a number n to copy, copies the topmost n items.

Look at the following program.

1 2 3 4
3 copy

The first line pushes the values 1, 2, 3 and 4 on the operand stack. The next line, specifically 3 copy, first puts 3 on the operand stack and then executes the copy operator. This pops the top most number from the stack, in this case that would be 3, and copies that many elements onto the stack. This results in a operand stack

1 2 3 4 2 3 4

roll

Just like how copy is a generalization of dup, roll is a generalization of exch.

Assume we have the following stack

\[ \ldots\ a_{n-1}\ a_{n-2}\ \ldots\ a_{0}
\]

The roll operator allows to select the top most n items from the stack and "roll" them through j positions. So executing n j roll with the above stack results in

\[ \ldots\ a_{j-1}\ \ldots\ a_{1}\ a_{0}\ a_{n-1}\ a_{n-2}\ \ldots\ a_{j}
\]

With a concrete example, the following program

1 2 3 4
3 2 roll

results in the operand stack being

1 3 4 2

index

The index operator allows you to copy a single element in the operand stack to the top. With an operand stack as below

\[ \ldots\ a_{n}\ a_{n-1}\ \ldots\ a_{j}\ \ldots\ a_{0}
\]

the snippet j index results in a stack like

\[ \ldots\ a_{n}\ a_{n-1}\ \ldots\ a_{j}\ \ldots\ a_{0}\ a_{j} \]

Or with a concrete example

1 2 3 4
2 index

results in the operand stack

1 2 3 4 2

count

To count the number of items on the operand stack use the count operator.

clear

If you want to remove all the items execute the clear operator

Philosophy

Manipulating the operand stack is an important skill to learn. So much so that idiomatic PostScript advocates to think hard about the order of arguments and exclusively use operand stack manipulations.

This advice is written for application that generate PostScript in mind. When using PostScript creatively there are other mechanisms to organize your program. Ways that are geared towards readability and maintainability.

That does not mean that stack manipulation isn't worthwhile. It allows great flexibility.

Exercises

  1. What happens when there is only one item on the operand stack when exch is executed?
  2. How can you use copy to simulate dup?
  3. How can you use roll to simulate exch?
  4. How can you use index to simulate dup?
  5. What happens when you use negative numbers as the second operand for the roll operator? The second operand is the one on the top on the stack when roll is executed.
  6. The stack contains 1 2 3 4. Create a program to reverse the operand stack that contains four items.