Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Reid G.C.Thinking in PostScript.1990.pdf
Скачиваний:
17
Добавлен:
23.08.2013
Размер:
846.44 Кб
Скачать

Figure 5.3: Visual Chunking for Example 5.3

/Times-Roman findfont (Testing) exch 12 scalefont setfont show

/Times-Roman findfont (Testing) exch12 scalefont setfont show (Testing) /Times-Roman findfont 12 scalefont setfont show

(Testing) /Times-Roman findfont 12 scalefont setfont show

(Testing) /Times-Roman findfont 12 scalefont setfont show

operators

exch setfont

boxed operations produce new objects bold operations rearrange their operands

bold-italic operations consume their operands empty boxes indicate values removed from stack

THINKING BACKWARD AND SIDEWAYS

A stack-based language such as PostScript makes you think differently than most programming languages. It seems, at first, as though you have to think backwards, since all the operators come after their operands. However, if you think of the entire expression at once, it is only slightly different than thinking in prefix or infix notation (see Example 5.4 through Example 5.6).

Example 5.4: Operator Prefix Notation in C

/* In a function call, the operands come in parentheses after the function name */ value = currentpoint(Y);

value = sqrt(X);

Example 5.5: Operator Infix Notation in C

/* Arithmetic operators typically come between their operands */ value = value - 12;

if ( value <= 72 ) showpage();

58

Chapter 5: UNDERSTANDING THE STACK

Example 5.6: Postfix Notation in PostScript

% In PostScript, the operators always come after the operands: currentpoint exch pop 72 lt { showpage } if

Since the PostScript language allows you to write programs in a very open format, the emphasis on backward thinking is even less, and sideways thinking becomes more important, such as in Example 5.7. The language would feel much more stack-oriented if you were forced to write only one token on each line, more like assembly language. That is, in fact, almost exactly what the interpreter sees, since it reads a single token and acts on it before reading the next token.

Example 5.7: Programming One Token at a Time

/Times-Roman findfont (Testing)

exch 12

scalefont setfont show

In reality, the most common occurrence is a combination of horizontal and vertical thinking. Consider the common case of a procedure that uses local names for its arguments (Example 5.8). Its output is shown in Figure 5.4 for your reference.

Example 5.8: Procedure Arguments on the Stack

/graybox

% gray linewidth Lx Ly Ux Uy graybox -

{ %def

 

/upperY exch def /upperX exch def /lowerY exch def /lowerX exch def /linewidth exch def /gray exch def

lowerX lowerY moveto lowerX upperY lineto upperX upperY lineto

upperX lowerY lineto closepath

Chapter 5: UNDERSTANDING THE STACK

59

gsave

gsave gray setgray fill grestore linewidth setlinewidth stroke

grestore } bind def

0.5 2 100 200 500 400 graybox

Figure 5.4: Output of Example 5.8

output page

 

 

 

 

 

Since stacks are last-in, first-out data structures, the last object on a line is

 

at the very top of the operand stack. In this example, this can be seen most

 

clearly by looking at the procedure call itself; that’s why the first line in

 

the procedure grabs the last argument on the line, since it is now on the

 

top of the operand stack (see Figure 5.5).

 

You can start to see the relationship in this example between the left-to-

 

right distribution of objects in the source program and the top-to-bottom

 

result on the operand stack. Notice the way the arguments to the

 

procedure line up with the exch def lines in the procedure definition itself.

 

 

 

 

TIP

When reading a PostScript program, find the executable names and use

 

them as reference points. If the name is a procedure call, look to the left of

 

the name in the body of the program to follow along as you read down

 

through the procedure definition (as in Figure 5.5).

 

 

 

 

60

Chapter 5: UNDERSTANDING THE STACK