greid@adobe.com (Glenn Reid) (08/24/89)
I've been writing serious PostScript code for over 4 years and I just thought of this. I wonder what that means.... There is only one comment mechanism in PostScript, which is the % character. It comments through the end of the line. So, to comment out a block of code, you do something like this: % /F { %def % findfont % exch scalefont % setfont % } bind def In fact, I've written an emacs macro to do this very thing, and also to delete them as necessary. 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. Since procedure bodies are always constructed as arrays with deferred execution, you just force the code into a procedure then pop it from the stack. It works with essentially all PostScript constructs in between, with the exception of mismatched (), <>, or {} delimiters and perhaps something else. Since { is easy to miss, I now use something a little more noticeable, like this: { %%%%%%%%%%% } pop %%%%%%% Just thought I would pass this on. I suppose the rest of you have been using this technique for years :-) Glenn Reid Adobe Systems
alo@kampi.hut.fi (Antti Louko) (08/24/89)
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!!!
geof@apolling (Geof Cooper) (08/26/89)
In article <1100@adobe.UUCP> greid@adobe.COM () writes: >{ %%%%%%%%%%% > >} pop %%%%%%% The only problem you might encounter is the limit described in the green book on the length of arrays that can be generated by the parser so you might get a limitcheck on processing a very long "comment". Since you wrote the green book, I guess you know about that one. - Geof
greid@adobe.com (Glenn Reid) (08/27/89)
In article <4300@imagen.UUCP> geof@apolling (Geof Cooper) writes: >In article <1100@adobe.UUCP> greid@adobe.COM () writes: >>{ %%%%%%%%%%% >> >>} pop %%%%%%% > >The only problem you might encounter is the limit described in the >green book on the length of arrays that can be generated by the parser >so you might get a limitcheck on processing a very long "comment". >Since you wrote the green book, I guess you know about that one. > >- Geof Yeah, I vaguely remember that part of the green book :-) You're right about that (except that it raises a stackoverflow on our implementations, not a limitcheck, I think). Luckily this is a limit you don't run into very often, but if you were commenting out a big block of stuff that was machine-generated (and hence had no { } arrays inside it) you would have problems, it's true. That's where a technique that just reads and discards a bunch of data up through some %%Flag comes in handy, although it is enough more work that I think just deleting with a text editor probably starts to look more appealing. Heck, none of us on this newsgroup ever needs to comment anything out anyway, do we? Doesn't it usually work the first time? Thought so, Glenn