brown@vidiot.UUCP (Vidiot) (12/16/89)
I have the three PostScript books, but that still doesn't help me in figuring out why this works. As I understand the books, when one opens up a dictionary and starts putting things in it, the current dictionary is pushed down on the dictionary stack. All good and dandy. But, when an end is done, the current dictionary that was being used is popped from the dictionary stack and its information is lost forever. Well, it seems like forever is not true. I will use as an example the Adobe prolog for psdit: (portions thereof) %!PS-Adobe-1.0 %%Creator: tester %%Title: stdin (ditroff) %%CreationDate: Fri Dec 15 13:46:27 1989 %%EndComments % Start of psdit.pro -- prolog for ditroff translator % Copyright (c) 1985,1987 Adobe Systems Incorporated. All Rights Reserved. % GOVERNMENT END USERS: See Notice file in TranScript library directory % -- probably /usr/lib/ps/Notice % RCS: $Header: psdit.pro,v 2.2 87/11/17 16:40:42 byron Rel $ Here is the dictionary in question.... /$DITroff 140 dict def $DITroff begin /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def /xi {0 72 11 mul translate 72 resolution div dup neg scale 0 0 moveto /fontnum 1 def /fontsize 10 def /fontheight 10 def /fontslant 0 def F /pagesave save def}def . many macro definitions created . /Ybi Ycont Bcontrol i 3 add get 2 div add def /Xcont Xcont Bcontrol i 2 add get add def /Ycont Ycont Bcontrol i 3 add get add def Xbi currentpoint pop sub Ybi currentpoint exch pop sub rcurveto }for dstroke}if}def end OK, all of these macros were created and then thrown away as nothing was done inside of $DITroff except creation of definitions. Then a definition is created for ditstart that does another dictionary for $DITroff. This time there isn't an end, so far so good. /ditstart{$DITroff begin /nfonts 60 def % NFONTS makedev/ditroff dependent! /fonts[nfonts{0}repeat]def /fontnames[nfonts{()}repeat]def /docsave save def }def . more dictionaries and macro definitions . OK, now to the heart of the document. The procedure ditstart is called, which starts the $DITroff dictionary again. ditstart (psc)xT 576 1 1 xr 1(NewCenturySchlbk-Roman)xf 1 f 2(NewCenturySchlbk-Italic)xf 2 f 3(NewCenturySchlbk-Bold)xf 3 f 4(NewCenturySchlbk-BoldItalic)xf 4 f 5(Helvetica)xf 5 f 6(Helvetica-Bold)xf 6 f 7(Courier)xf 7 f 8(Courier-Bold)xf 8 f 9(Symbol)xf 9 f 10(DIThacks)xf 10 f 10 s 1 f xi %%EndProlog %%Page: 1 1 10 s 0 xH 0 xS 1 f body of PostScript pages goes here %%Trailer xt This procedure does the end for the dictionary. xs What is my problem you ask? How can all of the definitions that were created the first time $DITroff was done be available the second time it is started in ditstart? The book say that an end closes the dictionary and the info is popped from the dictionary stack. The books even give an example of defining the same thing inside of a dictionary and how it returns to the old value when the new dictionary is ended. Unfortunately, I can't find where/how ended dictionary information is again available in the future. Can someone please explain this paradox, and/or point to a page/section in one of the manuals that does explain this completely? Thanks in advance. -- harvard\ att!nicmad\ Vidiot ucbvax!uwvax..........!astroatc!vidiot!brown rutgers/ decvax!nicmad/ ARPA/INTERNET: <@spool.cs.wisc.edu,@astroatc:brown@vidiot>
woody@rpp386.cactus.org (Woodrow Baker) (12/18/89)
When you create a dictionary with /exampledict 100 dect def you essentially set aside enough memory to hold 100 keys (names) and definitions. A dictionary is like any other composite object. It can be accessed like an array. It stays around like other composite objects. When you do a exampledict begin, what happens is that a pointer to the dictionary is put on the dict stack (essentially anyway, but it might be implemented diffrently) All unknown tokens are searched for in the dictionaries that are active on the stack. Upon doing an exit, the pointer (if you will) is popped off the stack and the dictionary stays around in memory. It is like the stdlib in 'C' in a perverse sort of way, but can also be thought of (a bit more accuratly) as a 'C' function, that does a caseswitch on the keyword passed to it, and then calls a routine to do that function. Think of them as a collection of proceedures like a library. You simply activate and deactivate the library. You can replace things in the library, just make it active, and PUT or STORE them there. Doing a DEF creates an entry. Apparently, each dictionary entry occupies 20 or so bytes, (create a 100 element dictionary) and look at the vm before and after, to see how much. Hope this helps, and if any of this is wrong, I appologize, but it's the way I view dictionaries. I may have a detail or two wrong. Dictionaries were the muddiest sort of things, until I started working on emulators, and them I came to understand them. My favorite way of thinking about them is a file or library that can be "opened" with begin, and "closed" with end. Hope this helps. Cheers Woody
henry%angel@Sun.COM (Henry McGilton -- Software Products) (12/19/89)
In article <314@vidiot.UUCP>, brown@vidiot.UUCP (Vidiot) writes: * I have the three PostScript books, Me too, plus a lot more that I wish I'd never bought. * but that still doesn't help me in figuring out * why this works. * As I understand the books, when one opens up a * dictionary and starts putting things in it, To be a little bit more precise, when you do a begin, the dictionary named in the begin is pushed onto the dictionary stack. * the current dictionary is pushed down on the dictionary stack. Yes. * All good and dandy. But, when an end is done, the * current dictionary that was being used is popped from * the dictionary stack and its information is lost forever. It doesn't work that way. The dictionary at the top of the stack is popped, true. But that dictionary is still around, to be used again, if you wish, by doing another begin. And the things you defined in that dictionary are still in there. None of the books say that the `information is lost forever'. The Red Book says that end: `pops the current dictionary off the dictionary stack'. The Blue Book says: `Once the new dictionary is popped from the dictionary stack, the values for names defined within the context of this dictionary will no longer be found', etc, etc. I don't read either as stating that the values are gone forever. * Well, it seems like forever is not true. Correct. < . . .large amounts of psdit prolog deleted, reading psdit prolog fries the brain. > * OK, all of these macros were created and then thrown * away as nothing was done inside of $DITroff except * creation of definitions. Great -- now you have a dictionary full of definitions. It just isn't on the dictionary stack right now. * Then a definition is created for ditstart that does * another dictionary for $DITroff. This time there isn't * an end, so far so good. * /ditstart{$DITroff begin * /nfonts 60 def * /fonts[nfonts{0}repeat]def * /fontnames[nfonts{()}repeat]def * /docsave save def * }def The $DITroff begin sequence inside the definition of ditstart doesn't do anything until such time as distart is actually executed. * OK, now to the heart of the document. The procedure * ditstart is called, which starts the $DITroff * dictionary again. ditstart pushes $DITroff onto the dictionary stack. * What is my problem you ask? How can all of the * definitions that were created the first time $DITroff * was done be available the second time it is started in * ditstart? See the explanation above. * The book say that an end closes the dictionary and the * info is popped from the dictionary stack. Just the dictionary is popped -- the dictionary, plus its associated key/value pairs, remains. * Can someone please explain this paradox, and/or point * to a page/section in one of the manuals that does * explain this completely? The Red Book. One last item. You might ask, `if the dictionary hangs around, how come we don't run out of VM?'. Placing the entire sequence inside a save/restore pair reclaims the VM. This is my understanding of the mechanisms. I'm sure the REAL PostScript wizards out there will no doubt correct me if I'm wrong. Here's a test program that demonstrates the concepts well enough: =========================== cut here ================================= %!PS /FirstDict 1 dict def % define two dictionaries, each big enough /SecondDict 1 dict def % to hold one item each. FirstDict begin % push FirstDict on dictionary stack /shape { % define a shape -- happens to be a square 0 0 moveto 100 0 lineto 100 100 lineto 0 100 lineto closepath } def end % pop FirstDict off dictionary stack SecondDict begin % push SecondDict on dictionary stack /shape { % define a shape -- happens to be a triangle 0 0 moveto 100 0 lineto 50 100 lineto closepath } def end % pop SecondDict off dictionary stack FirstDict begin % push FirstDict on dictionary stack 144 144 translate gsave shape stroke % execute shape operator -- should be square grestore SecondDict begin % push SecondDict on dictionary stack 144 144 translate gsave shape stroke % execute shape operator -- should be triangle grestore end % pop SecondDict off dictionary stack % Now we should be back to FirstDict 144 144 translate gsave shape stroke % execute shape operator -- should be square grestore end % pop FirstDict off dictionary stack showpage =========================== cut here ================================= ............... Henry +-------------------+---------------------------+---------------------------+ | Henry McGilton | I'll bet those people who | | | Sun Microsystems | put control-D characters | arpa: hmcgilton@sun.com | | 2550 Garcia | in PostScript files also | uucp: ...!sun!angel!henry | | Mountain View, CA | put beans in their chili. | | +-------------------+---------------------------+---------------------------+
brown@vidiot.UUCP (Vidiot) (12/21/89)
In article <129367@sun.Eng.Sun.COM> henry%angel@Sun.COM (Henry McGilton -- Software Products) writes: <In article <314@vidiot.UUCP>, brown@vidiot.UUCP (Vidiot) writes: < < * All good and dandy. But, when an end is done, the < * current dictionary that was being used is popped from < * the dictionary stack and its information is lost forever. < <It doesn't work that way. The dictionary at the top of the stack <is popped, true. But that dictionary is still around, to be used <again, if you wish, by doing another begin. And the things you <defined in that dictionary are still in there. < <None of the books say that the `information is lost forever'. < <The Red Book says that end: < `pops the current dictionary off the dictionary stack'. < <The Blue Book says: < `Once the new dictionary is popped from the dictionary stack, < the values for names defined within the context of this < dictionary will no longer be found', etc, etc. < <I don't read either as stating that the values are gone forever. Well, I did. Why, because it didn't say in the same area of the book that if the dictionary name is used again, that the original definitions are also still there. To me, "will no longer be found" means just that. This points out a major problem with manuals. The people that write them know what is happening, but they just can't get it all on paper. They (Adobe) should have started another paragraph in the same section that says BUT.... I look toward a manual to tell me how it works, not a lesson in how to read between the lines. < * to a page/section in one of the manuals that does < * explain this completely? <The Red Book. I have looked at that read book, but never got the info described from it. Adobe also used the word popped when describing taking the currently dictionary off the stack. OK, every microcomputer chip that I have programmed loses any data that is popped off of a stack, unles you move it somewhere else. I can't find in the red book where it says that when the current dictionary is popped of the stack it is actually saved somewhere (like VM). I just feel that it could have been explained better in the books. Thanks for the explanation and the example, it is appreciated. -- harvard\ att!nicmad\ Vidiot ucbvax!uwvax..........!astroatc!vidiot!brown rutgers/ decvax!nicmad/ ARPA/INTERNET: <@spool.cs.wisc.edu,@astroatc:brown@vidiot>
jmr@nada.kth.se (Jan Michael Rynning) (12/21/89)
In article <342@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes: >I have looked at that read book, but never got the info described from it. >Adobe also used the word popped when describing taking the currently dictionary >off the stack. OK, every microcomputer chip that I have programmed loses any >data that is popped off of a stack, unles you move it somewhere else. I can't >find in the red book where it says that when the current dictionary is popped >of the stack it is actually saved somewhere (like VM). A directory is a composite object, just like a string or an array. The PostScript interpreter will never push a composite object on any stack, only a pointer to it. So, when you do 20 dictionary the interpreter creates a dictionary which can hold up to 20 entries, and pushes a pointer to that dictionary on the operand stack. Then, when you do begin the interpreter pops that pointer from the operand stack and pushes it on the dictionary stack. Finally, when you do end the interpreter pops the pointer from the dictionary stack and throws it away. It does not destroy the dictionary that the pointer points to, so if you have saved away a copy of the pointer in some other place, you can still access that dictionary. Jan Michael Rynning, jmr@nada.kth.se Department of Numerical Analysis If you can't fully handle domains: and Computing Science, ARPA: jmr%nada.kth.se@uunet.uu.net Royal Institute of Technology, UUCP: {uunet,mcvax,...}!nada.kth.se!jmr S-100 44 Stockholm, BITNET: jmr@sekth Sweden. Phone: +46-8-7906288
mike@ntmtka.mn.org (Mike Tietel) (12/22/89)
In article <314@vidiot.UUCP>, brown@vidiot.UUCP (Vidiot) writes: > > /$DITroff 140 dict def $DITroff begin The above line is the key to the misunderstanding. The "/$DITroff 140 dict def" creates a dictionary named "$DITroff" with enough space for 140 key-value pairs. The "$DITroff begin" just makes the dictionary "$DITroff" current (i.e., puts the dictionary "$DITroff" on top of the dictstack). Placing the dictionary on top of the dictstack allows you to place key-value pairs in the dictionary using the "def" operator instead of the "put" operator (i.e., "/hi (hello) def" instead of "$DITroff /hi (hello) put"). > . > many definitions created > . > end The "end" pops the topmost dictionary off of the dictstack, note however that this dictionary is still known by the name "$DITroff". All that has been done up to this point is define a few key-value pairs in the dictionary "$DITroff". NOTHING HAS BEEN THROWN AWAY! The end does not cause this dictionary to be lost forever, because the dictionary is known by the name "$DITroff"!!! > Then a definition is created for ditstart that does another dictionary for > $DITroff. This time there isn't an end, so far so good. > > /ditstart{$DITroff begin The above line does not "do another dictionary" it makes the "$DITroff" dictionary current so that some new key-value pairs may be added to it. > /nfonts 60 def % NFONTS makedev/ditroff dependent! > ... > }def > . > more dictionaries and macro definitions > . > ditstart > (psc)xT > 576 1 1 xr > ... > 1 f > xi > %%EndProlog > %%Page: 1 1 > 10 s 0 xH 0 xS 1 f > %body of PostScript pages goes here > %%Trailer > xt > %This procedure does the end for the dictionary. > xs > Note from the red book that: dict - *creates* an *empty* dictionary and places it on the operand stack begin - pushes a dictionary on the dictstack end - pops a dictionary off the dictstack If I write a program like the following: 2 dict begin /hi (hello) def /bye (goodbye) def end the dictionary created *is* lost forever. However, if I write a program: /mydict 2 dict def % create a dict called "mydict" mydict begin % define key-value pairs /hi (hello) def /bye (goodbye) def end the dictionary is not lost because we have named it "mydict". We could also have written this program as follows: /mydict 2 dict def % create a dict called "mydict" mydict /hi (hello) put % define one key-value pair mydict /bye (goodbye) put % define one key-value pair or: /mydict 2 dict def % create a dict called "mydict" mydict begin /hi (hello) def % define one key-value pair mydict begin /bye (goodbye) def % define one key-value pair In all three cases "mydict" will contain the same key-value pairs. If there are more questions, don't hesitate... mjt -- Mike Tietel Northern Telecom, Inc. (612) 932-8017 9701 Data Park, H-200 mike@ntmtka.mn.org Minnetonka, MN 55343 {rosevax,bungia}!ntmtka!mike