> By the time the formatter is done processing an input line, what it has > to work with is a series of "nodes". These are each converted to one or > more device-independent output commands. At this point what we have > doesn't look much like *roff anymore.
My mental model of a macroprocessor is a switchyard for data streams. Distinct streams are recognized to and from files, each macro definition, and each macro argument. Stream processing, of course, entails coroutines as well as subroutines. In the switchyard model there is a point past which all macro-expanded text passes before the generated text is further processed. That point is not related to input lines. Guessing wildly about the nature of "nodes", I expect that point to map onto locations upstream of node creation. Unfortunately, implementing a natural coroutine structure in a subroutine framework contorts the logic. My hope is that the contortion doesn't entail many such upstream locations. Wishful thinking: Sethi's "Programming Languages: Concepts and Constructs" shows a fairly clean way to do coroutines in C++. It would be great if groff happened to be consciously implemented in such a way. Doug