Path: utzoo!attcan!uunet!mcsun!sunic!tut!santra!kampi.hut.fi!alo From: alo@kampi.hut.fi (Antti Louko) Newsgroups: comp.lang.postscript Subject: Re: commenting out blocks of code Message-ID: <24591@santra.UUCP> Date: 24 Aug 89 12:57:38 GMT References: <1100@adobe.UUCP> Sender: news@santra.UUCP Reply-To: alo@kampi.hut.fi (Antti Louko) Organization: Helsinki University of Technology, Finland Lines: 144 In article <1100@adobe.UUCP> greid@adobe.COM () writes: >Yesterday it dawned on me that there is another mechanism >for effectively commenting out blocks of code that is a >lot easier. It doesn't really comment out the code, but >it keeps it from executing, which amounts to the same thing, >since you typically only do it while you're debugging: > >{ % <--------- add this line > /F { %def > findfont > exch scalefont > setfont > } bind def >} pop % <--------- also this line > >It's only two lines, regardless of the number of lines in >between (assuming you don't overflow the operand stack, >that is). Reminiscent of Pascal comments, methinks. But this wastes memory. The procedure which is popped is still in VM although unreachable. Even better method is: save { % <--------- add this line /F { %def findfont exch scalefont setfont } bind def } pop restore % <--------- also this line But this might still be slow, because the interpreter must scan all tokens and generate new name objects and insert them into name-object hash lists etc. There is one more problem whith this approach. If there are immediately evaluated names which are not defined, an error occurs. My solution for commenting out large chunks of arbitrary text is in the end of this article. By the way, did you know that it is possible to generate VMerror by "put"ing new values into an existent array which is under save: /A 10000 array def /S save def 0 1 9999 { A exch 1 put % This put causes VMerror if memory is very short at % this time because there is no memory to save the info % about a changed location. } for I begun to think this possibility to cause VMerror after I had thought how save/restore machinery must be implemented. I think I guessed right. When a save is executed: 1. A global savelevel variable is incremented. 2. Top pointer of VM heap is saved in save stack When an array element, a location in memory space of a dict (but not a section of a string) is modified and the savelevel of this object is below the current savelevel and this memory location has not yet been saved in this savelevel: The address and ol contents of this memory location is saved, so that its contents can be later restored. When restore is executed: 1. restore examines the savelevel of the save object. 2. Save chain is scanned and every address/contents pair above the save level. All memory locations are restored into their previous states. The fact that is not mentioned in any PostScript books is that after a save, modifying previous arrays and dicts consumes VM and is also slower than modifying arrays which are created after the last save. Although there is a section ERRORS under all PostScript operators, ERRORS section doesn't tell all possible errors which may occur during each operator. In my opinionm, it would be a good thing to publish a book on Adobes PostScript implementation. I think it would be valuable information for PostScript users. All PostScript clone makers have probably reverse-engineered Adobes implementation. Trade secrets this book might reveal ahave not been any secrets for a long time. Antti Louko Here is my skipblock procset: %%BeginProcSet: skipblock 1.0 0 /stoppedreadline { /savedhandler errordict /rangecheck get def errordict /rangecheck { pop stop } put { readline } stopped errordict /rangecheck /savedhandler load put { exch pop true dup } { false } ifelse } bind def /readlinehead { /-str- exch def /-file- exch def -file- -str- stoppedreadline { { -file- str3 stoppedreadline not { pop pop exit} if pop pop } loop } if } bind def /skipblock { /-save- save def /str 60 string def /str2 60 string def /str3 60 string def currentfile str readlinehead not { stop } if (%%BeginProcSet:) anchorsearch { pop /-name- exch def } { stop } ifelse { currentfile str2 readlinehead not { stop } if (%%EndProcSet:) anchorsearch { pop -name- eq { exit } if } { pop } ifelse } loop -save- restore } bind def %%EndProcSet: skipblock 1.0 0 Usage is as follows: % The text following skipblock is completely ignored until a matching % EndProcSet: skipblock %BeginProcSet: foobar1 This text is ignored and it is not evaluated. %EndProcSet: foobar1 (This stuff is evaluated normally) If somebody want to put this idea in a book, please do so, as long as you mention somewhere in the book, who brought this idea up!!!