points by DonHopkins 9 years ago

What you've described sounds exactly like a PostScript interpreter! You can easily write a metacircular PostScript interpreter in PostScript!

http://www.donhopkins.com/home/psiber/cyber/ps.ps.txt

And here is a PostScript quine:

    {{[ exch /dup load /exec load ] cvx} dup exec}

If you wanted to produce "safe" PostScript file for printing, that used a standard header file and didn't require a Turing complete printer with loops, conditionals, functions, etc, you could write a partial evaluator for PostScript that projects it against the stencil-paint imaging model, optimizes the graphics, and prints out another "safe" PostScript program using a standard header, with all the loops unrolled and conditionals evaluated and functions called and graphics in the same coordinate system. That would enable you to capture anything you draw on the screen, independent of the PostScript algorithmic procedures and classes and libraries and application required to draw it.

http://www.donhopkins.com/home/psiber/cyber/distill.ps.txt

Glenn Reid, who also wrote books on PostScript like Thinking in PostScript, pioneered that idea in his "PostScript Language Distillery", which is the idea that grew into PDF.

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

Here's a post I wrote about printing and debugging PostScript in the NeWS window system:

https://news.ycombinator.com/item?id=11479364

And here's a paper I wrote in 1989 that describes the NeWS version of Distillery and the metacircular PostScript evaluator. At Sun we later built a PostScript distillery into the NeWS toolkit to support printing NeWS applications as PostScript:

http://www.donhopkins.com/drupal/node/97

The Shape of PSIBER Space: PostScript Interactive Bug Eradication Routines - October 1989

[...]

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.

[...]

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.

[...]

DonHopkins 9 years ago

Woops, the right link to the NeWS distillery is:

http://www.donhopkins.com/home/archive/psiber/cyber/distill....

And here is The NeWS Toolkit version of capture.ps that captures NeWS application window drawings as PostScript:

http://www.donhopkins.com/home/code/capture.ps.txt

But Glenn Reid's original tour-de-force PostScript Distillery is still the gold standard, that does the most optimization and works with more PostScript documents, and led the way to PDF. (Adobe's Acrobat Distiller is actually built into a real PostScript interpreter, not written in PostScript like Glenn's Distillery, but he proved the possibility and usefulness of the concept, and the power and flexibility of PostScript, long before PDF was a thing.) It's a great read if you want to learn a lot about the inner workings of PostScript:

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