DonHopkins
9 years ago
0
0
I love PostScript! I haven't written (or stroked) a line of it in years, but it's still fun to think in. I used to do a lot of Forth programming before that, but PostScript is a lot higher level and Lispier (and NeWS's object oriented programming system was very Smalltalky).

Here's a metacircular PostScript interpreter:

http://donhopkins.com/home/archive/NeWS/ps.ps.txt

Also check out Glenn Reid's PostScript Distillery, a partial evaluator for PostScript programs that reads in an input PostScript program that draws text and graphics to print a document, and it partially evaluates it against the PostScript stencil/paint imaging model, and then writes out another canonical output PostScript program that draws the exact same document, but optimized, all in the same default user coordinate system, with redundant graphics state changes removed.

Distillery was the initial idea and working proof of concept that led to PDF, Adobe Acrobat and its Distiller which converts PostScript to PDF.

Of course if the input PostScript program that draws the document is procedural and has loops or recursion, the optimized output program has all the loops unwound and may actually be much larger! But the whole point of PDF and the Distiller is to strip out the programming language parts of PostScript and just represent the effective drawing commands.

http://donhopkins.com/home/archive/postscript/newerstill.ps....

And here's a paper about a visual PostScript programming and debugging environment for NeWS, which discusses the metacircular evaluator and PostScript distillery:

The Shape of PSIBER Space: PostScript Interactive Bug Eradication Routines - October 1989: http://www.donhopkins.com/drupal/node/97

The Metacircular Postscript Interpreter

A program that interprets the language it is written in is said to be "metacircular". [Abelson, Structure and Interpretation of Computer Programs] Since PostScript, like Scheme, is a simple yet powerful language, with procedures as first class data structures, implementing "ps.ps", a metacircular PostScript interpreter, turned out to be straightforward (or drawrofthgiarts, with respect to the syntax). A metacircular PostScript interpreter should be compatible with the "exec" operator (modulo bugs and limitations). Some of the key ideas came from Crispin Goswell's PostScript implementation. [Goswell, An Implementation of PostScript]

The metacircular interpreter can be used as a debugging tool, to trace and single step through the execution of PostScript instructions. It calls a trace function before each instruction, that you can redefine to trace the execution in any way. One useful trace function animates the graphical stack on the PSIBER Space Deck step by step.

The meta-execution stack is a PostScript array, into which the metacircular interpreter pushes continuations for control structures. (forall, loop, stopped, etc...) A continuation is represented as a dictionary in which the state needed by the control structure is stored (plus some other information to help with debugging).

It is written in such a way that it can interpret itself: It has its own meta-execution stack to store the program's state, and it stashes its own state on the execution stack of the interpreter that's interpreting it, so the meta-interpreter's state does not get in the way of the program it's interpreting.

It is possible to experiment with modifications and extensions to PostScript, by revectoring functions and operators, and modifying the metacircular interpreter.

The metacircular interpreter can serve as a basis for PostScript algorithm animation. One very simple animation is a two dimensional plot of the operand stack depth (x), against the execution stack depth (y), over time.

Printing Distilled PostScript

The data structure displays (including those of the Pseudo Scientific Visualizer, described below) can be printed on a PostScript printer by capturing the drawing commands in a file.

Glenn Reid's "Distillery" program is a PostScript optimizer, that executes a page description, and (in most cases) produces another smaller, more efficient PostScript program, that prints the same image. [Reid, The Distillery] The trick is to redefine the path consuming operators, like fill, stroke, and show, so they write out the path in device space, and incremental changes to the graphics state. Even though the program that computes the display may be quite complicated, the distilled graphical output is very simple and low level, with all the loops unrolled.

The NeWS distillery uses the same basic technique as Glenn Reid's Distillery, but it is much simpler, does not optimize as much, and is not as complete.

PSIBER source: http://donhopkins.com/home/archive/psiber/cyber/litecyber.ps...

The source includes a twisty little version of QuickSort implemented in PostScript by Don Woods, who also wrote Adventure!

PSIBER is a terribly ugly example of 7775 lines of PostScript code that draws and edits and debugs other PostScript code, but here's some better code that is well commented and meant to serve as a programming example, which configures, draws and orders pizzas:

PizzaTool source: http://donhopkins.com/home/archive/NeWS/pizzatool.txt

PizzaTool man page: http://donhopkins.com/home/archive/NeWS/pizzatool.6