That's not quite how it works. Everything is an object, and the interpreter performs some action on each object, depending on the object's "type", "value" and "attributes". Sometimes it makes very little difference, for example, it doesn't matter what "attributes" a number has. When the interpreter encounters a number, it pushes that object's "value" on the stack.
Think of it this way: everything gets "looked-up". It tries to find things in the dictionaries (systemdict). If there is a definition found, something happens. If not, then the "value" of the object is left alone. There is no "waiting"... if you put a "moveto" on the stack without two numbers already on the stack, you will get a stack overflow error.
That said, your code will work just fine. How many items you can have on the operand stack is an "implementation limit", meaning various RIPs will have their own limit. It's sufficiently large: 500 operands is the figure that Appendix B gives.
The stack is the safest place to keep things, which is counterituitive to most "traditional" programmers.
One common "newbie" mistake is to write a procedure like this:
Code:
/newbyProc
{ /y exch def
/x exch def
x y moveto show
} def
This procedure obviously expects two numbers on the stack. It immediately takes them OFF the stack and puts them into userdict. Then the key "x" goes on the stack, the interpreter searches through the dictionary stack, finds a number, and puts that number BACK ONTO the stack. Same thing for "y". Take numbers off the stack, put them right back on. Why not just LEAVE THEM THERE? You can save a lot of dictionary overhead.
Arguments go: I'll re-use them later in the procedure. Fine! Then "dup" them first, and leave the duplicate on the stack until you need it. Organize your procedure so that when you need a value, it is there on the stack.
This means learning a lot about stack manipulation: dup, pop, exch, roll, copy. But you'll write better code.
Have fun!
Thomas D. Greer
Providing PostScript & PDF
Training, Development & Consulting