@Section @Tag { functional } @Title { Implementation of the functional subset } @Begin @PP The objects and definitions of Lout are very similar to those found in other functional languages, and they form a natural subset of the language. So we pause here and present an overview of the Basser Lout object evaluation algorithm. @PP The problem is to take an unsized object (pure parse tree), its environment (Section {@NumberOf defs.impl}), and its style (Section {@NumberOf style}), and to produce a PostScript file for rendering the object on an output device. This file is essentially a sequence of instructions to print a given string of characters in a given font at a given point. @PP Before the algorithm begins, the parse tree must be obtained, either by parsing input or by copying from the symbol table. Afterwards the data structure must be disposed. The algorithm proper consists of five passes, each a recursive traversal of the structure from the root down to the leaves and back. @DP @I {1. Evaluation of unsized objects.} On the way down, calculate environments and replace non-recursive, non-receptive symbols by their bodies (Section {@NumberOf defs.impl}); broadcast fonts to the leaves, and paragraph breaking and spacing styles to the paragraph nodes. On the way back up, delete @Eq { FONT }, @Eq { BREAK }, and @Eq { SPACE } nodes, and insert @Eq { SPLIT }, @Eq { COL }, and @Eq { ROW } nodes (Section {@NumberOf objects}). @DP @I {2. Width calculations and breaking.} Calculate the width of every subobject from the bottom up. As described in Section {@NumberOf objects}, @Eq { WIDE } nodes may trigger object breaking sub-traversals during this pass. @DP @I {3. Height calculations.} Calculate the height of every subobject, from the bottom up. @DP @I {4. Horizontal coordinates.} Calculate the horizontal coordinate of each subobject from the top down, and store each leaf's coordinate in the leaf. @DP @I {5. Vertical coordinates and PostScript generation.} Calculate the vertical coordinate of every subobject from the top down, and at each leaf, retrieve the character string, font, and horizontal coordinate, and print the PostScript instruction for rendering that leaf. @DP Figure {@NumberOf components} gives the amount of code required for each @Figure @Tag { components } @Caption { Major components of the Basser Lout interpreter, showing the approximate number of lines of C code. } @Begin @Tab vmargin { 0.5vx } @Fmta { @Col @RR A ! @Col B ! @Col @RR C } @Fmtb { @Col @RR A ! @Col B ! @Col C } { @Rowa A { 1. } B { Initialization } C { 200 } @Rowa A { 2. } B { Memory allocation, ordered dag operations } C { 400 } @Rowa A { 3. } B { Lexical analysis, macros, file handling } C { 1,350 } @Rowa A { 4. } B { Parsing of objects and definitions } C { 1,150 } @Rowa A { 5. } B { Symbol table and call graph } C { 600 } @Rowa A { 6. } B { Evaluation of pure parse trees } C { 1,650 } @Rowa A { 7. } B { Reading, storing, and scaling of fonts } C { 600 } @Rowa A { 8. } B { Cross references and databases } C { 1,000 } @Rowa A { 9. } B { Width and height calculations, and breaking } C { 700 } @Rowa A { 10. } B { @I Constrained and @I AdjustSize } C { 700 } @Rowa A { 11. } B { Transfer of sized objects into galley tree } C { 450 } @Rowa A { 12. } B { Galley flushing algorithm } C { 1,500 } @Rowa A { 13. } B { Coordinate calculations and PostScript output } C { 700 } @Rowa A { 14. } B { Debugging and error handling } C { 1,200 } @Rowb vmargin { 0.1c } C { @Line } @Rowa C { 12,200 } } @End @Figure pass. Symmetry between horizontal and vertical is exploited throughout Basser Lout, and passes 2 and 3, as well as 4 and 5, are executed on shared code. @PP The author can see no simple way to reduce the number of passes. The introduction of horizontal galleys (Section {@NumberOf horizontal}) would remove the need for the object breaking transformations within this algorithm that are the principal obstacles in the way of the merging of passes 2 and 3. @End @Section