Programming in PostScript is really pretty easy. The fundamentals are that you push operands onto the operand stack by naming them, and then you invoke the operator to use them. That’s really all there is to it. The real art is knowing which operator to use. Operators to draw and put text on the screen will be covered later, and these make up the bulk of PostScript code, but there are a couple that are used mainly for maintaining the program itself.
The first of these operators is def.
“def” is responsible for entering a definition into the top-most dictionary
on the dictionary stack. The top operand on the operand stack is the value,
and the operand below the value is the key (and should be a name). Let’s
say that we wanted to define the name “x” to have a value of 5. The PostScript
to do this is: /x 5 def
. Notice the use of the slash on the “x”.
The slash ensures that the name “x” will be pushed onto the stack
and not any value it may already have in the dictionary stack.
“def” is also used to define new operators. The value in this case is
just a procedure. The following code defines an operator “foo” which adds
its top-most two operands and multiplies the result with the next operand
on the stack: /foo {add mul} def
. Remember, operators that return
results push them onto the stack, where they may be used later.
An important point to know when defining procedures is that the elements
in the procedure are not evaluated until the procedure is invoked.
That means that in the procedure {1 2 add 3 mul}
, the actual names
“add” and “mul” are stored in the array that is the procedure. This is
different from an actual array in which the components are evaluated
when the array is created. For contrast, the array [1 2 add 3 mul]
contains one object: the number 9.
This delayed evaluation of procedure components has two important effects. First, the definition of an operator used in a procedure is the one that is in effect when the procedure is run, not when it is defined. Second, because each operator has to be looked up each time the procedure is invoked, things can be a little slow. Fortunately, PostScript provides a handy operator to replace each name in a procedure object with its current definition. This operator is called bind, and it can speed up your program considerably. Bind is typically used as:
/foo {add mul} bind def
This defines foo to be a procedure array with two components: the procedures for add and mul. Note that, if add or mul is re-defined after defining foo, foo will have the same behavior as before. Without the use of bind, foo’s behavior would change.