summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/mf.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/mf.tex')
-rw-r--r--Build/source/texk/web2c/mf.tex34385
1 files changed, 34385 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/mf.tex b/Build/source/texk/web2c/mf.tex
new file mode 100644
index 00000000000..a1a8bda5e63
--- /dev/null
+++ b/Build/source/texk/web2c/mf.tex
@@ -0,0 +1,34385 @@
+\input webmac
+% This program is copyright (C) 1984 by D. E. Knuth; all rights are reserved.
+% Copying of this file is authorized only if (1) you are D. E. Knuth, or if
+% (2) you make absolutely no changes to your copy. (The WEB system provides
+% for alterations via an auxiliary file; the master file should stay intact.)
+% In other words, METAFONT is under essentially the same ground rules as TeX.
+
+% TeX is a trademark of the American Mathematical Society.
+% METAFONT is a trademark of Addison-Wesley Publishing Company.
+
+% Version 0 was completed on July 28, 1984.
+% Version 1 was completed on January 4, 1986; it corresponds to "Volume D".
+% Version 1.1 trivially corrected the punctuation in one message (June 1986).
+% Version 1.2 corrected an arithmetic overflow problem (July 1986).
+% Version 1.3 improved rounding when elliptical pens are made (November 1986).
+% Version 1.4 corrected scan_declared_variable timing (May 1988).
+% Version 1.5 fixed negative halving in allocator when mem_min<0 (June 1988).
+% Version 1.6 kept open_log_file from calling fatal_error (November 1988).
+% Version 1.7 solved that problem a better way (December 1988).
+% Version 1.8 introduced major changes for 8-bit extensions (September 1989).
+% Version 1.9 improved skimping and was edited for style (December 1989).
+% Version 2.0 fixed bug in addto; released with TeX version 3.0 (March 1990).
+% Version 2.7 made consistent with TeX version 3.1 (September 1990).
+% Version 2.71 fixed bug in draw, allowed unprintable filenames (March 1992).
+% Version 2.718 fixed bug in <Choose a dependent...> (March 1995).
+% Version 2.7182 fixed bugs related to "<unprintable char>" (August 1996).
+% Version 2.71828 suppressed autorounding in dangerous cases (December 2002).
+
+% A reward of $327.68 will be paid to the first finder of any remaining bug.
+
+% Although considerable effort has been expended to make the METAFONT program
+% correct and reliable, no warranty is implied; the author disclaims any
+% obligation or liability for damages, including but not limited to
+% special, indirect, or consequential damages arising out of or in
+% connection with the use or performance of this software. This work has
+% been a ``labor of love'' and the author hopes that users enjoy it.
+
+% Here is TeX material that gets inserted after \input webmac
+\def\hang{\hangindent 3em\noindent\ignorespaces}
+\def\textindent#1{\hangindent2.5em\noindent\hbox to2.5em{\hss#1 }\ignorespaces}
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps for names like SAIL
+\def\PASCAL{Pascal}
+\def\ph{\hbox{Pascal-H}}
+\def\psqrt#1{\sqrt{\mathstrut#1}}
+\def\k{_{k+1}}
+\def\pct!{{\char`\%}} % percent sign in ordinary text
+\font\tenlogo=logo10 % font used for the METAFONT logo
+\font\logos=logosl10
+\font\eightlogo=logo8
+\def\MF{{\tenlogo META}\-{\tenlogo FONT}}
+\def\<#1>{$\langle#1\rangle$}
+\def\section{\mathhexbox278}
+\let\swap=\leftrightarrow
+\def\round{\mathop{\rm round}\nolimits}
+
+\def\(#1){} % this is used to make section names sort themselves better
+\def\9#1{} % this is used for sort keys in the index via @:sort key}{entry@>
+
+\outer\def\N#1. \[#2]#3.{\MN#1.\vfil\eject % begin starred section
+ \def\rhead{PART #2:\uppercase{#3}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\Z{\?#2]#3}{\modno}{\the\pageno}}}\next
+ \ifon\startsection{\bf\ignorespaces#3.\quad}\ignorespaces}
+\let\?=\relax % we want to be able to \write a \?
+
+\def\title{{\eightlogo METAFONT}}
+\def\topofcontents{\hsize 5.5in
+ \vglue -30pt plus 1fil minus 1.5in
+ \def\?##1]{\hbox to 1in{\hfil##1.\ }}
+ }
+\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in}
+\pageno=3
+\def\glob{13} % this should be the section number of "<Global...>"
+\def\gglob{20, 26} % this should be the next two sections of "<Global...>"
+
+
+\N1. \[1] Introduction.
+This is \MF, a font compiler intended to produce typefaces of high quality.
+The \PASCAL\ program that follows is the definition of \MF84, a standard
+version of \MF\ that is designed to be highly portable so that identical output
+will be obtainable on a great variety of computers. The conventions
+of \MF84 are the same as those of \TeX82.
+
+The main purpose of the following program is to explain the algorithms of \MF\
+as clearly as possible. As a result, the program will not necessarily be very
+efficient when a particular \PASCAL\ compiler has translated it into a
+particular machine language. However, the program has been written so that it
+can be tuned to run efficiently in a wide variety of operating environments
+by making comparatively few changes. Such flexibility is possible because
+the documentation that follows is written in the \.{WEB} language, which is
+at a higher level than \PASCAL; the preprocessing step that converts \.{WEB}
+to \PASCAL\ is able to introduce most of the necessary refinements.
+Semi-automatic translation to other languages is also feasible, because the
+program below does not make extensive use of features that are peculiar to
+\PASCAL.
+
+A large piece of software like \MF\ has inherent complexity that cannot
+be reduced below a certain level of difficulty, although each individual
+part is fairly simple by itself. The \.{WEB} language is intended to make
+the algorithms as readable as possible, by reflecting the way the
+individual program pieces fit together and by providing the
+cross-references that connect different parts. Detailed comments about
+what is going on, and about why things were done in certain ways, have
+been liberally sprinkled throughout the program. These comments explain
+features of the implementation, but they rarely attempt to explain the
+\MF\ language itself, since the reader is supposed to be familiar with
+{\sl The {\logos METAFONT\/}book}.
+
+\fi
+
+\M2. The present implementation has a long ancestry, beginning in the spring
+of~1977, when its author wrote a prototype set of subroutines and macros
+that were used to develop the first Computer Modern fonts.
+This original proto-\MF\ required the user to recompile a {\mc SAIL} program
+whenever any character was changed, because it was not a ``language'' for
+font design; the language was {\mc SAIL}. After several hundred characters
+had been designed in that way, the author developed an interpretable language
+called \MF, in which it was possible to express the Computer Modern programs
+less cryptically. A complete \MF\ processor was designed and coded by the
+author in 1979. This program, written in {\mc SAIL}, was adapted for use
+with a variety of typesetting equipment and display terminals by Leo Guibas,
+Lyle Ramshaw, and David Fuchs.
+Major improvements to the design of Computer Modern fonts were made in the
+spring of 1982, after which it became clear that a new language would
+better express the needs of letterform designers. Therefore an entirely
+new \MF\ language and system were developed in 1984; the present system
+retains the name and some of the spirit of \MF79, but all of the details
+have changed.
+
+No doubt there still is plenty of room for improvement, but the author
+is firmly committed to keeping \MF84 ``frozen'' from now on; stability
+and reliability are to be its main virtues.
+
+On the other hand, the \.{WEB} description can be extended without changing
+the core of \MF84 itself, and the program has been designed so that such
+extensions are not extremely difficult to make.
+The \\{banner} string defined here should be changed whenever \MF\
+undergoes any modifications, so that it will be clear which version of
+\MF\ might be the guilty party when a problem arises.
+
+If this program is changed, the resulting system should not be called
+`\MF\kern.5pt'; the official name `\MF\kern.5pt' by itself is reserved
+for software systems that are fully compatible with each other.
+A special test suite called the ``\.{TRAP} test'' is available for
+helping to determine whether an implementation deserves to be
+known as `\MF\kern.5pt' [cf.~Stanford Computer Science report CS1095,
+January 1986].
+
+\Y\P\D \37$\\{banner}\S\.{\'This\ is\ METAFONT,\ Version\ 2.71828\'}$\C{printed
+when \MF\ starts}\par
+\fi
+
+\M3. Different \PASCAL s have slightly different conventions, and the present
+program expresses \MF\ in terms of the \PASCAL\ that was
+available to the author in 1984. Constructions that apply to
+this particular compiler, which we shall call \ph, should help the
+reader see how to make an appropriate interface for other systems
+if necessary. (\ph\ is Charles Hedrick's modification of a compiler
+for the DECsystem-10 that was originally developed at the University of
+Hamburg; cf.\ {\sl SOFTWARE---Practice \AM\ Experience \bf6} (1976),
+29--42. The \MF\ program below is intended to be adaptable, without
+extensive changes, to most other versions of \PASCAL, so it does not fully
+use the admirable features of \ph. Indeed, a conscious effort has been
+made here to avoid using several idiosyncratic features of standard
+\PASCAL\ itself, so that most of the code can be translated mechanically
+into other high-level languages. For example, the `\&{with}' and `\\{new}'
+features are not used, nor are pointer types, set types, or enumerated
+scalar types; there are no `\&{var}' parameters, except in the case of files
+or in the system-dependent \\{paint\_row} procedure;
+there are no tag fields on variant records; there are no \\{real} variables;
+no procedures are declared local to other procedures.)
+
+The portions of this program that involve system-dependent code, where
+changes might be necessary because of differences between \PASCAL\ compilers
+and/or differences between
+operating systems, can be identified by looking at the sections whose
+numbers are listed under `system dependencies' in the index. Furthermore,
+the index entries for `dirty \PASCAL' list all places where the restrictions
+of \PASCAL\ have not been followed perfectly, for one reason or another.
+
+\fi
+
+\M4. The program begins with a normal \PASCAL\ program heading, whose
+components will be filled in later, using the conventions of \.{WEB}.
+For example, the portion of the program called `\X\glob:Global
+variables\X' below will be replaced by a sequence of variable declarations
+that starts in $\section\glob$ of this documentation. In this way, we are able
+to define each individual global variable when we are prepared to
+understand what it means; we do not have to define all of the globals at
+once. Cross references in $\section\glob$, where it says ``See also
+sections \gglob, \dots,'' also make it possible to look at the set of
+all global variables, if desired. Similar remarks apply to the other
+portions of the program heading.
+
+Actually the heading shown here is not quite normal: The \&{program}\ line
+does not mention any \\{output} file, because \ph\ would ask the \MF\ user
+to specify a file name if \\{output} were specified here.
+
+\Y\P\D \37$\\{mtype}\S\|t\J\|y\J\|p\J\|e$\C{this is a \.{WEB} coding trick:}\par
+\P\F \37$\\{mtype}\S\\{type}$\C{`\&{mtype}' will be equivalent to `\&{type}'}%
+\par
+\P\F \37$\\{type}\S\\{true}$\C{but `\\{type}' will not be treated as a reserved
+word}\par
+\Y\P\hbox{\4}\X9:Compiler directives\X\6
+\4\&{program}\1\ \37\\{MF};\C{all file names are defined dynamically}\6
+\4\&{label} \37\X6:Labels in the outer block\X\6
+\4\&{const} \37\X11:Constants in the outer block\X\6
+\4\&{mtype} \37\X18:Types in the outer block\X\6
+\4\&{var} \37\X13:Global variables\X\7
+\4\&{procedure}\1\ \37\\{initialize};\C{this procedure gets things started
+properly}\6
+\4\&{var} \37\X19:Local variables for initialization\X\2\6
+\&{begin} \37\X21:Set initial values of key variables\X\6
+\&{end};\7
+\hbox{\4}\X57:Basic printing procedures\X\6
+\hbox{\4}\X73:Error handling procedures\X\par
+\fi
+
+\M5. The overall \MF\ program begins with the heading just shown, after which
+comes a bunch of procedure declarations and function declarations.
+Finally we will get to the main program, which begins with the
+comment `\\{start\_here}'. If you want to skip down to the
+main program now, you can look up `\\{start\_here}' in the index.
+But the author suggests that the best way to understand this program
+is to follow pretty much the order of \MF's components as they appear in the
+\.{WEB} description you are now reading, since the present ordering is
+intended to combine the advantages of the ``bottom up'' and ``top down''
+approaches to the problem of understanding a somewhat complicated system.
+
+\fi
+
+\M6. Three labels must be declared in the main program, so we give them
+symbolic names.
+
+\Y\P\D \37$\\{start\_of\_MF}=1$\C{go here when \MF's variables are initialized}%
+\par
+\P\D \37$\\{end\_of\_MF}=9998$\C{go here to close files and terminate
+gracefully}\par
+\P\D \37$\\{final\_end}=9999$\C{this label marks the ending of the program}\par
+\Y\P$\4\X6:Labels in the outer block\X\S$\6
+$\\{start\_of\_MF}\hbox{\hskip-2pt},\39\\{end\_of\_MF}\hbox{\hskip-2pt},\39\,%
+\\{final\_end}$;\C{key control points}\par
+\U4.\fi
+
+\M7. Some of the code below is intended to be used only when diagnosing the
+strange behavior that sometimes occurs when \MF\ is being installed or
+when system wizards are fooling around with \MF\ without quite knowing
+what they are doing. Such code will not normally be compiled; it is
+delimited by the codewords `$ \&{debug} \ldots \&{gubed} $', with apologies
+to people who wish to preserve the purity of English.
+
+Similarly, there is some conditional code delimited by
+`$ \&{stat} \ldots \&{tats} $' that is intended for use when statistics are to
+be
+kept about \MF's memory usage. The \&{stat} $\ldots$ \&{tats} code also
+implements special diagnostic information that is printed when
+$\\{tracingedges}>1$.
+
+\Y\P\D \37$\\{debug}\S\B$\C{change this to `$\\{debug}\equiv\null$' when
+debugging}\par
+\P\D \37$\\{gubed}\S\hbox{}\T$\C{change this to `$\\{gubed}\equiv\null$' when
+debugging}\par
+\P\F \37$\\{debug}\S\\{begin}$\par
+\P\F \37$\\{gubed}\S\\{end}$\Y\par
+\P\D \37$\\{stat}\S\B$\C{change this to `$\\{stat}\equiv\null$' when gathering
+ usage statistics}\par
+\P\D \37$\\{tats}\S\hbox{}\T$\C{change this to `$\\{tats}\equiv\null$' when
+gathering usage statistics}\par
+\P\F \37$\\{stat}\S\\{begin}$\par
+\P\F \37$\\{tats}\S\\{end}$\par
+\fi
+
+\M8. This program has two important variations: (1) There is a long and slow
+version called \.{INIMF}, which does the extra calculations needed to
+initialize \MF's internal tables; and (2)~there is a shorter and faster
+production version, which cuts the initialization to a bare minimum.
+Parts of the program that are needed in (1) but not in (2) are delimited by
+the codewords `$ \&{init} \ldots \&{tini} $'.
+
+\Y\P\D \37$\\{init}\S$\C{change this to `$\\{init}\equiv\.{@\{}$' in the
+production version}\par
+\P\D \37$\\{tini}\S$\C{change this to `$\\{tini}\equiv\.{@\}}$' in the
+production version}\par
+\P\F \37$\\{init}\S\\{begin}$\par
+\P\F \37$\\{tini}\S\\{end}$\par
+\fi
+
+\M9. If the first character of a \PASCAL\ comment is a dollar sign,
+\ph\ treats the comment as a list of ``compiler directives'' that will
+affect the translation of this program into machine language. The
+directives shown below specify full checking and inclusion of the \PASCAL\
+debugger when \MF\ is being debugged, but they cause range checking and other
+redundant code to be eliminated when the production system is being generated.
+Arithmetic overflow will be detected in all cases.
+
+\Y\P$\4\X9:Compiler directives\X\S$\6
+$\B\J\$\|C-,\39\|A+,\39\|D-\T$\C{no range check, catch arithmetic overflow, no
+debug overhead}\6
+\&{debug} \37$\B\J\$\|C+,\39\|D+\T$\ \&{gubed}\C{but turn everything on when
+debugging}\par
+\U4.\fi
+
+\M10. This \MF\ implementation conforms to the rules of the {\sl Pascal User
+Manual} published by Jensen and Wirth in 1975, except where system-dependent
+code is necessary to make a useful system program, and except in another
+respect where such conformity would unnecessarily obscure the meaning
+and clutter up the code: We assume that \&{case} statements may include a
+default case that applies if no matching label is found. Thus, we shall use
+constructions like
+$$\vbox{\halign{\ignorespaces#\hfil\cr
+ \&{case} $\|x$ \&{of}\cr
+1: $\langle\,$code for $x=1\,\rangle$;\cr
+3: $\langle\,$code for $x=3\,\rangle$;\cr
+ \&{othercases} $\langle\,$code for $\|x\I1$ and $\|x\I3$$\,\rangle$\cr
+ \&{endcases} \cr}}$$
+since most \PASCAL\ compilers have plugged this hole in the language by
+incorporating some sort of default mechanism. For example, the \ph\
+compiler allows `\\{others}:' as a default label, and other \PASCAL s allow
+syntaxes like `\&{else}' or `\&{otherwise}' or `\\{otherwise}:', etc. The
+definitions of \&{othercases} and \&{endcases} should be changed to agree
+with
+local conventions. Note that no semicolon appears before \&{endcases} in
+this program, so the definition of \&{endcases} should include a semicolon
+if the compiler wants one. (Of course, if no default mechanism is
+available, the \&{case} statements of \MF\ will have to be laboriously
+extended by listing all remaining cases. People who are stuck with such
+\PASCAL s have, in fact, done this, successfully but not happily!)
+
+\Y\P\D \37$\\{othercases}\S\\{others}$: \37\C{default for cases not listed
+explicitly}\par
+\P\D \37$\\{endcases}\S$\ \&{end} \C{follows the default case in an extended %
+\&{case} statement}\par
+\P\F \37$\\{othercases}\S\\{else}$\par
+\P\F \37$\\{endcases}\S\\{end}$\par
+\fi
+
+\M11. The following parameters can be changed at compile time to extend or
+reduce \MF's capacity. They may have different values in \.{INIMF} and
+in production versions of \MF.
+
+\Y\P$\4\X11:Constants in the outer block\X\S$\6
+$\\{mem\_max}=30000$;\C{greatest index in \MF's internal \\{mem} array; must
+be strictly less than \\{max\_halfword}; must be equal to \\{mem\_top} in %
+\.{INIMF}, otherwise $\G\\{mem\_top}$}\6
+$\\{max\_internal}=100$;\C{maximum number of internal quantities}\6
+$\\{buf\_size}=500$;\C{maximum number of characters simultaneously present in
+current lines of open files; must not exceed \\{max\_halfword}}\6
+$\\{error\_line}=72$;\C{width of context lines on terminal error messages}\6
+$\\{half\_error\_line}=42$;\C{width of first lines of contexts in terminal
+error messages; should be between 30 and $\\{error\_line}-15$}\6
+$\\{max\_print\_line}=79$;\C{width of longest text lines output; should be at
+least 60}\6
+$\\{screen\_width}=768$;\C{number of pixels in each row of screen display}\6
+$\\{screen\_depth}=1024$;\C{number of pixels in each column of screen display}\6
+$\\{stack\_size}=30$;\C{maximum number of simultaneous input sources}\6
+$\\{max\_strings}=2000$;\C{maximum number of strings; must not exceed \\{max%
+\_halfword}}\6
+$\\{string\_vacancies}=8000$;\C{the minimum number of characters that should be
+ available for the user's identifier names and strings, after \MF's own
+error messages are stored}\6
+$\\{pool\_size}=32000$;\C{maximum number of characters in strings, including
+all error messages and help texts, and the names of all identifiers; must
+exceed \\{string\_vacancies} by the total length of \MF's own strings, which
+is currently about 22000}\6
+$\\{move\_size}=5000$;\C{space for storing moves in a single octant}\6
+$\\{max\_wiggle}=300$;\C{number of autorounded points per cycle}\6
+$\\{gf\_buf\_size}=800$;\C{size of the output buffer, must be a multiple of 8}\6
+$\\{file\_name\_size}=40$;\C{file names shouldn't be longer than this}\6
+$\\{pool\_name}=\.{\'MFbases:MF.POOL\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \
+\ \ \ \'}$;\C{string of length \\{file\_name\_size}; tells where the string
+pool appears}\6
+$\\{path\_size}=300$;\C{maximum number of knots between breakpoints of a path}\6
+$\\{bistack\_size}=785$;\C{size of stack for bisection algorithms; should
+probably be left at this value}\6
+$\\{header\_size}=100$;\C{maximum number of \.{TFM} header words, times~4}\6
+$\\{lig\_table\_size}=5000$;\C{maximum number of ligature/kern steps, must be
+at least 255 and at most 32510}\6
+$\\{max\_kerns}=500$;\C{maximum number of distinct kern amounts}\6
+$\\{max\_font\_dimen}=50$;\C{maximum number of \&{fontdimen} parameters}\par
+\U4.\fi
+
+\M12. Like the preceding parameters, the following quantities can be changed
+at compile time to extend or reduce \MF's capacity. But if they are changed,
+it is necessary to rerun the initialization program \.{INIMF}
+to generate new tables for the production \MF\ program.
+One can't simply make helter-skelter changes to the following constants,
+since certain rather complex initialization
+numbers are computed from them. They are defined here using
+\.{WEB} macros, instead of being put into \PASCAL's \&{const} list, in order
+to
+emphasize this distinction.
+
+\Y\P\D \37$\\{mem\_min}=0$\C{smallest index in the \\{mem} array, must not be
+less than \\{min\_halfword}}\par
+\P\D \37$\\{mem\_top}\S30000$\C{largest index in the \\{mem} array dumped by %
+\.{INIMF}; must be substantially larger than \\{mem\_min} and not greater
+than \\{mem\_max}}\par
+\P\D \37$\\{hash\_size}=2100$\C{maximum number of symbolic tokens, must be
+less than $\\{max\_halfword}-3\ast\\{param\_size}$}\par
+\P\D \37$\\{hash\_prime}=1777$\C{a prime number equal to about 85\pct! of %
+\\{hash\_size}}\par
+\P\D \37$\\{max\_in\_open}=6$\C{maximum number of input files and error
+insertions that can be going on simultaneously}\par
+\P\D \37$\\{param\_size}=150$\C{maximum number of simultaneous macro
+parameters}\par
+\fi
+
+\M13. In case somebody has inadvertently made bad settings of the
+``constants,''
+\MF\ checks them using a global variable called \\{bad}.
+
+This is the first of many sections of \MF\ where global variables are
+defined.
+
+\Y\P$\4\X13:Global variables\X\S$\6
+\4\\{bad}: \37\\{integer};\C{is some ``constant'' wrong?}\par
+\As20, 25, 29, 31, 38, 42, 50, 54, 68, 71, 74, 91, 97, 129, 137, 144, 148, 159,
+160, 161, 166, 178, 190, 196, 198, 200, 201, 225, 230, 250, 267, 279, 283, 298,
+308, 309, 327, 371, 379, 389, 395, 403, 427, 430, 448, 455, 461, 464, 507, 552,
+555, 557, 566, 569, 572, 579, 585, 592, 624, 628, 631, 633, 634, 659, 680, 699,
+738, 752, 767, 768, 775, 782, 785, 791, 796, 813, 821, 954, 1077, 1084, 1087,
+1096, 1119, 1125, 1130, 1149, 1152, 1162, 1183, 1188\ETs1203.
+\U4.\fi
+
+\M14. Later on we will say `\ignorespaces \&{if} $\\{mem\_max}\G\\{max%
+\_halfword}$ \&{then} $\\{bad}\K10$',
+or something similar. (We can't do that until \\{max\_halfword} has been
+defined.)
+
+\Y\P$\4\X14:Check the ``constant'' values for consistency\X\S$\6
+$\\{bad}\K0$;\6
+\&{if} $(\\{half\_error\_line}<30)\V(\\{half\_error\_line}>\\{error\_line}-15)$
+\1\&{then}\5
+$\\{bad}\K1$;\2\6
+\&{if} $\\{max\_print\_line}<60$ \1\&{then}\5
+$\\{bad}\K2$;\2\6
+\&{if} $\\{gf\_buf\_size}\mathbin{\&{mod}}8\I0$ \1\&{then}\5
+$\\{bad}\K3$;\2\6
+\&{if} $\\{mem\_min}+1100>\\{mem\_top}$ \1\&{then}\5
+$\\{bad}\K4$;\2\6
+\&{if} $\\{hash\_prime}>\\{hash\_size}$ \1\&{then}\5
+$\\{bad}\K5$;\2\6
+\&{if} $\\{header\_size}\mathbin{\&{mod}}4\I0$ \1\&{then}\5
+$\\{bad}\K6$;\2\6
+\&{if} $(\\{lig\_table\_size}<255)\V(\\{lig\_table\_size}>32510)$ \1\&{then}\5
+$\\{bad}\K7$;\2\par
+\As154, 204, 214, 310, 553\ETs777.
+\U1204.\fi
+
+\M15. Labels are given symbolic names by the following definitions, so that
+occasional \&{goto} statements will be meaningful. We insert the label
+`\\{exit}' just before the `\ignorespaces \&{end} \unskip' of a procedure in
+which we have used the `\&{return}' statement defined below; the label
+`\\{restart}' is occasionally used at the very beginning of a procedure; and
+the label `\\{reswitch}' is occasionally used just prior to a \&{case}
+statement in which some cases change the conditions and we wish to branch
+to the newly applicable case. Loops that are set up with the \~ \&{loop}
+construction defined below are commonly exited by going to `\\{done}' or to
+`\\{found}' or to `\\{not\_found}', and they are sometimes repeated by going to
+`\\{continue}'. If two or more parts of a subroutine start differently but
+end up the same, the shared code may be gathered together at
+`\\{common\_ending}'.
+
+Incidentally, this program never declares a label that isn't actually used,
+because some fussy \PASCAL\ compilers will complain about redundant labels.
+
+\Y\P\D \37$\\{exit}=10$\C{go here to leave a procedure}\par
+\P\D \37$\\{restart}=20$\C{go here to start a procedure again}\par
+\P\D \37$\\{reswitch}=21$\C{go here to start a case statement again}\par
+\P\D \37$\\{continue}=22$\C{go here to resume a loop}\par
+\P\D \37$\\{done}=30$\C{go here to exit a loop}\par
+\P\D \37$\\{done1}=31$\C{like \\{done}, when there is more than one loop}\par
+\P\D \37$\\{done2}=32$\C{for exiting the second loop in a long block}\par
+\P\D \37$\\{done3}=33$\C{for exiting the third loop in a very long block}\par
+\P\D \37$\\{done4}=34$\C{for exiting the fourth loop in an extremely long
+block}\par
+\P\D \37$\\{done5}=35$\C{for exiting the fifth loop in an immense block}\par
+\P\D \37$\\{done6}=36$\C{for exiting the sixth loop in a block}\par
+\P\D \37$\\{found}=40$\C{go here when you've found it}\par
+\P\D \37$\\{found1}=41$\C{like \\{found}, when there's more than one per
+routine}\par
+\P\D \37$\\{found2}=42$\C{like \\{found}, when there's more than two per
+routine}\par
+\P\D \37$\\{not\_found}=45$\C{go here when you've found nothing}\par
+\P\D \37$\\{common\_ending}=50$\C{go here when you want to merge with another
+branch}\par
+\fi
+
+\M16. Here are some macros for common programming idioms.
+
+\Y\P\D \37$\\{incr}(\#)\S\#\K\#+1$\C{increase a variable by unity}\par
+\P\D \37$\\{decr}(\#)\S\#\K\#-1$\C{decrease a variable by unity}\par
+\P\D \37$\\{negate}(\#)\S\#\K-\#$\C{change the sign of a variable}\par
+\P\D \37$\\{double}(\#)\S\#\K\#+\#$\C{multiply a variable by two}\par
+\P\D \37$\\{loop}\S$\ \&{while} $\\{true}$ \1\&{do}\ \C{repeat over and over
+until a \&{goto} happens}\par
+\P\F \37$\\{loop}\S\\{xclause}$\C{\.{WEB}'s \~ \&{xclause} acts like `%
+\ignorespaces \&{while} $\\{true}$ \&{do}\unskip'}\par
+\P\D \37$\\{do\_nothing}\S$\C{empty statement}\par
+\P\D \37$\\{return}\S$\1\5
+\&{goto} \37\\{exit}\C{terminate a procedure call}\2\par
+\P\F \37$\\{return}\S\\{nil}$\C{\.{WEB} will henceforth say \&{return} instead
+of \\{return}}\par
+\fi
+
+\N17. \[2] The character set.
+In order to make \MF\ readily portable to a wide variety of
+computers, all of its input text is converted to an internal eight-bit
+code that includes standard ASCII, the ``American Standard Code for
+Information Interchange.'' This conversion is done immediately when each
+character is read in. Conversely, characters are converted from ASCII to
+the user's external representation just before they are output to a
+text file.
+
+Such an internal code is relevant to users of \MF\ only with respect to
+the \&{char} and \&{ASCII} operations, and the comparison of strings.
+
+\fi
+
+\M18. Characters of text that have been converted to \MF's internal form
+are said to be of type \\{ASCII\_code}, which is a subrange of the integers.
+
+\Y\P$\4\X18:Types in the outer block\X\S$\6
+$\\{ASCII\_code}=0\to255$;\C{eight-bit numbers}\par
+\As24, 37, 101, 105, 106, 156, 186, 565, 571, 627\ETs1151.
+\U4.\fi
+
+\M19. The original \PASCAL\ compiler was designed in the late 60s, when six-bit
+character sets were common, so it did not make provision for lowercase
+letters. Nowadays, of course, we need to deal with both capital and small
+letters in a convenient way, especially in a program for font design;
+so the present specification of \MF\ has been written under the assumption
+that the \PASCAL\ compiler and run-time system permit the use of text files
+with more than 64 distinguishable characters. More precisely, we assume that
+the character set contains at least the letters and symbols associated
+with ASCII codes \O{40} through \O{176}; all of these characters are now
+available on most computer terminals.
+
+Since we are dealing with more characters than were present in the first
+\PASCAL\ compilers, we have to decide what to call the associated data
+type. Some \PASCAL s use the original name \\{char} for the
+characters in text files, even though there now are more than 64 such
+characters, while other \PASCAL s consider \\{char} to be a 64-element
+subrange of a larger data type that has some other name.
+
+In order to accommodate this difference, we shall use the name \\{text\_char}
+to stand for the data type of the characters that are converted to and
+from \\{ASCII\_code} when they are input and output. We shall also assume
+that \\{text\_char} consists of the elements $\\{chr}(\\{first\_text\_char})$
+through
+$\\{chr}(\\{last\_text\_char})$, inclusive. The following definitions should be
+adjusted if necessary.
+
+\Y\P\D \37$\\{text\_char}\S\\{char}$\C{the data type of characters in text
+files}\par
+\P\D \37$\\{first\_text\_char}=0$\C{ordinal number of the smallest element of %
+\\{text\_char}}\par
+\P\D \37$\\{last\_text\_char}=255$\C{ordinal number of the largest element of %
+\\{text\_char}}\par
+\Y\P$\4\X19:Local variables for initialization\X\S$\6
+\4\|i: \37\\{integer};\par
+\A130.
+\U4.\fi
+
+\M20. The \MF\ processor converts between ASCII code and
+the user's external character set by means of arrays \\{xord} and \\{xchr}
+that are analogous to \PASCAL's \\{ord} and \\{chr} functions.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{xord}: \37\&{array} $[\\{text\_char}]$ \1\&{of}\5
+\\{ASCII\_code};\C{specifies conversion of input characters}\2\6
+\4\\{xchr}: \37\&{array} $[\\{ASCII\_code}]$ \1\&{of}\5
+\\{text\_char};\C{specifies conversion of output characters}\2\par
+\fi
+
+\M21. Since we are assuming that our \PASCAL\ system is able to read and
+write the visible characters of standard ASCII (although not
+necessarily using the ASCII codes to represent them), the following
+assignment statements initialize the standard part of the \\{xchr} array
+properly, without needing any system-dependent changes. On the other
+hand, it is possible to implement \MF\ with less complete character
+sets, and in such cases it will be necessary to change something here.
+
+\Y\P$\4\X21:Set initial values of key variables\X\S$\6
+$\\{xchr}[\O{40}]\K\.{\'\ \'}$;\5
+$\\{xchr}[\O{41}]\K\.{\'!\'}$;\5
+$\\{xchr}[\O{42}]\K\.{\'"\'}$;\5
+$\\{xchr}[\O{43}]\K\.{\'\#\'}$;\5
+$\\{xchr}[\O{44}]\K\.{\'\$\'}$;\5
+$\\{xchr}[\O{45}]\K\.{\'\%\'}$;\5
+$\\{xchr}[\O{46}]\K\.{\'\&\'}$;\5
+$\\{xchr}[\O{47}]\K\.{\'\'}\.{\'\'}$;\6
+$\\{xchr}[\O{50}]\K\.{\'(\'}$;\5
+$\\{xchr}[\O{51}]\K\.{\')\'}$;\5
+$\\{xchr}[\O{52}]\K\.{\'*\'}$;\5
+$\\{xchr}[\O{53}]\K\.{\'+\'}$;\5
+$\\{xchr}[\O{54}]\K\.{\',\'}$;\5
+$\\{xchr}[\O{55}]\K\.{\'-\'}$;\5
+$\\{xchr}[\O{56}]\K\.{\'.\'}$;\5
+$\\{xchr}[\O{57}]\K\.{\'/\'}$;\6
+$\\{xchr}[\O{60}]\K\.{\'0\'}$;\5
+$\\{xchr}[\O{61}]\K\.{\'1\'}$;\5
+$\\{xchr}[\O{62}]\K\.{\'2\'}$;\5
+$\\{xchr}[\O{63}]\K\.{\'3\'}$;\5
+$\\{xchr}[\O{64}]\K\.{\'4\'}$;\5
+$\\{xchr}[\O{65}]\K\.{\'5\'}$;\5
+$\\{xchr}[\O{66}]\K\.{\'6\'}$;\5
+$\\{xchr}[\O{67}]\K\.{\'7\'}$;\6
+$\\{xchr}[\O{70}]\K\.{\'8\'}$;\5
+$\\{xchr}[\O{71}]\K\.{\'9\'}$;\5
+$\\{xchr}[\O{72}]\K\.{\':\'}$;\5
+$\\{xchr}[\O{73}]\K\.{\';\'}$;\5
+$\\{xchr}[\O{74}]\K\.{\'<\'}$;\5
+$\\{xchr}[\O{75}]\K\.{\'=\'}$;\5
+$\\{xchr}[\O{76}]\K\.{\'>\'}$;\5
+$\\{xchr}[\O{77}]\K\.{\'?\'}$;\6
+$\\{xchr}[\O{100}]\K\.{\'@\'}$;\5
+$\\{xchr}[\O{101}]\K\.{\'A\'}$;\5
+$\\{xchr}[\O{102}]\K\.{\'B\'}$;\5
+$\\{xchr}[\O{103}]\K\.{\'C\'}$;\5
+$\\{xchr}[\O{104}]\K\.{\'D\'}$;\5
+$\\{xchr}[\O{105}]\K\.{\'E\'}$;\5
+$\\{xchr}[\O{106}]\K\.{\'F\'}$;\5
+$\\{xchr}[\O{107}]\K\.{\'G\'}$;\6
+$\\{xchr}[\O{110}]\K\.{\'H\'}$;\5
+$\\{xchr}[\O{111}]\K\.{\'I\'}$;\5
+$\\{xchr}[\O{112}]\K\.{\'J\'}$;\5
+$\\{xchr}[\O{113}]\K\.{\'K\'}$;\5
+$\\{xchr}[\O{114}]\K\.{\'L\'}$;\5
+$\\{xchr}[\O{115}]\K\.{\'M\'}$;\5
+$\\{xchr}[\O{116}]\K\.{\'N\'}$;\5
+$\\{xchr}[\O{117}]\K\.{\'O\'}$;\6
+$\\{xchr}[\O{120}]\K\.{\'P\'}$;\5
+$\\{xchr}[\O{121}]\K\.{\'Q\'}$;\5
+$\\{xchr}[\O{122}]\K\.{\'R\'}$;\5
+$\\{xchr}[\O{123}]\K\.{\'S\'}$;\5
+$\\{xchr}[\O{124}]\K\.{\'T\'}$;\5
+$\\{xchr}[\O{125}]\K\.{\'U\'}$;\5
+$\\{xchr}[\O{126}]\K\.{\'V\'}$;\5
+$\\{xchr}[\O{127}]\K\.{\'W\'}$;\6
+$\\{xchr}[\O{130}]\K\.{\'X\'}$;\5
+$\\{xchr}[\O{131}]\K\.{\'Y\'}$;\5
+$\\{xchr}[\O{132}]\K\.{\'Z\'}$;\5
+$\\{xchr}[\O{133}]\K\.{\'[\'}$;\5
+$\\{xchr}[\O{134}]\K\.{\'\\\'}$;\5
+$\\{xchr}[\O{135}]\K\.{\']\'}$;\5
+$\\{xchr}[\O{136}]\K\.{\'\^\'}$;\5
+$\\{xchr}[\O{137}]\K\.{\'\_\'}$;\6
+$\\{xchr}[\O{140}]\K\.{\'\`\'}$;\5
+$\\{xchr}[\O{141}]\K\.{\'a\'}$;\5
+$\\{xchr}[\O{142}]\K\.{\'b\'}$;\5
+$\\{xchr}[\O{143}]\K\.{\'c\'}$;\5
+$\\{xchr}[\O{144}]\K\.{\'d\'}$;\5
+$\\{xchr}[\O{145}]\K\.{\'e\'}$;\5
+$\\{xchr}[\O{146}]\K\.{\'f\'}$;\5
+$\\{xchr}[\O{147}]\K\.{\'g\'}$;\6
+$\\{xchr}[\O{150}]\K\.{\'h\'}$;\5
+$\\{xchr}[\O{151}]\K\.{\'i\'}$;\5
+$\\{xchr}[\O{152}]\K\.{\'j\'}$;\5
+$\\{xchr}[\O{153}]\K\.{\'k\'}$;\5
+$\\{xchr}[\O{154}]\K\.{\'l\'}$;\5
+$\\{xchr}[\O{155}]\K\.{\'m\'}$;\5
+$\\{xchr}[\O{156}]\K\.{\'n\'}$;\5
+$\\{xchr}[\O{157}]\K\.{\'o\'}$;\6
+$\\{xchr}[\O{160}]\K\.{\'p\'}$;\5
+$\\{xchr}[\O{161}]\K\.{\'q\'}$;\5
+$\\{xchr}[\O{162}]\K\.{\'r\'}$;\5
+$\\{xchr}[\O{163}]\K\.{\'s\'}$;\5
+$\\{xchr}[\O{164}]\K\.{\'t\'}$;\5
+$\\{xchr}[\O{165}]\K\.{\'u\'}$;\5
+$\\{xchr}[\O{166}]\K\.{\'v\'}$;\5
+$\\{xchr}[\O{167}]\K\.{\'w\'}$;\6
+$\\{xchr}[\O{170}]\K\.{\'x\'}$;\5
+$\\{xchr}[\O{171}]\K\.{\'y\'}$;\5
+$\\{xchr}[\O{172}]\K\.{\'z\'}$;\5
+$\\{xchr}[\O{173}]\K\.{\'\{\'}$;\5
+$\\{xchr}[\O{174}]\K\.{\'|\'}$;\5
+$\\{xchr}[\O{175}]\K\.{\'\}\'}$;\5
+$\\{xchr}[\O{176}]\K\.{\'\~\'}$;\par
+\As22, 23, 69, 72, 75, 92, 98, 131, 138, 179, 191, 199, 202, 231, 251, 396,
+428, 449, 456, 462, 570, 573, 593, 739, 753, 776, 797, 822, 1078, 1085, 1097,
+1150, 1153\ETs1184.
+\U4.\fi
+
+\M22. The ASCII code is ``standard'' only to a certain extent, since many
+computer installations have found it advantageous to have ready access
+to more than 94 printing characters. If \MF\ is being used
+on a garden-variety \PASCAL\ for which only standard ASCII
+codes will appear in the input and output files, it doesn't really matter
+what codes are specified in $\\{xchr}[0\to\O{37}]$, but the safest policy is to
+blank everything out by using the code shown below.
+
+However, other settings of \\{xchr} will make \MF\ more friendly on
+computers that have an extended character set, so that users can type things
+like `\.^^Z' instead of `\.{<>}'.
+People with extended character sets can
+assign codes arbitrarily, giving an \\{xchr} equivalent to whatever
+characters the users of \MF\ are allowed to have in their input files.
+Appropriate changes to \MF's \\{char\_class} table should then be made.
+(Unlike \TeX, each installation of \MF\ has a fixed assignment of category
+codes, called the \\{char\_class}.) Such changes make portability of programs
+more difficult, so they should be introduced cautiously if at all.
+
+\Y\P$\4\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+\&{for} $\|i\K0\mathrel{\&{to}}\O{37}$ \1\&{do}\5
+$\\{xchr}[\|i]\K\.{\'\ \'}$;\2\6
+\&{for} $\|i\K\O{177}\mathrel{\&{to}}\O{377}$ \1\&{do}\5
+$\\{xchr}[\|i]\K\.{\'\ \'}$;\2\par
+\fi
+
+\M23. The following system-independent code makes the \\{xord} array contain a
+suitable inverse to the information in \\{xchr}. Note that if $\\{xchr}[\|i]=%
+\\{xchr}[\|j]$
+where $\|i<\|j<\O{177}$, the value of $\\{xord}[\\{xchr}[\|i]]$ will turn out
+to be
+\|j or more; hence, standard ASCII code numbers will be used instead of
+codes below \O{40} in case there is a coincidence.
+
+\Y\P$\4\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+\&{for} $\|i\K\\{first\_text\_char}\mathrel{\&{to}}\\{last\_text\_char}$ \1%
+\&{do}\5
+$\\{xord}[\\{chr}(\|i)]\K\O{177}$;\2\6
+\&{for} $\|i\K\O{200}\mathrel{\&{to}}\O{377}$ \1\&{do}\5
+$\\{xord}[\\{xchr}[\|i]]\K\|i$;\2\6
+\&{for} $\|i\K0\mathrel{\&{to}}\O{176}$ \1\&{do}\5
+$\\{xord}[\\{xchr}[\|i]]\K\|i$;\2\par
+\fi
+
+\N24. \[3] Input and output.
+The bane of portability is the fact that different operating systems treat
+input and output quite differently, perhaps because computer scientists
+have not given sufficient attention to this problem. People have felt somehow
+that input and output are not part of ``real'' programming. Well, it is true
+that some kinds of programming are more fun than others. With existing
+input/output conventions being so diverse and so messy, the only sources of
+joy in such parts of the code are the rare occasions when one can find a
+way to make the program a little less bad than it might have been. We have
+two choices, either to attack I/O now and get it over with, or to postpone
+I/O until near the end. Neither prospect is very attractive, so let's
+get it over with.
+
+The basic operations we need to do are (1)~inputting and outputting of
+text, to or from a file or the user's terminal; (2)~inputting and
+outputting of eight-bit bytes, to or from a file; (3)~instructing the
+operating system to initiate (``open'') or to terminate (``close'') input or
+output from a specified file; (4)~testing whether the end of an input
+file has been reached; (5)~display of bits on the user's screen.
+The bit-display operation will be discussed in a later section; we shall
+deal here only with more traditional kinds of I/O.
+
+\MF\ needs to deal with two kinds of files.
+We shall use the term \\{alpha\_file} for a file that contains textual data,
+and the term \\{byte\_file} for a file that contains eight-bit binary
+information.
+These two types turn out to be the same on many computers, but
+sometimes there is a significant distinction, so we shall be careful to
+distinguish between them. Standard protocols for transferring
+such files from computer to computer, via high-speed networks, are
+now becoming available to more and more communities of users.
+
+The program actually makes use also of a third kind of file, called a
+\\{word\_file}, when dumping and reloading base information for its own
+initialization. We shall define a word file later; but it will be possible
+for us to specify simple operations on word files before they are defined.
+
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{eight\_bits}=0\to255$;\C{unsigned one-byte quantity}\6
+$\\{alpha\_file}=$\1\5
+\&{packed} \37\&{file} \1\&{of}\5
+\\{text\_char};\C{files that contain textual data}\2\2\6
+$\\{byte\_file}=$\1\5
+\&{packed} \37\&{file} \1\&{of}\5
+\\{eight\_bits};\C{files that contain binary data}\2\2\par
+\fi
+
+\M25. Most of what we need to do with respect to input and output can be
+handled
+by the I/O facilities that are standard in \PASCAL, i.e., the routines
+called \\{get}, \\{put}, \\{eof}, and so on. But
+standard \PASCAL\ does not allow file variables to be associated with file
+names that are determined at run time, so it cannot be used to implement
+\MF; some sort of extension to \PASCAL's ordinary \\{reset} and \\{rewrite}
+is crucial for our purposes. We shall assume that \\{name\_of\_file} is a
+variable
+of an appropriate type such that the \PASCAL\ run-time system being used to
+implement \MF\ can open a file whose external name is specified by
+\\{name\_of\_file}.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{name\_of\_file}: \37\&{packed} \37\&{array} $[1\to\\{file\_name\_size}]$ %
+\1\&{of}\5
+\\{char};\2\6
+\C{on some systems this may be a \&{record} variable}\6
+\4\\{name\_length}: \37$0\to\\{file\_name\_size}$;\6
+\C{this many characters are actually relevant in \\{name\_of\_file} (the rest
+are blank)}\par
+\fi
+
+\M26. The \ph\ compiler with which the present version of \MF\ was prepared has
+extended the rules of \PASCAL\ in a very convenient way. To open file~\|f,
+we can write
+$$\vbox{\halign{#\hfil\qquad&#\hfil\cr
+$\\{reset}(\|f,\hbox{\\{name}},\.{\'/O\'})$&for input;\cr
+$\\{rewrite}(\|f,\hbox{\\{name}},\.{\'/O\'})$&for output.\cr}}$$
+The `\\{name}' parameter, which is of type `\ignorespaces\&{packed} \&{array}
+$[\hbox{\<\\{any}>}]$ \&{of} \\{text\_char}', stands for the name of
+the external file that is being opened for input or output.
+Blank spaces that might appear in \\{name} are ignored.
+
+The `\.{/O}' parameter tells the operating system not to issue its own
+error messages if something goes wrong. If a file of the specified name
+cannot be found, or if such a file cannot be opened for some other reason
+(e.g., someone may already be trying to write the same file), we will have
+$\\{erstat}(\|f)\I0$ after an unsuccessful \\{reset} or \\{rewrite}. This
+allows
+\MF\ to undertake appropriate corrective action.
+
+\MF's file-opening procedures return \\{false} if no file identified by
+\\{name\_of\_file} could be opened.
+
+\Y\P\D \37$\\{reset\_OK}(\#)\S\\{erstat}(\#)=0$\par
+\P\D \37$\\{rewrite\_OK}(\#)\S\\{erstat}(\#)=0$\par
+\Y\P\4\&{function}\1\ \37$\\{a\_open\_in}(\mathop{\&{var}}\|f:\\{alpha%
+\_file})$: \37\\{boolean};\C{open a text file for input}\2\6
+\&{begin} \37$\\{reset}(\|f,\39\\{name\_of\_file},\39\.{\'/O\'})$;\5
+$\\{a\_open\_in}\K\\{reset\_OK}(\|f)$;\6
+\&{end};\7
+\4\&{function}\1\ \37$\\{a\_open\_out}(\mathop{\&{var}}\|f:\\{alpha\_file})$: %
+\37\\{boolean};\C{open a text file for output}\2\6
+\&{begin} \37$\\{rewrite}(\|f,\39\\{name\_of\_file},\39\.{\'/O\'})$;\5
+$\\{a\_open\_out}\K\\{rewrite\_OK}(\|f)$;\6
+\&{end};\7
+\4\&{function}\1\ \37$\\{b\_open\_out}(\mathop{\&{var}}\|f:\\{byte\_file})$: %
+\37\\{boolean};\C{open a binary file for output}\2\6
+\&{begin} \37$\\{rewrite}(\|f,\39\\{name\_of\_file},\39\.{\'/O\'})$;\5
+$\\{b\_open\_out}\K\\{rewrite\_OK}(\|f)$;\6
+\&{end};\7
+\4\&{function}\1\ \37$\\{w\_open\_in}(\mathop{\&{var}}\|f:\\{word\_file})$: %
+\37\\{boolean};\C{open a word file for input}\2\6
+\&{begin} \37$\\{reset}(\|f,\39\\{name\_of\_file},\39\.{\'/O\'})$;\5
+$\\{w\_open\_in}\K\\{reset\_OK}(\|f)$;\6
+\&{end};\7
+\4\&{function}\1\ \37$\\{w\_open\_out}(\mathop{\&{var}}\|f:\\{word\_file})$: %
+\37\\{boolean};\C{open a word file for output}\2\6
+\&{begin} \37$\\{rewrite}(\|f,\39\\{name\_of\_file},\39\.{\'/O\'})$;\5
+$\\{w\_open\_out}\K\\{rewrite\_OK}(\|f)$;\6
+\&{end};\par
+\fi
+
+\M27. Files can be closed with the \ph\ routine `$\\{close}(\|f)$', which
+should be used when all input or output with respect to \|f has been completed.
+This makes \|f available to be opened again, if desired; and if \|f was used
+for
+output, the \\{close} operation makes the corresponding external file appear
+on the user's area, ready to be read.
+
+\Y\P\4\&{procedure}\1\ \37$\\{a\_close}(\mathop{\&{var}}\|f:\\{alpha\_file})$;%
+\C{close a text file}\2\6
+\&{begin} \37$\\{close}(\|f)$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37$\\{b\_close}(\mathop{\&{var}}\|f:\\{byte\_file})$;%
+\C{close a binary file}\2\6
+\&{begin} \37$\\{close}(\|f)$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37$\\{w\_close}(\mathop{\&{var}}\|f:\\{word\_file})$;%
+\C{close a word file}\2\6
+\&{begin} \37$\\{close}(\|f)$;\6
+\&{end};\par
+\fi
+
+\M28. Binary input and output are done with \PASCAL's ordinary \\{get} and %
+\\{put}
+procedures, so we don't have to make any other special arrangements for
+binary~I/O. Text output is also easy to do with standard \PASCAL\ routines.
+The treatment of text input is more difficult, however, because
+of the necessary translation to \\{ASCII\_code} values.
+\MF's conventions should be efficient, and they should
+blend nicely with the user's operating environment.
+
+\fi
+
+\M29. Input from text files is read one line at a time, using a routine called
+\\{input\_ln}. This function is defined in terms of global variables called
+\\{buffer}, \\{first}, and \\{last} that will be described in detail later; for
+now, it suffices for us to know that \\{buffer} is an array of \\{ASCII\_code}
+values, and that \\{first} and \\{last} are indices into this array
+representing the beginning and ending of a line of text.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{buffer}: \37\&{array} $[0\to\\{buf\_size}]$ \1\&{of}\5
+\\{ASCII\_code};\C{lines of characters being read}\2\6
+\4\\{first}: \37$0\to\\{buf\_size}$;\C{the first unused position in \\{buffer}}%
+\6
+\4\\{last}: \37$0\to\\{buf\_size}$;\C{end of the line just input to \\{buffer}}%
+\6
+\4\\{max\_buf\_stack}: \37$0\to\\{buf\_size}$;\C{largest index used in %
+\\{buffer}}\par
+\fi
+
+\M30. The \\{input\_ln} function brings the next line of input from the
+specified
+field into available positions of the buffer array and returns the value
+\\{true}, unless the file has already been entirely read, in which case it
+returns \\{false} and sets $\\{last}\K\\{first}$. In general, the \\{ASCII%
+\_code}
+numbers that represent the next line of the file are input into
+$\\{buffer}[\\{first}]$, $\\{buffer}[\\{first}+1]$, \dots, $\\{buffer}[%
+\\{last}-1]$; and the
+global variable \\{last} is set equal to \\{first} plus the length of the
+line. Trailing blanks are removed from the line; thus, either $\\{last}=%
+\\{first}$
+(in which case the line was entirely blank) or $\\{buffer}[\\{last}-1]\I\.{"\
+"}$.
+
+An overflow error is given, however, if the normal actions of \\{input\_ln}
+would make $\\{last}\G\\{buf\_size}$; this is done so that other parts of \MF\
+can safely look at the contents of $\\{buffer}[\\{last}+1]$ without
+overstepping
+the bounds of the \\{buffer} array. Upon entry to \\{input\_ln}, the condition
+$\\{first}<\\{buf\_size}$ will always hold, so that there is always room for an
+``empty'' line.
+
+The variable \\{max\_buf\_stack}, which is used to keep track of how large
+the \\{buf\_size} parameter must be to accommodate the present job, is
+also kept up to date by \\{input\_ln}.
+
+If the \\{bypass\_eoln} parameter is \\{true}, \\{input\_ln} will do a \\{get}
+before looking at the first character of the line; this skips over
+an \\{eoln} that was in $\|f\^$. The procedure does not do a \\{get} when it
+reaches the end of the line; therefore it can be used to acquire input
+from the user's terminal as well as from ordinary text files.
+
+Standard \PASCAL\ says that a file should have \\{eoln} immediately
+before \\{eof}, but \MF\ needs only a weaker restriction: If \\{eof}
+occurs in the middle of a line, the system function \\{eoln} should return
+a \\{true} result (even though $\|f\^$ will be undefined).
+
+\Y\P\4\&{function}\1\ \37$\\{input\_ln}(\mathop{\&{var}}\|f:\\{alpha\_file};\,%
+\35\\{bypass\_eoln}:\\{boolean})$: \37\\{boolean};\C{inputs the next line or
+returns \\{false}}\6
+\4\&{var} \37\\{last\_nonblank}: \37$0\to\\{buf\_size}$;\C{\\{last} with
+trailing blanks removed}\2\6
+\&{begin} \37\&{if} $\\{bypass\_eoln}$ \1\&{then}\6
+\&{if} $\R\\{eof}(\|f)$ \1\&{then}\5
+$\\{get}(\|f)$;\C{input the first character of the line into $\|f\^$}\2\2\6
+$\\{last}\K\\{first}$;\C{cf.\ Matthew 19\thinspace:\thinspace30}\6
+\&{if} $\\{eof}(\|f)$ \1\&{then}\5
+$\\{input\_ln}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\\{last\_nonblank}\K\\{first}$;\6
+\&{while} $\R\\{eoln}(\|f)$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{last}\G\\{max\_buf\_stack}$ \1\&{then}\6
+\&{begin} \37$\\{max\_buf\_stack}\K\\{last}+1$;\6
+\&{if} $\\{max\_buf\_stack}=\\{buf\_size}$ \1\&{then}\5
+\X34:Report overflow of the input buffer, and abort\X;\2\6
+\&{end};\2\6
+$\\{buffer}[\\{last}]\K\\{xord}[\|f\^]$;\5
+$\\{get}(\|f)$;\5
+$\\{incr}(\\{last})$;\6
+\&{if} $\\{buffer}[\\{last}-1]\I\.{"\ "}$ \1\&{then}\5
+$\\{last\_nonblank}\K\\{last}$;\2\6
+\&{end};\2\6
+$\\{last}\K\\{last\_nonblank}$;\5
+$\\{input\_ln}\K\\{true}$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M31. The user's terminal acts essentially like other files of text, except
+that it is used both for input and for output. When the terminal is
+considered an input file, the file variable is called \\{term\_in}, and when it
+is considered an output file the file variable is \\{term\_out}.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{term\_in}: \37\\{alpha\_file};\C{the terminal as an input file}\6
+\4\\{term\_out}: \37\\{alpha\_file};\C{the terminal as an output file}\par
+\fi
+
+\M32. Here is how to open the terminal files
+in \ph. The `\.{/I}' switch suppresses the first \\{get}.
+
+\Y\P\D \37$\\{t\_open\_in}\S\\{reset}(\\{term\_in},\39\.{\'TTY:\'},\39\.{\'/O/I%
+\'})$\C{open the terminal for text input}\par
+\P\D \37$\\{t\_open\_out}\S\\{rewrite}(\\{term\_out},\39\.{\'TTY:\'},\39\.{\'/O%
+\'})$\C{open the terminal for text output}\par
+\fi
+
+\M33. Sometimes it is necessary to synchronize the input/output mixture that
+happens on the user's terminal, and three system-dependent
+procedures are used for this
+purpose. The first of these, \\{update\_terminal}, is called when we want
+to make sure that everything we have output to the terminal so far has
+actually left the computer's internal buffers and been sent.
+The second, \\{clear\_terminal}, is called when we wish to cancel any
+input that the user may have typed ahead (since we are about to
+issue an unexpected error message). The third, \\{wake\_up\_terminal},
+is supposed to revive the terminal if the user has disabled it by
+some instruction to the operating system. The following macros show how
+these operations can be specified in \ph:
+
+\Y\P\D \37$\\{update\_terminal}\S\\{break}(\\{term\_out})$\C{empty the terminal
+output buffer}\par
+\P\D \37$\\{clear\_terminal}\S\\{break\_in}(\\{term\_in},\39\\{true})$\C{clear
+the terminal input buffer}\par
+\P\D \37$\\{wake\_up\_terminal}\S\\{do\_nothing}$\C{cancel the user's
+cancellation of output}\par
+\fi
+
+\M34. We need a special routine to read the first line of \MF\ input from
+the user's terminal. This line is different because it is read before we
+have opened the transcript file; there is sort of a ``chicken and
+egg'' problem here. If the user types `\.{input cmr10}' on the first
+line, or if some macro invoked by that line does such an \.{input},
+the transcript file will be named `\.{cmr10.log}'; but if no \.{input}
+commands are performed during the first line of terminal input, the transcript
+file will acquire its default name `\.{mfput.log}'. (The transcript file
+will not contain error messages generated by the first line before the
+first \.{input} command.)
+
+The first line is even more special if we are lucky enough to have an operating
+system that treats \MF\ differently from a run-of-the-mill \PASCAL\ object
+program. It's nice to let the user start running a \MF\ job by typing
+a command line like `\.{MF cmr10}'; in such a case, \MF\ will operate
+as if the first line of input were `\.{cmr10}', i.e., the first line will
+consist of the remainder of the command line, after the part that invoked \MF.
+
+The first line is special also because it may be read before \MF\ has
+input a base file. In such cases, normal error messages cannot yet
+be given. The following code uses concepts that will be explained later.
+(If the \PASCAL\ compiler does not support non-local \&{goto} , the
+statement `\&{goto} \\{final\_end}' should be replaced by something that
+quietly terminates the program.)
+
+\Y\P$\4\X34:Report overflow of the input buffer, and abort\X\S$\6
+\&{if} $\\{base\_ident}=0$ \1\&{then}\6
+\&{begin} \37$\\{write\_ln}(\\{term\_out},\39\.{\'Buffer\ size\ exceeded!\'})$;%
+\5
+\&{goto} \37\\{final\_end};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{cur\_input}.\\{loc\_field}\K\\{first}$;\5
+$\\{cur\_input}.\\{limit\_field}\K\\{last}-1$;\5
+$\\{overflow}(\.{"buffer\ size"},\39\\{buf\_size})$;\6
+\&{end}\2\par
+\U30.\fi
+
+\M35. Different systems have different ways to get started. But regardless of
+what conventions are adopted, the routine that initializes the terminal
+should satisfy the following specifications:
+
+\yskip\textindent{1)}It should open file \\{term\_in} for input from the
+terminal. (The file \\{term\_out} will already be open for output to the
+terminal.)
+
+\textindent{2)}If the user has given a command line, this line should be
+considered the first line of terminal input. Otherwise the
+user should be prompted with `\.{**}', and the first line of input
+should be whatever is typed in response.
+
+\textindent{3)}The first line of input, which might or might not be a
+command line, should appear in locations \\{first} to $\\{last}-1$ of the
+\\{buffer} array.
+
+\textindent{4)}The global variable \\{loc} should be set so that the
+character to be read next by \MF\ is in $\\{buffer}[\\{loc}]$. This
+character should not be blank, and we should have $\\{loc}<\\{last}$.
+
+\yskip\noindent(It may be necessary to prompt the user several times
+before a non-blank line comes in. The prompt is `\.{**}' instead of the
+later `\.*' because the meaning is slightly different: `\.{input}' need
+not be typed immediately after~`\.{**}'.)
+
+\Y\P\D \37$\\{loc}\S\\{cur\_input}.\\{loc\_field}$\C{location of first unread
+character in \\{buffer}}\par
+\fi
+
+\M36. The following program does the required initialization
+without retrieving a possible command line.
+It should be clear how to modify this routine to deal with command lines,
+if the system permits them.
+
+\Y\P\4\&{function}\1\ \37\\{init\_terminal}: \37\\{boolean};\C{gets the
+terminal input started}\6
+\4\&{label} \37\\{exit};\2\6
+\&{begin} \37\\{t\_open\_in};\6
+\~ \1\&{loop}\ \&{begin} \37\\{wake\_up\_terminal};\5
+$\\{write}(\\{term\_out},\39\.{\'**\'})$;\5
+\\{update\_terminal};\6
+\&{if} $\R\\{input\_ln}(\\{term\_in},\39\\{true})$ \1\&{then}\C{this shouldn't
+happen}\6
+\&{begin} \37$\\{write\_ln}(\\{term\_out})$;\5
+$\\{write}(\\{term\_out},\39\.{\'!\ End\ of\ file\ on\ the\ terminal...\ why?%
+\'})$;\5
+$\\{init\_terminal}\K\\{false}$;\5
+\&{return};\6
+\&{end};\2\6
+$\\{loc}\K\\{first}$;\6
+\&{while} $(\\{loc}<\\{last})\W(\\{buffer}[\\{loc}]=\.{"\ "})$ \1\&{do}\5
+$\\{incr}(\\{loc})$;\2\6
+\&{if} $\\{loc}<\\{last}$ \1\&{then}\6
+\&{begin} \37$\\{init\_terminal}\K\\{true}$;\5
+\&{return};\C{return unless the line was all blank}\6
+\&{end};\2\6
+$\\{write\_ln}(\\{term\_out},\39\.{\'Please\ type\ the\ name\ of\ your\ input\
+file.\'})$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\N37. \[4] String handling.
+Symbolic token names and diagnostic messages are variable-length strings
+of eight-bit characters. Since \PASCAL\ does not have a well-developed string
+mechanism, \MF\ does all of its string processing by homegrown methods.
+
+Elaborate facilities for dynamic strings are not needed, so all of the
+necessary operations can be handled with a simple data structure.
+The array \\{str\_pool} contains all of the (eight-bit) ASCII codes in all
+of the strings, and the array \\{str\_start} contains indices of the starting
+points of each string. Strings are referred to by integer numbers, so that
+string number \|s comprises the characters $\\{str\_pool}[\|j]$ for
+$\\{str\_start}[\|s]\L\|j<\\{str\_start}[\|s+1]$. Additional integer variables
+\\{pool\_ptr} and \\{str\_ptr} indicate the number of entries used so far
+in \\{str\_pool} and \\{str\_start}, respectively; locations
+$\\{str\_pool}[\\{pool\_ptr}]$ and $\\{str\_start}[\\{str\_ptr}]$ are
+ready for the next string to be allocated.
+
+String numbers 0 to 255 are reserved for strings that correspond to single
+ASCII characters. This is in accordance with the conventions of \.{WEB},
+which converts single-character strings into the ASCII code number of the
+single character involved, while it converts other strings into integers
+and builds a string pool file. Thus, when the string constant \.{"."} appears
+in the program below, \.{WEB} converts it into the integer 46, which is the
+ASCII code for a period, while \.{WEB} will convert a string like \.{"hello"}
+into some integer greater than~255. String number 46 will presumably be the
+single character `\..'\thinspace; but some ASCII codes have no standard visible
+representation, and \MF\ may need to be able to print an arbitrary
+ASCII character, so the first 256 strings are used to specify exactly what
+should be printed for each of the 256 possibilities.
+
+Elements of the \\{str\_pool} array must be ASCII codes that can actually be
+printed; i.e., they must have an \\{xchr} equivalent in the local
+character set. (This restriction applies only to preloaded strings,
+not to those generated dynamically by the user.)
+
+Some \PASCAL\ compilers won't pack integers into a single byte unless the
+integers lie in the range $-128\to127$. To accommodate such systems
+we access the string pool only via macros that can easily be redefined.
+
+\Y\P\D \37$\\{si}(\#)\S\#$\C{convert from \\{ASCII\_code} to \\{packed\_ASCII%
+\_code}}\par
+\P\D \37$\\{so}(\#)\S\#$\C{convert from \\{packed\_ASCII\_code} to \\{ASCII%
+\_code}}\par
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{pool\_pointer}=0\to\\{pool\_size}$;\C{for variables that point into \\{str%
+\_pool}}\6
+$\\{str\_number}=0\to\\{max\_strings}$;\C{for variables that point into \\{str%
+\_start}}\6
+$\\{packed\_ASCII\_code}=0\to255$;\C{elements of \\{str\_pool} array}\par
+\fi
+
+\M38. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{str\_pool}: \37\&{packed} \37\&{array} $[\\{pool\_pointer}]$ \1\&{of}\5
+\\{packed\_ASCII\_code};\C{the characters}\2\6
+\4\\{str\_start}: \37\&{array} $[\\{str\_number}]$ \1\&{of}\5
+\\{pool\_pointer};\C{the starting pointers}\2\6
+\4\\{pool\_ptr}: \37\\{pool\_pointer};\C{first unused position in \\{str%
+\_pool}}\6
+\4\\{str\_ptr}: \37\\{str\_number};\C{number of the current string being
+created}\6
+\4\\{init\_pool\_ptr}: \37\\{pool\_pointer};\C{the starting value of \\{pool%
+\_ptr}}\6
+\4\\{init\_str\_ptr}: \37\\{str\_number};\C{the starting value of \\{str\_ptr}}%
+\6
+\4\\{max\_pool\_ptr}: \37\\{pool\_pointer};\C{the maximum so far of \\{pool%
+\_ptr}}\6
+\4\\{max\_str\_ptr}: \37\\{str\_number};\C{the maximum so far of \\{str\_ptr}}%
+\par
+\fi
+
+\M39. Several of the elementary string operations are performed using \.{WEB}
+macros instead of \PASCAL\ procedures, because many of the
+operations are done quite frequently and we want to avoid the
+overhead of procedure calls. For example, here is
+a simple macro that computes the length of a string.
+
+\Y\P\D \37$\\{length}(\#)\S(\\{str\_start}[\#+1]-\\{str\_start}[\#])$\C{the
+number of characters in string number \#}\par
+\fi
+
+\M40. The length of the current string is called \\{cur\_length}:
+
+\Y\P\D \37$\\{cur\_length}\S(\\{pool\_ptr}-\\{str\_start}[\\{str\_ptr}])$\par
+\fi
+
+\M41. Strings are created by appending character codes to \\{str\_pool}.
+The \\{append\_char} macro, defined here, does not check to see if the
+value of \\{pool\_ptr} has gotten too high; this test is supposed to be
+made before \\{append\_char} is used.
+
+To test if there is room to append \|l more characters to \\{str\_pool},
+we shall write $\\{str\_room}(\|l)$, which aborts \MF\ and gives an
+apologetic error message if there isn't enough room.
+
+\Y\P\D \37$\\{append\_char}(\#)\S$\C{put \\{ASCII\_code} \# at the end of %
+\\{str\_pool}}\6
+\&{begin} \37$\\{str\_pool}[\\{pool\_ptr}]\K\\{si}(\#)$;\5
+$\\{incr}(\\{pool\_ptr})$;\6
+\&{end}\par
+\P\D \37$\\{str\_room}(\#)\S$\C{make sure that the pool hasn't overflowed}\6
+\&{begin} \37\&{if} $\\{pool\_ptr}+\#>\\{max\_pool\_ptr}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{pool\_ptr}+\#>\\{pool\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"pool\ size"},\39\\{pool\_size}-\\{init\_pool\_ptr})$;\2\6
+$\\{max\_pool\_ptr}\K\\{pool\_ptr}+\#$;\6
+\&{end};\2\6
+\&{end}\par
+\fi
+
+\M42. \MF's string expressions are implemented in a brute-force way: Every
+new string or substring that is needed is simply copied into the string pool.
+
+Such a scheme can be justified because string expressions aren't a big
+deal in \MF\ applications; strings rarely need to be saved from one
+statement to the next. But it would waste space needlessly if we didn't
+try to reclaim the space of strings that are going to be used only once.
+
+Therefore a simple reference count mechanism is provided: If there are
+no references to a certain string from elsewhere in the program, and
+if there are no references to any strings created subsequent to it,
+then the string space will be reclaimed.
+
+The number of references to string number \|s will be $\\{str\_ref}[\|s]$. The
+special value $\\{str\_ref}[\|s]=\\{max\_str\_ref}=127$ is used to denote an
+unknown
+positive number of references; such strings will never be recycled. If
+a string is ever referred to more than 126 times, simultaneously, we
+put it in this category. Hence a single byte suffices to store each \\{str%
+\_ref}.
+
+\Y\P\D \37$\\{max\_str\_ref}=127$\C{``infinite'' number of references}\par
+\P\D \37$\\{add\_str\_ref}(\#)\S$\1\6
+\&{begin} \37\&{if} $\\{str\_ref}[\#]<\\{max\_str\_ref}$ \1\&{then}\5
+$\\{incr}(\\{str\_ref}[\#])$;\2\6
+\&{end}\2\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{str\_ref}: \37\&{array} $[\\{str\_number}]$ \1\&{of}\5
+$0\to\\{max\_str\_ref}$;\2\par
+\fi
+
+\M43. Here's what we do when a string reference disappears:
+
+\Y\P\D \37$\\{delete\_str\_ref}(\#)\S$\1\6
+\&{begin} \37\&{if} $\\{str\_ref}[\#]<\\{max\_str\_ref}$ \1\&{then}\6
+\&{if} $\\{str\_ref}[\#]>1$ \1\&{then}\5
+$\\{decr}(\\{str\_ref}[\#])$\ \&{else} $\\{flush\_string}(\#)$;\2\2\6
+\&{end}\2\par
+\Y\P$\4\X43:Declare the procedure called \\{flush\_string}\X\S$\6
+\4\&{procedure}\1\ \37$\\{flush\_string}(\|s:\\{str\_number})$;\2\6
+\&{begin} \37\&{if} $\|s<\\{str\_ptr}-1$ \1\&{then}\5
+$\\{str\_ref}[\|s]\K0$\6
+\4\&{else} \1\&{repeat} \37$\\{decr}(\\{str\_ptr})$;\6
+\4\&{until}\5
+$\\{str\_ref}[\\{str\_ptr}-1]\I0$;\2\2\6
+$\\{pool\_ptr}\K\\{str\_start}[\\{str\_ptr}]$;\6
+\&{end};\par
+\U73.\fi
+
+\M44. Once a sequence of characters has been appended to \\{str\_pool}, it
+officially becomes a string when the function \\{make\_string} is called.
+This function returns the identification number of the new string as its
+value.
+
+\Y\P\4\&{function}\1\ \37\\{make\_string}: \37\\{str\_number};\C{current
+string enters the pool}\2\6
+\&{begin} \37\&{if} $\\{str\_ptr}=\\{max\_str\_ptr}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{str\_ptr}=\\{max\_strings}$ \1\&{then}\5
+$\\{overflow}(\.{"number\ of\ strings"},\39\\{max\_strings}-\\{init\_str%
+\_ptr})$;\2\6
+$\\{incr}(\\{max\_str\_ptr})$;\6
+\&{end};\2\6
+$\\{str\_ref}[\\{str\_ptr}]\K1$;\5
+$\\{incr}(\\{str\_ptr})$;\5
+$\\{str\_start}[\\{str\_ptr}]\K\\{pool\_ptr}$;\5
+$\\{make\_string}\K\\{str\_ptr}-1$;\6
+\&{end};\par
+\fi
+
+\M45. The following subroutine compares string \|s with another string of the
+same length that appears in \\{buffer} starting at position \|k;
+the result is \\{true} if and only if the strings are equal.
+
+\Y\P\4\&{function}\1\ \37$\\{str\_eq\_buf}(\|s:\\{str\_number};\,\35\|k:%
+\\{integer})$: \37\\{boolean};\C{test equality of strings}\6
+\4\&{label} \37\\{not\_found};\C{loop exit}\6
+\4\&{var} \37\|j: \37\\{pool\_pointer};\C{running index}\6
+\\{result}: \37\\{boolean};\C{result of comparison}\2\6
+\&{begin} \37$\|j\K\\{str\_start}[\|s]$;\6
+\&{while} $\|j<\\{str\_start}[\|s+1]$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{so}(\\{str\_pool}[\|j])\I\\{buffer}[\|k]$ \1\&{then}\6
+\&{begin} \37$\\{result}\K\\{false}$;\5
+\&{goto} \37\\{not\_found};\6
+\&{end};\2\6
+$\\{incr}(\|j)$;\5
+$\\{incr}(\|k)$;\6
+\&{end};\2\6
+$\\{result}\K\\{true}$;\6
+\4\\{not\_found}: \37$\\{str\_eq\_buf}\K\\{result}$;\6
+\&{end};\par
+\fi
+
+\M46. Here is a similar routine, but it compares two strings in the string
+pool,
+and it does not assume that they have the same length. If the first string
+is lexicographically greater than, less than, or equal to the second,
+the result is respectively positive, negative, or zero.
+
+\Y\P\4\&{function}\1\ \37$\\{str\_vs\_str}(\|s,\39\|t:\\{str\_number})$: \37%
+\\{integer};\C{test equality of strings}\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\|j,\39\|k$: \37\\{pool\_pointer};\C{running indices}\6
+$\\{ls},\39\\{lt}$: \37\\{integer};\C{lengths}\6
+\|l: \37\\{integer};\C{length remaining to test}\2\6
+\&{begin} \37$\\{ls}\K\\{length}(\|s)$;\5
+$\\{lt}\K\\{length}(\|t)$;\6
+\&{if} $\\{ls}\L\\{lt}$ \1\&{then}\5
+$\|l\K\\{ls}$\ \&{else} $\|l\K\\{lt}$;\2\6
+$\|j\K\\{str\_start}[\|s]$;\5
+$\|k\K\\{str\_start}[\|t]$;\6
+\&{while} $\|l>0$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{str\_pool}[\|j]\I\\{str\_pool}[\|k]$ \1\&{then}\6
+\&{begin} \37$\\{str\_vs\_str}\K\\{str\_pool}[\|j]-\\{str\_pool}[\|k]$;\5
+\&{return};\6
+\&{end};\2\6
+$\\{incr}(\|j)$;\5
+$\\{incr}(\|k)$;\5
+$\\{decr}(\|l)$;\6
+\&{end};\2\6
+$\\{str\_vs\_str}\K\\{ls}-\\{lt}$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M47. The initial values of \\{str\_pool}, \\{str\_start}, \\{pool\_ptr},
+and \\{str\_ptr} are computed by the \.{INIMF} program, based in part
+on the information that \.{WEB} has output while processing \MF.
+
+\Y\P\&{init} \37\&{function}\1\ \37\\{get\_strings\_started}: \37\\{boolean};%
+\C{initializes the string pool, but returns \\{false} if something goes
+wrong}\6
+\4\&{label} \37$\\{done},\39\\{exit}$;\6
+\4\&{var} \37$\|k,\39\|l$: \37$0\to255$;\C{small indices or counters}\6
+$\|m,\39\|n$: \37\\{text\_char};\C{characters input from \\{pool\_file}}\6
+\|g: \37\\{str\_number};\C{garbage}\6
+\|a: \37\\{integer};\C{accumulator for check sum}\6
+\|c: \37\\{boolean};\C{check sum has been checked}\2\6
+\&{begin} \37$\\{pool\_ptr}\K0$;\5
+$\\{str\_ptr}\K0$;\5
+$\\{max\_pool\_ptr}\K0$;\5
+$\\{max\_str\_ptr}\K0$;\5
+$\\{str\_start}[0]\K0$;\5
+\X48:Make the first 256 strings\X;\6
+\X51:Read the other strings from the \.{MF.POOL} file and return \\{true}, or
+give an error message and return \\{false}\X;\6
+\4\\{exit}: \37\&{end};\6
+\&{tini}\par
+\fi
+
+\M48. \P\D \37$\\{app\_lc\_hex}(\#)\S\|l\K\#$;\6
+\&{if} $\|l<10$ \1\&{then}\5
+$\\{append\_char}(\|l+\.{"0"})$\ \&{else} $\\{append\_char}(\|l-10+\.{"a"})$\2%
+\par
+\Y\P$\4\X48:Make the first 256 strings\X\S$\6
+\&{for} $\|k\K0\mathrel{\&{to}}255$ \1\&{do}\6
+\&{begin} \37\&{if} $(\X49:Character \|k cannot be printed\X)$ \1\&{then}\6
+\&{begin} \37$\\{append\_char}(\.{"\^"})$;\5
+$\\{append\_char}(\.{"\^"})$;\6
+\&{if} $\|k<\O{100}$ \1\&{then}\5
+$\\{append\_char}(\|k+\O{100})$\6
+\4\&{else} \&{if} $\|k<\O{200}$ \1\&{then}\5
+$\\{append\_char}(\|k-\O{100})$\6
+\4\&{else} \&{begin} \37$\\{app\_lc\_hex}(\|k\mathbin{\&{div}}16)$;\5
+$\\{app\_lc\_hex}(\|k\mathbin{\&{mod}}16)$;\6
+\&{end};\2\2\6
+\&{end}\6
+\4\&{else} $\\{append\_char}(\|k)$;\2\6
+$\|g\K\\{make\_string}$;\5
+$\\{str\_ref}[\|g]\K\\{max\_str\_ref}$;\6
+\&{end}\2\par
+\U47.\fi
+
+\M49. The first 128 strings will contain 95 standard ASCII characters, and the
+other 33 characters will be printed in three-symbol form like `\.{\^\^A}'
+unless a system-dependent change is made here. Installations that have
+an extended character set, where for example $\\{xchr}[\O{32}]=\hbox{\.{\'^^Z%
+\'}}$,
+would like string \O{32} to be the single character \O{32} instead of the
+three characters \O{136}, \O{136}, \O{132} (\.{\^\^Z}). On the other hand,
+even people with an extended character set will want to represent string
+\O{15} by \.{\^\^M}, since \O{15} is ASCII's ``carriage return'' code; the idea
+is
+to produce visible strings instead of tabs or line-feeds or carriage-returns
+or bell-rings or characters that are treated anomalously in text files.
+
+Unprintable characters of codes 128--255 are, similarly, rendered
+\.{\^\^80}--\.{\^\^ff}.
+
+The boolean expression defined here should be \\{true} unless \MF\ internal
+code number~\|k corresponds to a non-troublesome visible symbol in the
+local character set.
+If character \|k cannot be printed, and $\|k<\O{200}$, then character $\|k+%
+\O{100}$ or
+$\|k-\O{100}$ must be printable; moreover, ASCII codes $[\O{60}\to\O{71},%
+\O{141}\to\O{146}]$
+must be printable.
+
+\Y\P$\4\X49:Character \|k cannot be printed\X\S$\6
+$(\|k<\.{"\ "})\V(\|k>\.{"\~"})$\par
+\U48.\fi
+
+\M50. When the \.{WEB} system program called \.{TANGLE} processes the %
+\.{MF.WEB}
+description that you are now reading, it outputs the \PASCAL\ program
+\.{MF.PAS} and also a string pool file called \.{MF.POOL}. The \.{INIMF}
+program reads the latter file, where each string appears as a two-digit decimal
+length followed by the string itself, and the information is recorded in
+\MF's string memory.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\&{init} \37\\{pool\_file}: \37\\{alpha\_file};\C{the string-pool file output
+by \.{TANGLE}}\6
+\&{tini}\par
+\fi
+
+\M51. \P\D \37$\\{bad\_pool}(\#)\S$\1\6
+\&{begin} \37\\{wake\_up\_terminal};\5
+$\\{write\_ln}(\\{term\_out},\39\#)$;\5
+$\\{a\_close}(\\{pool\_file})$;\5
+$\\{get\_strings\_started}\K\\{false}$;\5
+\&{return};\6
+\&{end}\2\par
+\Y\P$\4\X51:Read the other strings from the \.{MF.POOL} file and return %
+\\{true}, or give an error message and return \\{false}\X\S$\6
+$\\{name\_of\_file}\K\\{pool\_name}$;\C{we needn't set \\{name\_length}}\6
+\&{if} $\\{a\_open\_in}(\\{pool\_file})$ \1\&{then}\6
+\&{begin} \37$\|c\K\\{false}$;\6
+\1\&{repeat} \37\X52:Read one string, but return \\{false} if the string memory
+space is getting too tight for comfort\X;\6
+\4\&{until}\5
+\|c;\2\6
+$\\{a\_close}(\\{pool\_file})$;\5
+$\\{get\_strings\_started}\K\\{true}$;\6
+\&{end}\6
+\4\&{else} $\\{bad\_pool}(\.{\'!\ I\ can\'}\.{\'t\ read\ MF.POOL.\'})$\2\par
+\U47.\fi
+
+\M52. \P$\X52:Read one string, but return \\{false} if the string memory space
+is getting too tight for comfort\X\S$\6
+\&{begin} \37\&{if} $\\{eof}(\\{pool\_file})$ \1\&{then}\5
+$\\{bad\_pool}(\.{\'!\ MF.POOL\ has\ no\ check\ sum.\'})$;\2\6
+$\\{read}(\\{pool\_file},\39\|m,\39\|n)$;\C{read two digits of string length}\6
+\&{if} $\|m=\.{\'*\'}$ \1\&{then}\5
+\X53:Check the pool check sum\X\6
+\4\&{else} \&{begin} \37\&{if} $(\\{xord}[\|m]<\.{"0"})\V(\\{xord}[\|m]>%
+\.{"9"})\V\30(\\{xord}[\|n]<\.{"0"})\V(\\{xord}[\|n]>\.{"9"})$ \1\&{then}\5
+$\\{bad\_pool}(\.{\'!\ MF.POOL\ line\ doesn\'}\.{\'t\ begin\ with\ two\ digits.%
+\'})$;\2\6
+$\|l\K\\{xord}[\|m]\ast10+\\{xord}[\|n]-\.{"0"}\ast11$;\C{compute the length}\6
+\&{if} $\\{pool\_ptr}+\|l+\\{string\_vacancies}>\\{pool\_size}$ \1\&{then}\5
+$\\{bad\_pool}(\.{\'!\ You\ have\ to\ increase\ POOLSIZE.\'})$;\2\6
+\&{for} $\|k\K1\mathrel{\&{to}}\|l$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{eoln}(\\{pool\_file})$ \1\&{then}\5
+$\|m\K\.{\'\ \'}$\ \&{else} $\\{read}(\\{pool\_file},\39\|m)$;\2\6
+$\\{append\_char}(\\{xord}[\|m])$;\6
+\&{end};\2\6
+$\\{read\_ln}(\\{pool\_file})$;\5
+$\|g\K\\{make\_string}$;\5
+$\\{str\_ref}[\|g]\K\\{max\_str\_ref}$;\6
+\&{end};\2\6
+\&{end}\par
+\U51.\fi
+
+\M53. The \.{WEB} operation \.{@\$} denotes the value that should be at the
+end of this \.{MF.POOL} file; any other value means that the wrong pool
+file has been loaded.
+
+\Y\P$\4\X53:Check the pool check sum\X\S$\6
+\&{begin} \37$\|a\K0$;\5
+$\|k\K1$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $(\\{xord}[\|n]<\.{"0"})\V(\\{xord}[\|n]>%
+\.{"9"})$ \1\&{then}\5
+$\\{bad\_pool}(\.{\'!\ MF.POOL\ check\ sum\ doesn\'}\.{\'t\ have\ nine\ digits.%
+\'})$;\2\6
+$\|a\K10\ast\|a+\\{xord}[\|n]-\.{"0"}$;\6
+\&{if} $\|k=9$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{incr}(\|k)$;\5
+$\\{read}(\\{pool\_file},\39\|n)$;\6
+\&{end};\2\6
+\4\\{done}: \37\&{if} $\|a\I\)$ \1\&{then}\5
+$\\{bad\_pool}(\.{\'!\ MF.POOL\ doesn\'}\.{\'t\ match;\ TANGLE\ me\ again.%
+\'})$;\2\6
+$\|c\K\\{true}$;\6
+\&{end}\par
+\U52.\fi
+
+\N54. \[5] On-line and off-line printing.
+Messages that are sent to a user's terminal and to the transcript-log file
+are produced by several `\\{print}' procedures. These procedures will
+direct their output to a variety of places, based on the setting of
+the global variable \\{selector}, which has the following possible
+values:
+
+\yskip
+\hang \\{term\_and\_log}, the normal setting, prints on the terminal and on the
+transcript file.
+
+\hang \\{log\_only}, prints only on the transcript file.
+
+\hang \\{term\_only}, prints only on the terminal.
+
+\hang \\{no\_print}, doesn't print at all. This is used only in rare cases
+before the transcript file is open.
+
+\hang \\{pseudo}, puts output into a cyclic buffer that is used
+by the \\{show\_context} routine; when we get to that routine we shall discuss
+the reasoning behind this curious mode.
+
+\hang \\{new\_string}, appends the output to the current string in the
+string pool.
+
+\yskip
+\noindent The symbolic names `\\{term\_and\_log}', etc., have been assigned
+numeric codes that satisfy the convenient relations $\\{no\_print}+1=\\{term%
+\_only}$,
+$\\{no\_print}+2=\\{log\_only}$, $\\{term\_only}+2=\\{log\_only}+1=\\{term\_and%
+\_log}$.
+
+Three additional global variables, \\{tally} and \\{term\_offset} and
+\\{file\_offset}, record the number of characters that have been printed
+since they were most recently cleared to zero. We use \\{tally} to record
+the length of (possibly very long) stretches of printing; \\{term\_offset}
+and \\{file\_offset}, on the other hand, keep track of how many characters
+have appeared so far on the current line that has been output to the
+terminal or to the transcript file, respectively.
+
+\Y\P\D \37$\\{no\_print}=0$\C{\\{selector} setting that makes data disappear}%
+\par
+\P\D \37$\\{term\_only}=1$\C{printing is destined for the terminal only}\par
+\P\D \37$\\{log\_only}=2$\C{printing is destined for the transcript file only}%
+\par
+\P\D \37$\\{term\_and\_log}=3$\C{normal \\{selector} setting}\par
+\P\D \37$\\{pseudo}=4$\C{special \\{selector} setting for \\{show\_context}}\par
+\P\D \37$\\{new\_string}=5$\C{printing is deflected to the string pool}\par
+\P\D \37$\\{max\_selector}=5$\C{highest selector setting}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{log\_file}: \37\\{alpha\_file};\C{transcript of \MF\ session}\6
+\4\\{selector}: \37$0\to\\{max\_selector}$;\C{where to print a message}\6
+\4\\{dig}: \37\&{array} $[0\to22]$ \1\&{of}\5
+$0\to15$;\C{digits in a number being output}\2\6
+\4\\{tally}: \37\\{integer};\C{the number of characters recently printed}\6
+\4\\{term\_offset}: \37$0\to\\{max\_print\_line}$;\C{the number of characters
+on the current terminal line}\6
+\4\\{file\_offset}: \37$0\to\\{max\_print\_line}$;\C{the number of characters
+on the current file line}\6
+\4\\{trick\_buf}: \37\&{array} $[0\to\\{error\_line}]$ \1\&{of}\5
+\\{ASCII\_code};\C{circular buffer for pseudoprinting}\2\6
+\4\\{trick\_count}: \37\\{integer};\C{threshold for pseudoprinting, explained
+later}\6
+\4\\{first\_count}: \37\\{integer};\C{another variable for pseudoprinting}\par
+\fi
+
+\M55. \P$\X55:Initialize the output routines\X\S$\6
+$\\{selector}\K\\{term\_only}$;\5
+$\\{tally}\K0$;\5
+$\\{term\_offset}\K0$;\5
+$\\{file\_offset}\K0$;\par
+\As61, 783\ETs792.
+\U1204.\fi
+
+\M56. Macro abbreviations for output to the terminal and to the log file are
+defined here for convenience. Some systems need special conventions
+for terminal output, and it is possible to adhere to those conventions
+by changing \\{wterm}, \\{wterm\_ln}, and \\{wterm\_cr} here.
+
+\Y\P\D \37$\\{wterm}(\#)\S\\{write}(\\{term\_out},\39\#)$\par
+\P\D \37$\\{wterm\_ln}(\#)\S\\{write\_ln}(\\{term\_out},\39\#)$\par
+\P\D \37$\\{wterm\_cr}\S\\{write\_ln}(\\{term\_out})$\par
+\P\D \37$\\{wlog}(\#)\S\\{write}(\\{log\_file},\39\#)$\par
+\P\D \37$\\{wlog\_ln}(\#)\S\\{write\_ln}(\\{log\_file},\39\#)$\par
+\P\D \37$\\{wlog\_cr}\S\\{write\_ln}(\\{log\_file})$\par
+\fi
+
+\M57. To end a line of text output, we call \\{print\_ln}.
+
+\Y\P$\4\X57:Basic printing procedures\X\S$\6
+\4\&{procedure}\1\ \37\\{print\_ln};\C{prints an end-of-line}\2\6
+\&{begin} \37\&{case} $\\{selector}$ \1\&{of}\6
+\4\\{term\_and\_log}: \37\&{begin} \37\\{wterm\_cr};\5
+\\{wlog\_cr};\5
+$\\{term\_offset}\K0$;\5
+$\\{file\_offset}\K0$;\6
+\&{end};\6
+\4\\{log\_only}: \37\&{begin} \37\\{wlog\_cr};\5
+$\\{file\_offset}\K0$;\6
+\&{end};\6
+\4\\{term\_only}: \37\&{begin} \37\\{wterm\_cr};\5
+$\\{term\_offset}\K0$;\6
+\&{end};\6
+\4$\\{no\_print},\39\\{pseudo},\39\\{new\_string}$: \37\\{do\_nothing};\2\6
+\&{end};\C{there are no other cases}\6
+\&{end};\C{note that \\{tally} is not affected}\par
+\As58, 59, 60, 62, 63, 64, 103, 104, 187, 195, 197\ETs773.
+\U4.\fi
+
+\M58. The \\{print\_char} procedure sends one character to the desired
+destination,
+using the \\{xchr} array to map it into an external character compatible with
+\\{input\_ln}. All printing comes through \\{print\_ln} or \\{print\_char}.
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_char}(\|s:\\{ASCII\_code})$;\C{prints a
+single character}\2\6
+\&{begin} \37\&{case} $\\{selector}$ \1\&{of}\6
+\4\\{term\_and\_log}: \37\&{begin} \37$\\{wterm}(\\{xchr}[\|s])$;\5
+$\\{wlog}(\\{xchr}[\|s])$;\5
+$\\{incr}(\\{term\_offset})$;\5
+$\\{incr}(\\{file\_offset})$;\6
+\&{if} $\\{term\_offset}=\\{max\_print\_line}$ \1\&{then}\6
+\&{begin} \37\\{wterm\_cr};\5
+$\\{term\_offset}\K0$;\6
+\&{end};\2\6
+\&{if} $\\{file\_offset}=\\{max\_print\_line}$ \1\&{then}\6
+\&{begin} \37\\{wlog\_cr};\5
+$\\{file\_offset}\K0$;\6
+\&{end};\2\6
+\&{end};\6
+\4\\{log\_only}: \37\&{begin} \37$\\{wlog}(\\{xchr}[\|s])$;\5
+$\\{incr}(\\{file\_offset})$;\6
+\&{if} $\\{file\_offset}=\\{max\_print\_line}$ \1\&{then}\5
+\\{print\_ln};\2\6
+\&{end};\6
+\4\\{term\_only}: \37\&{begin} \37$\\{wterm}(\\{xchr}[\|s])$;\5
+$\\{incr}(\\{term\_offset})$;\6
+\&{if} $\\{term\_offset}=\\{max\_print\_line}$ \1\&{then}\5
+\\{print\_ln};\2\6
+\&{end};\6
+\4\\{no\_print}: \37\\{do\_nothing};\6
+\4\\{pseudo}: \37\&{if} $\\{tally}<\\{trick\_count}$ \1\&{then}\5
+$\\{trick\_buf}[\\{tally}\mathbin{\&{mod}}\\{error\_line}]\K\|s$;\2\6
+\4\\{new\_string}: \37\&{begin} \37\&{if} $\\{pool\_ptr}<\\{pool\_size}$ \1%
+\&{then}\5
+$\\{append\_char}(\|s)$;\2\6
+\&{end};\C{we drop characters if the string space is full}\2\6
+\&{end};\C{there are no other cases}\6
+$\\{incr}(\\{tally})$;\6
+\&{end};\par
+\fi
+
+\M59. An entire string is output by calling \\{print}. Note that if we are
+outputting
+the single standard ASCII character \.c, we could call $\\{print}(\.{"c"})$,
+since
+$\.{"c"}=99$ is the number of a single-character string, as explained above.
+But
+$\\{print\_char}(\.{"c"})$ is quicker, so \MF\ goes directly to the \\{print%
+\_char}
+routine when it knows that this is safe. (The present implementation
+assumes that it is always safe to print a visible ASCII character.)
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print}(\|s:\\{integer})$;\C{prints string \|s}\6
+\4\&{var} \37\|j: \37\\{pool\_pointer};\C{current character code position}\2\6
+\&{begin} \37\&{if} $(\|s<0)\V(\|s\G\\{str\_ptr})$ \1\&{then}\5
+$\|s\K\.{"???"}$;\C{this can't happen}\2\6
+\&{if} $(\|s<256)\W(\\{selector}>\\{pseudo})$ \1\&{then}\5
+$\\{print\_char}(\|s)$\6
+\4\&{else} \&{begin} \37$\|j\K\\{str\_start}[\|s]$;\6
+\&{while} $\|j<\\{str\_start}[\|s+1]$ \1\&{do}\6
+\&{begin} \37$\\{print\_char}(\\{so}(\\{str\_pool}[\|j]))$;\5
+$\\{incr}(\|j)$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M60. Sometimes it's necessary to print a string whose characters
+may not be visible ASCII codes. In that case \\{slow\_print} is used.
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{slow\_print}(\|s:\\{integer})$;\C{prints string \|s}%
+\6
+\4\&{var} \37\|j: \37\\{pool\_pointer};\C{current character code position}\2\6
+\&{begin} \37\&{if} $(\|s<0)\V(\|s\G\\{str\_ptr})$ \1\&{then}\5
+$\|s\K\.{"???"}$;\C{this can't happen}\2\6
+\&{if} $(\|s<256)\W(\\{selector}>\\{pseudo})$ \1\&{then}\5
+$\\{print\_char}(\|s)$\6
+\4\&{else} \&{begin} \37$\|j\K\\{str\_start}[\|s]$;\6
+\&{while} $\|j<\\{str\_start}[\|s+1]$ \1\&{do}\6
+\&{begin} \37$\\{print}(\\{so}(\\{str\_pool}[\|j]))$;\5
+$\\{incr}(\|j)$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M61. Here is the very first thing that \MF\ prints: a headline that identifies
+the version number and base name. The \\{term\_offset} variable is temporarily
+incorrect, but the discrepancy is not serious since we assume that the banner
+and base identifier together will occupy at most \\{max\_print\_line}
+character positions.
+
+\Y\P$\4\X55:Initialize the output routines\X\mathrel{+}\S$\6
+$\\{wterm}(\\{banner})$;\6
+\&{if} $\\{base\_ident}=0$ \1\&{then}\5
+$\\{wterm\_ln}(\.{\'\ (no\ base\ preloaded)\'})$\6
+\4\&{else} \&{begin} \37$\\{slow\_print}(\\{base\_ident})$;\5
+\\{print\_ln};\6
+\&{end};\2\6
+\\{update\_terminal};\par
+\fi
+
+\M62. The procedure \\{print\_nl} is like \\{print}, but it makes sure that the
+string appears at the beginning of a new line.
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_nl}(\|s:\\{str\_number})$;\C{prints string %
+\|s at beginning of line}\2\6
+\&{begin} \37\&{if} $((\\{term\_offset}>0)\W(\\{odd}(\\{selector})))\V\30((%
+\\{file\_offset}>0)\W(\\{selector}\G\\{log\_only}))$ \1\&{then}\5
+\\{print\_ln};\2\6
+$\\{print}(\|s)$;\6
+\&{end};\par
+\fi
+
+\M63. An array of digits in the range $0\to9$ is printed by \\{print\_the%
+\_digs}.
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_the\_digs}(\|k:\\{eight\_bits})$;\C{prints $%
+\\{dig}[\|k-1]$$\,\ldots\,$$\\{dig}[0]$}\2\6
+\&{begin} \37\&{while} $\|k>0$ \1\&{do}\6
+\&{begin} \37$\\{decr}(\|k)$;\5
+$\\{print\_char}(\.{"0"}+\\{dig}[\|k])$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M64. The following procedure, which prints out the decimal representation of a
+given integer \|n, has been written carefully so that it works properly
+if $\|n=0$ or if $(-\|n)$ would cause overflow. It does not apply $\mathbin{%
+\&{mod}}$ or $\mathbin{\&{div}}$
+to negative arguments, since such operations are not implemented consistently
+by all \PASCAL\ compilers.
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_int}(\|n:\\{integer})$;\C{prints an integer
+in decimal form}\6
+\4\&{var} \37\|k: \37$0\to23$;\C{index to current digit; we assume that $%
+\|n<10^{23}$}\6
+\|m: \37\\{integer};\C{used to negate \|n in possibly dangerous cases}\2\6
+\&{begin} \37$\|k\K0$;\6
+\&{if} $\|n<0$ \1\&{then}\6
+\&{begin} \37$\\{print\_char}(\.{"-"})$;\6
+\&{if} $\|n>-100000000$ \1\&{then}\5
+$\\{negate}(\|n)$\6
+\4\&{else} \&{begin} \37$\|m\K-1-\|n$;\5
+$\|n\K\|m\mathbin{\&{div}}10$;\5
+$\|m\K(\|m\mathbin{\&{mod}}10)+1$;\5
+$\|k\K1$;\6
+\&{if} $\|m<10$ \1\&{then}\5
+$\\{dig}[0]\K\|m$\6
+\4\&{else} \&{begin} \37$\\{dig}[0]\K0$;\5
+$\\{incr}(\|n)$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\2\6
+\1\&{repeat} \37$\\{dig}[\|k]\K\|n\mathbin{\&{mod}}10$;\5
+$\|n\K\|n\mathbin{\&{div}}10$;\5
+$\\{incr}(\|k)$;\6
+\4\&{until}\5
+$\|n=0$;\2\6
+$\\{print\_the\_digs}(\|k)$;\6
+\&{end};\par
+\fi
+
+\M65. \MF\ also makes use of a trivial procedure to print two digits. The
+following subroutine is usually called with a parameter in the range $0\L\|n%
+\L99$.
+
+\Y\P\4\&{procedure}\1\ \37$\\{print\_dd}(\|n:\\{integer})$;\C{prints two least
+significant digits}\2\6
+\&{begin} \37$\|n\K\\{abs}(\|n)\mathbin{\&{mod}}100$;\5
+$\\{print\_char}(\.{"0"}+(\|n\mathbin{\&{div}}10))$;\5
+$\\{print\_char}(\.{"0"}+(\|n\mathbin{\&{mod}}10))$;\6
+\&{end};\par
+\fi
+
+\M66. Here is a procedure that asks the user to type a line of input,
+assuming that the \\{selector} setting is either \\{term\_only} or \\{term\_and%
+\_log}.
+The input is placed into locations \\{first} through $\\{last}-1$ of the
+\\{buffer} array, and echoed on the transcript file if appropriate.
+
+This procedure is never called when $\\{interaction}<\\{scroll\_mode}$.
+
+\Y\P\D \37$\\{prompt\_input}(\#)\S$\1\6
+\&{begin} \37\\{wake\_up\_terminal};\5
+$\\{print}(\#)$;\5
+\\{term\_input};\6
+\&{end}\C{prints a string and gets a line of input}\2\par
+\Y\P\4\&{procedure}\1\ \37\\{term\_input};\C{gets a line from the terminal}\6
+\4\&{var} \37\|k: \37$0\to\\{buf\_size}$;\C{index into \\{buffer}}\2\6
+\&{begin} \37\\{update\_terminal};\C{now the user sees the prompt for sure}\6
+\&{if} $\R\\{input\_ln}(\\{term\_in},\39\\{true})$ \1\&{then}\5
+$\\{fatal\_error}(\.{"End\ of\ file\ on\ the\ terminal!"})$;\2\6
+$\\{term\_offset}\K0$;\C{the user's line ended with \<\rm return>}\6
+$\\{decr}(\\{selector})$;\C{prepare to echo the input}\6
+\&{if} $\\{last}\I\\{first}$ \1\&{then}\6
+\&{for} $\|k\K\\{first}\mathrel{\&{to}}\\{last}-1$ \1\&{do}\5
+$\\{print}(\\{buffer}[\|k])$;\2\2\6
+\\{print\_ln};\5
+$\\{buffer}[\\{last}]\K\.{"\%"}$;\5
+$\\{incr}(\\{selector})$;\C{restore previous status}\6
+\&{end};\par
+\fi
+
+\N67. \[6] Reporting errors.
+When something anomalous is detected, \MF\ typically does something like this:
+$$\vbox{\halign{#\hfil\cr
+$\\{print\_err}(\.{"Something\ anomalous\ has\ been\ detected"})$;\cr
+$\\{help3}(\.{"This\ is\ the\ first\ line\ of\ my\ offer\ to\ help."})$\cr
+$(\.{"This\ is\ the\ second\ line.\ I\'m\ trying\ to"})$\cr
+$(\.{"explain\ the\ best\ way\ for\ you\ to\ proceed."})$;\cr
+\\{error};\cr}}$$
+A two-line help message would be given using \\{help2}, etc.; these informal
+helps should use simple vocabulary that complements the words used in the
+official error message that was printed. (Outside the U.S.A., the help
+messages should preferably be translated into the local vernacular. Each
+line of help is at most 60 characters long, in the present implementation,
+so that \\{max\_print\_line} will not be exceeded.)
+
+The \\{print\_err} procedure supplies a `\.!' before the official message,
+and makes sure that the terminal is awake if a stop is going to occur.
+The \\{error} procedure supplies a `\..' after the official message, then it
+shows the location of the error; and if $\\{interaction}=\\{error\_stop%
+\_mode}$,
+it also enters into a dialog with the user, during which time the help
+message may be printed.
+
+\fi
+
+\M68. The global variable \\{interaction} has four settings, representing
+increasing
+amounts of user interaction:
+
+\Y\P\D \37$\\{batch\_mode}=0$\C{omits all stops and omits terminal output}\par
+\P\D \37$\\{nonstop\_mode}=1$\C{omits all stops}\par
+\P\D \37$\\{scroll\_mode}=2$\C{omits error stops}\par
+\P\D \37$\\{error\_stop\_mode}=3$\C{stops at every opportunity to interact}\par
+\P\D \37$\\{print\_err}(\#)\S$\1\6
+\&{begin} \37\&{if} $\\{interaction}=\\{error\_stop\_mode}$ \1\&{then}\5
+\\{wake\_up\_terminal};\2\6
+$\\{print\_nl}(\.{"!\ "})$;\5
+$\\{print}(\#)$;\6
+\&{end}\2\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{interaction}: \37$\\{batch\_mode}\to\\{error\_stop\_mode}$;\C{current
+level of interaction}\par
+\fi
+
+\M69. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{interaction}\K\\{error\_stop\_mode}$;\par
+\fi
+
+\M70. \MF\ is careful not to call \\{error} when the print \\{selector} setting
+might be unusual. The only possible values of \\{selector} at the time of
+error messages are
+
+\yskip\hang\\{no\_print} (when $\\{interaction}=\\{batch\_mode}$
+and \\{log\_file} not yet open);
+
+\hang\\{term\_only} (when $\\{interaction}>\\{batch\_mode}$ and \\{log\_file}
+not yet open);
+
+\hang\\{log\_only} (when $\\{interaction}=\\{batch\_mode}$ and \\{log\_file} is
+open);
+
+\hang\\{term\_and\_log} (when $\\{interaction}>\\{batch\_mode}$ and \\{log%
+\_file} is open).
+
+\Y\P$\4\X70:Initialize the print \\{selector} based on \\{interaction}\X\S$\6
+\&{if} $\\{interaction}=\\{batch\_mode}$ \1\&{then}\5
+$\\{selector}\K\\{no\_print}$\ \&{else} $\\{selector}\K\\{term\_only}$\2\par
+\Us1023\ET1211.\fi
+
+\M71. A global variable \\{deletions\_allowed} is set \\{false} if the \\{get%
+\_next}
+routine is active when \\{error} is called; this ensures that \\{get\_next}
+will never be called recursively.
+
+The global variable \\{history} records the worst level of error that
+has been detected. It has four possible values: \\{spotless}, \\{warning%
+\_issued},
+\\{error\_message\_issued}, and \\{fatal\_error\_stop}.
+
+Another global variable, \\{error\_count}, is increased by one when an
+\\{error} occurs without an interactive dialog, and it is reset to zero at
+the end of every statement. If \\{error\_count} reaches 100, \MF\ decides
+that there is no point in continuing further.
+
+\Y\P\D \37$\\{spotless}=0$\C{\\{history} value when nothing has been amiss yet}%
+\par
+\P\D \37$\\{warning\_issued}=1$\C{\\{history} value when \\{begin\_diagnostic}
+has been called}\par
+\P\D \37$\\{error\_message\_issued}=2$\C{\\{history} value when \\{error} has
+been called}\par
+\P\D \37$\\{fatal\_error\_stop}=3$\C{\\{history} value when termination was
+premature}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{deletions\_allowed}: \37\\{boolean};\C{is it safe for \\{error} to call %
+\\{get\_next}?}\6
+\4\\{history}: \37$\\{spotless}\to\\{fatal\_error\_stop}$;\C{has the source
+input been clean so far?}\6
+\4\\{error\_count}: \37$-1\to100$;\C{the number of scrolled errors since the
+last statement ended}\par
+\fi
+
+\M72. The value of \\{history} is initially \\{fatal\_error\_stop}, but it will
+be changed to \\{spotless} if \MF\ survives the initialization process.
+
+\Y\P$\4\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{deletions\_allowed}\K\\{true}$;\5
+$\\{error\_count}\K0$;\C{\\{history} is initialized elsewhere}\par
+\fi
+
+\M73. Since errors can be detected almost anywhere in \MF, we want to declare
+the
+error procedures near the beginning of the program. But the error procedures
+in turn use some other procedures, which need to be declared \\{forward}
+before we get to \\{error} itself.
+
+It is possible for \\{error} to be called recursively if some error arises
+when \\{get\_next} is being used to delete a token, and/or if some fatal error
+occurs while \MF\ is trying to fix a non-fatal one. But such recursion
+is never more than two levels deep.
+
+\Y\P$\4\X73:Error handling procedures\X\S$\6
+\4\&{procedure}\1\ \37\\{normalize\_selector};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{get\_next};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{term\_input};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{show\_context};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{begin\_file\_reading};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{open\_log\_file};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{close\_files\_and\_terminate};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{clear\_for\_error\_prompt};\5
+\\{forward};\5
+\hbox{\2}\6
+\hbox{\4\hskip-\fontdimen2\font}\ \&{debug} \37\ \&{procedure}\1\ \37\\{debug%
+\_help};\5
+\\{forward};\ \&{gubed} \6
+\hbox{\4}\X43:Declare the procedure called \\{flush\_string}\X\par
+\As76, 77, 88, 89\ETs90.
+\U4.\fi
+
+\M74. Individual lines of help are recorded in the array \\{help\_line}, which
+contains entries in positions $0\to(\\{help\_ptr}-1)$. They should be printed
+in reverse order, i.e., with $\\{help\_line}[0]$ appearing last.
+
+\Y\P\D \37$\\{hlp1}(\#)\S\\{help\_line}[0]\K\#$;\ \&{end} \par
+\P\D \37$\\{hlp2}(\#)\S\\{help\_line}[1]\K\#$;\5
+\\{hlp1}\par
+\P\D \37$\\{hlp3}(\#)\S\\{help\_line}[2]\K\#$;\5
+\\{hlp2}\par
+\P\D \37$\\{hlp4}(\#)\S\\{help\_line}[3]\K\#$;\5
+\\{hlp3}\par
+\P\D \37$\\{hlp5}(\#)\S\\{help\_line}[4]\K\#$;\5
+\\{hlp4}\par
+\P\D \37$\\{hlp6}(\#)\S\\{help\_line}[5]\K\#$;\5
+\\{hlp5}\par
+\P\D \37$\\{help0}\S\\{help\_ptr}\K0$\C{sometimes there might be no help}\par
+\P\D \37$\\{help1}\S$\ \&{begin} \37$\\{help\_ptr}\K1$;\5
+\\{hlp1}\C{use this with one help line}\par
+\P\D \37$\\{help2}\S$\ \&{begin} \37$\\{help\_ptr}\K2$;\5
+\\{hlp2}\C{use this with two help lines}\par
+\P\D \37$\\{help3}\S$\ \&{begin} \37$\\{help\_ptr}\K3$;\5
+\\{hlp3}\C{use this with three help lines}\par
+\P\D \37$\\{help4}\S$\ \&{begin} \37$\\{help\_ptr}\K4$;\5
+\\{hlp4}\C{use this with four help lines}\par
+\P\D \37$\\{help5}\S$\ \&{begin} \37$\\{help\_ptr}\K5$;\5
+\\{hlp5}\C{use this with five help lines}\par
+\P\D \37$\\{help6}\S$\ \&{begin} \37$\\{help\_ptr}\K6$;\5
+\\{hlp6}\C{use this with six help lines}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{help\_line}: \37\&{array} $[0\to5]$ \1\&{of}\5
+\\{str\_number};\C{helps for the next \\{error}}\2\6
+\4\\{help\_ptr}: \37$0\to6$;\C{the number of help lines present}\6
+\4\\{use\_err\_help}: \37\\{boolean};\C{should the \\{err\_help} string be
+shown?}\6
+\4\\{err\_help}: \37\\{str\_number};\C{a string set up by \&{errhelp}}\par
+\fi
+
+\M75. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{help\_ptr}\K0$;\5
+$\\{use\_err\_help}\K\\{false}$;\5
+$\\{err\_help}\K0$;\par
+\fi
+
+\M76. The \\{jump\_out} procedure just cuts across all active procedure levels
+and
+goes to \\{end\_of\_MF}. This is the only nontrivial \&{goto} statement in the
+whole program. It is used when there is no recovery from a particular error.
+
+Some \PASCAL\ compilers do not implement non-local \&{goto} statements.
+In such cases the body of \\{jump\_out} should simply be
+`\\{close\_files\_and\_terminate};\thinspace' followed by a call on some system
+procedure that quietly terminates the program.
+
+\Y\P$\4\X73:Error handling procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{jump\_out};\2\6
+\&{begin} \37\&{goto} \37\\{end\_of\_MF};\6
+\&{end};\par
+\fi
+
+\M77. Here now is the general \\{error} routine.
+
+\Y\P$\4\X73:Error handling procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{error};\C{completes the job of error reporting}\6
+\4\&{label} \37$\\{continue},\39\\{exit}$;\6
+\4\&{var} \37\|c: \37\\{ASCII\_code};\C{what the user types}\6
+$\\{s1},\39\\{s2},\39\\{s3}$: \37\\{integer};\C{used to save global variables
+when deleting tokens}\6
+\|j: \37\\{pool\_pointer};\C{character position being printed}\2\6
+\&{begin} \37\&{if} $\\{history}<\\{error\_message\_issued}$ \1\&{then}\5
+$\\{history}\K\\{error\_message\_issued}$;\2\6
+$\\{print\_char}(\.{"."})$;\5
+\\{show\_context};\6
+\&{if} $\\{interaction}=\\{error\_stop\_mode}$ \1\&{then}\5
+\X78:Get user's advice and \&{return}\X;\2\6
+$\\{incr}(\\{error\_count})$;\6
+\&{if} $\\{error\_count}=100$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"(That\ makes\ 100\ errors;\ please\ try\
+again.)"})$;\5
+$\\{history}\K\\{fatal\_error\_stop}$;\5
+\\{jump\_out};\6
+\&{end};\2\6
+\X86:Put help message on the transcript file\X;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M78. \P$\X78:Get user's advice and \&{return}\X\S$\6
+\~ \1\&{loop}\ \&{begin} \37\\{continue}: \37\\{clear\_for\_error\_prompt};\5
+$\\{prompt\_input}(\.{"?\ "})$;\6
+\&{if} $\\{last}=\\{first}$ \1\&{then}\5
+\&{return};\2\6
+$\|c\K\\{buffer}[\\{first}]$;\6
+\&{if} $\|c\G\.{"a"}$ \1\&{then}\5
+$\|c\K\|c+\.{"A"}-\.{"a"}$;\C{convert to uppercase}\2\6
+\X79:Interpret code \|c and \&{return} if done\X;\6
+\&{end}\2\par
+\U77.\fi
+
+\M79. It is desirable to provide an `\.E' option here that gives the user
+an easy way to return from \MF\ to the system editor, with the offending
+line ready to be edited. But such an extension requires some system
+wizardry, so the present implementation simply types out the name of the
+file that should be
+edited and the relevant line number.
+
+There is a secret `\.D' option available when the debugging routines haven't
+been commented~out.
+
+\Y\P$\4\X79:Interpret code \|c and \&{return} if done\X\S$\6
+\&{case} $\|c$ \1\&{of}\6
+\4$\.{"0"},\39\.{"1"},\39\.{"2"},\39\.{"3"},\39\.{"4"},\39\.{"5"},\39\.{"6"},%
+\39\.{"7"},\39\.{"8"},\39\.{"9"}$: \37\&{if} $\\{deletions\_allowed}$ \1%
+\&{then}\5
+\X83:Delete $\|c-\.{"0"}$ tokens and \&{goto} \\{continue}\X;\2\6
+\hbox{\4\4}\ \&{debug} \37\.{"D"}: \37\&{begin} \37\\{debug\_help};\5
+\&{goto} \37\\{continue};\ \&{end};\ \&{gubed}\6
+\4\.{"E"}: \37\&{if} $\\{file\_ptr}>0$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"You\ want\ to\ edit\ file\ "})$;\5
+$\\{slow\_print}(\\{input\_stack}[\\{file\_ptr}].\\{name\_field})$;\5
+$\\{print}(\.{"\ at\ line\ "})$;\5
+$\\{print\_int}(\\{line})$;\6
+$\\{interaction}\K\\{scroll\_mode}$;\5
+\\{jump\_out};\6
+\&{end};\2\6
+\4\.{"H"}: \37\X84:Print the help information and \&{goto} \\{continue}\X;\6
+\4\.{"I"}: \37\X82:Introduce new material from the terminal and \&{return}\X;\6
+\4$\.{"Q"},\39\.{"R"},\39\.{"S"}$: \37\X81:Change the interaction level and %
+\&{return}\X;\6
+\4\.{"X"}: \37\&{begin} \37$\\{interaction}\K\\{scroll\_mode}$;\5
+\\{jump\_out};\6
+\&{end};\6
+\4\&{othercases} \37\\{do\_nothing}\2\6
+\&{endcases};\6
+\X80:Print the menu of available options\X\par
+\U78.\fi
+
+\M80. \P$\X80:Print the menu of available options\X\S$\6
+\&{begin} \37$\\{print}(\.{"Type\ <return>\ to\ proceed,\ S\ to\ scroll\ future%
+\ error\ messages,"})$;\6
+$\\{print\_nl}(\.{"R\ to\ run\ without\ stopping,\ Q\ to\ run\ quietly,"})$;\6
+$\\{print\_nl}(\.{"I\ to\ insert\ something,\ "})$;\6
+\&{if} $\\{file\_ptr}>0$ \1\&{then}\5
+$\\{print}(\.{"E\ to\ edit\ your\ file,"})$;\2\6
+\&{if} $\\{deletions\_allowed}$ \1\&{then}\5
+$\\{print\_nl}(\.{"1\ or\ ...\ or\ 9\ to\ ignore\ the\ next\ 1\ to\ 9\ tokens\
+of\ input,"})$;\2\6
+$\\{print\_nl}(\.{"H\ for\ help,\ X\ to\ quit."})$;\6
+\&{end}\par
+\U79.\fi
+
+\M81. Here the author of \MF\ apologizes for making use of the numerical
+relation between \.{"Q"}, \.{"R"}, \.{"S"}, and the desired interaction
+settings
+\\{batch\_mode}, \\{nonstop\_mode}, \\{scroll\_mode}.
+
+\Y\P$\4\X81:Change the interaction level and \&{return}\X\S$\6
+\&{begin} \37$\\{error\_count}\K0$;\5
+$\\{interaction}\K\\{batch\_mode}+\|c-\.{"Q"}$;\5
+$\\{print}(\.{"OK,\ entering\ "})$;\6
+\&{case} $\|c$ \1\&{of}\6
+\4\.{"Q"}: \37\&{begin} \37$\\{print}(\.{"batchmode"})$;\5
+$\\{decr}(\\{selector})$;\6
+\&{end};\6
+\4\.{"R"}: \37$\\{print}(\.{"nonstopmode"})$;\6
+\4\.{"S"}: \37$\\{print}(\.{"scrollmode"})$;\2\6
+\&{end};\C{there are no other cases}\6
+$\\{print}(\.{"..."})$;\5
+\\{print\_ln};\5
+\\{update\_terminal};\5
+\&{return};\6
+\&{end}\par
+\U79.\fi
+
+\M82. When the following code is executed, $\\{buffer}[(\\{first}+1)\to(%
+\\{last}-1)]$ may
+contain the material inserted by the user; otherwise another prompt will
+be given. In order to understand this part of the program fully, you need
+to be familiar with \MF's input stacks.
+
+\Y\P$\4\X82:Introduce new material from the terminal and \&{return}\X\S$\6
+\&{begin} \37\\{begin\_file\_reading};\C{enter a new syntactic level for
+terminal input}\6
+\&{if} $\\{last}>\\{first}+1$ \1\&{then}\6
+\&{begin} \37$\\{loc}\K\\{first}+1$;\5
+$\\{buffer}[\\{first}]\K\.{"\ "}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{prompt\_input}(\.{"insert>"})$;\5
+$\\{loc}\K\\{first}$;\6
+\&{end};\2\6
+$\\{first}\K\\{last}+1$;\5
+$\\{cur\_input}.\\{limit\_field}\K\\{last}$;\5
+\&{return};\6
+\&{end}\par
+\U79.\fi
+
+\M83. We allow deletion of up to 99 tokens at a time.
+
+\Y\P$\4\X83:Delete $\|c-\.{"0"}$ tokens and \&{goto} \\{continue}\X\S$\6
+\&{begin} \37$\\{s1}\K\\{cur\_cmd}$;\5
+$\\{s2}\K\\{cur\_mod}$;\5
+$\\{s3}\K\\{cur\_sym}$;\5
+$\\{OK\_to\_interrupt}\K\\{false}$;\6
+\&{if} $(\\{last}>\\{first}+1)\W(\\{buffer}[\\{first}+1]\G\.{"0"})\W(%
+\\{buffer}[\\{first}+1]\L\.{"9"})$ \1\&{then}\5
+$\|c\K\|c\ast10+\\{buffer}[\\{first}+1]-\.{"0"}\ast11$\6
+\4\&{else} $\|c\K\|c-\.{"0"}$;\2\6
+\&{while} $\|c>0$ \1\&{do}\6
+\&{begin} \37\\{get\_next};\C{one-level recursive call of \\{error} is
+possible}\6
+\X743:Decrease the string reference count, if the current token is a string\X;\6
+$\\{decr}(\|c)$;\6
+\&{end};\2\6
+$\\{cur\_cmd}\K\\{s1}$;\5
+$\\{cur\_mod}\K\\{s2}$;\5
+$\\{cur\_sym}\K\\{s3}$;\5
+$\\{OK\_to\_interrupt}\K\\{true}$;\5
+$\\{help2}(\.{"I\ have\ just\ deleted\ some\ text,\ as\ you\ asked."})$\6
+$(\.{"You\ can\ now\ delete\ more,\ or\ insert,\ or\ whatever."})$;\5
+\\{show\_context};\5
+\&{goto} \37\\{continue};\6
+\&{end}\par
+\U79.\fi
+
+\M84. \P$\X84:Print the help information and \&{goto} \\{continue}\X\S$\6
+\&{begin} \37\&{if} $\\{use\_err\_help}$ \1\&{then}\6
+\&{begin} \37\X85:Print the string \\{err\_help}, possibly on several lines\X;\6
+$\\{use\_err\_help}\K\\{false}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{help\_ptr}=0$ \1\&{then}\5
+$\\{help2}(\.{"Sorry,\ I\ don\'t\ know\ how\ to\ help\ in\ this\ situation."})$%
+\2\6
+$\hbox{\kern1em}(\.{"Maybe\ you\ should\ try\ asking\ a\ human?"})$;\6
+\1\&{repeat} \37$\\{decr}(\\{help\_ptr})$;\5
+$\\{print}(\\{help\_line}[\\{help\_ptr}])$;\5
+\\{print\_ln};\6
+\4\&{until}\5
+$\\{help\_ptr}=0$;\2\6
+\&{end};\2\6
+$\\{help4}(\.{"Sorry,\ I\ already\ gave\ what\ help\ I\ could..."})$\6
+$(\.{"Maybe\ you\ should\ try\ asking\ a\ human?"})$\6
+$(\.{"An\ error\ might\ have\ occurred\ before\ I\ noticed\ any\ problems."})$\6
+$(\.{"\`\`If\ all\ else\ fails,\ read\ the\ instructions.\'\'"})$;\6
+\&{goto} \37\\{continue};\6
+\&{end}\par
+\U79.\fi
+
+\M85. \P$\X85:Print the string \\{err\_help}, possibly on several lines\X\S$\6
+$\|j\K\\{str\_start}[\\{err\_help}]$;\6
+\&{while} $\|j<\\{str\_start}[\\{err\_help}+1]$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{str\_pool}[\|j]\I\\{si}(\.{"\%"})$ \1\&{then}\5
+$\\{print}(\\{so}(\\{str\_pool}[\|j]))$\6
+\4\&{else} \&{if} $\|j+1=\\{str\_start}[\\{err\_help}+1]$ \1\&{then}\5
+\\{print\_ln}\6
+\4\&{else} \&{if} $\\{str\_pool}[\|j+1]\I\\{si}(\.{"\%"})$ \1\&{then}\5
+\\{print\_ln}\6
+\4\&{else} \&{begin} \37$\\{incr}(\|j)$;\5
+$\\{print\_char}(\.{"\%"})$;\6
+\&{end};\2\2\2\6
+$\\{incr}(\|j)$;\6
+\&{end}\2\par
+\Us84\ET86.\fi
+
+\M86. \P$\X86:Put help message on the transcript file\X\S$\6
+\&{if} $\\{interaction}>\\{batch\_mode}$ \1\&{then}\5
+$\\{decr}(\\{selector})$;\C{avoid terminal output}\2\6
+\&{if} $\\{use\_err\_help}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{""})$;\5
+\X85:Print the string \\{err\_help}, possibly on several lines\X;\6
+\&{end}\6
+\4\&{else} \&{while} $\\{help\_ptr}>0$ \1\&{do}\6
+\&{begin} \37$\\{decr}(\\{help\_ptr})$;\5
+$\\{print\_nl}(\\{help\_line}[\\{help\_ptr}])$;\6
+\&{end};\2\2\6
+\\{print\_ln};\6
+\&{if} $\\{interaction}>\\{batch\_mode}$ \1\&{then}\5
+$\\{incr}(\\{selector})$;\C{re-enable terminal output}\2\6
+\\{print\_ln}\par
+\U77.\fi
+
+\M87. In anomalous cases, the print selector might be in an unknown state;
+the following subroutine is called to fix things just enough to keep
+running a bit longer.
+
+\Y\P\4\&{procedure}\1\ \37\\{normalize\_selector};\2\6
+\&{begin} \37\&{if} $\\{log\_opened}$ \1\&{then}\5
+$\\{selector}\K\\{term\_and\_log}$\6
+\4\&{else} $\\{selector}\K\\{term\_only}$;\2\6
+\&{if} $\\{job\_name}=0$ \1\&{then}\5
+\\{open\_log\_file};\2\6
+\&{if} $\\{interaction}=\\{batch\_mode}$ \1\&{then}\5
+$\\{decr}(\\{selector})$;\2\6
+\&{end};\par
+\fi
+
+\M88. The following procedure prints \MF's last words before dying.
+
+\Y\P\D \37$\\{succumb}\S$\1\6
+\&{begin} \37\&{if} $\\{interaction}=\\{error\_stop\_mode}$ \1\&{then}\5
+$\\{interaction}\K\\{scroll\_mode}$;\C{no more interaction}\2\6
+\&{if} $\\{log\_opened}$ \1\&{then}\5
+\\{error};\2\6
+\&{debug} \37\&{if} $\\{interaction}>\\{batch\_mode}$ \1\&{then}\5
+\\{debug\_help};\2\ \&{gubed}\6
+$\\{history}\K\\{fatal\_error\_stop}$;\5
+\\{jump\_out};\C{irrecoverable error}\6
+\&{end}\2\par
+\Y\P$\4\X73:Error handling procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{fatal\_error}(\|s:\\{str\_number})$;\C{prints \|s,
+and that's it}\2\6
+\&{begin} \37\\{normalize\_selector};\6
+$\\{print\_err}(\.{"Emergency\ stop"})$;\5
+$\\{help1}(\|s)$;\5
+\\{succumb};\6
+\&{end};\par
+\fi
+
+\M89. Here is the most dreaded error message.
+
+\Y\P$\4\X73:Error handling procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{overflow}(\|s:\\{str\_number};\,\35\|n:%
+\\{integer})$;\C{stop due to finiteness}\2\6
+\&{begin} \37\\{normalize\_selector};\5
+$\\{print\_err}(\.{"METAFONT\ capacity\ exceeded,\ sorry\ ["})$;\5
+$\\{print}(\|s)$;\5
+$\\{print\_char}(\.{"="})$;\5
+$\\{print\_int}(\|n)$;\5
+$\\{print\_char}(\.{"]"})$;\5
+$\\{help2}(\.{"If\ you\ really\ absolutely\ need\ more\ capacity,"})$\6
+$(\.{"you\ can\ ask\ a\ wizard\ to\ enlarge\ me."})$;\5
+\\{succumb};\6
+\&{end};\par
+\fi
+
+\M90. The program might sometime run completely amok, at which point there is
+no choice but to stop. If no previous error has been detected, that's bad
+news; a message is printed that is really intended for the \MF\
+maintenance person instead of the user (unless the user has been
+particularly diabolical). The index entries for `this can't happen' may
+help to pinpoint the problem.
+
+\Y\P$\4\X73:Error handling procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{confusion}(\|s:\\{str\_number})$;\C{consistency
+check violated; \|s tells where}\2\6
+\&{begin} \37\\{normalize\_selector};\6
+\&{if} $\\{history}<\\{error\_message\_issued}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"This\ can\'t\ happen\ ("})$;\5
+$\\{print}(\|s)$;\5
+$\\{print\_char}(\.{")"})$;\5
+$\\{help1}(\.{"I\'m\ broken.\ Please\ show\ this\ to\ someone\ who\ can\ fix\
+can\ fix"})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"I\ can\'t\ go\ on\ meeting\ you\
+like\ this"})$;\5
+$\\{help2}(\.{"One\ of\ your\ faux\ pas\ seems\ to\ have\ wounded\ me\
+deeply..."})$\6
+$(\.{"in\ fact,\ I\'m\ barely\ conscious.\ Please\ fix\ it\ and\ try\
+again."})$;\6
+\&{end};\2\6
+\\{succumb};\6
+\&{end};\par
+\fi
+
+\M91. Users occasionally want to interrupt \MF\ while it's running.
+If the \PASCAL\ runtime system allows this, one can implement
+a routine that sets the global variable \\{interrupt} to some nonzero value
+when such an interrupt is signalled. Otherwise there is probably at least
+a way to make \\{interrupt} nonzero using the \PASCAL\ debugger.
+
+\Y\P\D \37$\\{check\_interrupt}\S$\1\6
+\&{begin} \37\&{if} $\\{interrupt}\I0$ \1\&{then}\5
+\\{pause\_for\_instructions};\2\6
+\&{end}\2\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{interrupt}: \37\\{integer};\C{should \MF\ pause for instructions?}\6
+\4\\{OK\_to\_interrupt}: \37\\{boolean};\C{should interrupts be observed?}\par
+\fi
+
+\M92. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{interrupt}\K0$;\5
+$\\{OK\_to\_interrupt}\K\\{true}$;\par
+\fi
+
+\M93. When an interrupt has been detected, the program goes into its
+highest interaction level and lets the user have the full flexibility of
+the \\{error} routine. \MF\ checks for interrupts only at times when it is
+safe to do this.
+
+\Y\P\4\&{procedure}\1\ \37\\{pause\_for\_instructions};\2\6
+\&{begin} \37\&{if} $\\{OK\_to\_interrupt}$ \1\&{then}\6
+\&{begin} \37$\\{interaction}\K\\{error\_stop\_mode}$;\6
+\&{if} $(\\{selector}=\\{log\_only})\V(\\{selector}=\\{no\_print})$ \1\&{then}\5
+$\\{incr}(\\{selector})$;\2\6
+$\\{print\_err}(\.{"Interruption"})$;\5
+$\\{help3}(\.{"You\ rang?"})$\6
+$(\.{"Try\ to\ insert\ some\ instructions\ for\ me\ (e.g.,\`I\ show\ x\'),"})$\6
+$(\.{"unless\ you\ just\ want\ to\ quit\ by\ typing\ \`X\'."})$;\5
+$\\{deletions\_allowed}\K\\{false}$;\5
+\\{error};\5
+$\\{deletions\_allowed}\K\\{true}$;\5
+$\\{interrupt}\K0$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M94. Many of \MF's error messages state that a missing token has been
+inserted behind the scenes. We can save string space and program space
+by putting this common code into a subroutine.
+
+\Y\P\4\&{procedure}\1\ \37$\\{missing\_err}(\|s:\\{str\_number})$;\2\6
+\&{begin} \37$\\{print\_err}(\.{"Missing\ \`"})$;\5
+$\\{print}(\|s)$;\5
+$\\{print}(\.{"\'\ has\ been\ inserted"})$;\6
+\&{end};\par
+\fi
+
+\N95. \[7] Arithmetic with scaled numbers.
+The principal computations performed by \MF\ are done entirely in terms of
+integers less than $2^{31}$ in magnitude; thus, the arithmetic specified in
+this
+program can be carried out in exactly the same way on a wide variety of
+computers, including some small ones.
+
+But \PASCAL\ does not define the $\mathbin{\&{div}}$
+operation in the case of negative dividends; for example, the result of
+$(-2\ast\|n-1)\mathbin{\&{div}}2$ is $-(\|n+1)$ on some computers and $-\|n$ on
+others.
+There are two principal types of arithmetic: ``translation-preserving,''
+in which the identity $(\|a+\|q\ast\|b)\mathbin{\&{div}}\|b=(\|a\mathbin{%
+\&{div}}\|b)+\|q$ is valid; and
+``negation-preserving,'' in which $(-\|a)\mathbin{\&{div}}\|b=-(\|a\mathbin{%
+\&{div}}\|b)$. This leads to
+two \MF s, which can produce different results, although the differences
+should be negligible when the language is being used properly.
+The \TeX\ processor has been defined carefully so that both varieties
+of arithmetic will produce identical output, but it would be too
+inefficient to constrain \MF\ in a similar way.
+
+\Y\P\D \37$\\{el\_gordo}\S\O{17777777777}$\C{$2^{31}-1$, the largest value that
+\MF\ likes}\par
+\fi
+
+\M96. One of \MF's most common operations is the calculation of
+$\lfloor{a+b\over2}\rfloor$,
+the midpoint of two given integers \|a and~\|b. The only decent way to do
+this in \PASCAL\ is to write `$(\|a+\|b)\mathbin{\&{div}}2$'; but on most
+machines it is
+far more efficient to calculate `$(\|a+\|b)$ right shifted one bit'.
+
+Therefore the midpoint operation will always be denoted by `$\\{half}(\|a+%
+\|b)$'
+in this program. If \MF\ is being implemented with languages that permit
+binary shifting, the \\{half} macro should be changed to make this operation
+as efficient as possible.
+
+\Y\P\D \37$\\{half}(\#)\S(\#)\mathbin{\&{div}}2$\par
+\fi
+
+\M97. A single computation might use several subroutine calls, and it is
+desirable to avoid producing multiple error messages in case of arithmetic
+overflow. So the routines below set the global variable \\{arith\_error} to %
+\\{true}
+instead of reporting errors directly to the user.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{arith\_error}: \37\\{boolean};\C{has arithmetic overflow occurred
+recently?}\par
+\fi
+
+\M98. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{arith\_error}\K\\{false}$;\par
+\fi
+
+\M99. At crucial points the program will say \\{check\_arith}, to test if
+an arithmetic error has been detected.
+
+\Y\P\D \37$\\{check\_arith}\S$\1\6
+\&{begin} \37\&{if} $\\{arith\_error}$ \1\&{then}\5
+\\{clear\_arith};\ \2\6
+\&{end}\2\par
+\Y\P\4\&{procedure}\1\ \37\\{clear\_arith};\2\6
+\&{begin} \37$\\{print\_err}(\.{"Arithmetic\ overflow"})$;\5
+$\\{help4}(\.{"Uh,\ oh.\ A\ little\ while\ ago\ one\ of\ the\ quantities\ that\
+I\ was"})$\6
+$(\.{"computing\ got\ too\ large,\ so\ I\'m\ afraid\ your\ answers\ will\
+be"})$\6
+$(\.{"somewhat\ askew.\ You\'ll\ probably\ have\ to\ adopt\ different"})$\6
+$(\.{"tactics\ next\ time.\ But\ I\ shall\ try\ to\ carry\ on\ anyway."})$;\5
+\\{error};\5
+$\\{arith\_error}\K\\{false}$;\6
+\&{end};\par
+\fi
+
+\M100. Addition is not always checked to make sure that it doesn't overflow,
+but in places where overflow isn't too unlikely the \\{slow\_add} routine
+is used.
+
+\Y\P\4\&{function}\1\ \37$\\{slow\_add}(\|x,\39\|y:\\{integer})$: \37%
+\\{integer};\2\6
+\&{begin} \37\&{if} $\|x\G0$ \1\&{then}\6
+\&{if} $\|y\L\\{el\_gordo}-\|x$ \1\&{then}\5
+$\\{slow\_add}\K\|x+\|y$\6
+\4\&{else} \&{begin} \37$\\{arith\_error}\K\\{true}$;\5
+$\\{slow\_add}\K\\{el\_gordo}$;\6
+\&{end}\2\6
+\4\&{else} \&{if} $-\|y\L\\{el\_gordo}+\|x$ \1\&{then}\5
+$\\{slow\_add}\K\|x+\|y$\6
+\4\&{else} \&{begin} \37$\\{arith\_error}\K\\{true}$;\5
+$\\{slow\_add}\K-\\{el\_gordo}$;\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M101. Fixed-point arithmetic is done on {\sl scaled integers\/} that are
+multiples
+of $2^{-16}$. In other words, a binary point is assumed to be sixteen bit
+positions from the right end of a binary computer word.
+
+\Y\P\D \37$\\{quarter\_unit}\S\O{40000}$\C{$2^{14}$, represents 0.250000}\par
+\P\D \37$\\{half\_unit}\S\O{100000}$\C{$2^{15}$, represents 0.50000}\par
+\P\D \37$\\{three\_quarter\_unit}\S\O{140000}$\C{$3\cdot2^{14}$, represents
+0.75000}\par
+\P\D \37$\\{unity}\S\O{200000}$\C{$2^{16}$, represents 1.00000}\par
+\P\D \37$\\{two}\S\O{400000}$\C{$2^{17}$, represents 2.00000}\par
+\P\D \37$\\{three}\S\O{600000}$\C{$2^{17}+2^{16}$, represents 3.00000}\par
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{scaled}=\\{integer}$;\C{this type is used for scaled integers}\6
+$\\{small\_number}=0\to63$;\C{this type is self-explanatory}\par
+\fi
+
+\M102. The following function is used to create a scaled integer from a given
+decimal
+fraction $(.d_0d_1\ldots d_{k-1})$, where $0\L\|k\L17$. The digit $d_i$ is
+given in $\\{dig}[\|i]$, and the calculation produces a correctly rounded
+result.
+
+\Y\P\4\&{function}\1\ \37$\\{round\_decimals}(\|k:\\{small\_number})$: \37%
+\\{scaled};\C{converts a decimal fraction}\6
+\4\&{var} \37\|a: \37\\{integer};\C{the accumulator}\2\6
+\&{begin} \37$\|a\K0$;\6
+\&{while} $\|k>0$ \1\&{do}\6
+\&{begin} \37$\\{decr}(\|k)$;\5
+$\|a\K(\|a+\\{dig}[\|k]\ast\\{two})\mathbin{\&{div}}10$;\6
+\&{end};\2\6
+$\\{round\_decimals}\K\\{half}(\|a+1)$;\6
+\&{end};\par
+\fi
+
+\M103. Conversely, here is a procedure analogous to \\{print\_int}. If the
+output
+of this procedure is subsequently read by \MF\ and converted by the
+\\{round\_decimals} routine above, it turns out that the original value will
+be reproduced exactly. A decimal point is printed only if the value is
+not an integer. If there is more than one way to print the result with
+the optimum number of digits following the decimal point, the closest
+possible value is given.
+
+The invariant relation in the \&{repeat} loop is that a sequence of
+decimal digits yet to be printed will yield the original number if and only if
+they form a fraction~$f$ in the range $s-\delta\L10\cdot2^{16}f<s$.
+We can stop if and only if $f=0$ satisfies this condition; the loop will
+terminate before $s$ can possibly become zero.
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_scaled}(\|s:\\{scaled})$;\C{prints scaled
+real, rounded to five digits}\6
+\4\&{var} \37\\{delta}: \37\\{scaled};\C{amount of allowable inaccuracy}\2\6
+\&{begin} \37\&{if} $\|s<0$ \1\&{then}\6
+\&{begin} \37$\\{print\_char}(\.{"-"})$;\5
+$\\{negate}(\|s)$;\C{print the sign, if negative}\6
+\&{end};\2\6
+$\\{print\_int}(\|s\mathbin{\&{div}}\\{unity})$;\C{print the integer part}\6
+$\|s\K10\ast(\|s\mathbin{\&{mod}}\\{unity})+5$;\6
+\&{if} $\|s\I5$ \1\&{then}\6
+\&{begin} \37$\\{delta}\K10$;\5
+$\\{print\_char}(\.{"."})$;\6
+\1\&{repeat} \37\&{if} $\\{delta}>\\{unity}$ \1\&{then}\5
+$\|s\K\|s+\O{100000}-(\\{delta}\mathbin{\&{div}}2)$;\C{round the final digit}\2%
+\6
+$\\{print\_char}(\.{"0"}+(\|s\mathbin{\&{div}}\\{unity}))$;\5
+$\|s\K10\ast(\|s\mathbin{\&{mod}}\\{unity})$;\5
+$\\{delta}\K\\{delta}\ast10$;\6
+\4\&{until}\5
+$\|s\L\\{delta}$;\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M104. We often want to print two scaled quantities in parentheses,
+separated by a comma.
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_two}(\|x,\39\|y:\\{scaled})$;\C{prints `$(%
+\|x,\|y)$'}\2\6
+\&{begin} \37$\\{print\_char}(\.{"("})$;\5
+$\\{print\_scaled}(\|x)$;\5
+$\\{print\_char}(\.{","})$;\5
+$\\{print\_scaled}(\|y)$;\5
+$\\{print\_char}(\.{")"})$;\6
+\&{end};\par
+\fi
+
+\M105. The \\{scaled} quantities in \MF\ programs are generally supposed to be
+less than $2^{12}$ in absolute value, so \MF\ does much of its internal
+arithmetic with 28~significant bits of precision. A \\{fraction} denotes
+a scaled integer whose binary point is assumed to be 28 bit positions
+from the right.
+
+\Y\P\D \37$\\{fraction\_half}\S\O{1000000000}$\C{$2^{27}$, represents
+0.50000000}\par
+\P\D \37$\\{fraction\_one}\S\O{2000000000}$\C{$2^{28}$, represents 1.00000000}%
+\par
+\P\D \37$\\{fraction\_two}\S\O{4000000000}$\C{$2^{29}$, represents 2.00000000}%
+\par
+\P\D \37$\\{fraction\_three}\S\O{6000000000}$\C{$3\cdot2^{28}$, represents
+3.00000000}\par
+\P\D \37$\\{fraction\_four}\S\O{10000000000}$\C{$2^{30}$, represents
+4.00000000}\par
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{fraction}=\\{integer}$;\C{this type is used for scaled fractions}\par
+\fi
+
+\M106. In fact, the two sorts of scaling discussed above aren't quite
+sufficient; \MF\ has yet another, used internally to keep track of angles
+in units of $2^{-20}$ degrees.
+
+\Y\P\D \37$\\{forty\_five\_deg}\S\O{264000000}$\C{$45\cdot2^{20}$, represents
+$45^\circ$}\par
+\P\D \37$\\{ninety\_deg}\S\O{550000000}$\C{$90\cdot2^{20}$, represents $90^%
+\circ$}\par
+\P\D \37$\\{one\_eighty\_deg}\S\O{1320000000}$\C{$180\cdot2^{20}$, represents
+$180^\circ$}\par
+\P\D \37$\\{three\_sixty\_deg}\S\O{2640000000}$\C{$360\cdot2^{20}$, represents
+$360^\circ$}\par
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{angle}=\\{integer}$;\C{this type is used for scaled angles}\par
+\fi
+
+\M107. The \\{make\_fraction} routine produces the \\{fraction} equivalent of
+$\|p/\|q$, given integers \|p and~\|q; it computes the integer
+$f=\lfloor2^{28}p/q+{1\over2}\rfloor$, when $p$ and $q$ are
+positive. If \|p and \|q are both of the same scaled type \|t,
+the ``type relation'' $\\{make\_fraction}(\|t,\|t)=\\{fraction}$ is valid;
+and it's also possible to use the subroutine ``backwards,'' using
+the relation $\\{make\_fraction}(\|t,\\{fraction})=\|t$ between scaled types.
+
+If the result would have magnitude $2^{31}$ or more, \\{make\_fraction}
+sets $\\{arith\_error}\K\\{true}$. Most of \MF's internal computations have
+been designed to avoid this sort of error.
+
+Notice that if 64-bit integer arithmetic were available,
+we could simply compute $(\hbox{$(2^{29}$}\ast\|p+\|q)\mathbin{\&{div}}(2\ast%
+\|q)$.
+But when we are restricted to \PASCAL's 32-bit arithmetic we
+must either resort to multiple-precision maneuvering
+or use a simple but slow iteration. The multiple-precision technique
+would be about three times faster than the code adopted here, but it
+would be comparatively long and tricky, involving about sixteen
+additional multiplications and divisions.
+
+This operation is part of \MF's ``inner loop''; indeed, it will
+consume nearly 10\pct! of the running time (exclusive of input and output)
+if the code below is left unchanged. A machine-dependent recoding
+will therefore make \MF\ run faster. The present implementation
+is highly portable, but slow; it avoids multiplication and division
+except in the initial stage. System wizards should be careful to
+replace it with a routine that is guaranteed to produce identical
+results in all cases.
+
+As noted below, a few more routines should also be replaced by
+machine-dependent
+code, for efficiency. But when a procedure is not part of the ``inner loop,''
+such changes aren't advisable; simplicity and robustness are
+preferable to trickery, unless the cost is too high.
+
+\Y\P\4\&{function}\1\ \37$\\{make\_fraction}(\|p,\39\|q:\\{integer})$: \37%
+\\{fraction};\6
+\4\&{var} \37\|f: \37\\{integer};\C{the fraction bits, with a leading 1 bit}\6
+\|n: \37\\{integer};\C{the integer part of $\vert p/q\vert$}\6
+\\{negative}: \37\\{boolean};\C{should the result be negated?}\6
+\\{be\_careful}: \37\\{integer};\C{disables certain compiler optimizations}\2\6
+\&{begin} \37\&{if} $\|p\G0$ \1\&{then}\5
+$\\{negative}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\\{negate}(\|p)$;\5
+$\\{negative}\K\\{true}$;\6
+\&{end};\2\6
+\&{if} $\|q\L0$ \1\&{then}\6
+\&{begin} \37\&{debug} \37\&{if} $\|q=0$ \1\&{then}\5
+$\\{confusion}(\.{"/"})$;\2\ \&{gubed}\6
+$\\{negate}(\|q)$;\5
+$\\{negative}\K\R\\{negative}$;\6
+\&{end};\2\6
+$\|n\K\|p\mathbin{\&{div}}\|q$;\5
+$\|p\K\|p\mathbin{\&{mod}}\|q$;\6
+\&{if} $\|n\G8$ \1\&{then}\6
+\&{begin} \37$\\{arith\_error}\K\\{true}$;\6
+\&{if} $\\{negative}$ \1\&{then}\5
+$\\{make\_fraction}\K-\\{el\_gordo}$\ \&{else} $\\{make\_fraction}\K\\{el%
+\_gordo}$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|n\K(\|n-1)\ast\\{fraction\_one}$;\5
+\X108:Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$\X;\6
+\&{if} $\\{negative}$ \1\&{then}\5
+$\\{make\_fraction}\K-(\|f+\|n)$\ \&{else} $\\{make\_fraction}\K\|f+\|n$;\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M108. The \&{repeat} loop here preserves the following invariant relations
+between \|f, \|p, and~\|q:
+(i)~$0\L\|p<\|q$; (ii)~$fq+p=2^k(q+p_0)$, where $k$ is an integer and
+$p_0$ is the original value of~$p$.
+
+Notice that the computation specifies
+$(\|p-\|q)+\|p$ instead of $(\|p+\|p)-\|q$, because the latter could overflow.
+Let us hope that optimizing compilers do not miss this point; a
+special variable \\{be\_careful} is used to emphasize the necessary
+order of computation. Optimizing compilers should keep \\{be\_careful}
+in a register, not store it in memory.
+
+\Y\P$\4\X108:Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$\X\S$\6
+$\|f\K1$;\6
+\1\&{repeat} \37$\\{be\_careful}\K\|p-\|q$;\5
+$\|p\K\\{be\_careful}+\|p$;\6
+\&{if} $\|p\G0$ \1\&{then}\5
+$\|f\K\|f+\|f+1$\6
+\4\&{else} \&{begin} \37$\\{double}(\|f)$;\5
+$\|p\K\|p+\|q$;\6
+\&{end};\2\6
+\4\&{until}\5
+$\|f\G\\{fraction\_one}$;\2\6
+$\\{be\_careful}\K\|p-\|q$;\6
+\&{if} $\\{be\_careful}+\|p\G0$ \1\&{then}\5
+$\\{incr}(\|f)$\2\par
+\U107.\fi
+
+\M109. The dual of \\{make\_fraction} is \\{take\_fraction}, which multiplies a
+given integer~\|q by a fraction~\|f. When the operands are positive, it
+computes $p=\lfloor qf/2^{28}+{1\over2}\rfloor$, a symmetric function
+of \|q and~\|f.
+
+This routine is even more ``inner loopy'' than \\{make\_fraction};
+the present implementation consumes almost 20\pct! of \MF's computation
+time during typical jobs, so a machine-language or 64-bit
+substitute is advisable.
+
+\Y\P\4\&{function}\1\ \37$\\{take\_fraction}(\|q:\\{integer};\,\35\|f:%
+\\{fraction})$: \37\\{integer};\6
+\4\&{var} \37\|p: \37\\{integer};\C{the fraction so far}\6
+\\{negative}: \37\\{boolean};\C{should the result be negated?}\6
+\|n: \37\\{integer};\C{additional multiple of $q$}\6
+\\{be\_careful}: \37\\{integer};\C{disables certain compiler optimizations}\2\6
+\&{begin} \37\X110:Reduce to the case that $\|f\G0$ and $\|q>0$\X;\6
+\&{if} $\|f<\\{fraction\_one}$ \1\&{then}\5
+$\|n\K0$\6
+\4\&{else} \&{begin} \37$\|n\K\|f\mathbin{\&{div}}\\{fraction\_one}$;\5
+$\|f\K\|f\mathbin{\&{mod}}\\{fraction\_one}$;\6
+\&{if} $\|q\L\\{el\_gordo}\mathbin{\&{div}}\|n$ \1\&{then}\5
+$\|n\K\|n\ast\|q$\6
+\4\&{else} \&{begin} \37$\\{arith\_error}\K\\{true}$;\5
+$\|n\K\\{el\_gordo}$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\|f\K\|f+\\{fraction\_one}$;\5
+\X111:Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$\X;\6
+$\\{be\_careful}\K\|n-\\{el\_gordo}$;\6
+\&{if} $\\{be\_careful}+\|p>0$ \1\&{then}\6
+\&{begin} \37$\\{arith\_error}\K\\{true}$;\5
+$\|n\K\\{el\_gordo}-\|p$;\6
+\&{end};\2\6
+\&{if} $\\{negative}$ \1\&{then}\5
+$\\{take\_fraction}\K-(\|n+\|p)$\6
+\4\&{else} $\\{take\_fraction}\K\|n+\|p$;\2\6
+\&{end};\par
+\fi
+
+\M110. \P$\X110:Reduce to the case that $\|f\G0$ and $\|q>0$\X\S$\6
+\&{if} $\|f\G0$ \1\&{then}\5
+$\\{negative}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\\{negate}(\|f)$;\5
+$\\{negative}\K\\{true}$;\6
+\&{end};\2\6
+\&{if} $\|q<0$ \1\&{then}\6
+\&{begin} \37$\\{negate}(\|q)$;\5
+$\\{negative}\K\R\\{negative}$;\6
+\&{end};\2\par
+\Us109\ET112.\fi
+
+\M111. The invariant relations in this case are (i)~$\lfloor(qf+p)/2^k\rfloor
+=\lfloor qf_0/2^{28}+{1\over2}\rfloor$, where $k$ is an integer and
+$f_0$ is the original value of~$f$; (ii)~$2^k\L f<2^{k+1}$.
+
+\Y\P$\4\X111:Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$\X\S$\6
+$\|p\K\\{fraction\_half}$;\C{that's $2^{27}$; the invariants hold now with
+$k=28$}\6
+\&{if} $\|q<\\{fraction\_four}$ \1\&{then}\6
+\1\&{repeat} \37\&{if} $\\{odd}(\|f)$ \1\&{then}\5
+$\|p\K\\{half}(\|p+\|q)$\ \&{else} $\|p\K\\{half}(\|p)$;\2\6
+$\|f\K\\{half}(\|f)$;\6
+\4\&{until}\5
+$\|f=1$\2\6
+\4\&{else} \1\&{repeat} \37\&{if} $\\{odd}(\|f)$ \1\&{then}\5
+$\|p\K\|p+\\{half}(\|q-\|p)$\ \&{else} $\|p\K\\{half}(\|p)$;\2\6
+$\|f\K\\{half}(\|f)$;\6
+\4\&{until}\5
+$\|f=1$\2\2\par
+\U109.\fi
+
+\M112. When we want to multiply something by a \\{scaled} quantity, we use a
+scheme
+analogous to \\{take\_fraction} but with a different scaling.
+Given positive operands, \\{take\_scaled}
+computes the quantity $p=\lfloor qf/2^{16}+{1\over2}\rfloor$.
+
+Once again it is a good idea to use 64-bit arithmetic if
+possible; otherwise \\{take\_scaled} will use more than 2\pct! of the running
+time
+when the Computer Modern fonts are being generated.
+
+\Y\P\4\&{function}\1\ \37$\\{take\_scaled}(\|q:\\{integer};\,\35\|f:%
+\\{scaled})$: \37\\{integer};\6
+\4\&{var} \37\|p: \37\\{integer};\C{the fraction so far}\6
+\\{negative}: \37\\{boolean};\C{should the result be negated?}\6
+\|n: \37\\{integer};\C{additional multiple of $q$}\6
+\\{be\_careful}: \37\\{integer};\C{disables certain compiler optimizations}\2\6
+\&{begin} \37\X110:Reduce to the case that $\|f\G0$ and $\|q>0$\X;\6
+\&{if} $\|f<\\{unity}$ \1\&{then}\5
+$\|n\K0$\6
+\4\&{else} \&{begin} \37$\|n\K\|f\mathbin{\&{div}}\\{unity}$;\5
+$\|f\K\|f\mathbin{\&{mod}}\\{unity}$;\6
+\&{if} $\|q\L\\{el\_gordo}\mathbin{\&{div}}\|n$ \1\&{then}\5
+$\|n\K\|n\ast\|q$\6
+\4\&{else} \&{begin} \37$\\{arith\_error}\K\\{true}$;\5
+$\|n\K\\{el\_gordo}$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\|f\K\|f+\\{unity}$;\5
+\X113:Compute $p=\lfloor qf/2^{16}+{1\over2}\rfloor-q$\X;\6
+$\\{be\_careful}\K\|n-\\{el\_gordo}$;\6
+\&{if} $\\{be\_careful}+\|p>0$ \1\&{then}\6
+\&{begin} \37$\\{arith\_error}\K\\{true}$;\5
+$\|n\K\\{el\_gordo}-\|p$;\6
+\&{end};\2\6
+\&{if} $\\{negative}$ \1\&{then}\5
+$\\{take\_scaled}\K-(\|n+\|p)$\6
+\4\&{else} $\\{take\_scaled}\K\|n+\|p$;\2\6
+\&{end};\par
+\fi
+
+\M113. \P$\X113:Compute $p=\lfloor qf/2^{16}+{1\over2}\rfloor-q$\X\S$\6
+$\|p\K\\{half\_unit}$;\C{that's $2^{15}$; the invariants hold now with $k=16$}\6
+\&{if} $\|q<\\{fraction\_four}$ \1\&{then}\6
+\1\&{repeat} \37\&{if} $\\{odd}(\|f)$ \1\&{then}\5
+$\|p\K\\{half}(\|p+\|q)$\ \&{else} $\|p\K\\{half}(\|p)$;\2\6
+$\|f\K\\{half}(\|f)$;\6
+\4\&{until}\5
+$\|f=1$\2\6
+\4\&{else} \1\&{repeat} \37\&{if} $\\{odd}(\|f)$ \1\&{then}\5
+$\|p\K\|p+\\{half}(\|q-\|p)$\ \&{else} $\|p\K\\{half}(\|p)$;\2\6
+$\|f\K\\{half}(\|f)$;\6
+\4\&{until}\5
+$\|f=1$\2\2\par
+\U112.\fi
+
+\M114. For completeness, there's also \\{make\_scaled}, which computes a
+quotient as a \\{scaled} number instead of as a \\{fraction}.
+In other words, the result is $\lfloor2^{16}p/q+{1\over2}\rfloor$, if the
+operands are positive. \ (This procedure is not used especially often,
+so it is not part of \MF's inner loop.)
+
+\Y\P\4\&{function}\1\ \37$\\{make\_scaled}(\|p,\39\|q:\\{integer})$: \37%
+\\{scaled};\6
+\4\&{var} \37\|f: \37\\{integer};\C{the fraction bits, with a leading 1 bit}\6
+\|n: \37\\{integer};\C{the integer part of $\vert p/q\vert$}\6
+\\{negative}: \37\\{boolean};\C{should the result be negated?}\6
+\\{be\_careful}: \37\\{integer};\C{disables certain compiler optimizations}\2\6
+\&{begin} \37\&{if} $\|p\G0$ \1\&{then}\5
+$\\{negative}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\\{negate}(\|p)$;\5
+$\\{negative}\K\\{true}$;\6
+\&{end};\2\6
+\&{if} $\|q\L0$ \1\&{then}\6
+\&{begin} \37\&{debug} \37\&{if} $\|q=0$ \1\&{then}\5
+$\\{confusion}(\.{"/"})$;\ \2\6
+\&{gubed}\6
+$\\{negate}(\|q)$;\5
+$\\{negative}\K\R\\{negative}$;\6
+\&{end};\2\6
+$\|n\K\|p\mathbin{\&{div}}\|q$;\5
+$\|p\K\|p\mathbin{\&{mod}}\|q$;\6
+\&{if} $\|n\G\O{100000}$ \1\&{then}\6
+\&{begin} \37$\\{arith\_error}\K\\{true}$;\6
+\&{if} $\\{negative}$ \1\&{then}\5
+$\\{make\_scaled}\K-\\{el\_gordo}$\ \&{else} $\\{make\_scaled}\K\\{el\_gordo}$;%
+\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|n\K(\|n-1)\ast\\{unity}$;\5
+\X115:Compute $f=\lfloor 2^{16}(1+p/q)+{1\over2}\rfloor$\X;\6
+\&{if} $\\{negative}$ \1\&{then}\5
+$\\{make\_scaled}\K-(\|f+\|n)$\ \&{else} $\\{make\_scaled}\K\|f+\|n$;\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M115. \P$\X115:Compute $f=\lfloor 2^{16}(1+p/q)+{1\over2}\rfloor$\X\S$\6
+$\|f\K1$;\6
+\1\&{repeat} \37$\\{be\_careful}\K\|p-\|q$;\5
+$\|p\K\\{be\_careful}+\|p$;\6
+\&{if} $\|p\G0$ \1\&{then}\5
+$\|f\K\|f+\|f+1$\6
+\4\&{else} \&{begin} \37$\\{double}(\|f)$;\5
+$\|p\K\|p+\|q$;\6
+\&{end};\2\6
+\4\&{until}\5
+$\|f\G\\{unity}$;\2\6
+$\\{be\_careful}\K\|p-\|q$;\6
+\&{if} $\\{be\_careful}+\|p\G0$ \1\&{then}\5
+$\\{incr}(\|f)$\2\par
+\U114.\fi
+
+\M116. Here is a typical example of how the routines above can be used.
+It computes the function
+$${1\over3\tau}f(\theta,\phi)=
+{\tau^{-1}\bigl(2+\sqrt2\,(\sin\theta-{1\over16}\sin\phi)
+(\sin\phi-{1\over16}\sin\theta)(\cos\theta-\cos\phi)\bigr)\over
+3\,\bigl(1+{1\over2}(\sqrt5-1)\cos\theta+{1\over2}(3-\sqrt5\,)\cos\phi%
+\bigr)},$$
+where $\tau$ is a \\{scaled} ``tension'' parameter. This is \MF's magic
+fudge factor for placing the first control point of a curve that starts
+at an angle $\theta$ and ends at an angle $\phi$ from the straight path.
+(Actually, if the stated quantity exceeds 4, \MF\ reduces it to~4.)
+
+The trigonometric quantity to be multiplied by $\sqrt2$ is less than $\sqrt2$.
+(It's a sum of eight terms whose absolute values can be bounded using
+relations such as $\sin\theta\cos\theta\L{1\over2}$.) Thus the numerator
+is positive; and since the tension $\tau$ is constrained to be at least
+$3\over4$, the numerator is less than $16\over3$. The denominator is
+nonnegative and at most~6. Hence the fixed-point calculations below
+are guaranteed to stay within the bounds of a 32-bit computer word.
+
+The angles $\theta$ and $\phi$ are given implicitly in terms of \\{fraction}
+arguments \\{st}, \\{ct}, \\{sf}, and \\{cf}, representing $\sin\theta$, $\cos%
+\theta$,
+$\sin\phi$, and $\cos\phi$, respectively.
+
+\Y\P\4\&{function}\1\ \37$\\{velocity}(\\{st},\39\\{ct},\39\\{sf},\39\\{cf}:%
+\\{fraction};\,\35\|t:\\{scaled})$: \37\\{fraction};\6
+\4\&{var} \37$\\{acc},\39\\{num},\39\\{denom}$: \37\\{integer};\C{registers for
+intermediate calculations}\2\6
+\&{begin} \37$\\{acc}\K\\{take\_fraction}(\\{st}-(\\{sf}\mathbin{\&{div}}16),%
+\39\\{sf}-(\\{st}\mathbin{\&{div}}16))$;\5
+$\\{acc}\K\\{take\_fraction}(\\{acc},\39\\{ct}-\\{cf})$;\5
+$\\{num}\K\\{fraction\_two}+\\{take\_fraction}(\\{acc},\39379625062)$;%
+\C{$2^{28}\sqrt2\approx379625062.497$}\6
+$\\{denom}\K\\{fraction\_three}+\\{take\_fraction}(\\{ct},\39497706707)+\\{take%
+\_fraction}(\\{cf},\39307599661)$;\C{$3\cdot2^{27}\cdot(\sqrt5-1)%
+\approx497706706.78$ and $3\cdot2^{27}\cdot(3-\sqrt5\,)%
+\approx307599661.22$}\6
+\&{if} $\|t\I\\{unity}$ \1\&{then}\5
+$\\{num}\K\\{make\_scaled}(\\{num},\39\|t)$;\C{$\\{make\_scaled}(\\{fraction},%
+\\{scaled})=\\{fraction}$}\2\6
+\&{if} $\\{num}\mathbin{\&{div}}4\G\\{denom}$ \1\&{then}\5
+$\\{velocity}\K\\{fraction\_four}$\6
+\4\&{else} $\\{velocity}\K\\{make\_fraction}(\\{num},\39\\{denom})$;\2\6
+\&{end};\par
+\fi
+
+\M117. The following somewhat different subroutine tests rigorously if $ab$ is
+greater than, equal to, or less than~$cd$,
+given integers $(a,b,c,d)$. In most cases a quick decision is reached.
+The result is $+1$, 0, or~$-1$ in the three respective cases.
+
+\Y\P\D \37$\\{return\_sign}(\#)\S$\1\6
+\&{begin} \37$\\{ab\_vs\_cd}\K\#$;\5
+\&{return};\6
+\&{end}\2\par
+\Y\P\4\&{function}\1\ \37$\\{ab\_vs\_cd}(\|a,\39\|b,\39\|c,\39\|d:%
+\\{integer})$: \37\\{integer};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\|q,\39\|r$: \37\\{integer};\C{temporary registers}\2\6
+\&{begin} \37\X118:Reduce to the case that $\|a,\|c\G0$, $\|b,\|d>0$\X;\6
+\~ \1\&{loop}\ \&{begin} \37$\|q\K\|a\mathbin{\&{div}}\|d$;\5
+$\|r\K\|c\mathbin{\&{div}}\|b$;\6
+\&{if} $\|q\I\|r$ \1\&{then}\6
+\&{if} $\|q>\|r$ \1\&{then}\5
+$\\{return\_sign}(1)$\ \&{else} $\\{return\_sign}(-1)$;\2\2\6
+$\|q\K\|a\mathbin{\&{mod}}\|d$;\5
+$\|r\K\|c\mathbin{\&{mod}}\|b$;\6
+\&{if} $\|r=0$ \1\&{then}\6
+\&{if} $\|q=0$ \1\&{then}\5
+$\\{return\_sign}(0)$\ \&{else} $\\{return\_sign}(1)$;\2\2\6
+\&{if} $\|q=0$ \1\&{then}\5
+$\\{return\_sign}(-1)$;\2\6
+$\|a\K\|b$;\5
+$\|b\K\|q$;\5
+$\|c\K\|d$;\5
+$\|d\K\|r$;\6
+\&{end};\C{now $\|a>\|d>0$ and $\|c>\|b>0$}\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M118. \P$\X118:Reduce to the case that $\|a,\|c\G0$, $\|b,\|d>0$\X\S$\6
+\&{if} $\|a<0$ \1\&{then}\6
+\&{begin} \37$\\{negate}(\|a)$;\5
+$\\{negate}(\|b)$;\6
+\&{end};\2\6
+\&{if} $\|c<0$ \1\&{then}\6
+\&{begin} \37$\\{negate}(\|c)$;\5
+$\\{negate}(\|d)$;\6
+\&{end};\2\6
+\&{if} $\|d\L0$ \1\&{then}\6
+\&{begin} \37\&{if} $\|b\G0$ \1\&{then}\6
+\&{if} $((\|a=0)\V(\|b=0))\W((\|c=0)\V(\|d=0))$ \1\&{then}\5
+$\\{return\_sign}(0)$\6
+\4\&{else} $\\{return\_sign}(1)$;\2\2\6
+\&{if} $\|d=0$ \1\&{then}\6
+\&{if} $\|a=0$ \1\&{then}\5
+$\\{return\_sign}(0)$\ \&{else} $\\{return\_sign}(-1)$;\2\2\6
+$\|q\K\|a$;\5
+$\|a\K\|c$;\5
+$\|c\K\|q$;\5
+$\|q\K-\|b$;\5
+$\|b\K-\|d$;\5
+$\|d\K\|q$;\6
+\&{end}\6
+\4\&{else} \&{if} $\|b\L0$ \1\&{then}\6
+\&{begin} \37\&{if} $\|b<0$ \1\&{then}\6
+\&{if} $\|a>0$ \1\&{then}\5
+$\\{return\_sign}(-1)$;\2\2\6
+\&{if} $\|c=0$ \1\&{then}\5
+$\\{return\_sign}(0)$\6
+\4\&{else} $\\{return\_sign}(-1)$;\2\6
+\&{end}\2\2\par
+\U117.\fi
+
+\M119. We conclude this set of elementary routines with some simple rounding
+and truncation operations that are coded in a machine-independent fashion.
+The routines are slightly complicated because we want them to work
+without overflow whenever $-2^{31}\L x<2^{31}$.
+
+\Y\P\4\&{function}\1\ \37$\\{floor\_scaled}(\|x:\\{scaled})$: \37\\{scaled};%
+\C{$2^{16}\lfloor x/2^{16}\rfloor$}\6
+\4\&{var} \37\\{be\_careful}: \37\\{integer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\|x\G0$ \1\&{then}\5
+$\\{floor\_scaled}\K\|x-(\|x\mathbin{\&{mod}}\\{unity})$\6
+\4\&{else} \&{begin} \37$\\{be\_careful}\K\|x+1$;\5
+$\\{floor\_scaled}\K\|x+((-\\{be\_careful})\mathbin{\&{mod}}\\{unity})+1-%
+\\{unity}$;\6
+\&{end};\2\6
+\&{end};\7
+\4\&{function}\1\ \37$\\{floor\_unscaled}(\|x:\\{scaled})$: \37\\{integer};%
+\C{$\lfloor x/2^{16}\rfloor$}\6
+\4\&{var} \37\\{be\_careful}: \37\\{integer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\|x\G0$ \1\&{then}\5
+$\\{floor\_unscaled}\K\|x\mathbin{\&{div}}\\{unity}$\6
+\4\&{else} \&{begin} \37$\\{be\_careful}\K\|x+1$;\5
+$\\{floor\_unscaled}\K-(1+((-\\{be\_careful})\mathbin{\&{div}}\\{unity}))$;\6
+\&{end};\2\6
+\&{end};\7
+\4\&{function}\1\ \37$\\{round\_unscaled}(\|x:\\{scaled})$: \37\\{integer};%
+\C{$\lfloor x/2^{16}+.5\rfloor$}\6
+\4\&{var} \37\\{be\_careful}: \37\\{integer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\|x\G\\{half\_unit}$ \1\&{then}\5
+$\\{round\_unscaled}\K1+((\|x-\\{half\_unit})\mathbin{\&{div}}\\{unity})$\6
+\4\&{else} \&{if} $\|x\G-\\{half\_unit}$ \1\&{then}\5
+$\\{round\_unscaled}\K0$\6
+\4\&{else} \&{begin} \37$\\{be\_careful}\K\|x+1$;\5
+$\\{round\_unscaled}\K-(1+((-\\{be\_careful}-\\{half\_unit})\mathbin{\&{div}}%
+\\{unity}))$;\6
+\&{end};\2\2\6
+\&{end};\7
+\4\&{function}\1\ \37$\\{round\_fraction}(\|x:\\{fraction})$: \37\\{scaled};%
+\C{$\lfloor x/2^{12}+.5\rfloor$}\6
+\4\&{var} \37\\{be\_careful}: \37\\{integer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\|x\G2048$ \1\&{then}\5
+$\\{round\_fraction}\K1+((\|x-2048)\mathbin{\&{div}}4096)$\6
+\4\&{else} \&{if} $\|x\G-2048$ \1\&{then}\5
+$\\{round\_fraction}\K0$\6
+\4\&{else} \&{begin} \37$\\{be\_careful}\K\|x+1$;\5
+$\\{round\_fraction}\K-(1+((-\\{be\_careful}-2048)\mathbin{\&{div}}4096))$;\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\N120. \[8] Algebraic and transcendental functions.
+\MF\ computes all of the necessary special functions from scratch, without
+relying on \\{real} arithmetic or system subroutines for sines, cosines, etc.
+
+\fi
+
+\M121. To get the square root of a \\{scaled} number \|x, we want to calculate
+$s=\lfloor 2^8\!\sqrt x +{1\over2}\rfloor$. If $x>0$, this is the unique
+integer such that $2^{16}x-s\L s^2<2^{16}x+s$. The following subroutine
+determines $s$ by an iterative method that maintains the invariant
+relations $x=2^{46-2k}x_0\bmod 2^{30}$, $0<y=\lfloor 2^{16-2k}x_0\rfloor
+-s^2+s\L q=2s$, where $x_0$ is the initial value of $x$. The value of~$y$
+might, however, be zero at the start of the first iteration.
+
+\Y\P\4\&{function}\1\ \37$\\{square\_rt}(\|x:\\{scaled})$: \37\\{scaled};\6
+\4\&{var} \37\|k: \37\\{small\_number};\C{iteration control counter}\6
+$\|y,\39\|q$: \37\\{integer};\C{registers for intermediate calculations}\2\6
+\&{begin} \37\&{if} $\|x\L0$ \1\&{then}\5
+\X122:Handle square root of zero or negative argument\X\6
+\4\&{else} \&{begin} \37$\|k\K23$;\5
+$\|q\K2$;\6
+\&{while} $\|x<\\{fraction\_two}$ \1\&{do}\C{i.e., \&{while} $\|x<%
+\hbox{$2^{29}$}$\unskip}\6
+\&{begin} \37$\\{decr}(\|k)$;\5
+$\|x\K\|x+\|x+\|x+\|x$;\6
+\&{end};\2\6
+\&{if} $\|x<\\{fraction\_four}$ \1\&{then}\5
+$\|y\K0$\6
+\4\&{else} \&{begin} \37$\|x\K\|x-\\{fraction\_four}$;\5
+$\|y\K1$;\6
+\&{end};\2\6
+\1\&{repeat} \37\X123:Decrease \|k by 1, maintaining the invariant relations
+between \|x, \|y, and~\|q\X;\6
+\4\&{until}\5
+$\|k=0$;\2\6
+$\\{square\_rt}\K\\{half}(\|q)$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M122. \P$\X122:Handle square root of zero or negative argument\X\S$\6
+\&{begin} \37\&{if} $\|x<0$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Square\ root\ of\ "})$;\5
+$\\{print\_scaled}(\|x)$;\5
+$\\{print}(\.{"\ has\ been\ replaced\ by\ 0"})$;\5
+$\\{help2}(\.{"Since\ I\ don\'t\ take\ square\ roots\ of\ negative\
+numbers,"})$\6
+$(\.{"I\'m\ zeroing\ this\ one.\ Proceed,\ with\ fingers\ crossed."})$;\5
+\\{error};\6
+\&{end};\2\6
+$\\{square\_rt}\K0$;\6
+\&{end}\par
+\U121.\fi
+
+\M123. \P$\X123:Decrease \|k by 1, maintaining the invariant relations between %
+\|x, \|y, and~\|q\X\S$\6
+$\\{double}(\|x)$;\5
+$\\{double}(\|y)$;\6
+\&{if} $\|x\G\\{fraction\_four}$ \1\&{then}\C{note that $\\{fraction\_four}=%
+\hbox{$2^{30}$}$}\6
+\&{begin} \37$\|x\K\|x-\\{fraction\_four}$;\5
+$\\{incr}(\|y)$;\6
+\&{end};\2\6
+$\\{double}(\|x)$;\5
+$\|y\K\|y+\|y-\|q$;\5
+$\\{double}(\|q)$;\6
+\&{if} $\|x\G\\{fraction\_four}$ \1\&{then}\6
+\&{begin} \37$\|x\K\|x-\\{fraction\_four}$;\5
+$\\{incr}(\|y)$;\6
+\&{end};\2\6
+\&{if} $\|y>\|q$ \1\&{then}\6
+\&{begin} \37$\|y\K\|y-\|q$;\5
+$\|q\K\|q+2$;\6
+\&{end}\6
+\4\&{else} \&{if} $\|y\L0$ \1\&{then}\6
+\&{begin} \37$\|q\K\|q-2$;\5
+$\|y\K\|y+\|q$;\6
+\&{end};\2\2\6
+$\\{decr}(\|k)$\par
+\U121.\fi
+
+\M124. Pythagorean addition $\psqrt{a^2+b^2}$ is implemented by an elegant
+iterative scheme due to Cleve Moler and Donald Morrison [{\sl IBM Journal
+of Research and Development\/ \bf27} (1983), 577--581]. It modifies \|a and~\|b
+in such a way that their Pythagorean sum remains invariant, while the
+smaller argument decreases.
+
+\Y\P\4\&{function}\1\ \37$\\{pyth\_add}(\|a,\39\|b:\\{integer})$: \37%
+\\{integer};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|r: \37\\{fraction};\C{register used to transform \|a and \|b}\6
+\\{big}: \37\\{boolean};\C{is the result dangerously near $2^{31}$?}\2\6
+\&{begin} \37$\|a\K\\{abs}(\|a)$;\5
+$\|b\K\\{abs}(\|b)$;\6
+\&{if} $\|a<\|b$ \1\&{then}\6
+\&{begin} \37$\|r\K\|b$;\5
+$\|b\K\|a$;\5
+$\|a\K\|r$;\6
+\&{end};\C{now $0\L\|b\L\|a$}\2\6
+\&{if} $\|b>0$ \1\&{then}\6
+\&{begin} \37\&{if} $\|a<\\{fraction\_two}$ \1\&{then}\5
+$\\{big}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\|a\K\|a\mathbin{\&{div}}4$;\5
+$\|b\K\|b\mathbin{\&{div}}4$;\5
+$\\{big}\K\\{true}$;\6
+\&{end};\C{we reduced the precision to avoid arithmetic overflow}\2\6
+\X125:Replace \|a by an approximation to $\psqrt{a^2+b^2}$\X;\6
+\&{if} $\\{big}$ \1\&{then}\6
+\&{if} $\|a<\\{fraction\_two}$ \1\&{then}\5
+$\|a\K\|a+\|a+\|a+\|a$\6
+\4\&{else} \&{begin} \37$\\{arith\_error}\K\\{true}$;\5
+$\|a\K\\{el\_gordo}$;\6
+\&{end};\2\2\6
+\&{end};\2\6
+$\\{pyth\_add}\K\|a$;\6
+\&{end};\par
+\fi
+
+\M125. The key idea here is to reflect the vector $(a,b)$ about the
+line through $(a,b/2)$.
+
+\Y\P$\4\X125:Replace \|a by an approximation to $\psqrt{a^2+b^2}$\X\S$\6
+\~ \1\&{loop}\ \&{begin} \37$\|r\K\\{make\_fraction}(\|b,\39\|a)$;\5
+$\|r\K\\{take\_fraction}(\|r,\39\|r)$;\C{now $r\approx b^2/a^2$}\6
+\&{if} $\|r=0$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|r\K\\{make\_fraction}(\|r,\39\\{fraction\_four}+\|r)$;\5
+$\|a\K\|a+\\{take\_fraction}(\|a+\|a,\39\|r)$;\5
+$\|b\K\\{take\_fraction}(\|b,\39\|r)$;\6
+\&{end};\2\6
+\4\\{done}: \37\par
+\U124.\fi
+
+\M126. Here is a similar algorithm for $\psqrt{a^2-b^2}$.
+It converges slowly when $b$ is near $a$, but otherwise it works fine.
+
+\Y\P\4\&{function}\1\ \37$\\{pyth\_sub}(\|a,\39\|b:\\{integer})$: \37%
+\\{integer};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|r: \37\\{fraction};\C{register used to transform \|a and \|b}\6
+\\{big}: \37\\{boolean};\C{is the input dangerously near $2^{31}$?}\2\6
+\&{begin} \37$\|a\K\\{abs}(\|a)$;\5
+$\|b\K\\{abs}(\|b)$;\6
+\&{if} $\|a\L\|b$ \1\&{then}\5
+\X128:Handle erroneous \\{pyth\_sub} and set $\|a\K0$\X\6
+\4\&{else} \&{begin} \37\&{if} $\|a<\\{fraction\_four}$ \1\&{then}\5
+$\\{big}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\|a\K\\{half}(\|a)$;\5
+$\|b\K\\{half}(\|b)$;\5
+$\\{big}\K\\{true}$;\6
+\&{end};\2\6
+\X127:Replace \|a by an approximation to $\psqrt{a^2-b^2}$\X;\6
+\&{if} $\\{big}$ \1\&{then}\5
+$\|a\K\|a+\|a$;\2\6
+\&{end};\2\6
+$\\{pyth\_sub}\K\|a$;\6
+\&{end};\par
+\fi
+
+\M127. \P$\X127:Replace \|a by an approximation to $\psqrt{a^2-b^2}$\X\S$\6
+\~ \1\&{loop}\ \&{begin} \37$\|r\K\\{make\_fraction}(\|b,\39\|a)$;\5
+$\|r\K\\{take\_fraction}(\|r,\39\|r)$;\C{now $r\approx b^2/a^2$}\6
+\&{if} $\|r=0$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|r\K\\{make\_fraction}(\|r,\39\\{fraction\_four}-\|r)$;\5
+$\|a\K\|a-\\{take\_fraction}(\|a+\|a,\39\|r)$;\5
+$\|b\K\\{take\_fraction}(\|b,\39\|r)$;\6
+\&{end};\2\6
+\4\\{done}: \37\par
+\U126.\fi
+
+\M128. \P$\X128:Handle erroneous \\{pyth\_sub} and set $\|a\K0$\X\S$\6
+\&{begin} \37\&{if} $\|a<\|b$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Pythagorean\ subtraction\ "})$;\5
+$\\{print\_scaled}(\|a)$;\5
+$\\{print}(\.{"+-+"})$;\5
+$\\{print\_scaled}(\|b)$;\5
+$\\{print}(\.{"\ has\ been\ replaced\ by\ 0"})$;\5
+$\\{help2}(\.{"Since\ I\ don\'t\ take\ square\ roots\ of\ negative\
+numbers,"})$\6
+$(\.{"I\'m\ zeroing\ this\ one.\ Proceed,\ with\ fingers\ crossed."})$;\5
+\\{error};\6
+\&{end};\2\6
+$\|a\K0$;\6
+\&{end}\par
+\U126.\fi
+
+\M129. The subroutines for logarithm and exponential involve two tables.
+The first is simple: $\\{two\_to\_the}[\|k]$ equals $2^k$. The second involves
+a bit more calculation, which the author claims to have done correctly:
+$\\{spec\_log}[\|k]$ is $2^{27}$ times $\ln\bigl(1/(1-2^{-k})\bigr)=
+2^{-k}+{1\over2}2^{-2k}+{1\over3}2^{-3k}+\cdots\,$, rounded to the
+nearest integer.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{two\_to\_the}: \37\&{array} $[0\to30]$ \1\&{of}\5
+\\{integer};\C{powers of two}\2\6
+\4\\{spec\_log}: \37\&{array} $[1\to28]$ \1\&{of}\5
+\\{integer};\C{special logarithms}\2\par
+\fi
+
+\M130. \P$\X19:Local variables for initialization\X\mathrel{+}\S$\6
+\4\|k: \37\\{integer};\C{all-purpose loop index}\par
+\fi
+
+\M131. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{two\_to\_the}[0]\K1$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}30$ \1\&{do}\5
+$\\{two\_to\_the}[\|k]\K2\ast\\{two\_to\_the}[\|k-1]$;\2\6
+$\\{spec\_log}[1]\K93032640$;\5
+$\\{spec\_log}[2]\K38612034$;\5
+$\\{spec\_log}[3]\K17922280$;\5
+$\\{spec\_log}[4]\K8662214$;\5
+$\\{spec\_log}[5]\K4261238$;\5
+$\\{spec\_log}[6]\K2113709$;\5
+$\\{spec\_log}[7]\K1052693$;\5
+$\\{spec\_log}[8]\K525315$;\5
+$\\{spec\_log}[9]\K262400$;\5
+$\\{spec\_log}[10]\K131136$;\5
+$\\{spec\_log}[11]\K65552$;\5
+$\\{spec\_log}[12]\K32772$;\5
+$\\{spec\_log}[13]\K16385$;\6
+\&{for} $\|k\K14\mathrel{\&{to}}27$ \1\&{do}\5
+$\\{spec\_log}[\|k]\K\\{two\_to\_the}[27-\|k]$;\2\6
+$\\{spec\_log}[28]\K1$;\par
+\fi
+
+\M132. Here is the routine that calculates $2^8$ times the natural logarithm
+of a \\{scaled} quantity; it is an integer approximation to $2^{24}%
+\ln(x/2^{16})$,
+when \|x is a given positive integer.
+
+The method is based on exercise 1.2.2--25 in {\sl The Art of Computer
+Programming\/}: During the main iteration we have $1\L 2^{-30}x<1/(1-2^{1-k})$,
+and the logarithm of $2^{30}x$ remains to be added to an accumulator
+register called~$y$. Three auxiliary bits of accuracy are retained in~$y$
+during the calculation, and sixteen auxiliary bits to extend \|y are
+kept in~\|z during the initial argument reduction. (We add
+$100\cdot2^{16}=6553600$ to~\|z and subtract 100 from~\|y so that \|z will
+not become negative; also, the actual amount subtracted from~\|y is~96,
+not~100, because we want to add~4 for rounding before the final division by~8.)
+
+\Y\P\4\&{function}\1\ \37$\\{m\_log}(\|x:\\{scaled})$: \37\\{scaled};\6
+\4\&{var} \37$\|y,\39\|z$: \37\\{integer};\C{auxiliary registers}\6
+\|k: \37\\{integer};\C{iteration counter}\2\6
+\&{begin} \37\&{if} $\|x\L0$ \1\&{then}\5
+\X134:Handle non-positive logarithm\X\6
+\4\&{else} \&{begin} \37$\|y\K1302456956+4-100$;\C{$14\times2^{27}\ln2%
+\approx1302456956.421063$}\6
+$\|z\K27595+6553600$;\C{and $2^{16}\times .421063\approx 27595$}\6
+\&{while} $\|x<\\{fraction\_four}$ \1\&{do}\6
+\&{begin} \37$\\{double}(\|x)$;\5
+$\|y\K\|y-93032639$;\5
+$\|z\K\|z-48782$;\6
+\&{end};\C{$2^{27}\ln2\approx 93032639.74436163$ and $2^{16}%
+\times.74436163\approx 48782$}\2\6
+$\|y\K\|y+(\|z\mathbin{\&{div}}\\{unity})$;\5
+$\|k\K2$;\6
+\&{while} $\|x>\\{fraction\_four}+4$ \1\&{do}\5
+\X133:Increase \|k until \|x can be multiplied by a factor of $2^{-k}$, and
+adjust $y$ accordingly\X;\2\6
+$\\{m\_log}\K\|y\mathbin{\&{div}}8$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M133. \P$\X133:Increase \|k until \|x can be multiplied by a factor of
+$2^{-k}$, and adjust $y$ accordingly\X\S$\6
+\&{begin} \37$\|z\K((\|x-1)\mathbin{\&{div}}\\{two\_to\_the}[\|k])+1$;\C{$z=%
+\lceil x/2^k\rceil$}\6
+\&{while} $\|x<\\{fraction\_four}+\|z$ \1\&{do}\6
+\&{begin} \37$\|z\K\\{half}(\|z+1)$;\5
+$\|k\K\|k+1$;\6
+\&{end};\2\6
+$\|y\K\|y+\\{spec\_log}[\|k]$;\5
+$\|x\K\|x-\|z$;\6
+\&{end}\par
+\U132.\fi
+
+\M134. \P$\X134:Handle non-positive logarithm\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Logarithm\ of\ "})$;\5
+$\\{print\_scaled}(\|x)$;\5
+$\\{print}(\.{"\ has\ been\ replaced\ by\ 0"})$;\5
+$\\{help2}(\.{"Since\ I\ don\'t\ take\ logs\ of\ non-positive\ numbers,"})$\6
+$(\.{"I\'m\ zeroing\ this\ one.\ Proceed,\ with\ fingers\ crossed."})$;\5
+\\{error};\5
+$\\{m\_log}\K0$;\6
+\&{end}\par
+\U132.\fi
+
+\M135. Conversely, the exponential routine calculates $\exp(x/2^8)$,
+when \|x is \\{scaled}. The result is an integer approximation to
+$2^{16}\exp(x/2^{24})$, when \|x is regarded as an integer.
+
+\Y\P\4\&{function}\1\ \37$\\{m\_exp}(\|x:\\{scaled})$: \37\\{scaled};\6
+\4\&{var} \37\|k: \37\\{small\_number};\C{loop control index}\6
+$\|y,\39\|z$: \37\\{integer};\C{auxiliary registers}\2\6
+\&{begin} \37\&{if} $\|x>174436200$ \1\&{then}\C{$2^{24}\ln((2^{31}-1)/2^{16})%
+\approx 174436199.51$}\6
+\&{begin} \37$\\{arith\_error}\K\\{true}$;\5
+$\\{m\_exp}\K\\{el\_gordo}$;\6
+\&{end}\6
+\4\&{else} \&{if} $\|x<-197694359$ \1\&{then}\5
+$\\{m\_exp}\K0$\C{$2^{24}\ln(2^{-1}/2^{16})\approx-197694359.45$}\6
+\4\&{else} \&{begin} \37\&{if} $\|x\L0$ \1\&{then}\6
+\&{begin} \37$\|z\K-8\ast\|x$;\5
+$\|y\K\O{4000000}$;\C{$y=2^{20}$}\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\|x\L127919879$ \1\&{then}\5
+$\|z\K1023359037-8\ast\|x$\C{$2^{27}\ln((2^{31}-1)/2^{20})\approx
+1023359037.125$}\6
+\4\&{else} $\|z\K8\ast(174436200-\|x)$;\C{\|z is always nonnegative}\2\6
+$\|y\K\\{el\_gordo}$;\6
+\&{end};\2\6
+\X136:Multiply \|y by $\exp(-z/2^{27})$\X;\6
+\&{if} $\|x\L127919879$ \1\&{then}\5
+$\\{m\_exp}\K(\|y+8)\mathbin{\&{div}}16$\ \&{else} $\\{m\_exp}\K\|y$;\2\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M136. The idea here is that subtracting $\\{spec\_log}[\|k]$ from \|z
+corresponds
+to multiplying \|y by $1-2^{-k}$.
+
+A subtle point (which had to be checked) was that if $x=127919879$, the
+value of~\|y will decrease so that $\|y+8$ doesn't overflow. In fact,
+$z$ will be 5 in this case, and \|y will decrease by~64 when $\|k=25$
+and by~16 when $\|k=27$.
+
+\Y\P$\4\X136:Multiply \|y by $\exp(-z/2^{27})$\X\S$\6
+$\|k\K1$;\6
+\&{while} $\|z>0$ \1\&{do}\6
+\&{begin} \37\&{while} $\|z\G\\{spec\_log}[\|k]$ \1\&{do}\6
+\&{begin} \37$\|z\K\|z-\\{spec\_log}[\|k]$;\5
+$\|y\K\|y-1-((\|y-\\{two\_to\_the}[\|k-1])\mathbin{\&{div}}\\{two\_to\_the}[%
+\|k])$;\6
+\&{end};\2\6
+$\\{incr}(\|k)$;\6
+\&{end}\2\par
+\U135.\fi
+
+\M137. The trigonometric subroutines use an auxiliary table such that
+$\\{spec\_atan}[\|k]$ contains an approximation to the \\{angle} whose tangent
+is~$1/2^k$.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{spec\_atan}: \37\&{array} $[1\to26]$ \1\&{of}\5
+\\{angle};\C{$\arctan2^{-k}$ times $2^{20}\cdot180/\pi$}\2\par
+\fi
+
+\M138. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{spec\_atan}[1]\K27855475$;\5
+$\\{spec\_atan}[2]\K14718068$;\5
+$\\{spec\_atan}[3]\K7471121$;\5
+$\\{spec\_atan}[4]\K3750058$;\5
+$\\{spec\_atan}[5]\K1876857$;\5
+$\\{spec\_atan}[6]\K938658$;\5
+$\\{spec\_atan}[7]\K469357$;\5
+$\\{spec\_atan}[8]\K234682$;\5
+$\\{spec\_atan}[9]\K117342$;\5
+$\\{spec\_atan}[10]\K58671$;\5
+$\\{spec\_atan}[11]\K29335$;\5
+$\\{spec\_atan}[12]\K14668$;\5
+$\\{spec\_atan}[13]\K7334$;\5
+$\\{spec\_atan}[14]\K3667$;\5
+$\\{spec\_atan}[15]\K1833$;\5
+$\\{spec\_atan}[16]\K917$;\5
+$\\{spec\_atan}[17]\K458$;\5
+$\\{spec\_atan}[18]\K229$;\5
+$\\{spec\_atan}[19]\K115$;\5
+$\\{spec\_atan}[20]\K57$;\5
+$\\{spec\_atan}[21]\K29$;\5
+$\\{spec\_atan}[22]\K14$;\5
+$\\{spec\_atan}[23]\K7$;\5
+$\\{spec\_atan}[24]\K4$;\5
+$\\{spec\_atan}[25]\K2$;\5
+$\\{spec\_atan}[26]\K1$;\par
+\fi
+
+\M139. Given integers \|x and \|y, not both zero, the \\{n\_arg} function
+returns the \\{angle} whose tangent points in the direction $(x,y)$.
+This subroutine first determines the correct octant, then solves the
+problem for $0\L\|y\L\|x$, then converts the result appropriately to
+return an answer in the range $-\\{one\_eighty\_deg}\L\hbox{$\theta$}\L\\{one%
+\_eighty\_deg}$.
+(The answer is $+\\{one\_eighty\_deg}$ if $\|y=0$ and $\|x<0$, but an answer of
+$-\\{one\_eighty\_deg}$ is possible if, for example, $\|y=-1$ and $x=-2^{30}$.)
+
+The octants are represented in a ``Gray code,'' since that turns out
+to be computationally simplest.
+
+\Y\P\D \37$\\{negate\_x}=1$\par
+\P\D \37$\\{negate\_y}=2$\par
+\P\D \37$\\{switch\_x\_and\_y}=4$\par
+\P\D \37$\\{first\_octant}=1$\par
+\P\D \37$\\{second\_octant}=\\{first\_octant}+\\{switch\_x\_and\_y}$\par
+\P\D \37$\\{third\_octant}=\\{first\_octant}+\\{switch\_x\_and\_y}+\\{negate%
+\_x}$\par
+\P\D \37$\\{fourth\_octant}=\\{first\_octant}+\\{negate\_x}$\par
+\P\D \37$\\{fifth\_octant}=\\{first\_octant}+\\{negate\_x}+\\{negate\_y}$\par
+\P\D \37$\\{sixth\_octant}=\\{first\_octant}+\\{switch\_x\_and\_y}+\\{negate%
+\_x}+\\{negate\_y}$\par
+\P\D \37$\\{seventh\_octant}=\\{first\_octant}+\\{switch\_x\_and\_y}+\\{negate%
+\_y}$\par
+\P\D \37$\\{eighth\_octant}=\\{first\_octant}+\\{negate\_y}$\par
+\Y\P\4\&{function}\1\ \37$\\{n\_arg}(\|x,\39\|y:\\{integer})$: \37\\{angle};\6
+\4\&{var} \37\|z: \37\\{angle};\C{auxiliary register}\6
+\|t: \37\\{integer};\C{temporary storage}\6
+\|k: \37\\{small\_number};\C{loop counter}\6
+\\{octant}: \37$\\{first\_octant}\to\\{sixth\_octant}$;\C{octant code}\2\6
+\&{begin} \37\&{if} $\|x\G0$ \1\&{then}\5
+$\\{octant}\K\\{first\_octant}$\6
+\4\&{else} \&{begin} \37$\\{negate}(\|x)$;\5
+$\\{octant}\K\\{first\_octant}+\\{negate\_x}$;\6
+\&{end};\2\6
+\&{if} $\|y<0$ \1\&{then}\6
+\&{begin} \37$\\{negate}(\|y)$;\5
+$\\{octant}\K\\{octant}+\\{negate\_y}$;\6
+\&{end};\2\6
+\&{if} $\|x<\|y$ \1\&{then}\6
+\&{begin} \37$\|t\K\|y$;\5
+$\|y\K\|x$;\5
+$\|x\K\|t$;\5
+$\\{octant}\K\\{octant}+\\{switch\_x\_and\_y}$;\6
+\&{end};\2\6
+\&{if} $\|x=0$ \1\&{then}\5
+\X140:Handle undefined arg\X\6
+\4\&{else} \&{begin} \37\X142:Set variable \|z to the arg of $(x,y)$\X;\6
+\X141:Return an appropriate answer based on \|z and \\{octant}\X;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M140. \P$\X140:Handle undefined arg\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"angle(0,0)\ is\ taken\ as\ zero"})$;\5
+$\\{help2}(\.{"The\ \`angle\'\ between\ two\ identical\ points\ is\
+undefined."})$\6
+$(\.{"I\'m\ zeroing\ this\ one.\ Proceed,\ with\ fingers\ crossed."})$;\5
+\\{error};\5
+$\\{n\_arg}\K0$;\6
+\&{end}\par
+\U139.\fi
+
+\M141. \P$\X141:Return an appropriate answer based on \|z and \\{octant}\X\S$\6
+\&{case} $\\{octant}$ \1\&{of}\6
+\4\\{first\_octant}: \37$\\{n\_arg}\K\|z$;\6
+\4\\{second\_octant}: \37$\\{n\_arg}\K\\{ninety\_deg}-\|z$;\6
+\4\\{third\_octant}: \37$\\{n\_arg}\K\\{ninety\_deg}+\|z$;\6
+\4\\{fourth\_octant}: \37$\\{n\_arg}\K\\{one\_eighty\_deg}-\|z$;\6
+\4\\{fifth\_octant}: \37$\\{n\_arg}\K\|z-\\{one\_eighty\_deg}$;\6
+\4\\{sixth\_octant}: \37$\\{n\_arg}\K-\|z-\\{ninety\_deg}$;\6
+\4\\{seventh\_octant}: \37$\\{n\_arg}\K\|z-\\{ninety\_deg}$;\6
+\4\\{eighth\_octant}: \37$\\{n\_arg}\K-\|z$;\2\6
+\&{end}\C{there are no other cases}\par
+\U139.\fi
+
+\M142. At this point we have $\|x\G\|y\G0$, and $\|x>0$. The numbers are scaled
+up
+or down until $2^{28}\L x<2^{29}$, so that accurate fixed-point calculations
+will be made.
+
+\Y\P$\4\X142:Set variable \|z to the arg of $(x,y)$\X\S$\6
+\&{while} $\|x\G\\{fraction\_two}$ \1\&{do}\6
+\&{begin} \37$\|x\K\\{half}(\|x)$;\5
+$\|y\K\\{half}(\|y)$;\6
+\&{end};\2\6
+$\|z\K0$;\6
+\&{if} $\|y>0$ \1\&{then}\6
+\&{begin} \37\&{while} $\|x<\\{fraction\_one}$ \1\&{do}\6
+\&{begin} \37$\\{double}(\|x)$;\5
+$\\{double}(\|y)$;\6
+\&{end};\2\6
+\X143:Increase \|z to the arg of $(x,y)$\X;\6
+\&{end}\2\par
+\U139.\fi
+
+\M143. During the calculations of this section, variables \|x and~\|y
+represent actual coordinates $(x,2^{-k}y)$. We will maintain the
+condition $\|x\G\|y$, so that the tangent will be at most $2^{-k}$.
+If $x<2y$, the tangent is greater than $2^{-k-1}$. The transformation
+$(a,b)\mapsto(a+b\tan\phi,b-a\tan\phi)$ replaces $(a,b)$ by
+coordinates whose angle has decreased by~$\phi$; in the special case
+$a=x$, $b=2^{-k}y$, and $\tan\phi=2^{-k-1}$, this operation reduces
+to the particularly simple iteration shown here. [Cf.~John E. Meggitt,
+{\sl IBM Journal of Research and Development\/ \bf6} (1962), 210--226.]
+
+The initial value of \|x will be multiplied by at most
+$(1+{1\over2})(1+{1\over8})(1+{1\over32})\cdots\approx 1.7584$; hence
+there is no chance of integer overflow.
+
+\Y\P$\4\X143:Increase \|z to the arg of $(x,y)$\X\S$\6
+$\|k\K0$;\6
+\1\&{repeat} \37$\\{double}(\|y)$;\5
+$\\{incr}(\|k)$;\6
+\&{if} $\|y>\|x$ \1\&{then}\6
+\&{begin} \37$\|z\K\|z+\\{spec\_atan}[\|k]$;\5
+$\|t\K\|x$;\5
+$\|x\K\|x+(\|y\mathbin{\&{div}}\\{two\_to\_the}[\|k+\|k])$;\5
+$\|y\K\|y-\|t$;\6
+\&{end};\2\6
+\4\&{until}\5
+$\|k=15$;\2\6
+\1\&{repeat} \37$\\{double}(\|y)$;\5
+$\\{incr}(\|k)$;\6
+\&{if} $\|y>\|x$ \1\&{then}\6
+\&{begin} \37$\|z\K\|z+\\{spec\_atan}[\|k]$;\5
+$\|y\K\|y-\|x$;\6
+\&{end};\2\6
+\4\&{until}\5
+$\|k=26$\2\par
+\U142.\fi
+
+\M144. Conversely, the \\{n\_sin\_cos} routine takes an \\{angle} and produces
+the sine
+and cosine of that angle. The results of this routine are
+stored in global integer variables \\{n\_sin} and \\{n\_cos}.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{n\_sin},\39\\{n\_cos}$: \37\\{fraction};\C{results computed by \\{n\_sin%
+\_cos}}\par
+\fi
+
+\M145. Given an integer \|z that is $2^{20}$ times an angle $\theta$ in
+degrees,
+the purpose of $\\{n\_sin\_cos}(\|z)$ is to set
+$\|x=\hbox{$r\cos\theta$}$ and $\|y=\hbox{$r\sin\theta$}$ (approximately),
+for some rather large number~\|r. The maximum of \|x and \|y
+will be between $2^{28}$ and $2^{30}$, so that there will be hardly
+any loss of accuracy. Then \|x and~\|y are divided by~\|r.
+
+\Y\P\4\&{procedure}\1\ \37$\\{n\_sin\_cos}(\|z:\\{angle})$;\C{computes a
+multiple of the sine and cosine}\6
+\4\&{var} \37\|k: \37\\{small\_number};\C{loop control variable}\6
+\|q: \37$0\to7$;\C{specifies the quadrant}\6
+\|r: \37\\{fraction};\C{magnitude of $(\|x,\|y)$}\6
+$\|x,\39\|y,\39\|t$: \37\\{integer};\C{temporary registers}\2\6
+\&{begin} \37\&{while} $\|z<0$ \1\&{do}\5
+$\|z\K\|z+\\{three\_sixty\_deg}$;\2\6
+$\|z\K\|z\mathbin{\&{mod}}\\{three\_sixty\_deg}$;\C{now $0\L\|z<\\{three\_sixty%
+\_deg}$}\6
+$\|q\K\|z\mathbin{\&{div}}\\{forty\_five\_deg}$;\5
+$\|z\K\|z\mathbin{\&{mod}}\\{forty\_five\_deg}$;\5
+$\|x\K\\{fraction\_one}$;\5
+$\|y\K\|x$;\6
+\&{if} $\R\\{odd}(\|q)$ \1\&{then}\5
+$\|z\K\\{forty\_five\_deg}-\|z$;\2\6
+\X147:Subtract angle \|z from $(\|x,\|y)$\X;\6
+\X146:Convert $(\|x,\|y)$ to the octant determined by~\|q\X;\6
+$\|r\K\\{pyth\_add}(\|x,\39\|y)$;\5
+$\\{n\_cos}\K\\{make\_fraction}(\|x,\39\|r)$;\5
+$\\{n\_sin}\K\\{make\_fraction}(\|y,\39\|r)$;\6
+\&{end};\par
+\fi
+
+\M146. In this case the octants are numbered sequentially.
+
+\Y\P$\4\X146:Convert $(\|x,\|y)$ to the octant determined by~\|q\X\S$\6
+\&{case} $\|q$ \1\&{of}\6
+\40: \37\\{do\_nothing};\6
+\41: \37\&{begin} \37$\|t\K\|x$;\5
+$\|x\K\|y$;\5
+$\|y\K\|t$;\6
+\&{end};\6
+\42: \37\&{begin} \37$\|t\K\|x$;\5
+$\|x\K-\|y$;\5
+$\|y\K\|t$;\6
+\&{end};\6
+\43: \37$\\{negate}(\|x)$;\6
+\44: \37\&{begin} \37$\\{negate}(\|x)$;\5
+$\\{negate}(\|y)$;\6
+\&{end};\6
+\45: \37\&{begin} \37$\|t\K\|x$;\5
+$\|x\K-\|y$;\5
+$\|y\K-\|t$;\6
+\&{end};\6
+\46: \37\&{begin} \37$\|t\K\|x$;\5
+$\|x\K\|y$;\5
+$\|y\K-\|t$;\6
+\&{end};\6
+\47: \37$\\{negate}(\|y)$;\2\6
+\&{end}\C{there are no other cases}\par
+\U145.\fi
+
+\M147. The main iteration of \\{n\_sin\_cos} is similar to that of \\{n\_arg}
+but
+applied in reverse. The values of $\\{spec\_atan}[\|k]$ decrease slowly enough
+that this loop is guaranteed to terminate before the (nonexistent) value
+$\\{spec\_atan}[27]$ would be required.
+
+\Y\P$\4\X147:Subtract angle \|z from $(\|x,\|y)$\X\S$\6
+$\|k\K1$;\6
+\&{while} $\|z>0$ \1\&{do}\6
+\&{begin} \37\&{if} $\|z\G\\{spec\_atan}[\|k]$ \1\&{then}\6
+\&{begin} \37$\|z\K\|z-\\{spec\_atan}[\|k]$;\5
+$\|t\K\|x$;\6
+$\|x\K\|t+\|y\mathbin{\&{div}}\\{two\_to\_the}[\|k]$;\5
+$\|y\K\|y-\|t\mathbin{\&{div}}\\{two\_to\_the}[\|k]$;\6
+\&{end};\2\6
+$\\{incr}(\|k)$;\6
+\&{end};\2\6
+\&{if} $\|y<0$ \1\&{then}\5
+$\|y\K0$\C{this precaution may never be needed}\2\par
+\U145.\fi
+
+\M148. And now let's complete our collection of numeric utility routines
+by considering random number generation.
+\MF\ generates pseudo-random numbers with the additive scheme recommended
+in Section 3.6 of {\sl The Art of Computer Programming}; however, the
+results are random fractions between 0 and $\\{fraction\_one}-1$, inclusive.
+
+There's an auxiliary array \\{randoms} that contains 55 pseudo-random
+fractions. Using the recurrence $x_n=(x_{n-55}-x_{n-24})\bmod 2^{28}$,
+we generate batches of 55 new $x_n$'s at a time by calling \\{new\_randoms}.
+The global variable \\{j\_random} tells which element has most recently
+been consumed.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{randoms}: \37\&{array} $[0\to54]$ \1\&{of}\5
+\\{fraction};\C{the last 55 random values generated}\2\6
+\4\\{j\_random}: \37$0\to54$;\C{the number of unused \\{randoms}}\par
+\fi
+
+\M149. To consume a random fraction, the program below will say `\\{next%
+\_random}'
+and then it will fetch $\\{randoms}[\\{j\_random}]$. The \\{next\_random} macro
+actually accesses the numbers backwards; blocks of 55~$x$'s are
+essentially being ``flipped.'' But that doesn't make them less random.
+
+\Y\P\D \37$\\{next\_random}\S$\1\6
+\&{if} $\\{j\_random}=0$ \1\&{then}\5
+\\{new\_randoms}\6
+\4\&{else} $\\{decr}(\\{j\_random})$\2\2\par
+\Y\P\4\&{procedure}\1\ \37\\{new\_randoms};\6
+\4\&{var} \37\|k: \37$0\to54$;\C{index into \\{randoms}}\6
+\|x: \37\\{fraction};\C{accumulator}\2\6
+\&{begin} \37\&{for} $\|k\K0\mathrel{\&{to}}23$ \1\&{do}\6
+\&{begin} \37$\|x\K\\{randoms}[\|k]-\\{randoms}[\|k+31]$;\6
+\&{if} $\|x<0$ \1\&{then}\5
+$\|x\K\|x+\\{fraction\_one}$;\2\6
+$\\{randoms}[\|k]\K\|x$;\6
+\&{end};\2\6
+\&{for} $\|k\K24\mathrel{\&{to}}54$ \1\&{do}\6
+\&{begin} \37$\|x\K\\{randoms}[\|k]-\\{randoms}[\|k-24]$;\6
+\&{if} $\|x<0$ \1\&{then}\5
+$\|x\K\|x+\\{fraction\_one}$;\2\6
+$\\{randoms}[\|k]\K\|x$;\6
+\&{end};\2\6
+$\\{j\_random}\K54$;\6
+\&{end};\par
+\fi
+
+\M150. To initialize the \\{randoms} table, we call the following routine.
+
+\Y\P\4\&{procedure}\1\ \37$\\{init\_randoms}(\\{seed}:\\{scaled})$;\6
+\4\&{var} \37$\|j,\39\\{jj},\39\|k$: \37\\{fraction};\C{more or less random
+integers}\6
+\|i: \37$0\to54$;\C{index into \\{randoms}}\2\6
+\&{begin} \37$\|j\K\\{abs}(\\{seed})$;\6
+\&{while} $\|j\G\\{fraction\_one}$ \1\&{do}\5
+$\|j\K\\{half}(\|j)$;\2\6
+$\|k\K1$;\6
+\&{for} $\|i\K0\mathrel{\&{to}}54$ \1\&{do}\6
+\&{begin} \37$\\{jj}\K\|k$;\5
+$\|k\K\|j-\|k$;\5
+$\|j\K\\{jj}$;\6
+\&{if} $\|k<0$ \1\&{then}\5
+$\|k\K\|k+\\{fraction\_one}$;\2\6
+$\\{randoms}[(\|i\ast21)\mathbin{\&{mod}}55]\K\|j$;\6
+\&{end};\2\6
+\\{new\_randoms};\5
+\\{new\_randoms};\5
+\\{new\_randoms};\C{``warm up'' the array}\6
+\&{end};\par
+\fi
+
+\M151. To produce a uniform random number in the range $0\L\|u<\|x$ or $0\G\|u>%
+\|x$
+or $0=\|u=\|x$, given a \\{scaled} value~\|x, we proceed as shown here.
+
+Note that the call of \\{take\_fraction} will produce the values 0 and~\|x
+with about half the probability that it will produce any other particular
+values between 0 and~\|x, because it rounds its answers.
+
+\Y\P\4\&{function}\1\ \37$\\{unif\_rand}(\|x:\\{scaled})$: \37\\{scaled};\6
+\4\&{var} \37\|y: \37\\{scaled};\C{trial value}\2\6
+\&{begin} \37\\{next\_random};\5
+$\|y\K\\{take\_fraction}(\\{abs}(\|x),\39\\{randoms}[\\{j\_random}])$;\6
+\&{if} $\|y=\\{abs}(\|x)$ \1\&{then}\5
+$\\{unif\_rand}\K0$\6
+\4\&{else} \&{if} $\|x>0$ \1\&{then}\5
+$\\{unif\_rand}\K\|y$\6
+\4\&{else} $\\{unif\_rand}\K-\|y$;\2\2\6
+\&{end};\par
+\fi
+
+\M152. Finally, a normal deviate with mean zero and unit standard deviation
+can readily be obtained with the ratio method (Algorithm 3.4.1R in
+{\sl The Art of Computer Programming\/}).
+
+\Y\P\4\&{function}\1\ \37\\{norm\_rand}: \37\\{scaled};\6
+\4\&{var} \37$\|x,\39\|u,\39\|l$: \37\\{integer};\C{what the book would call
+$2^{16}X$, $2^{28}U$, and $-2^{24}\ln U$}\2\6
+\&{begin} \37\1\&{repeat} \37\1\&{repeat} \37\\{next\_random};\5
+$\|x\K\\{take\_fraction}(112429,\39\\{randoms}[\\{j\_random}]-\\{fraction%
+\_half})$;\C{$2^{16}\sqrt{8/e}\approx 112428.82793$}\6
+\\{next\_random};\5
+$\|u\K\\{randoms}[\\{j\_random}]$;\6
+\4\&{until}\5
+$\\{abs}(\|x)<\|u$;\2\6
+$\|x\K\\{make\_fraction}(\|x,\39\|u)$;\5
+$\|l\K139548960-\\{m\_log}(\|u)$;\C{$2^{24}\cdot12\ln2\approx139548959.6165$}\6
+\4\&{until}\5
+$\\{ab\_vs\_cd}(1024,\39\|l,\39\|x,\39\|x)\G0$;\2\6
+$\\{norm\_rand}\K\|x$;\6
+\&{end};\par
+\fi
+
+\N153. \[9] Packed data.
+In order to make efficient use of storage space, \MF\ bases its major data
+structures on a \\{memory\_word}, which contains either a (signed) integer,
+possibly scaled, or a small number of fields that are one half or one
+quarter of the size used for storing integers.
+
+If \|x is a variable of type \\{memory\_word}, it contains up to four
+fields that can be referred to as follows:
+$$\vbox{\halign{\hfil#&#\hfil&#\hfil\cr
+\|x&.\\{int}&(an \\{integer})\cr
+\|x&.\\{sc}\qquad&(a \\{scaled} integer)\cr
+\|x.\\{hh}.\\{lh}, \|x.\\{hh}&.\\{rh}&(two halfword fields)\cr
+\|x.\\{hh}.\\{b0}, \|x.\\{hh}.\\{b1}, \|x.\\{hh}&.\\{rh}&(two quarterword
+fields, one halfword
+field)\cr
+\|x.\\{qqqq}.\\{b0}, \|x.\\{qqqq}.\\{b1}, \|x.\\{qqqq}&.\\{b2}, \|x.\\{qqqq}.%
+\\{b3}\hskip-100pt
+&\qquad\qquad\qquad(four quarterword fields)\cr}}$$
+This is somewhat cumbersome to write, and not very readable either, but
+macros will be used to make the notation shorter and more transparent.
+The \PASCAL\ code below gives a formal definition of \\{memory\_word} and
+its subsidiary types, using packed variant records. \MF\ makes no
+assumptions about the relative positions of the fields within a word.
+
+Since we are assuming 32-bit integers, a halfword must contain at least
+16 bits, and a quarterword must contain at least 8 bits.
+But it doesn't hurt to have more bits; for example, with enough 36-bit
+words you might be able to have \\{mem\_max} as large as 262142.
+
+N.B.: Valuable memory space will be dreadfully wasted unless \MF\ is compiled
+by a \PASCAL\ that packs all of the \\{memory\_word} variants into
+the space of a single integer. Some \PASCAL\ compilers will pack an
+integer whose subrange is `$0\to255$' into an eight-bit field, but others
+insist on allocating space for an additional sign bit; on such systems you
+can get 256 values into a quarterword only if the subrange is `$-128\to127$'.
+
+The present implementation tries to accommodate as many variations as possible,
+so it makes few assumptions. If integers having the subrange
+`$\\{min\_quarterword}\to\\{max\_quarterword}$' can be packed into a
+quarterword,
+and if integers having the subrange `$\\{min\_halfword}\to\\{max\_halfword}$'
+can be packed into a halfword, everything should work satisfactorily.
+
+It is usually most efficient to have $\\{min\_quarterword}=\\{min%
+\_halfword}=0$,
+so one should try to achieve this unless it causes a severe problem.
+The values defined here are recommended for most 32-bit computers.
+
+\Y\P\D \37$\\{min\_quarterword}=0$\C{smallest allowable value in a %
+\\{quarterword}}\par
+\P\D \37$\\{max\_quarterword}=255$\C{largest allowable value in a %
+\\{quarterword}}\par
+\P\D \37$\\{min\_halfword}\S0$\C{smallest allowable value in a \\{halfword}}\par
+\P\D \37$\\{max\_halfword}\S65535$\C{largest allowable value in a \\{halfword}}%
+\par
+\fi
+
+\M154. Here are the inequalities that the quarterword and halfword values
+must satisfy (or rather, the inequalities that they mustn't satisfy):
+
+\Y\P$\4\X14:Check the ``constant'' values for consistency\X\mathrel{+}\S$\6
+\&{init} \37\&{if} $\\{mem\_max}\I\\{mem\_top}$ \1\&{then}\5
+$\\{bad}\K10$;\ \2\6
+\&{tini}\6
+\&{if} $\\{mem\_max}<\\{mem\_top}$ \1\&{then}\5
+$\\{bad}\K10$;\2\6
+\&{if} $(\\{min\_quarterword}>0)\V(\\{max\_quarterword}<127)$ \1\&{then}\5
+$\\{bad}\K11$;\2\6
+\&{if} $(\\{min\_halfword}>0)\V(\\{max\_halfword}<32767)$ \1\&{then}\5
+$\\{bad}\K12$;\2\6
+\&{if} $(\\{min\_quarterword}<\\{min\_halfword})\V\30(\\{max\_quarterword}>%
+\\{max\_halfword})$ \1\&{then}\5
+$\\{bad}\K13$;\2\6
+\&{if} $(\\{mem\_min}<\\{min\_halfword})\V(\\{mem\_max}\G\\{max\_halfword})$ \1%
+\&{then}\5
+$\\{bad}\K14$;\2\6
+\&{if} $\\{max\_strings}>\\{max\_halfword}$ \1\&{then}\5
+$\\{bad}\K15$;\2\6
+\&{if} $\\{buf\_size}>\\{max\_halfword}$ \1\&{then}\5
+$\\{bad}\K16$;\2\6
+\&{if} $(\\{max\_quarterword}-\\{min\_quarterword}<255)\V\30(\\{max\_halfword}-%
+\\{min\_halfword}<65535)$ \1\&{then}\5
+$\\{bad}\K17$;\2\par
+\fi
+
+\M155. The operation of subtracting \\{min\_halfword} occurs rather frequently
+in
+\MF, so it is convenient to abbreviate this operation by using the macro
+\\{ho} defined here. \MF\ will run faster with respect to compilers that
+don't optimize the expression `$\|x-0$', if this macro is simplified in the
+obvious way when $\\{min\_halfword}=0$. Similarly, \\{qi} and \\{qo} are used
+for
+input to and output from quarterwords.
+
+\Y\P\D \37$\\{ho}(\#)\S\#-\\{min\_halfword}$\C{to take a sixteen-bit item from
+a halfword}\par
+\P\D \37$\\{qo}(\#)\S\#-\\{min\_quarterword}$\C{to read eight bits from a
+quarterword}\par
+\P\D \37$\\{qi}(\#)\S\#+\\{min\_quarterword}$\C{to store eight bits in a
+quarterword}\par
+\fi
+
+\M156. The reader should study the following definitions closely:
+
+\Y\P\D \37$\\{sc}\S\\{int}$\C{\\{scaled} data is equivalent to \\{integer}}\par
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{quarterword}=\\{min\_quarterword}\to\\{max\_quarterword}$;\C{1/4 of a word}%
+\6
+$\\{halfword}=\\{min\_halfword}\to\\{max\_halfword}$;\C{1/2 of a word}\6
+$\\{two\_choices}=1\to2$;\C{used when there are two variants in a record}\6
+$\\{three\_choices}=1\to3$;\C{used when there are three variants in a record}\6
+$\\{two\_halves}=$\1\5
+\&{packed} \37\1\&{record} \37\\{rh}: \37\\{halfword};\2\6
+\&{case} $\\{two\_choices}$ \1\&{of}\6
+\41: \37$(\\{lh}:\\{halfword})$;\6
+\42: \37$(\\{b0}:\\{quarterword};\,\35\\{b1}:\\{quarterword})$;\2\6
+\&{end};\2\6
+$\\{four\_quarters}=$\1\5
+\&{packed} \37\1\&{record} \37\\{b0}: \37\\{quarterword};\6
+\4\\{b1}: \37\\{quarterword};\6
+\4\\{b2}: \37\\{quarterword};\6
+\4\\{b3}: \37\\{quarterword};\2\6
+\&{end};\2\6
+$\\{memory\_word}=$\1\5
+\1\&{record} \37\2\6
+\&{case} $\\{three\_choices}$ \1\&{of}\6
+\41: \37$(\\{int}:\\{integer})$;\6
+\42: \37$(\\{hh}:\\{two\_halves})$;\6
+\43: \37$(\\{qqqq}:\\{four\_quarters})$;\2\6
+\&{end};\2\6
+$\\{word\_file}=$\1\5
+\&{file} \1\&{of}\5
+\\{memory\_word};\2\2\par
+\fi
+
+\M157. When debugging, we may want to print a \\{memory\_word} without knowing
+what type it is; so we print it in all modes.
+
+\Y\P\&{debug} \37\&{procedure}\1\ \37$\\{print\_word}(\|w:\\{memory\_word})$;%
+\C{prints \|w in all ways}\2\6
+\&{begin} \37$\\{print\_int}(\|w.\\{int})$;\5
+$\\{print\_char}(\.{"\ "})$;\6
+$\\{print\_scaled}(\|w.\\{sc})$;\5
+$\\{print\_char}(\.{"\ "})$;\5
+$\\{print\_scaled}(\|w.\\{sc}\mathbin{\&{div}}\O{10000})$;\5
+\\{print\_ln};\6
+$\\{print\_int}(\|w.\\{hh}.\\{lh})$;\5
+$\\{print\_char}(\.{"="})$;\5
+$\\{print\_int}(\|w.\\{hh}.\\{b0})$;\5
+$\\{print\_char}(\.{":"})$;\5
+$\\{print\_int}(\|w.\\{hh}.\\{b1})$;\5
+$\\{print\_char}(\.{";"})$;\5
+$\\{print\_int}(\|w.\\{hh}.\\{rh})$;\5
+$\\{print\_char}(\.{"\ "})$;\6
+$\\{print\_int}(\|w.\\{qqqq}.\\{b0})$;\5
+$\\{print\_char}(\.{":"})$;\5
+$\\{print\_int}(\|w.\\{qqqq}.\\{b1})$;\5
+$\\{print\_char}(\.{":"})$;\5
+$\\{print\_int}(\|w.\\{qqqq}.\\{b2})$;\5
+$\\{print\_char}(\.{":"})$;\5
+$\\{print\_int}(\|w.\\{qqqq}.\\{b3})$;\6
+\&{end};\6
+\&{gubed}\par
+\fi
+
+\N158. \[10] Dynamic memory allocation.
+The \MF\ system does nearly all of its own memory allocation, so that it
+can readily be transported into environments that do not have automatic
+facilities for strings, garbage collection, etc., and so that it can be in
+control of what error messages the user receives. The dynamic storage
+requirements of \MF\ are handled by providing a large array \\{mem} in
+which consecutive blocks of words are used as nodes by the \MF\ routines.
+
+Pointer variables are indices into this array, or into another array
+called \\{eqtb} that will be explained later. A pointer variable might
+also be a special flag that lies outside the bounds of \\{mem}, so we
+allow pointers to assume any \\{halfword} value. The minimum memory
+index represents a null pointer.
+
+\Y\P\D \37$\\{pointer}\S\\{halfword}$\C{a flag or a location in \\{mem} or %
+\\{eqtb}}\par
+\P\D \37$\\{null}\S\\{mem\_min}$\C{the null pointer}\par
+\fi
+
+\M159. The \\{mem} array is divided into two regions that are allocated
+separately,
+but the dividing line between these two regions is not fixed; they grow
+together until finding their ``natural'' size in a particular job.
+Locations less than or equal to \\{lo\_mem\_max} are used for storing
+variable-length records consisting of two or more words each. This region
+is maintained using an algorithm similar to the one described in exercise
+2.5--19 of {\sl The Art of Computer Programming}. However, no size field
+appears in the allocated nodes; the program is responsible for knowing the
+relevant size when a node is freed. Locations greater than or equal to
+\\{hi\_mem\_min} are used for storing one-word records; a conventional
+\.{AVAIL} stack is used for allocation in this region.
+
+Locations of \\{mem} between \\{mem\_min} and \\{mem\_top} may be dumped as
+part
+of preloaded format files, by the \.{INIMF} preprocessor.
+Production versions of \MF\ may extend the memory at the top end in order to
+provide more space; these locations, between \\{mem\_top} and \\{mem\_max},
+are always used for single-word nodes.
+
+The key pointers that govern \\{mem} allocation have a prescribed order:
+$$\hbox{$\\{null}=\\{mem\_min}<\\{lo\_mem\_max}<\\{hi\_mem\_min}<\\{mem\_top}\L%
+\\{mem\_end}\L\\{mem\_max}$.}$$
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{mem}: \37\&{array} $[\\{mem\_min}\to\\{mem\_max}]$ \1\&{of}\5
+\\{memory\_word};\C{the big dynamic storage area}\2\6
+\4\\{lo\_mem\_max}: \37\\{pointer};\C{the largest location of variable-size
+memory in use}\6
+\4\\{hi\_mem\_min}: \37\\{pointer};\C{the smallest location of one-word memory
+in use}\par
+\fi
+
+\M160. Users who wish to study the memory requirements of specific applications
+can
+use optional special features that keep track of current and
+maximum memory usage. When code between the delimiters \&{stat} $\ldots$
+ \&{tats} is not ``commented out,'' \MF\ will run a bit slower but it will
+report these statistics when \\{tracing\_stats} is positive.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{var\_used},\39\\{dyn\_used}$: \37\\{integer};\C{how much memory is in
+use}\par
+\fi
+
+\M161. Let's consider the one-word memory region first, since it's the
+simplest. The pointer variable \\{mem\_end} holds the highest-numbered location
+of \\{mem} that has ever been used. The free locations of \\{mem} that
+occur between \\{hi\_mem\_min} and \\{mem\_end}, inclusive, are of type
+\\{two\_halves}, and we write $\\{info}(\|p)$ and $\\{link}(\|p)$ for the %
+\\{lh}
+and \\{rh} fields of $\\{mem}[\|p]$ when it is of this type. The single-word
+free locations form a linked list
+$$\\{avail},\;\hbox{$\\{link}(\\{avail})$},\;\hbox{$\\{link}(\\{link}(%
+\\{avail}))$},\;\ldots$$
+terminated by \\{null}.
+
+\Y\P\D \37$\\{link}(\#)\S\\{mem}[\#].\\{hh}.\\{rh}$\C{the \\{link} field of a
+memory word}\par
+\P\D \37$\\{info}(\#)\S\\{mem}[\#].\\{hh}.\\{lh}$\C{the \\{info} field of a
+memory word}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{avail}: \37\\{pointer};\C{head of the list of available one-word nodes}\6
+\4\\{mem\_end}: \37\\{pointer};\C{the last one-word node used in \\{mem}}\par
+\fi
+
+\M162. If one-word memory is exhausted, it might mean that the user has
+forgotten
+a token like `\&{enddef}' or `\&{endfor}'. We will define some procedures
+later that try to help pinpoint the trouble.
+
+\Y\P\hbox{\4}\X217:Declare the procedure called \\{show\_token\_list}\X\6
+\hbox{\4}\X665:Declare the procedure called \\{runaway}\X\par
+\fi
+
+\M163. The function \\{get\_avail} returns a pointer to a new one-word node
+whose
+\\{link} field is null. However, \MF\ will halt if there is no more room left.
+
+\Y\P\4\&{function}\1\ \37\\{get\_avail}: \37\\{pointer};\C{single-word node
+allocation}\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the new node being got}\2\6
+\&{begin} \37$\|p\K\\{avail}$;\C{get top location in the \\{avail} stack}\6
+\&{if} $\|p\I\\{null}$ \1\&{then}\5
+$\\{avail}\K\\{link}(\\{avail})$\C{and pop it off}\6
+\4\&{else} \&{if} $\\{mem\_end}<\\{mem\_max}$ \1\&{then}\C{or go into virgin
+territory}\6
+\&{begin} \37$\\{incr}(\\{mem\_end})$;\5
+$\|p\K\\{mem\_end}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{decr}(\\{hi\_mem\_min})$;\5
+$\|p\K\\{hi\_mem\_min}$;\6
+\&{if} $\\{hi\_mem\_min}\L\\{lo\_mem\_max}$ \1\&{then}\6
+\&{begin} \37\\{runaway};\C{if memory is exhausted, display possible runaway
+text}\6
+$\\{overflow}(\.{"main\ memory\ size"},\39\\{mem\_max}+1-\\{mem\_min})$;%
+\C{quit; all one-word nodes are busy}\6
+\&{end};\2\6
+\&{end};\2\2\6
+$\\{link}(\|p)\K\\{null}$;\C{provide an oft-desired initialization of the new
+node}\6
+\&{stat} \37$\\{incr}(\\{dyn\_used})$;\ \&{tats}\C{maintain statistics}\6
+$\\{get\_avail}\K\|p$;\6
+\&{end};\par
+\fi
+
+\M164. Conversely, a one-word node is recycled by calling \\{free\_avail}.
+
+\Y\P\D \37$\\{free\_avail}(\#)\S$\C{single-word node liberation}\6
+\&{begin} \37$\\{link}(\#)\K\\{avail}$;\5
+$\\{avail}\K\#$;\6
+\&{stat} \37$\\{decr}(\\{dyn\_used})$;\ \&{tats}\6
+\&{end}\par
+\fi
+
+\M165. There's also a \\{fast\_get\_avail} routine, which saves the
+procedure-call
+overhead at the expense of extra programming. This macro is used in
+the places that would otherwise account for the most calls of \\{get\_avail}.
+
+\Y\P\D \37$\\{fast\_get\_avail}(\#)\S\hbox{}$\6
+\&{begin} \37$\#\K\\{avail}$;\C{avoid \\{get\_avail} if possible, to save time}%
+\6
+\&{if} $\#=\\{null}$ \1\&{then}\5
+$\#\K\\{get\_avail}$\6
+\4\&{else} \&{begin} \37$\\{avail}\K\\{link}(\#)$;\5
+$\\{link}(\#)\K\\{null}$;\6
+\&{stat} \37$\\{incr}(\\{dyn\_used})$;\ \&{tats}\6
+\&{end};\2\6
+\&{end}\par
+\fi
+
+\M166. The available-space list that keeps track of the variable-size portion
+of \\{mem} is a nonempty, doubly-linked circular list of empty nodes,
+pointed to by the roving pointer \\{rover}.
+
+Each empty node has size 2 or more; the first word contains the special
+value \\{max\_halfword} in its \\{link} field and the size in its \\{info}
+field;
+the second word contains the two pointers for double linking.
+
+Each nonempty node also has size 2 or more. Its first word is of type
+\\{two\_halves}\kern-1pt, and its \\{link} field is never equal to \\{max%
+\_halfword}.
+Otherwise there is complete flexibility with respect to the contents
+of its other fields and its other words.
+
+(We require $\\{mem\_max}<\\{max\_halfword}$ because terrible things can happen
+when \\{max\_halfword} appears in the \\{link} field of a nonempty node.)
+
+\Y\P\D \37$\\{empty\_flag}\S\\{max\_halfword}$\C{the \\{link} of an empty
+variable-size node}\par
+\P\D \37$\\{is\_empty}(\#)\S(\\{link}(\#)=\\{empty\_flag})$\C{tests for empty
+node}\par
+\P\D \37$\\{node\_size}\S\\{info}$\C{the size field in empty variable-size
+nodes}\par
+\P\D \37$\\{llink}(\#)\S\\{info}(\#+1)$\C{left link in doubly-linked list of
+empty nodes}\par
+\P\D \37$\\{rlink}(\#)\S\\{link}(\#+1)$\C{right link in doubly-linked list of
+empty nodes}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{rover}: \37\\{pointer};\C{points to some node in the list of empties}\par
+\fi
+
+\M167. A call to \\{get\_node} with argument \|s returns a pointer to a new
+node
+of size~\|s, which must be 2~or more. The \\{link} field of the first word
+of this new node is set to null. An overflow stop occurs if no suitable
+space exists.
+
+If \\{get\_node} is called with $s=2^{30}$, it simply merges adjacent free
+areas and returns the value \\{max\_halfword}.
+
+\Y\P\4\&{function}\1\ \37$\\{get\_node}(\|s:\\{integer})$: \37\\{pointer};%
+\C{variable-size node allocation}\6
+\4\&{label} \37$\\{found},\39\\{exit},\39\\{restart}$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the node currently under inspection}\6
+\|q: \37\\{pointer};\C{the node physically after node \|p}\6
+\|r: \37\\{integer};\C{the newly allocated node, or a candidate for this honor}%
+\6
+$\|t,\39\\{tt}$: \37\\{integer};\C{temporary registers}\2\6
+\&{begin} \37\\{restart}: \37$\|p\K\\{rover}$;\C{start at some free node in the
+ring}\6
+\1\&{repeat} \37\X169:Try to allocate within node \|p and its physical
+successors, and \&{goto} \\{found} if allocation was possible\X;\6
+$\|p\K\\{rlink}(\|p)$;\C{move to the next node in the ring}\6
+\4\&{until}\5
+$\|p=\\{rover}$;\C{repeat until the whole list has been traversed}\2\6
+\&{if} $\|s=\O{10000000000}$ \1\&{then}\6
+\&{begin} \37$\\{get\_node}\K\\{max\_halfword}$;\5
+\&{return};\6
+\&{end};\2\6
+\&{if} $\\{lo\_mem\_max}+2<\\{hi\_mem\_min}$ \1\&{then}\6
+\&{if} $\\{lo\_mem\_max}+2\L\\{mem\_min}+\\{max\_halfword}$ \1\&{then}\5
+\X168:Grow more variable-size memory and \&{goto} \\{restart}\X;\2\2\6
+$\\{overflow}(\.{"main\ memory\ size"},\39\\{mem\_max}+1-\\{mem\_min})$;%
+\C{sorry, nothing satisfactory is left}\6
+\4\\{found}: \37$\\{link}(\|r)\K\\{null}$;\C{this node is now nonempty}\6
+\&{stat} \37$\\{var\_used}\K\\{var\_used}+\|s$;\C{maintain usage statistics}\6
+\&{tats}\6
+$\\{get\_node}\K\|r$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M168. The lower part of \\{mem} grows by 1000 words at a time, unless
+we are very close to going under. When it grows, we simply link
+a new node into the available-space list. This method of controlled
+growth helps to keep the \\{mem} usage consecutive when \MF\ is
+implemented on ``virtual memory'' systems.
+
+\Y\P$\4\X168:Grow more variable-size memory and \&{goto} \\{restart}\X\S$\6
+\&{begin} \37\&{if} $\\{hi\_mem\_min}-\\{lo\_mem\_max}\G1998$ \1\&{then}\5
+$\|t\K\\{lo\_mem\_max}+1000$\6
+\4\&{else} $\|t\K\\{lo\_mem\_max}+1+(\\{hi\_mem\_min}-\\{lo\_mem\_max})%
+\mathbin{\&{div}}2$;\C{$\\{lo\_mem\_max}+2\L\|t<\\{hi\_mem\_min}$}\2\6
+\&{if} $\|t>\\{mem\_min}+\\{max\_halfword}$ \1\&{then}\5
+$\|t\K\\{mem\_min}+\\{max\_halfword}$;\2\6
+$\|p\K\\{llink}(\\{rover})$;\5
+$\|q\K\\{lo\_mem\_max}$;\5
+$\\{rlink}(\|p)\K\|q$;\5
+$\\{llink}(\\{rover})\K\|q$;\6
+$\\{rlink}(\|q)\K\\{rover}$;\5
+$\\{llink}(\|q)\K\|p$;\5
+$\\{link}(\|q)\K\\{empty\_flag}$;\5
+$\\{node\_size}(\|q)\K\|t-\\{lo\_mem\_max}$;\6
+$\\{lo\_mem\_max}\K\|t$;\5
+$\\{link}(\\{lo\_mem\_max})\K\\{null}$;\5
+$\\{info}(\\{lo\_mem\_max})\K\\{null}$;\5
+$\\{rover}\K\|q$;\5
+\&{goto} \37\\{restart};\6
+\&{end}\par
+\U167.\fi
+
+\M169. \P$\X169:Try to allocate within node \|p and its physical successors,
+and \&{goto} \\{found} if allocation was possible\X\S$\6
+$\|q\K\|p+\\{node\_size}(\|p)$;\C{find the physical successor}\6
+\&{while} $\\{is\_empty}(\|q)$ \1\&{do}\C{merge node \|p with node \|q}\6
+\&{begin} \37$\|t\K\\{rlink}(\|q)$;\5
+$\\{tt}\K\\{llink}(\|q)$;\6
+\&{if} $\|q=\\{rover}$ \1\&{then}\5
+$\\{rover}\K\|t$;\2\6
+$\\{llink}(\|t)\K\\{tt}$;\5
+$\\{rlink}(\\{tt})\K\|t$;\6
+$\|q\K\|q+\\{node\_size}(\|q)$;\6
+\&{end};\2\6
+$\|r\K\|q-\|s$;\6
+\&{if} $\|r>\|p+1$ \1\&{then}\5
+\X170:Allocate from the top of node \|p and \&{goto} \\{found}\X;\2\6
+\&{if} $\|r=\|p$ \1\&{then}\6
+\&{if} $\\{rlink}(\|p)\I\|p$ \1\&{then}\5
+\X171:Allocate entire node \|p and \&{goto} \\{found}\X;\2\2\6
+$\\{node\_size}(\|p)\K\|q-\|p$\C{reset the size in case it grew}\par
+\U167.\fi
+
+\M170. \P$\X170:Allocate from the top of node \|p and \&{goto} \\{found}\X\S$\6
+\&{begin} \37$\\{node\_size}(\|p)\K\|r-\|p$;\C{store the remaining size}\6
+$\\{rover}\K\|p$;\C{start searching here next time}\6
+\&{goto} \37\\{found};\6
+\&{end}\par
+\U169.\fi
+
+\M171. Here we delete node \|p from the ring, and let \\{rover} rove around.
+
+\Y\P$\4\X171:Allocate entire node \|p and \&{goto} \\{found}\X\S$\6
+\&{begin} \37$\\{rover}\K\\{rlink}(\|p)$;\5
+$\|t\K\\{llink}(\|p)$;\5
+$\\{llink}(\\{rover})\K\|t$;\5
+$\\{rlink}(\|t)\K\\{rover}$;\5
+\&{goto} \37\\{found};\6
+\&{end}\par
+\U169.\fi
+
+\M172. Conversely, when some variable-size node \|p of size \|s is no longer
+needed,
+the operation $\\{free\_node}(\|p,\|s)$ will make its words available, by
+inserting
+\|p as a new empty node just before where \\{rover} now points.
+
+\Y\P\4\&{procedure}\1\ \37$\\{free\_node}(\|p:\\{pointer};\,\35\|s:%
+\\{halfword})$;\C{variable-size node liberation}\6
+\4\&{var} \37\|q: \37\\{pointer};\C{$\\{llink}(\\{rover})$}\2\6
+\&{begin} \37$\\{node\_size}(\|p)\K\|s$;\5
+$\\{link}(\|p)\K\\{empty\_flag}$;\5
+$\|q\K\\{llink}(\\{rover})$;\5
+$\\{llink}(\|p)\K\|q$;\5
+$\\{rlink}(\|p)\K\\{rover}$;\C{set both links}\6
+$\\{llink}(\\{rover})\K\|p$;\5
+$\\{rlink}(\|q)\K\|p$;\C{insert \|p into the ring}\6
+\&{stat} \37$\\{var\_used}\K\\{var\_used}-\|s$;\ \&{tats}\C{maintain
+statistics}\6
+\&{end};\par
+\fi
+
+\M173. Just before \.{INIMF} writes out the memory, it sorts the doubly linked
+available space list. The list is probably very short at such times, so a
+simple insertion sort is used. The smallest available location will be
+pointed to by \\{rover}, the next-smallest by $\\{rlink}(\\{rover})$, etc.
+
+\Y\P\&{init} \37\&{procedure}\1\ \37\\{sort\_avail};\C{sorts the available
+variable-size nodes by location}\6
+\4\&{var} \37$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{indices into \\{mem}}\6
+\\{old\_rover}: \37\\{pointer};\C{initial \\{rover} setting}\2\6
+\&{begin} \37$\|p\K\\{get\_node}(\O{10000000000})$;\C{merge adjacent free
+areas}\6
+$\|p\K\\{rlink}(\\{rover})$;\5
+$\\{rlink}(\\{rover})\K\\{max\_halfword}$;\5
+$\\{old\_rover}\K\\{rover}$;\6
+\&{while} $\|p\I\\{old\_rover}$ \1\&{do}\5
+\X174:Sort \|p into the list starting at \\{rover} and advance \|p to $%
+\\{rlink}(\|p)$\X;\2\6
+$\|p\K\\{rover}$;\6
+\&{while} $\\{rlink}(\|p)\I\\{max\_halfword}$ \1\&{do}\6
+\&{begin} \37$\\{llink}(\\{rlink}(\|p))\K\|p$;\5
+$\|p\K\\{rlink}(\|p)$;\6
+\&{end};\2\6
+$\\{rlink}(\|p)\K\\{rover}$;\5
+$\\{llink}(\\{rover})\K\|p$;\6
+\&{end};\6
+\&{tini}\par
+\fi
+
+\M174. The following \&{while} loop is guaranteed to
+terminate, since the list that starts at
+\\{rover} ends with \\{max\_halfword} during the sorting procedure.
+
+\Y\P$\4\X174:Sort \|p into the list starting at \\{rover} and advance \|p to $%
+\\{rlink}(\|p)$\X\S$\6
+\&{if} $\|p<\\{rover}$ \1\&{then}\6
+\&{begin} \37$\|q\K\|p$;\5
+$\|p\K\\{rlink}(\|q)$;\5
+$\\{rlink}(\|q)\K\\{rover}$;\5
+$\\{rover}\K\|q$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|q\K\\{rover}$;\6
+\&{while} $\\{rlink}(\|q)<\|p$ \1\&{do}\5
+$\|q\K\\{rlink}(\|q)$;\2\6
+$\|r\K\\{rlink}(\|p)$;\5
+$\\{rlink}(\|p)\K\\{rlink}(\|q)$;\5
+$\\{rlink}(\|q)\K\|p$;\5
+$\|p\K\|r$;\6
+\&{end}\2\par
+\U173.\fi
+
+\N175. \[11] Memory layout.
+Some areas of \\{mem} are dedicated to fixed usage, since static allocation is
+more efficient than dynamic allocation when we can get away with it. For
+example, locations \\{mem\_min} to $\\{mem\_min}+2$ are always used to store
+the
+specification for null pen coordinates that are `$(0,0)$'. The
+following macro definitions accomplish the static allocation by giving
+symbolic names to the fixed positions. Static variable-size nodes appear
+in locations \\{mem\_min} through \\{lo\_mem\_stat\_max}, and static
+single-word nodes
+appear in locations \\{hi\_mem\_stat\_min} through \\{mem\_top}, inclusive.
+
+\Y\P\D \37$\\{null\_coords}\S\\{mem\_min}$\C{specification for pen offsets of
+$(0,0)$}\par
+\P\D \37$\\{null\_pen}\S\\{null\_coords}+3$\C{we will define $\\{coord\_node%
+\_size}=3$}\par
+\P\D \37$\\{dep\_head}\S\\{null\_pen}+10$\C{and $\\{pen\_node\_size}=10$}\par
+\P\D \37$\\{zero\_val}\S\\{dep\_head}+2$\C{two words for a permanently zero
+value}\par
+\P\D \37$\\{temp\_val}\S\\{zero\_val}+2$\C{two words for a temporary value
+node}\par
+\P\D \37$\\{end\_attr}\S\\{temp\_val}$\C{we use $\\{end\_attr}+2$ only}\par
+\P\D \37$\\{inf\_val}\S\\{end\_attr}+2$\C{and $\\{inf\_val}+1$ only}\par
+\P\D \37$\\{bad\_vardef}\S\\{inf\_val}+2$\C{two words for \&{vardef} error
+recovery}\par
+\P\D \37$\\{lo\_mem\_stat\_max}\S\\{bad\_vardef}+1$\C{largest statically
+allocated word in the variable-size \\{mem}}\Y\par
+\P\D \37$\\{sentinel}\S\\{mem\_top}$\C{end of sorted lists}\par
+\P\D \37$\\{temp\_head}\S\\{mem\_top}-1$\C{head of a temporary list of some
+kind}\par
+\P\D \37$\\{hold\_head}\S\\{mem\_top}-2$\C{head of a temporary list of another
+kind}\par
+\P\D \37$\\{hi\_mem\_stat\_min}\S\\{mem\_top}-2$\C{smallest statically
+allocated word in the one-word \\{mem}}\par
+\fi
+
+\M176. The following code gets the dynamic part of \\{mem} off to a good start,
+when \MF\ is initializing itself the slow way.
+
+\Y\P$\4\X176:Initialize table entries (done by \.{INIMF} only)\X\S$\6
+$\\{rover}\K\\{lo\_mem\_stat\_max}+1$;\C{initialize the dynamic memory}\6
+$\\{link}(\\{rover})\K\\{empty\_flag}$;\5
+$\\{node\_size}(\\{rover})\K1000$;\C{which is a 1000-word available node}\6
+$\\{llink}(\\{rover})\K\\{rover}$;\5
+$\\{rlink}(\\{rover})\K\\{rover}$;\6
+$\\{lo\_mem\_max}\K\\{rover}+1000$;\5
+$\\{link}(\\{lo\_mem\_max})\K\\{null}$;\5
+$\\{info}(\\{lo\_mem\_max})\K\\{null}$;\6
+\&{for} $\|k\K\\{hi\_mem\_stat\_min}\mathrel{\&{to}}\\{mem\_top}$ \1\&{do}\5
+$\\{mem}[\|k]\K\\{mem}[\\{lo\_mem\_max}]$;\C{clear list heads}\2\6
+$\\{avail}\K\\{null}$;\5
+$\\{mem\_end}\K\\{mem\_top}$;\5
+$\\{hi\_mem\_min}\K\\{hi\_mem\_stat\_min}$;\C{initialize the one-word memory}\6
+$\\{var\_used}\K\\{lo\_mem\_stat\_max}+1-\\{mem\_min}$;\5
+$\\{dyn\_used}\K\\{mem\_top}+1-\\{hi\_mem\_min}$;\C{initialize statistics}\par
+\As193, 203, 229, 324, 475, 587, 702, 759, 911, 1116, 1127\ETs1185.
+\U1210.\fi
+
+\M177. The procedure $\\{flush\_list}(\|p)$ frees an entire linked list of
+one-word
+nodes that starts at a given position, until coming to \\{sentinel} or a
+pointer that is not in the one-word region. Another procedure,
+\\{flush\_node\_list}, frees an entire linked list of one-word and two-word
+nodes, until coming to a \\{null} pointer.
+
+\Y\P\4\&{procedure}\1\ \37$\\{flush\_list}(\|p:\\{pointer})$;\C{makes list of
+single-word nodes available}\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\|q,\39\|r$: \37\\{pointer};\C{list traversers}\2\6
+\&{begin} \37\&{if} $\|p\G\\{hi\_mem\_min}$ \1\&{then}\6
+\&{if} $\|p\I\\{sentinel}$ \1\&{then}\6
+\&{begin} \37$\|r\K\|p$;\6
+\1\&{repeat} \37$\|q\K\|r$;\5
+$\|r\K\\{link}(\|r)$;\6
+\&{stat} \37$\\{decr}(\\{dyn\_used})$;\ \&{tats}\6
+\&{if} $\|r<\\{hi\_mem\_min}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\4\&{until}\5
+$\|r=\\{sentinel}$;\2\6
+\4\\{done}: \37\C{now \|q is the last node on the list}\6
+$\\{link}(\|q)\K\\{avail}$;\5
+$\\{avail}\K\|p$;\6
+\&{end};\2\2\6
+\&{end};\7
+\4\&{procedure}\1\ \37$\\{flush\_node\_list}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the node being recycled}\2\6
+\&{begin} \37\&{while} $\|p\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\|q\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{if} $\|q<\\{hi\_mem\_min}$ \1\&{then}\5
+$\\{free\_node}(\|q,\392)$\ \&{else} $\\{free\_avail}(\|q)$;\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M178. If \MF\ is extended improperly, the \\{mem} array might get screwed up.
+For example, some pointers might be wrong, or some ``dead'' nodes might not
+have been freed when the last reference to them disappeared. Procedures
+\\{check\_mem} and \\{search\_mem} are available to help diagnose such
+problems. These procedures make use of two arrays called \\{free} and
+\\{was\_free} that are present only if \MF's debugging routines have
+been included. (You may want to decrease the size of \\{mem} while you
+are debugging.)
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\&{debug} \37\\{free}: \37\&{packed} \37\&{array} $[\\{mem\_min}\to\\{mem%
+\_max}]$ \1\&{of}\5
+\\{boolean};\C{free cells}\2\6
+\4\hbox{\hskip1em}\\{was\_free}: \37\&{packed} \37\&{array} $[\\{mem\_min}\to%
+\\{mem\_max}]$ \1\&{of}\5
+\\{boolean};\C{previously free cells}\2\6
+\4$\hbox{\hskip1em}\\{was\_mem\_end},\39\\{was\_lo\_max},\39\\{was\_hi\_min}$: %
+\37\\{pointer};\C{previous \\{mem\_end}, \\{lo\_mem\_max}, and \\{hi\_mem%
+\_min}}\6
+\4\hbox{\hskip1em}\\{panicking}: \37\\{boolean};\C{do we want to check memory
+constantly?}\6
+\&{gubed}\par
+\fi
+
+\M179. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+\&{debug} \37$\\{was\_mem\_end}\K\\{mem\_min}$;\C{indicate that everything was
+previously free}\6
+$\\{was\_lo\_max}\K\\{mem\_min}$;\5
+$\\{was\_hi\_min}\K\\{mem\_max}$;\5
+$\\{panicking}\K\\{false}$;\6
+\&{gubed}\par
+\fi
+
+\M180. Procedure \\{check\_mem} makes sure that the available space lists of
+\\{mem} are well formed, and it optionally prints out all locations
+that are reserved now but were free the last time this procedure was called.
+
+\Y\P\&{debug} \37\&{procedure}\1\ \37$\\{check\_mem}(\\{print\_locs}:%
+\\{boolean})$;\6
+\4\&{label} \37$\\{done1},\39\\{done2}$;\C{loop exits}\6
+\4\&{var} \37$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{current locations of
+interest in \\{mem}}\6
+\\{clobbered}: \37\\{boolean};\C{is something amiss?}\2\6
+\&{begin} \37\&{for} $\|p\K\\{mem\_min}\mathrel{\&{to}}\\{lo\_mem\_max}$ \1%
+\&{do}\5
+$\\{free}[\|p]\K\\{false}$;\C{you can probably do this faster}\2\6
+\&{for} $\|p\K\\{hi\_mem\_min}\mathrel{\&{to}}\\{mem\_end}$ \1\&{do}\5
+$\\{free}[\|p]\K\\{false}$;\C{ditto}\2\6
+\X181:Check single-word \\{avail} list\X;\6
+\X182:Check variable-size \\{avail} list\X;\6
+\X183:Check flags of unavailable nodes\X;\6
+\X617:Check the list of linear dependencies\X;\6
+\&{if} $\\{print\_locs}$ \1\&{then}\5
+\X184:Print newly busy locations\X;\2\6
+\&{for} $\|p\K\\{mem\_min}\mathrel{\&{to}}\\{lo\_mem\_max}$ \1\&{do}\5
+$\\{was\_free}[\|p]\K\\{free}[\|p]$;\2\6
+\&{for} $\|p\K\\{hi\_mem\_min}\mathrel{\&{to}}\\{mem\_end}$ \1\&{do}\5
+$\\{was\_free}[\|p]\K\\{free}[\|p]$;\C{$\\{was\_free}\K\\{free}$ might be
+faster}\2\6
+$\\{was\_mem\_end}\K\\{mem\_end}$;\5
+$\\{was\_lo\_max}\K\\{lo\_mem\_max}$;\5
+$\\{was\_hi\_min}\K\\{hi\_mem\_min}$;\6
+\&{end};\6
+\&{gubed}\par
+\fi
+
+\M181. \P$\X181:Check single-word \\{avail} list\X\S$\6
+$\|p\K\\{avail}$;\5
+$\|q\K\\{null}$;\5
+$\\{clobbered}\K\\{false}$;\6
+\&{while} $\|p\I\\{null}$ \1\&{do}\6
+\&{begin} \37\&{if} $(\|p>\\{mem\_end})\V(\|p<\\{hi\_mem\_min})$ \1\&{then}\5
+$\\{clobbered}\K\\{true}$\6
+\4\&{else} \&{if} $\\{free}[\|p]$ \1\&{then}\5
+$\\{clobbered}\K\\{true}$;\2\2\6
+\&{if} $\\{clobbered}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"AVAIL\ list\ clobbered\ at\ "})$;\5
+$\\{print\_int}(\|q)$;\5
+\&{goto} \37\\{done1};\6
+\&{end};\2\6
+$\\{free}[\|p]\K\\{true}$;\5
+$\|q\K\|p$;\5
+$\|p\K\\{link}(\|q)$;\6
+\&{end};\2\6
+\4\\{done1}: \37\par
+\U180.\fi
+
+\M182. \P$\X182:Check variable-size \\{avail} list\X\S$\6
+$\|p\K\\{rover}$;\5
+$\|q\K\\{null}$;\5
+$\\{clobbered}\K\\{false}$;\6
+\1\&{repeat} \37\&{if} $(\|p\G\\{lo\_mem\_max})\V(\|p<\\{mem\_min})$ \1\&{then}%
+\5
+$\\{clobbered}\K\\{true}$\6
+\4\&{else} \&{if} $(\\{rlink}(\|p)\G\\{lo\_mem\_max})\V(\\{rlink}(\|p)<\\{mem%
+\_min})$ \1\&{then}\5
+$\\{clobbered}\K\\{true}$\6
+\4\&{else} \&{if} $\R(\\{is\_empty}(\|p))\V(\\{node\_size}(\|p)<2)\V\30(\|p+%
+\\{node\_size}(\|p)>\\{lo\_mem\_max})\V\30(\\{llink}(\\{rlink}(\|p))\I\|p)$ \1%
+\&{then}\5
+$\\{clobbered}\K\\{true}$;\2\2\2\6
+\&{if} $\\{clobbered}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"Double-AVAIL\ list\ clobbered\ at\ "})$;\5
+$\\{print\_int}(\|q)$;\5
+\&{goto} \37\\{done2};\6
+\&{end};\2\6
+\&{for} $\|q\K\|p\mathrel{\&{to}}\|p+\\{node\_size}(\|p)-1$ \1\&{do}\C{mark all
+locations free}\6
+\&{begin} \37\&{if} $\\{free}[\|q]$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"Doubly\ free\ location\ at\ "})$;\5
+$\\{print\_int}(\|q)$;\5
+\&{goto} \37\\{done2};\6
+\&{end};\2\6
+$\\{free}[\|q]\K\\{true}$;\6
+\&{end};\2\6
+$\|q\K\|p$;\5
+$\|p\K\\{rlink}(\|p)$;\6
+\4\&{until}\5
+$\|p=\\{rover}$;\2\6
+\4\\{done2}: \37\par
+\U180.\fi
+
+\M183. \P$\X183:Check flags of unavailable nodes\X\S$\6
+$\|p\K\\{mem\_min}$;\6
+\&{while} $\|p\L\\{lo\_mem\_max}$ \1\&{do}\C{node \|p should not be empty}\6
+\&{begin} \37\&{if} $\\{is\_empty}(\|p)$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"Bad\ flag\ at\ "})$;\5
+$\\{print\_int}(\|p)$;\6
+\&{end};\2\6
+\&{while} $(\|p\L\\{lo\_mem\_max})\W\R\\{free}[\|p]$ \1\&{do}\5
+$\\{incr}(\|p)$;\2\6
+\&{while} $(\|p\L\\{lo\_mem\_max})\W\\{free}[\|p]$ \1\&{do}\5
+$\\{incr}(\|p)$;\2\6
+\&{end}\2\par
+\U180.\fi
+
+\M184. \P$\X184:Print newly busy locations\X\S$\6
+\&{begin} \37$\\{print\_nl}(\.{"New\ busy\ locs:"})$;\6
+\&{for} $\|p\K\\{mem\_min}\mathrel{\&{to}}\\{lo\_mem\_max}$ \1\&{do}\6
+\&{if} $\R\\{free}[\|p]\W((\|p>\\{was\_lo\_max})\V\\{was\_free}[\|p])$ \1%
+\&{then}\6
+\&{begin} \37$\\{print\_char}(\.{"\ "})$;\5
+$\\{print\_int}(\|p)$;\6
+\&{end};\2\2\6
+\&{for} $\|p\K\\{hi\_mem\_min}\mathrel{\&{to}}\\{mem\_end}$ \1\&{do}\6
+\&{if} $\R\\{free}[\|p]\W((\|p<\\{was\_hi\_min})\V(\|p>\\{was\_mem\_end})\V%
+\\{was\_free}[\|p])$ \1\&{then}\6
+\&{begin} \37$\\{print\_char}(\.{"\ "})$;\5
+$\\{print\_int}(\|p)$;\6
+\&{end};\2\2\6
+\&{end}\par
+\U180.\fi
+
+\M185. The \\{search\_mem} procedure attempts to answer the question ``Who
+points
+to node~\|p?'' In doing so, it fetches \\{link} and \\{info} fields of \\{mem}
+that might not be of type \\{two\_halves}. Strictly speaking, this is
+undefined in \PASCAL, and it can lead to ``false drops'' (words that seem to
+point to \|p purely by coincidence). But for debugging purposes, we want
+to rule out the places that do {\sl not\/} point to \|p, so a few false
+drops are tolerable.
+
+\Y\P\&{debug} \37\&{procedure}\1\ \37$\\{search\_mem}(\|p:\\{pointer})$;%
+\C{look for pointers to \|p}\6
+\4\&{var} \37\|q: \37\\{integer};\C{current position being searched}\2\6
+\&{begin} \37\&{for} $\|q\K\\{mem\_min}\mathrel{\&{to}}\\{lo\_mem\_max}$ \1%
+\&{do}\6
+\&{begin} \37\&{if} $\\{link}(\|q)=\|p$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"LINK("})$;\5
+$\\{print\_int}(\|q)$;\5
+$\\{print\_char}(\.{")"})$;\6
+\&{end};\2\6
+\&{if} $\\{info}(\|q)=\|p$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"INFO("})$;\5
+$\\{print\_int}(\|q)$;\5
+$\\{print\_char}(\.{")"})$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{for} $\|q\K\\{hi\_mem\_min}\mathrel{\&{to}}\\{mem\_end}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{link}(\|q)=\|p$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"LINK("})$;\5
+$\\{print\_int}(\|q)$;\5
+$\\{print\_char}(\.{")"})$;\6
+\&{end};\2\6
+\&{if} $\\{info}(\|q)=\|p$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"INFO("})$;\5
+$\\{print\_int}(\|q)$;\5
+$\\{print\_char}(\.{")"})$;\6
+\&{end};\2\6
+\&{end};\2\6
+\X209:Search \\{eqtb} for equivalents equal to \|p\X;\6
+\&{end};\6
+\&{gubed}\par
+\fi
+
+\N186. \[12] The command codes.
+Before we can go much further, we need to define symbolic names for the
+internal
+code numbers that represent the various commands obeyed by \MF. These codes
+are somewhat arbitrary, but not completely so. For example,
+some codes have been made adjacent so that \&{case} statements in the
+program need not consider cases that are widely spaced, or so that \&{case}
+statements can be replaced by \&{if} statements. A command can begin an
+expression if and only if its code lies between \\{min\_primary\_command} and
+\\{max\_primary\_command}, inclusive. The first token of a statement that
+doesn't
+begin with an expression has a command code between \\{min\_command} and
+\\{max\_statement\_command}, inclusive. The ordering of the highest-numbered
+commands ($\\{comma}<\\{semicolon}<\\{end\_group}<\\{stop}$) is crucial for the
+parsing
+and error-recovery methods of this program.
+
+At any rate, here is the list, for future reference.
+
+\Y\P\D \37$\\{if\_test}=1$\C{conditional text (\&{if})}\par
+\P\D \37$\\{fi\_or\_else}=2$\C{delimiters for conditionals (\&{elseif}, %
+\&{else}, \&{fi}}\par
+\P\D \37$\\{input}=3$\C{input a source file (\&{input}, \&{endinput})}\par
+\P\D \37$\\{iteration}=4$\C{iterate (\&{for}, \&{forsuffixes}, \&{forever}, %
+\&{endfor})}\par
+\P\D \37$\\{repeat\_loop}=5$\C{special command substituted for \&{endfor}}\par
+\P\D \37$\\{exit\_test}=6$\C{premature exit from a loop (\&{exitif})}\par
+\P\D \37$\\{relax}=7$\C{do nothing (\.{\char`\\})}\par
+\P\D \37$\\{scan\_tokens}=8$\C{put a string into the input buffer}\par
+\P\D \37$\\{expand\_after}=9$\C{look ahead one token}\par
+\P\D \37$\\{defined\_macro}=10$\C{a macro defined by the user}\par
+\P\D \37$\\{min\_command}=\\{defined\_macro}+1$\par
+\P\D \37$\\{display\_command}=11$\C{online graphic output (\&{display})}\par
+\P\D \37$\\{save\_command}=12$\C{save a list of tokens (\&{save})}\par
+\P\D \37$\\{interim\_command}=13$\C{save an internal quantity (\&{interim})}\par
+\P\D \37$\\{let\_command}=14$\C{redefine a symbolic token (\&{let})}\par
+\P\D \37$\\{new\_internal}=15$\C{define a new internal quantity (%
+\&{newinternal})}\par
+\P\D \37$\\{macro\_def}=16$\C{define a macro (\&{def}, \&{vardef}, etc.)}\par
+\P\D \37$\\{ship\_out\_command}=17$\C{output a character (\&{shipout})}\par
+\P\D \37$\\{add\_to\_command}=18$\C{add to edges (\&{addto})}\par
+\P\D \37$\\{cull\_command}=19$\C{cull and normalize edges (\&{cull})}\par
+\P\D \37$\\{tfm\_command}=20$\C{command for font metric info (\&{ligtable},
+etc.)}\par
+\P\D \37$\\{protection\_command}=21$\C{set protection flag (\&{outer}, %
+\&{inner})}\par
+\P\D \37$\\{show\_command}=22$\C{diagnostic output (\&{show}, \&{showvariable},
+etc.)}\par
+\P\D \37$\\{mode\_command}=23$\C{set interaction level (\&{batchmode}, etc.)}%
+\par
+\P\D \37$\\{random\_seed}=24$\C{initialize random number generator (%
+\&{randomseed})}\par
+\P\D \37$\\{message\_command}=25$\C{communicate to user (\&{message}, %
+\&{errmessage})}\par
+\P\D \37$\\{every\_job\_command}=26$\C{designate a starting token (%
+\&{everyjob})}\par
+\P\D \37$\\{delimiters}=27$\C{define a pair of delimiters (\&{delimiters})}\par
+\P\D \37$\\{open\_window}=28$\C{define a window on the screen (\&{openwindow})}%
+\par
+\P\D \37$\\{special\_command}=29$\C{output special info (\&{special}, %
+\&{numspecial})}\par
+\P\D \37$\\{type\_name}=30$\C{declare a type (\&{numeric}, \&{pair}, etc.}\par
+\P\D \37$\\{max\_statement\_command}=\\{type\_name}$\par
+\P\D \37$\\{min\_primary\_command}=\\{type\_name}$\par
+\P\D \37$\\{left\_delimiter}=31$\C{the left delimiter of a matching pair}\par
+\P\D \37$\\{begin\_group}=32$\C{beginning of a group (\&{begingroup})}\par
+\P\D \37$\\{nullary}=33$\C{an operator without arguments (e.g., %
+\&{normaldeviate})}\par
+\P\D \37$\\{unary}=34$\C{an operator with one argument (e.g., \&{sqrt})}\par
+\P\D \37$\\{str\_op}=35$\C{convert a suffix to a string (\&{str})}\par
+\P\D \37$\\{cycle}=36$\C{close a cyclic path (\&{cycle})}\par
+\P\D \37$\\{primary\_binary}=37$\C{binary operation taking `\&{of}' (e.g., %
+\&{point})}\par
+\P\D \37$\\{capsule\_token}=38$\C{a value that has been put into a token list}%
+\par
+\P\D \37$\\{string\_token}=39$\C{a string constant (e.g., \.{"hello"})}\par
+\P\D \37$\\{internal\_quantity}=40$\C{internal numeric parameter (e.g., %
+\&{pausing})}\par
+\P\D \37$\\{min\_suffix\_token}=\\{internal\_quantity}$\par
+\P\D \37$\\{tag\_token}=41$\C{a symbolic token without a primitive meaning}\par
+\P\D \37$\\{numeric\_token}=42$\C{a numeric constant (e.g., \.{3.14159})}\par
+\P\D \37$\\{max\_suffix\_token}=\\{numeric\_token}$\par
+\P\D \37$\\{plus\_or\_minus}=43$\C{either `\.+' or `\.-'}\par
+\P\D \37$\\{max\_primary\_command}=\\{plus\_or\_minus}$\C{should also be $%
+\\{numeric\_token}+1$}\par
+\P\D \37$\\{min\_tertiary\_command}=\\{plus\_or\_minus}$\par
+\P\D \37$\\{tertiary\_secondary\_macro}=44$\C{a macro defined by %
+\&{secondarydef}}\par
+\P\D \37$\\{tertiary\_binary}=45$\C{an operator at the tertiary level (e.g., `%
+\.{++}')}\par
+\P\D \37$\\{max\_tertiary\_command}=\\{tertiary\_binary}$\par
+\P\D \37$\\{left\_brace}=46$\C{the operator `\.{\char`\{}'}\par
+\P\D \37$\\{min\_expression\_command}=\\{left\_brace}$\par
+\P\D \37$\\{path\_join}=47$\C{the operator `\.{..}'}\par
+\P\D \37$\\{ampersand}=48$\C{the operator `\.\&'}\par
+\P\D \37$\\{expression\_tertiary\_macro}=49$\C{a macro defined by %
+\&{tertiarydef}}\par
+\P\D \37$\\{expression\_binary}=50$\C{an operator at the expression level
+(e.g., `\.<')}\par
+\P\D \37$\\{equals}=51$\C{the operator `\.='}\par
+\P\D \37$\\{max\_expression\_command}=\\{equals}$\par
+\P\D \37$\\{and\_command}=52$\C{the operator `\&{and}'}\par
+\P\D \37$\\{min\_secondary\_command}=\\{and\_command}$\par
+\P\D \37$\\{secondary\_primary\_macro}=53$\C{a macro defined by \&{primarydef}}%
+\par
+\P\D \37$\\{slash}=54$\C{the operator `\./'}\par
+\P\D \37$\\{secondary\_binary}=55$\C{an operator at the binary level (e.g., %
+\&{shifted})}\par
+\P\D \37$\\{max\_secondary\_command}=\\{secondary\_binary}$\par
+\P\D \37$\\{param\_type}=56$\C{type of parameter (\&{primary}, \&{expr}, %
+\&{suffix}, etc.)}\par
+\P\D \37$\\{controls}=57$\C{specify control points explicitly (\&{controls})}%
+\par
+\P\D \37$\\{tension}=58$\C{specify tension between knots (\&{tension})}\par
+\P\D \37$\\{at\_least}=59$\C{bounded tension value (\&{atleast})}\par
+\P\D \37$\\{curl\_command}=60$\C{specify curl at an end knot (\&{curl})}\par
+\P\D \37$\\{macro\_special}=61$\C{special macro operators (\&{quote}, \.{\#%
+\AT!}, etc.)}\par
+\P\D \37$\\{right\_delimiter}=62$\C{the right delimiter of a matching pair}\par
+\P\D \37$\\{left\_bracket}=63$\C{the operator `\.['}\par
+\P\D \37$\\{right\_bracket}=64$\C{the operator `\.]'}\par
+\P\D \37$\\{right\_brace}=65$\C{the operator `\.{\char`\}}'}\par
+\P\D \37$\\{with\_option}=66$\C{option for filling (\&{withpen}, %
+\&{withweight})}\par
+\P\D \37$\\{cull\_op}=67$\C{the operator `\&{keeping}' or `\&{dropping}'}\par
+\P\D \37$\\{thing\_to\_add}=68$\C{variant of \&{addto} (\&{contour}, %
+\&{doublepath}, \&{also})}\par
+\P\D \37$\\{of\_token}=69$\C{the operator `\&{of}'}\par
+\P\D \37$\\{from\_token}=70$\C{the operator `\&{from}'}\par
+\P\D \37$\\{to\_token}=71$\C{the operator `\&{to}'}\par
+\P\D \37$\\{at\_token}=72$\C{the operator `\&{at}'}\par
+\P\D \37$\\{in\_window}=73$\C{the operator `\&{inwindow}'}\par
+\P\D \37$\\{step\_token}=74$\C{the operator `\&{step}'}\par
+\P\D \37$\\{until\_token}=75$\C{the operator `\&{until}'}\par
+\P\D \37$\\{lig\_kern\_token}=76$\C{the operators `\&{kern}' and `\.{=:}' and `%
+\.{=:\char'174}, etc.}\par
+\P\D \37$\\{assignment}=77$\C{the operator `\.{:=}'}\par
+\P\D \37$\\{skip\_to}=78$\C{the operation `\&{skipto}'}\par
+\P\D \37$\\{bchar\_label}=79$\C{the operator `\.{\char'174\char'174:}'}\par
+\P\D \37$\\{double\_colon}=80$\C{the operator `\.{::}'}\par
+\P\D \37$\\{colon}=81$\C{the operator `\.:'}\Y\par
+\P\D \37$\\{comma}=82$\C{the operator `\.,', must be $\\{colon}+1$}\par
+\P\D \37$\\{end\_of\_statement}\S\\{cur\_cmd}>\\{comma}$\par
+\P\D \37$\\{semicolon}=83$\C{the operator `\.;', must be $\\{comma}+1$}\par
+\P\D \37$\\{end\_group}=84$\C{end a group (\&{endgroup}), must be $%
+\\{semicolon}+1$}\par
+\P\D \37$\\{stop}=85$\C{end a job (\&{end}, \&{dump}), must be $\\{end%
+\_group}+1$}\par
+\P\D \37$\\{max\_command\_code}=\\{stop}$\par
+\P\D \37$\\{outer\_tag}=\\{max\_command\_code}+1$\C{protection code added to
+command code}\par
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{command\_code}=1\to\\{max\_command\_code}$;\par
+\fi
+
+\M187. Variables and capsules in \MF\ have a variety of ``types,''
+distinguished by the following code numbers:
+
+\Y\P\D \37$\\{undefined}=0$\C{no type has been declared}\par
+\P\D \37$\\{unknown\_tag}=1$\C{this constant is added to certain type codes
+below}\par
+\P\D \37$\\{vacuous}=1$\C{no expression was present}\par
+\P\D \37$\\{boolean\_type}=2$\C{\&{boolean} with a known value}\par
+\P\D \37$\\{unknown\_boolean}=\\{boolean\_type}+\\{unknown\_tag}$\par
+\P\D \37$\\{string\_type}=4$\C{\&{string} with a known value}\par
+\P\D \37$\\{unknown\_string}=\\{string\_type}+\\{unknown\_tag}$\par
+\P\D \37$\\{pen\_type}=6$\C{\&{pen} with a known value}\par
+\P\D \37$\\{unknown\_pen}=\\{pen\_type}+\\{unknown\_tag}$\par
+\P\D \37$\\{future\_pen}=8$\C{subexpression that will become a \&{pen} at a
+higher level}\par
+\P\D \37$\\{path\_type}=9$\C{\&{path} with a known value}\par
+\P\D \37$\\{unknown\_path}=\\{path\_type}+\\{unknown\_tag}$\par
+\P\D \37$\\{picture\_type}=11$\C{\&{picture} with a known value}\par
+\P\D \37$\\{unknown\_picture}=\\{picture\_type}+\\{unknown\_tag}$\par
+\P\D \37$\\{transform\_type}=13$\C{\&{transform} variable or capsule}\par
+\P\D \37$\\{pair\_type}=14$\C{\&{pair} variable or capsule}\par
+\P\D \37$\\{numeric\_type}=15$\C{variable that has been declared \&{numeric}
+but not used}\par
+\P\D \37$\\{known}=16$\C{\&{numeric} with a known value}\par
+\P\D \37$\\{dependent}=17$\C{a linear combination with \\{fraction}
+coefficients}\par
+\P\D \37$\\{proto\_dependent}=18$\C{a linear combination with \\{scaled}
+coefficients}\par
+\P\D \37$\\{independent}=19$\C{\&{numeric} with unknown value}\par
+\P\D \37$\\{token\_list}=20$\C{variable name or suffix argument or text
+argument}\par
+\P\D \37$\\{structured}=21$\C{variable with subscripts and attributes}\par
+\P\D \37$\\{unsuffixed\_macro}=22$\C{variable defined with \&{vardef} but no %
+\.{\AT!\#}}\par
+\P\D \37$\\{suffixed\_macro}=23$\C{variable defined with \&{vardef} and \.{\AT!%
+\#}}\Y\par
+\P\D \37$\\{unknown\_types}\S\\{unknown\_boolean},\39\\{unknown\_string},\39%
+\\{unknown\_pen},\39\\{unknown\_picture},\39\\{unknown\_path}$\par
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_type}(\|t:\\{small\_number})$;\2\6
+\&{begin} \37\&{case} $\|t$ \1\&{of}\6
+\4\\{vacuous}: \37$\\{print}(\.{"vacuous"})$;\6
+\4\\{boolean\_type}: \37$\\{print}(\.{"boolean"})$;\6
+\4\\{unknown\_boolean}: \37$\\{print}(\.{"unknown\ boolean"})$;\6
+\4\\{string\_type}: \37$\\{print}(\.{"string"})$;\6
+\4\\{unknown\_string}: \37$\\{print}(\.{"unknown\ string"})$;\6
+\4\\{pen\_type}: \37$\\{print}(\.{"pen"})$;\6
+\4\\{unknown\_pen}: \37$\\{print}(\.{"unknown\ pen"})$;\6
+\4\\{future\_pen}: \37$\\{print}(\.{"future\ pen"})$;\6
+\4\\{path\_type}: \37$\\{print}(\.{"path"})$;\6
+\4\\{unknown\_path}: \37$\\{print}(\.{"unknown\ path"})$;\6
+\4\\{picture\_type}: \37$\\{print}(\.{"picture"})$;\6
+\4\\{unknown\_picture}: \37$\\{print}(\.{"unknown\ picture"})$;\6
+\4\\{transform\_type}: \37$\\{print}(\.{"transform"})$;\6
+\4\\{pair\_type}: \37$\\{print}(\.{"pair"})$;\6
+\4\\{known}: \37$\\{print}(\.{"known\ numeric"})$;\6
+\4\\{dependent}: \37$\\{print}(\.{"dependent"})$;\6
+\4\\{proto\_dependent}: \37$\\{print}(\.{"proto-dependent"})$;\6
+\4\\{numeric\_type}: \37$\\{print}(\.{"numeric"})$;\6
+\4\\{independent}: \37$\\{print}(\.{"independent"})$;\6
+\4\\{token\_list}: \37$\\{print}(\.{"token\ list"})$;\6
+\4\\{structured}: \37$\\{print}(\.{"structured"})$;\6
+\4\\{unsuffixed\_macro}: \37$\\{print}(\.{"unsuffixed\ macro"})$;\6
+\4\\{suffixed\_macro}: \37$\\{print}(\.{"suffixed\ macro"})$;\6
+\4\&{othercases} \37$\\{print}(\.{"undefined"})$\2\6
+\&{endcases};\6
+\&{end};\par
+\fi
+
+\M188. Values inside \MF\ are stored in two-word nodes that have a \\{name%
+\_type}
+as well as a \\{type}. The possibilities for \\{name\_type} are defined
+here; they will be explained in more detail later.
+
+\Y\P\D \37$\\{root}=0$\C{\\{name\_type} at the top level of a variable}\par
+\P\D \37$\\{saved\_root}=1$\C{same, when the variable has been saved}\par
+\P\D \37$\\{structured\_root}=2$\C{\\{name\_type} where a \\{structured} branch
+occurs}\par
+\P\D \37$\\{subscr}=3$\C{\\{name\_type} in a subscript node}\par
+\P\D \37$\\{attr}=4$\C{\\{name\_type} in an attribute node}\par
+\P\D \37$\\{x\_part\_sector}=5$\C{\\{name\_type} in the \&{xpart} of a node}\par
+\P\D \37$\\{y\_part\_sector}=6$\C{\\{name\_type} in the \&{ypart} of a node}\par
+\P\D \37$\\{xx\_part\_sector}=7$\C{\\{name\_type} in the \&{xxpart} of a node}%
+\par
+\P\D \37$\\{xy\_part\_sector}=8$\C{\\{name\_type} in the \&{xypart} of a node}%
+\par
+\P\D \37$\\{yx\_part\_sector}=9$\C{\\{name\_type} in the \&{yxpart} of a node}%
+\par
+\P\D \37$\\{yy\_part\_sector}=10$\C{\\{name\_type} in the \&{yypart} of a node}%
+\par
+\P\D \37$\\{capsule}=11$\C{\\{name\_type} in stashed-away subexpressions}\par
+\P\D \37$\\{token}=12$\C{\\{name\_type} in a numeric token or string token}\par
+\fi
+
+\M189. Primitive operations that produce values have a secondary identification
+code in addition to their command code; it's something like genera and species.
+For example, `\.*' has the command code \\{primary\_binary}, and its
+secondary identification is \\{times}. The secondary codes start at 30 so that
+they don't overlap with the type codes; some type codes (e.g., \\{string%
+\_type})
+are used as operators as well as type identifications.
+
+\Y\P\D \37$\\{true\_code}=30$\C{operation code for \.{true}}\par
+\P\D \37$\\{false\_code}=31$\C{operation code for \.{false}}\par
+\P\D \37$\\{null\_picture\_code}=32$\C{operation code for \.{nullpicture}}\par
+\P\D \37$\\{null\_pen\_code}=33$\C{operation code for \.{nullpen}}\par
+\P\D \37$\\{job\_name\_op}=34$\C{operation code for \.{jobname}}\par
+\P\D \37$\\{read\_string\_op}=35$\C{operation code for \.{readstring}}\par
+\P\D \37$\\{pen\_circle}=36$\C{operation code for \.{pencircle}}\par
+\P\D \37$\\{normal\_deviate}=37$\C{operation code for \.{normaldeviate}}\par
+\P\D \37$\\{odd\_op}=38$\C{operation code for \.{odd}}\par
+\P\D \37$\\{known\_op}=39$\C{operation code for \.{known}}\par
+\P\D \37$\\{unknown\_op}=40$\C{operation code for \.{unknown}}\par
+\P\D \37$\\{not\_op}=41$\C{operation code for \.{not}}\par
+\P\D \37$\\{decimal}=42$\C{operation code for \.{decimal}}\par
+\P\D \37$\\{reverse}=43$\C{operation code for \.{reverse}}\par
+\P\D \37$\\{make\_path\_op}=44$\C{operation code for \.{makepath}}\par
+\P\D \37$\\{make\_pen\_op}=45$\C{operation code for \.{makepen}}\par
+\P\D \37$\\{total\_weight\_op}=46$\C{operation code for \.{totalweight}}\par
+\P\D \37$\\{oct\_op}=47$\C{operation code for \.{oct}}\par
+\P\D \37$\\{hex\_op}=48$\C{operation code for \.{hex}}\par
+\P\D \37$\\{ASCII\_op}=49$\C{operation code for \.{ASCII}}\par
+\P\D \37$\\{char\_op}=50$\C{operation code for \.{char}}\par
+\P\D \37$\\{length\_op}=51$\C{operation code for \.{length}}\par
+\P\D \37$\\{turning\_op}=52$\C{operation code for \.{turningnumber}}\par
+\P\D \37$\\{x\_part}=53$\C{operation code for \.{xpart}}\par
+\P\D \37$\\{y\_part}=54$\C{operation code for \.{ypart}}\par
+\P\D \37$\\{xx\_part}=55$\C{operation code for \.{xxpart}}\par
+\P\D \37$\\{xy\_part}=56$\C{operation code for \.{xypart}}\par
+\P\D \37$\\{yx\_part}=57$\C{operation code for \.{yxpart}}\par
+\P\D \37$\\{yy\_part}=58$\C{operation code for \.{yypart}}\par
+\P\D \37$\\{sqrt\_op}=59$\C{operation code for \.{sqrt}}\par
+\P\D \37$\\{m\_exp\_op}=60$\C{operation code for \.{mexp}}\par
+\P\D \37$\\{m\_log\_op}=61$\C{operation code for \.{mlog}}\par
+\P\D \37$\\{sin\_d\_op}=62$\C{operation code for \.{sind}}\par
+\P\D \37$\\{cos\_d\_op}=63$\C{operation code for \.{cosd}}\par
+\P\D \37$\\{floor\_op}=64$\C{operation code for \.{floor}}\par
+\P\D \37$\\{uniform\_deviate}=65$\C{operation code for \.{uniformdeviate}}\par
+\P\D \37$\\{char\_exists\_op}=66$\C{operation code for \.{charexists}}\par
+\P\D \37$\\{angle\_op}=67$\C{operation code for \.{angle}}\par
+\P\D \37$\\{cycle\_op}=68$\C{operation code for \.{cycle}}\par
+\P\D \37$\\{plus}=69$\C{operation code for \.+}\par
+\P\D \37$\\{minus}=70$\C{operation code for \.-}\par
+\P\D \37$\\{times}=71$\C{operation code for \.*}\par
+\P\D \37$\\{over}=72$\C{operation code for \./}\par
+\P\D \37$\\{pythag\_add}=73$\C{operation code for \.{++}}\par
+\P\D \37$\\{pythag\_sub}=74$\C{operation code for \.{+-+}}\par
+\P\D \37$\\{or\_op}=75$\C{operation code for \.{or}}\par
+\P\D \37$\\{and\_op}=76$\C{operation code for \.{and}}\par
+\P\D \37$\\{less\_than}=77$\C{operation code for \.<}\par
+\P\D \37$\\{less\_or\_equal}=78$\C{operation code for \.{<=}}\par
+\P\D \37$\\{greater\_than}=79$\C{operation code for \.>}\par
+\P\D \37$\\{greater\_or\_equal}=80$\C{operation code for \.{>=}}\par
+\P\D \37$\\{equal\_to}=81$\C{operation code for \.=}\par
+\P\D \37$\\{unequal\_to}=82$\C{operation code for \.{<>}}\par
+\P\D \37$\\{concatenate}=83$\C{operation code for \.\&}\par
+\P\D \37$\\{rotated\_by}=84$\C{operation code for \.{rotated}}\par
+\P\D \37$\\{slanted\_by}=85$\C{operation code for \.{slanted}}\par
+\P\D \37$\\{scaled\_by}=86$\C{operation code for \.{scaled}}\par
+\P\D \37$\\{shifted\_by}=87$\C{operation code for \.{shifted}}\par
+\P\D \37$\\{transformed\_by}=88$\C{operation code for \.{transformed}}\par
+\P\D \37$\\{x\_scaled}=89$\C{operation code for \.{xscaled}}\par
+\P\D \37$\\{y\_scaled}=90$\C{operation code for \.{yscaled}}\par
+\P\D \37$\\{z\_scaled}=91$\C{operation code for \.{zscaled}}\par
+\P\D \37$\\{intersect}=92$\C{operation code for \.{intersectiontimes}}\par
+\P\D \37$\\{double\_dot}=93$\C{operation code for improper \.{..}}\par
+\P\D \37$\\{substring\_of}=94$\C{operation code for \.{substring}}\par
+\P\D \37$\\{min\_of}=\\{substring\_of}$\par
+\P\D \37$\\{subpath\_of}=95$\C{operation code for \.{subpath}}\par
+\P\D \37$\\{direction\_time\_of}=96$\C{operation code for \.{directiontime}}\par
+\P\D \37$\\{point\_of}=97$\C{operation code for \.{point}}\par
+\P\D \37$\\{precontrol\_of}=98$\C{operation code for \.{precontrol}}\par
+\P\D \37$\\{postcontrol\_of}=99$\C{operation code for \.{postcontrol}}\par
+\P\D \37$\\{pen\_offset\_of}=100$\C{operation code for \.{penoffset}}\par
+\Y\P\4\&{procedure}\1\ \37$\\{print\_op}(\|c:\\{quarterword})$;\2\6
+\&{begin} \37\&{if} $\|c\L\\{numeric\_type}$ \1\&{then}\5
+$\\{print\_type}(\|c)$\6
+\4\&{else} \&{case} $\|c$ \1\&{of}\6
+\4\\{true\_code}: \37$\\{print}(\.{"true"})$;\6
+\4\\{false\_code}: \37$\\{print}(\.{"false"})$;\6
+\4\\{null\_picture\_code}: \37$\\{print}(\.{"nullpicture"})$;\6
+\4\\{null\_pen\_code}: \37$\\{print}(\.{"nullpen"})$;\6
+\4\\{job\_name\_op}: \37$\\{print}(\.{"jobname"})$;\6
+\4\\{read\_string\_op}: \37$\\{print}(\.{"readstring"})$;\6
+\4\\{pen\_circle}: \37$\\{print}(\.{"pencircle"})$;\6
+\4\\{normal\_deviate}: \37$\\{print}(\.{"normaldeviate"})$;\6
+\4\\{odd\_op}: \37$\\{print}(\.{"odd"})$;\6
+\4\\{known\_op}: \37$\\{print}(\.{"known"})$;\6
+\4\\{unknown\_op}: \37$\\{print}(\.{"unknown"})$;\6
+\4\\{not\_op}: \37$\\{print}(\.{"not"})$;\6
+\4\\{decimal}: \37$\\{print}(\.{"decimal"})$;\6
+\4\\{reverse}: \37$\\{print}(\.{"reverse"})$;\6
+\4\\{make\_path\_op}: \37$\\{print}(\.{"makepath"})$;\6
+\4\\{make\_pen\_op}: \37$\\{print}(\.{"makepen"})$;\6
+\4\\{total\_weight\_op}: \37$\\{print}(\.{"totalweight"})$;\6
+\4\\{oct\_op}: \37$\\{print}(\.{"oct"})$;\6
+\4\\{hex\_op}: \37$\\{print}(\.{"hex"})$;\6
+\4\\{ASCII\_op}: \37$\\{print}(\.{"ASCII"})$;\6
+\4\\{char\_op}: \37$\\{print}(\.{"char"})$;\6
+\4\\{length\_op}: \37$\\{print}(\.{"length"})$;\6
+\4\\{turning\_op}: \37$\\{print}(\.{"turningnumber"})$;\6
+\4\\{x\_part}: \37$\\{print}(\.{"xpart"})$;\6
+\4\\{y\_part}: \37$\\{print}(\.{"ypart"})$;\6
+\4\\{xx\_part}: \37$\\{print}(\.{"xxpart"})$;\6
+\4\\{xy\_part}: \37$\\{print}(\.{"xypart"})$;\6
+\4\\{yx\_part}: \37$\\{print}(\.{"yxpart"})$;\6
+\4\\{yy\_part}: \37$\\{print}(\.{"yypart"})$;\6
+\4\\{sqrt\_op}: \37$\\{print}(\.{"sqrt"})$;\6
+\4\\{m\_exp\_op}: \37$\\{print}(\.{"mexp"})$;\6
+\4\\{m\_log\_op}: \37$\\{print}(\.{"mlog"})$;\6
+\4\\{sin\_d\_op}: \37$\\{print}(\.{"sind"})$;\6
+\4\\{cos\_d\_op}: \37$\\{print}(\.{"cosd"})$;\6
+\4\\{floor\_op}: \37$\\{print}(\.{"floor"})$;\6
+\4\\{uniform\_deviate}: \37$\\{print}(\.{"uniformdeviate"})$;\6
+\4\\{char\_exists\_op}: \37$\\{print}(\.{"charexists"})$;\6
+\4\\{angle\_op}: \37$\\{print}(\.{"angle"})$;\6
+\4\\{cycle\_op}: \37$\\{print}(\.{"cycle"})$;\6
+\4\\{plus}: \37$\\{print\_char}(\.{"+"})$;\6
+\4\\{minus}: \37$\\{print\_char}(\.{"-"})$;\6
+\4\\{times}: \37$\\{print\_char}(\.{"*"})$;\6
+\4\\{over}: \37$\\{print\_char}(\.{"/"})$;\6
+\4\\{pythag\_add}: \37$\\{print}(\.{"++"})$;\6
+\4\\{pythag\_sub}: \37$\\{print}(\.{"+-+"})$;\6
+\4\\{or\_op}: \37$\\{print}(\.{"or"})$;\6
+\4\\{and\_op}: \37$\\{print}(\.{"and"})$;\6
+\4\\{less\_than}: \37$\\{print\_char}(\.{"<"})$;\6
+\4\\{less\_or\_equal}: \37$\\{print}(\.{"<="})$;\6
+\4\\{greater\_than}: \37$\\{print\_char}(\.{">"})$;\6
+\4\\{greater\_or\_equal}: \37$\\{print}(\.{">="})$;\6
+\4\\{equal\_to}: \37$\\{print\_char}(\.{"="})$;\6
+\4\\{unequal\_to}: \37$\\{print}(\.{"<>"})$;\6
+\4\\{concatenate}: \37$\\{print}(\.{"\&"})$;\6
+\4\\{rotated\_by}: \37$\\{print}(\.{"rotated"})$;\6
+\4\\{slanted\_by}: \37$\\{print}(\.{"slanted"})$;\6
+\4\\{scaled\_by}: \37$\\{print}(\.{"scaled"})$;\6
+\4\\{shifted\_by}: \37$\\{print}(\.{"shifted"})$;\6
+\4\\{transformed\_by}: \37$\\{print}(\.{"transformed"})$;\6
+\4\\{x\_scaled}: \37$\\{print}(\.{"xscaled"})$;\6
+\4\\{y\_scaled}: \37$\\{print}(\.{"yscaled"})$;\6
+\4\\{z\_scaled}: \37$\\{print}(\.{"zscaled"})$;\6
+\4\\{intersect}: \37$\\{print}(\.{"intersectiontimes"})$;\6
+\4\\{substring\_of}: \37$\\{print}(\.{"substring"})$;\6
+\4\\{subpath\_of}: \37$\\{print}(\.{"subpath"})$;\6
+\4\\{direction\_time\_of}: \37$\\{print}(\.{"directiontime"})$;\6
+\4\\{point\_of}: \37$\\{print}(\.{"point"})$;\6
+\4\\{precontrol\_of}: \37$\\{print}(\.{"precontrol"})$;\6
+\4\\{postcontrol\_of}: \37$\\{print}(\.{"postcontrol"})$;\6
+\4\\{pen\_offset\_of}: \37$\\{print}(\.{"penoffset"})$;\6
+\4\&{othercases} \37$\\{print}(\.{".."})$\2\6
+\&{endcases};\2\6
+\&{end};\par
+\fi
+
+\M190. \MF\ also has a bunch of internal parameters that a user might want to
+fuss with. Every such parameter has an identifying code number, defined here.
+
+\Y\P\D \37$\\{tracing\_titles}=1$\C{show titles online when they appear}\par
+\P\D \37$\\{tracing\_equations}=2$\C{show each variable when it becomes known}%
+\par
+\P\D \37$\\{tracing\_capsules}=3$\C{show capsules too}\par
+\P\D \37$\\{tracing\_choices}=4$\C{show the control points chosen for paths}\par
+\P\D \37$\\{tracing\_specs}=5$\C{show subdivision of paths into octants before
+digitizing}\par
+\P\D \37$\\{tracing\_pens}=6$\C{show details of pens that are made}\par
+\P\D \37$\\{tracing\_commands}=7$\C{show commands and operations before they
+are performed}\par
+\P\D \37$\\{tracing\_restores}=8$\C{show when a variable or internal is
+restored}\par
+\P\D \37$\\{tracing\_macros}=9$\C{show macros before they are expanded}\par
+\P\D \37$\\{tracing\_edges}=10$\C{show digitized edges as they are computed}\par
+\P\D \37$\\{tracing\_output}=11$\C{show digitized edges as they are output}\par
+\P\D \37$\\{tracing\_stats}=12$\C{show memory usage at end of job}\par
+\P\D \37$\\{tracing\_online}=13$\C{show long diagnostics on terminal and in the
+log file}\par
+\P\D \37$\\{year}=14$\C{the current year (e.g., 1984)}\par
+\P\D \37$\\{month}=15$\C{the current month (e.g, 3 $\equiv$ March)}\par
+\P\D \37$\\{day}=16$\C{the current day of the month}\par
+\P\D \37$\\{time}=17$\C{the number of minutes past midnight when this job
+started}\par
+\P\D \37$\\{char\_code}=18$\C{the number of the next character to be output}\par
+\P\D \37$\\{char\_ext}=19$\C{the extension code of the next character to be
+output}\par
+\P\D \37$\\{char\_wd}=20$\C{the width of the next character to be output}\par
+\P\D \37$\\{char\_ht}=21$\C{the height of the next character to be output}\par
+\P\D \37$\\{char\_dp}=22$\C{the depth of the next character to be output}\par
+\P\D \37$\\{char\_ic}=23$\C{the italic correction of the next character to be
+output}\par
+\P\D \37$\\{char\_dx}=24$\C{the device's $x$ movement for the next character,
+in pixels}\par
+\P\D \37$\\{char\_dy}=25$\C{the device's $y$ movement for the next character,
+in pixels}\par
+\P\D \37$\\{design\_size}=26$\C{the unit of measure used for $\\{char\_wd}\to%
+\\{char\_ic}$, in points}\par
+\P\D \37$\\{hppp}=27$\C{the number of horizontal pixels per point}\par
+\P\D \37$\\{vppp}=28$\C{the number of vertical pixels per point}\par
+\P\D \37$\\{x\_offset}=29$\C{horizontal displacement of shipped-out characters}%
+\par
+\P\D \37$\\{y\_offset}=30$\C{vertical displacement of shipped-out characters}%
+\par
+\P\D \37$\\{pausing}=31$\C{positive to display lines on the terminal before
+they are read}\par
+\P\D \37$\\{showstopping}=32$\C{positive to stop after each \&{show} command}%
+\par
+\P\D \37$\\{fontmaking}=33$\C{positive if font metric output is to be produced}%
+\par
+\P\D \37$\\{proofing}=34$\C{positive for proof mode, negative to suppress
+output}\par
+\P\D \37$\\{smoothing}=35$\C{positive if moves are to be ``smoothed''}\par
+\P\D \37$\\{autorounding}=36$\C{controls path modification to ``good'' points}%
+\par
+\P\D \37$\\{granularity}=37$\C{autorounding uses this pixel size}\par
+\P\D \37$\\{fillin}=38$\C{extra darkness of diagonal lines}\par
+\P\D \37$\\{turning\_check}=39$\C{controls reorientation of clockwise paths}\par
+\P\D \37$\\{warning\_check}=40$\C{controls error message when variable value is
+large}\par
+\P\D \37$\\{boundary\_char}=41$\C{the right boundary character for ligatures}%
+\par
+\P\D \37$\\{max\_given\_internal}=41$\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{internal}: \37\&{array} $[1\to\\{max\_internal}]$ \1\&{of}\5
+\\{scaled};\C{the values of internal quantities}\2\6
+\4\\{int\_name}: \37\&{array} $[1\to\\{max\_internal}]$ \1\&{of}\5
+\\{str\_number};\C{their names}\2\6
+\4\\{int\_ptr}: \37$\\{max\_given\_internal}\to\\{max\_internal}$;\C{the
+maximum internal quantity defined so far}\par
+\fi
+
+\M191. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+\&{for} $\|k\K1\mathrel{\&{to}}\\{max\_given\_internal}$ \1\&{do}\5
+$\\{internal}[\|k]\K0$;\2\6
+$\\{int\_ptr}\K\\{max\_given\_internal}$;\par
+\fi
+
+\M192. The symbolic names for internal quantities are put into \MF's hash table
+by using a routine called \\{primitive}, which will be defined later. Let us
+enter them now, so that we don't have to list all those names again
+anywhere else.
+
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\S$\6
+$\\{primitive}(\.{"tracingtitles"},\39\\{internal\_quantity},\39\\{tracing%
+\_titles})$;\6
+$\\{primitive}(\.{"tracingequations"},\39\\{internal\_quantity},\39\\{tracing%
+\_equations})$;\6
+$\\{primitive}(\.{"tracingcapsules"},\39\\{internal\_quantity},\39\\{tracing%
+\_capsules})$;\6
+$\\{primitive}(\.{"tracingchoices"},\39\\{internal\_quantity},\39\\{tracing%
+\_choices})$;\6
+$\\{primitive}(\.{"tracingspecs"},\39\\{internal\_quantity},\39\\{tracing%
+\_specs})$;\6
+$\\{primitive}(\.{"tracingpens"},\39\\{internal\_quantity},\39\\{tracing%
+\_pens})$;\6
+$\\{primitive}(\.{"tracingcommands"},\39\\{internal\_quantity},\39\\{tracing%
+\_commands})$;\6
+$\\{primitive}(\.{"tracingrestores"},\39\\{internal\_quantity},\39\\{tracing%
+\_restores})$;\6
+$\\{primitive}(\.{"tracingmacros"},\39\\{internal\_quantity},\39\\{tracing%
+\_macros})$;\6
+$\\{primitive}(\.{"tracingedges"},\39\\{internal\_quantity},\39\\{tracing%
+\_edges})$;\6
+$\\{primitive}(\.{"tracingoutput"},\39\\{internal\_quantity},\39\\{tracing%
+\_output})$;\6
+$\\{primitive}(\.{"tracingstats"},\39\\{internal\_quantity},\39\\{tracing%
+\_stats})$;\6
+$\\{primitive}(\.{"tracingonline"},\39\\{internal\_quantity},\39\\{tracing%
+\_online})$;\6
+$\\{primitive}(\.{"year"},\39\\{internal\_quantity},\39\\{year})$;\6
+$\\{primitive}(\.{"month"},\39\\{internal\_quantity},\39\\{month})$;\6
+$\\{primitive}(\.{"day"},\39\\{internal\_quantity},\39\\{day})$;\6
+$\\{primitive}(\.{"time"},\39\\{internal\_quantity},\39\\{time})$;\6
+$\\{primitive}(\.{"charcode"},\39\\{internal\_quantity},\39\\{char\_code})$;\6
+$\\{primitive}(\.{"charext"},\39\\{internal\_quantity},\39\\{char\_ext})$;\6
+$\\{primitive}(\.{"charwd"},\39\\{internal\_quantity},\39\\{char\_wd})$;\6
+$\\{primitive}(\.{"charht"},\39\\{internal\_quantity},\39\\{char\_ht})$;\6
+$\\{primitive}(\.{"chardp"},\39\\{internal\_quantity},\39\\{char\_dp})$;\6
+$\\{primitive}(\.{"charic"},\39\\{internal\_quantity},\39\\{char\_ic})$;\6
+$\\{primitive}(\.{"chardx"},\39\\{internal\_quantity},\39\\{char\_dx})$;\6
+$\\{primitive}(\.{"chardy"},\39\\{internal\_quantity},\39\\{char\_dy})$;\6
+$\\{primitive}(\.{"designsize"},\39\\{internal\_quantity},\39\\{design%
+\_size})$;\6
+$\\{primitive}(\.{"hppp"},\39\\{internal\_quantity},\39\\{hppp})$;\6
+$\\{primitive}(\.{"vppp"},\39\\{internal\_quantity},\39\\{vppp})$;\6
+$\\{primitive}(\.{"xoffset"},\39\\{internal\_quantity},\39\\{x\_offset})$;\6
+$\\{primitive}(\.{"yoffset"},\39\\{internal\_quantity},\39\\{y\_offset})$;\6
+$\\{primitive}(\.{"pausing"},\39\\{internal\_quantity},\39\\{pausing})$;\6
+$\\{primitive}(\.{"showstopping"},\39\\{internal\_quantity},\39%
+\\{showstopping})$;\6
+$\\{primitive}(\.{"fontmaking"},\39\\{internal\_quantity},\39\\{fontmaking})$;\6
+$\\{primitive}(\.{"proofing"},\39\\{internal\_quantity},\39\\{proofing})$;\6
+$\\{primitive}(\.{"smoothing"},\39\\{internal\_quantity},\39\\{smoothing})$;\6
+$\\{primitive}(\.{"autorounding"},\39\\{internal\_quantity},\39%
+\\{autorounding})$;\6
+$\\{primitive}(\.{"granularity"},\39\\{internal\_quantity},\39%
+\\{granularity})$;\6
+$\\{primitive}(\.{"fillin"},\39\\{internal\_quantity},\39\\{fillin})$;\6
+$\\{primitive}(\.{"turningcheck"},\39\\{internal\_quantity},\39\\{turning%
+\_check})$;\6
+$\\{primitive}(\.{"warningcheck"},\39\\{internal\_quantity},\39\\{warning%
+\_check})$;\6
+$\\{primitive}(\.{"boundarychar"},\39\\{internal\_quantity},\39\\{boundary%
+\_char})$;\par
+\As211, 683, 688, 695, 709, 740, 893, 1013, 1018, 1024, 1027, 1037, 1052, 1079,
+1101, 1108\ETs1176.
+\U1210.\fi
+
+\M193. Well, we do have to list the names one more time, for use in symbolic
+printouts.
+
+\Y\P$\4\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}\S$\6
+$\\{int\_name}[\\{tracing\_titles}]\K\.{"tracingtitles"}$;\5
+$\\{int\_name}[\\{tracing\_equations}]\K\.{"tracingequations"}$;\5
+$\\{int\_name}[\\{tracing\_capsules}]\K\.{"tracingcapsules"}$;\5
+$\\{int\_name}[\\{tracing\_choices}]\K\.{"tracingchoices"}$;\5
+$\\{int\_name}[\\{tracing\_specs}]\K\.{"tracingspecs"}$;\5
+$\\{int\_name}[\\{tracing\_pens}]\K\.{"tracingpens"}$;\5
+$\\{int\_name}[\\{tracing\_commands}]\K\.{"tracingcommands"}$;\5
+$\\{int\_name}[\\{tracing\_restores}]\K\.{"tracingrestores"}$;\5
+$\\{int\_name}[\\{tracing\_macros}]\K\.{"tracingmacros"}$;\5
+$\\{int\_name}[\\{tracing\_edges}]\K\.{"tracingedges"}$;\5
+$\\{int\_name}[\\{tracing\_output}]\K\.{"tracingoutput"}$;\5
+$\\{int\_name}[\\{tracing\_stats}]\K\.{"tracingstats"}$;\5
+$\\{int\_name}[\\{tracing\_online}]\K\.{"tracingonline"}$;\5
+$\\{int\_name}[\\{year}]\K\.{"year"}$;\5
+$\\{int\_name}[\\{month}]\K\.{"month"}$;\5
+$\\{int\_name}[\\{day}]\K\.{"day"}$;\5
+$\\{int\_name}[\\{time}]\K\.{"time"}$;\5
+$\\{int\_name}[\\{char\_code}]\K\.{"charcode"}$;\5
+$\\{int\_name}[\\{char\_ext}]\K\.{"charext"}$;\5
+$\\{int\_name}[\\{char\_wd}]\K\.{"charwd"}$;\5
+$\\{int\_name}[\\{char\_ht}]\K\.{"charht"}$;\5
+$\\{int\_name}[\\{char\_dp}]\K\.{"chardp"}$;\5
+$\\{int\_name}[\\{char\_ic}]\K\.{"charic"}$;\5
+$\\{int\_name}[\\{char\_dx}]\K\.{"chardx"}$;\5
+$\\{int\_name}[\\{char\_dy}]\K\.{"chardy"}$;\5
+$\\{int\_name}[\\{design\_size}]\K\.{"designsize"}$;\5
+$\\{int\_name}[\\{hppp}]\K\.{"hppp"}$;\5
+$\\{int\_name}[\\{vppp}]\K\.{"vppp"}$;\5
+$\\{int\_name}[\\{x\_offset}]\K\.{"xoffset"}$;\5
+$\\{int\_name}[\\{y\_offset}]\K\.{"yoffset"}$;\5
+$\\{int\_name}[\\{pausing}]\K\.{"pausing"}$;\5
+$\\{int\_name}[\\{showstopping}]\K\.{"showstopping"}$;\5
+$\\{int\_name}[\\{fontmaking}]\K\.{"fontmaking"}$;\5
+$\\{int\_name}[\\{proofing}]\K\.{"proofing"}$;\5
+$\\{int\_name}[\\{smoothing}]\K\.{"smoothing"}$;\5
+$\\{int\_name}[\\{autorounding}]\K\.{"autorounding"}$;\5
+$\\{int\_name}[\\{granularity}]\K\.{"granularity"}$;\5
+$\\{int\_name}[\\{fillin}]\K\.{"fillin"}$;\5
+$\\{int\_name}[\\{turning\_check}]\K\.{"turningcheck"}$;\5
+$\\{int\_name}[\\{warning\_check}]\K\.{"warningcheck"}$;\5
+$\\{int\_name}[\\{boundary\_char}]\K\.{"boundarychar"}$;\par
+\fi
+
+\M194. The following procedure, which is called just before \MF\ initializes
+its
+input and output, establishes the initial values of the date and time.
+Since standard \PASCAL\ cannot provide such information, something special
+is needed. The program here simply specifies July 4, 1776, at noon; but
+users probably want a better approximation to the truth.
+
+Note that the values are \\{scaled} integers. Hence \MF\ can no longer
+be used after the year 32767.
+
+\Y\P\4\&{procedure}\1\ \37\\{fix\_date\_and\_time};\2\6
+\&{begin} \37$\\{internal}[\\{time}]\K12\ast60\ast\\{unity}$;\C{minutes since
+midnight}\6
+$\\{internal}[\\{day}]\K4\ast\\{unity}$;\C{fourth day of the month}\6
+$\\{internal}[\\{month}]\K7\ast\\{unity}$;\C{seventh month of the year}\6
+$\\{internal}[\\{year}]\K1776\ast\\{unity}$;\C{Anno Domini}\6
+\&{end};\par
+\fi
+
+\M195. \MF\ is occasionally supposed to print diagnostic information that
+goes only into the transcript file, unless \\{tracing\_online} is positive.
+Now that we have defined \\{tracing\_online} we can define
+two routines that adjust the destination of print commands:
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{begin\_diagnostic};\C{prepare to do some tracing}\2\6
+\&{begin} \37$\\{old\_setting}\K\\{selector}$;\6
+\&{if} $(\\{internal}[\\{tracing\_online}]\L0)\W(\\{selector}=\\{term\_and%
+\_log})$ \1\&{then}\6
+\&{begin} \37$\\{decr}(\\{selector})$;\6
+\&{if} $\\{history}=\\{spotless}$ \1\&{then}\5
+$\\{history}\K\\{warning\_issued}$;\2\6
+\&{end};\2\6
+\&{end};\7
+\4\&{procedure}\1\ \37$\\{end\_diagnostic}(\\{blank\_line}:\\{boolean})$;%
+\C{restore proper conditions after tracing}\2\6
+\&{begin} \37$\\{print\_nl}(\.{""})$;\6
+\&{if} $\\{blank\_line}$ \1\&{then}\5
+\\{print\_ln};\2\6
+$\\{selector}\K\\{old\_setting}$;\6
+\&{end};\par
+\fi
+
+\M196. Of course we had better declare another global variable, if the previous
+routines are going to work.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{old\_setting}: \37$0\to\\{max\_selector}$;\par
+\fi
+
+\M197. We will occasionally use \\{begin\_diagnostic} in connection with
+line-number
+printing, as follows. (The parameter \|s is typically \.{"Path"} or
+\.{"Cycle\ spec"}, etc.)
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_diagnostic}(\|s,\39\|t:\\{str\_number};\,\35%
+\\{nuline}:\\{boolean})$;\2\6
+\&{begin} \37\\{begin\_diagnostic};\6
+\&{if} $\\{nuline}$ \1\&{then}\5
+$\\{print\_nl}(\|s)$\ \&{else} $\\{print}(\|s)$;\2\6
+$\\{print}(\.{"\ at\ line\ "})$;\5
+$\\{print\_int}(\\{line})$;\5
+$\\{print}(\|t)$;\5
+$\\{print\_char}(\.{":"})$;\6
+\&{end};\par
+\fi
+
+\M198. The 256 \\{ASCII\_code} characters are grouped into classes by means of
+the \\{char\_class} table. Individual class numbers have no semantic
+or syntactic significance, except in a few instances defined here.
+There's also \\{max\_class}, which can be used as a basis for additional
+class numbers in nonstandard extensions of \MF.
+
+\Y\P\D \37$\\{digit\_class}=0$\C{the class number of \.{0123456789}}\par
+\P\D \37$\\{period\_class}=1$\C{the class number of `\..'}\par
+\P\D \37$\\{space\_class}=2$\C{the class number of spaces and nonstandard
+characters}\par
+\P\D \37$\\{percent\_class}=3$\C{the class number of `\.\%'}\par
+\P\D \37$\\{string\_class}=4$\C{the class number of `\."'}\par
+\P\D \37$\\{right\_paren\_class}=8$\C{the class number of `\.)'}\par
+\P\D \37$\\{isolated\_classes}\S5,\396,\397,\398$\C{characters that make
+length-one tokens only}\par
+\P\D \37$\\{letter\_class}=9$\C{letters and the underline character}\par
+\P\D \37$\\{left\_bracket\_class}=17$\C{`\.['}\par
+\P\D \37$\\{right\_bracket\_class}=18$\C{`\.]'}\par
+\P\D \37$\\{invalid\_class}=20$\C{bad character in the input}\par
+\P\D \37$\\{max\_class}=20$\C{the largest class number}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{char\_class}: \37\&{array} $[\\{ASCII\_code}]$ \1\&{of}\5
+$0\to\\{max\_class}$;\C{the class numbers}\2\par
+\fi
+
+\M199. If changes are made to accommodate non-ASCII character sets, they should
+follow the guidelines in Appendix~C of {\sl The {\logos METAFONT\/}book}.
+
+\Y\P$\4\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+\&{for} $\|k\K\.{"0"}\mathrel{\&{to}}\.{"9"}$ \1\&{do}\5
+$\\{char\_class}[\|k]\K\\{digit\_class}$;\2\6
+$\\{char\_class}[\.{"."}]\K\\{period\_class}$;\5
+$\\{char\_class}[\.{"\ "}]\K\\{space\_class}$;\5
+$\\{char\_class}[\.{"\%"}]\K\\{percent\_class}$;\5
+$\\{char\_class}[\.{""}\.{""}]\K\\{string\_class}$;\6
+$\\{char\_class}[\.{","}]\K5$;\5
+$\\{char\_class}[\.{";"}]\K6$;\5
+$\\{char\_class}[\.{"("}]\K7$;\5
+$\\{char\_class}[\.{")"}]\K\\{right\_paren\_class}$;\6
+\&{for} $\|k\K\.{"A"}\mathrel{\&{to}}\.{"Z"}$ \1\&{do}\5
+$\\{char\_class}[\|k]\K\\{letter\_class}$;\2\6
+\&{for} $\|k\K\.{"a"}\mathrel{\&{to}}\.{"z"}$ \1\&{do}\5
+$\\{char\_class}[\|k]\K\\{letter\_class}$;\2\6
+$\\{char\_class}[\.{"\_"}]\K\\{letter\_class}$;\6
+$\\{char\_class}[\.{"<"}]\K10$;\5
+$\\{char\_class}[\.{"="}]\K10$;\5
+$\\{char\_class}[\.{">"}]\K10$;\5
+$\\{char\_class}[\.{":"}]\K10$;\5
+$\\{char\_class}[\.{"|"}]\K10$;\6
+$\\{char\_class}[\.{"\`"}]\K11$;\5
+$\\{char\_class}[\.{"\'"}]\K11$;\6
+$\\{char\_class}[\.{"+"}]\K12$;\5
+$\\{char\_class}[\.{"-"}]\K12$;\6
+$\\{char\_class}[\.{"/"}]\K13$;\5
+$\\{char\_class}[\.{"*"}]\K13$;\5
+$\\{char\_class}[\.{"\\"}]\K13$;\6
+$\\{char\_class}[\.{"!"}]\K14$;\5
+$\\{char\_class}[\.{"?"}]\K14$;\6
+$\\{char\_class}[\.{"\#"}]\K15$;\5
+$\\{char\_class}[\.{"\&"}]\K15$;\5
+$\\{char\_class}[\.{"@"}]\K15$;\5
+$\\{char\_class}[\.{"\$"}]\K15$;\6
+$\\{char\_class}[\.{"\^"}]\K16$;\5
+$\\{char\_class}[\.{"\~"}]\K16$;\6
+$\\{char\_class}[\.{"["}]\K\\{left\_bracket\_class}$;\5
+$\\{char\_class}[\.{"]"}]\K\\{right\_bracket\_class}$;\6
+$\\{char\_class}[\.{"\{"}]\K19$;\5
+$\\{char\_class}[\.{"\}"}]\K19$;\6
+\&{for} $\|k\K0\mathrel{\&{to}}\.{"\ "}-1$ \1\&{do}\5
+$\\{char\_class}[\|k]\K\\{invalid\_class}$;\2\6
+\&{for} $\|k\K127\mathrel{\&{to}}255$ \1\&{do}\5
+$\\{char\_class}[\|k]\K\\{invalid\_class}$;\2\par
+\fi
+
+\N200. \[13] The hash table.
+Symbolic tokens are stored and retrieved by means of a fairly standard hash
+table algorithm called the method of ``coalescing lists'' (cf.\ Algorithm 6.4C
+in {\sl The Art of Computer Programming\/}). Once a symbolic token enters the
+table, it is never removed.
+
+The actual sequence of characters forming a symbolic token is
+stored in the \\{str\_pool} array together with all the other strings. An
+auxiliary array \\{hash} consists of items with two halfword fields per
+word. The first of these, called $\\{next}(\|p)$, points to the next identifier
+belonging to the same coalesced list as the identifier corresponding to~\|p;
+and the other, called $\\{text}(\|p)$, points to the \\{str\_start} entry for
+\|p's identifier. If position~\|p of the hash table is empty, we have
+$\\{text}(\|p)=0$; if position \|p is either empty or the end of a coalesced
+hash list, we have $\\{next}(\|p)=0$.
+
+An auxiliary pointer variable called \\{hash\_used} is maintained in such a
+way that all locations $\|p\G\\{hash\_used}$ are nonempty. The global variable
+\\{st\_count} tells how many symbolic tokens have been defined, if statistics
+are being kept.
+
+The first 256 locations of \\{hash} are reserved for symbols of length one.
+
+There's a parallel array called \\{eqtb} that contains the current equivalent
+values of each symbolic token. The entries of this array consist of
+two halfwords called \\{eq\_type} (a command code) and \\{equiv} (a secondary
+piece of information that qualifies the \\{eq\_type}).
+
+\Y\P\D \37$\\{next}(\#)\S\\{hash}[\#].\\{lh}$\C{link for coalesced lists}\par
+\P\D \37$\\{text}(\#)\S\\{hash}[\#].\\{rh}$\C{string number for symbolic token
+name}\par
+\P\D \37$\\{eq\_type}(\#)\S\\{eqtb}[\#].\\{lh}$\C{the current ``meaning'' of a
+symbolic token}\par
+\P\D \37$\\{equiv}(\#)\S\\{eqtb}[\#].\\{rh}$\C{parametric part of a token's
+meaning}\par
+\P\D \37$\\{hash\_base}=257$\C{hashing actually starts here}\par
+\P\D \37$\\{hash\_is\_full}\S(\\{hash\_used}=\\{hash\_base})$\C{are all
+positions occupied?}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{hash\_used}: \37\\{pointer};\C{allocation pointer for \\{hash}}\6
+\4\\{st\_count}: \37\\{integer};\C{total number of known identifiers}\par
+\fi
+
+\M201. Certain entries in the hash table are ``frozen'' and not redefinable,
+since they are used in error recovery.
+
+\Y\P\D \37$\\{hash\_top}\S\\{hash\_base}+\\{hash\_size}$\C{the first location
+of the frozen area}\par
+\P\D \37$\\{frozen\_inaccessible}\S\\{hash\_top}$\C{\\{hash} location to
+protect the frozen area}\par
+\P\D \37$\\{frozen\_repeat\_loop}\S\\{hash\_top}+1$\C{\\{hash} location of a
+loop-repeat token}\par
+\P\D \37$\\{frozen\_right\_delimiter}\S\\{hash\_top}+2$\C{\\{hash} location of
+a permanent `\.)'}\par
+\P\D \37$\\{frozen\_left\_bracket}\S\\{hash\_top}+3$\C{\\{hash} location of a
+permanent `\.['}\par
+\P\D \37$\\{frozen\_slash}\S\\{hash\_top}+4$\C{\\{hash} location of a permanent
+`\./'}\par
+\P\D \37$\\{frozen\_colon}\S\\{hash\_top}+5$\C{\\{hash} location of a permanent
+`\.:'}\par
+\P\D \37$\\{frozen\_semicolon}\S\\{hash\_top}+6$\C{\\{hash} location of a
+permanent `\.;'}\par
+\P\D \37$\\{frozen\_end\_for}\S\\{hash\_top}+7$\C{\\{hash} location of a
+permanent \&{endfor}}\par
+\P\D \37$\\{frozen\_end\_def}\S\\{hash\_top}+8$\C{\\{hash} location of a
+permanent \&{enddef}}\par
+\P\D \37$\\{frozen\_fi}\S\\{hash\_top}+9$\C{\\{hash} location of a permanent %
+\&{fi}}\par
+\P\D \37$\\{frozen\_end\_group}\S\\{hash\_top}+10$\C{\\{hash} location of a
+permanent `\.{endgroup}'}\par
+\P\D \37$\\{frozen\_bad\_vardef}\S\\{hash\_top}+11$\C{\\{hash} location of `%
+\.{a bad variable}'}\par
+\P\D \37$\\{frozen\_undefined}\S\\{hash\_top}+12$\C{\\{hash} location that
+never gets defined}\par
+\P\D \37$\\{hash\_end}\S\\{hash\_top}+12$\C{the actual size of the \\{hash} and
+\\{eqtb} arrays}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{hash}: \37\&{array} $[1\to\\{hash\_end}]$ \1\&{of}\5
+\\{two\_halves};\C{the hash table}\2\6
+\4\\{eqtb}: \37\&{array} $[1\to\\{hash\_end}]$ \1\&{of}\5
+\\{two\_halves};\C{the equivalents}\2\par
+\fi
+
+\M202. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{next}(1)\K0$;\5
+$\\{text}(1)\K0$;\5
+$\\{eq\_type}(1)\K\\{tag\_token}$;\5
+$\\{equiv}(1)\K\\{null}$;\6
+\&{for} $\|k\K2\mathrel{\&{to}}\\{hash\_end}$ \1\&{do}\6
+\&{begin} \37$\\{hash}[\|k]\K\\{hash}[1]$;\5
+$\\{eqtb}[\|k]\K\\{eqtb}[1]$;\6
+\&{end};\2\par
+\fi
+
+\M203. \P$\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}%
+\S$\6
+$\\{hash\_used}\K\\{frozen\_inaccessible}$;\C{nothing is used}\6
+$\\{st\_count}\K0$;\6
+$\\{text}(\\{frozen\_bad\_vardef})\K\.{"a\ bad\ variable"}$;\5
+$\\{text}(\\{frozen\_fi})\K\.{"fi"}$;\5
+$\\{text}(\\{frozen\_end\_group})\K\.{"endgroup"}$;\5
+$\\{text}(\\{frozen\_end\_def})\K\.{"enddef"}$;\5
+$\\{text}(\\{frozen\_end\_for})\K\.{"endfor"}$;\6
+$\\{text}(\\{frozen\_semicolon})\K\.{";"}$;\5
+$\\{text}(\\{frozen\_colon})\K\.{":"}$;\5
+$\\{text}(\\{frozen\_slash})\K\.{"/"}$;\5
+$\\{text}(\\{frozen\_left\_bracket})\K\.{"["}$;\5
+$\\{text}(\\{frozen\_right\_delimiter})\K\.{")"}$;\6
+$\\{text}(\\{frozen\_inaccessible})\K\.{"\ INACCESSIBLE"}$;\6
+$\\{eq\_type}(\\{frozen\_right\_delimiter})\K\\{right\_delimiter}$;\par
+\fi
+
+\M204. \P$\X14:Check the ``constant'' values for consistency\X\mathrel{+}\S$\6
+\&{if} $\\{hash\_end}+\\{max\_internal}>\\{max\_halfword}$ \1\&{then}\5
+$\\{bad}\K21$;\2\par
+\fi
+
+\M205. Here is the subroutine that searches the hash table for an identifier
+that matches a given string of length~\|l appearing in $\\{buffer}[\|j\to(\|j+%
+\|l-1)]$. If the identifier is not found, it is inserted; hence it
+will always be found, and the corresponding hash table address
+will be returned.
+
+\Y\P\4\&{function}\1\ \37$\\{id\_lookup}(\|j,\39\|l:\\{integer})$: \37%
+\\{pointer};\C{search the hash table}\6
+\4\&{label} \37\\{found};\C{go here when you've found it}\6
+\4\&{var} \37\|h: \37\\{integer};\C{hash code}\6
+\|p: \37\\{pointer};\C{index in \\{hash} array}\6
+\|k: \37\\{pointer};\C{index in \\{buffer} array}\2\6
+\&{begin} \37\&{if} $\|l=1$ \1\&{then}\5
+\X206:Treat special case of length 1 and \&{goto} \\{found}\X;\2\6
+\X208:Compute the hash code \|h\X;\6
+$\|p\K\|h+\\{hash\_base}$;\C{we start searching here; note that $0\L\|h<\\{hash%
+\_prime}$}\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\\{text}(\|p)>0$ \1\&{then}\6
+\&{if} $\\{length}(\\{text}(\|p))=\|l$ \1\&{then}\6
+\&{if} $\\{str\_eq\_buf}(\\{text}(\|p),\39\|j)$ \1\&{then}\5
+\&{goto} \37\\{found};\2\2\2\6
+\&{if} $\\{next}(\|p)=0$ \1\&{then}\5
+\X207:Insert a new symbolic token after \|p, then make \|p point to it and %
+\&{goto} \\{found}\X;\2\6
+$\|p\K\\{next}(\|p)$;\6
+\&{end};\2\6
+\4\\{found}: \37$\\{id\_lookup}\K\|p$;\6
+\&{end};\par
+\fi
+
+\M206. \P$\X206:Treat special case of length 1 and \&{goto} \\{found}\X\S$\6
+\&{begin} \37$\|p\K\\{buffer}[\|j]+1$;\5
+$\\{text}(\|p)\K\|p-1$;\5
+\&{goto} \37\\{found};\6
+\&{end}\par
+\U205.\fi
+
+\M207. \P$\X207:Insert a new symbolic token after \|p, then make \|p point to
+it and \&{goto} \\{found}\X\S$\6
+\&{begin} \37\&{if} $\\{text}(\|p)>0$ \1\&{then}\6
+\&{begin} \37\1\&{repeat} \37\&{if} $\\{hash\_is\_full}$ \1\&{then}\5
+$\\{overflow}(\.{"hash\ size"},\39\\{hash\_size})$;\2\6
+$\\{decr}(\\{hash\_used})$;\6
+\4\&{until}\5
+$\\{text}(\\{hash\_used})=0$;\C{search for an empty location in \\{hash}}\2\6
+$\\{next}(\|p)\K\\{hash\_used}$;\5
+$\|p\K\\{hash\_used}$;\6
+\&{end};\2\6
+$\\{str\_room}(\|l)$;\6
+\&{for} $\|k\K\|j\mathrel{\&{to}}\|j+\|l-1$ \1\&{do}\5
+$\\{append\_char}(\\{buffer}[\|k])$;\2\6
+$\\{text}(\|p)\K\\{make\_string}$;\5
+$\\{str\_ref}[\\{text}(\|p)]\K\\{max\_str\_ref}$;\6
+\&{stat} \37$\\{incr}(\\{st\_count})$;\ \&{tats}\6
+\&{goto} \37\\{found};\6
+\&{end}\par
+\U205.\fi
+
+\M208. The value of \\{hash\_prime} should be roughly 85\pct! of \\{hash%
+\_size}, and it
+should be a prime number. The theory of hashing tells us to expect fewer
+than two table probes, on the average, when the search is successful.
+[See J.~S. Vitter, {\sl Journal of the ACM\/ \bf30} (1983), 231--258.]
+
+\Y\P$\4\X208:Compute the hash code \|h\X\S$\6
+$\|h\K\\{buffer}[\|j]$;\6
+\&{for} $\|k\K\|j+1\mathrel{\&{to}}\|j+\|l-1$ \1\&{do}\6
+\&{begin} \37$\|h\K\|h+\|h+\\{buffer}[\|k]$;\6
+\&{while} $\|h\G\\{hash\_prime}$ \1\&{do}\5
+$\|h\K\|h-\\{hash\_prime}$;\2\6
+\&{end}\2\par
+\U205.\fi
+
+\M209. \P$\X209:Search \\{eqtb} for equivalents equal to \|p\X\S$\6
+\&{for} $\|q\K1\mathrel{\&{to}}\\{hash\_end}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{equiv}(\|q)=\|p$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"EQUIV("})$;\5
+$\\{print\_int}(\|q)$;\5
+$\\{print\_char}(\.{")"})$;\6
+\&{end};\2\6
+\&{end}\2\par
+\U185.\fi
+
+\M210. We need to put \MF's ``primitive'' symbolic tokens into the hash
+table, together with their command code (which will be the \\{eq\_type})
+and an operand (which will be the \\{equiv}). The \\{primitive} procedure
+does this, in a way that no \MF\ user can. The global value \\{cur\_sym}
+contains the new \\{eqtb} pointer after \\{primitive} has acted.
+
+\Y\P\&{init} \37\&{procedure}\1\ \37$\\{primitive}(\|s:\\{str\_number};\,\35%
+\|c:\\{halfword};\,\35\|o:\\{halfword})$;\6
+\4\&{var} \37\|k: \37\\{pool\_pointer};\C{index into \\{str\_pool}}\6
+\|j: \37\\{small\_number};\C{index into \\{buffer}}\6
+\|l: \37\\{small\_number};\C{length of the string}\2\6
+\&{begin} \37$\|k\K\\{str\_start}[\|s]$;\5
+$\|l\K\\{str\_start}[\|s+1]-\|k$;\C{we will move \|s into the (empty) %
+\\{buffer}}\6
+\&{for} $\|j\K0\mathrel{\&{to}}\|l-1$ \1\&{do}\5
+$\\{buffer}[\|j]\K\\{so}(\\{str\_pool}[\|k+\|j])$;\2\6
+$\\{cur\_sym}\K\\{id\_lookup}(0,\39\|l)$;\6
+\&{if} $\|s\G256$ \1\&{then}\C{we don't want to have the string twice}\6
+\&{begin} \37$\\{flush\_string}(\\{str\_ptr}-1)$;\5
+$\\{text}(\\{cur\_sym})\K\|s$;\6
+\&{end};\2\6
+$\\{eq\_type}(\\{cur\_sym})\K\|c$;\5
+$\\{equiv}(\\{cur\_sym})\K\|o$;\6
+\&{end};\6
+\&{tini}\par
+\fi
+
+\M211. Many of \MF's primitives need no \\{equiv}, since they are identifiable
+by their \\{eq\_type} alone. These primitives are loaded into the hash table
+as follows:
+
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{".."},\39\\{path\_join},\390)$;\6
+$\\{primitive}(\.{"["},\39\\{left\_bracket},\390)$;\5
+$\\{eqtb}[\\{frozen\_left\_bracket}]\K\\{eqtb}[\\{cur\_sym}]$;\6
+$\\{primitive}(\.{"]"},\39\\{right\_bracket},\390)$;\6
+$\\{primitive}(\.{"\}"},\39\\{right\_brace},\390)$;\6
+$\\{primitive}(\.{"\{"},\39\\{left\_brace},\390)$;\6
+$\\{primitive}(\.{":"},\39\\{colon},\390)$;\5
+$\\{eqtb}[\\{frozen\_colon}]\K\\{eqtb}[\\{cur\_sym}]$;\6
+$\\{primitive}(\.{"::"},\39\\{double\_colon},\390)$;\6
+$\\{primitive}(\.{"||:"},\39\\{bchar\_label},\390)$;\6
+$\\{primitive}(\.{":="},\39\\{assignment},\390)$;\6
+$\\{primitive}(\.{","},\39\\{comma},\390)$;\6
+$\\{primitive}(\.{";"},\39\\{semicolon},\390)$;\5
+$\\{eqtb}[\\{frozen\_semicolon}]\K\\{eqtb}[\\{cur\_sym}]$;\6
+$\\{primitive}(\.{"\\"},\39\\{relax},\390)$;\7
+$\\{primitive}(\.{"addto"},\39\\{add\_to\_command},\390)$;\6
+$\\{primitive}(\.{"at"},\39\\{at\_token},\390)$;\6
+$\\{primitive}(\.{"atleast"},\39\\{at\_least},\390)$;\6
+$\\{primitive}(\.{"begingroup"},\39\\{begin\_group},\390)$;\5
+$\\{bg\_loc}\K\\{cur\_sym}$;\6
+$\\{primitive}(\.{"controls"},\39\\{controls},\390)$;\6
+$\\{primitive}(\.{"cull"},\39\\{cull\_command},\390)$;\6
+$\\{primitive}(\.{"curl"},\39\\{curl\_command},\390)$;\6
+$\\{primitive}(\.{"delimiters"},\39\\{delimiters},\390)$;\6
+$\\{primitive}(\.{"display"},\39\\{display\_command},\390)$;\6
+$\\{primitive}(\.{"endgroup"},\39\\{end\_group},\390)$;\5
+$\\{eqtb}[\\{frozen\_end\_group}]\K\\{eqtb}[\\{cur\_sym}]$;\5
+$\\{eg\_loc}\K\\{cur\_sym}$;\6
+$\\{primitive}(\.{"everyjob"},\39\\{every\_job\_command},\390)$;\6
+$\\{primitive}(\.{"exitif"},\39\\{exit\_test},\390)$;\6
+$\\{primitive}(\.{"expandafter"},\39\\{expand\_after},\390)$;\6
+$\\{primitive}(\.{"from"},\39\\{from\_token},\390)$;\6
+$\\{primitive}(\.{"inwindow"},\39\\{in\_window},\390)$;\6
+$\\{primitive}(\.{"interim"},\39\\{interim\_command},\390)$;\6
+$\\{primitive}(\.{"let"},\39\\{let\_command},\390)$;\6
+$\\{primitive}(\.{"newinternal"},\39\\{new\_internal},\390)$;\6
+$\\{primitive}(\.{"of"},\39\\{of\_token},\390)$;\6
+$\\{primitive}(\.{"openwindow"},\39\\{open\_window},\390)$;\6
+$\\{primitive}(\.{"randomseed"},\39\\{random\_seed},\390)$;\6
+$\\{primitive}(\.{"save"},\39\\{save\_command},\390)$;\6
+$\\{primitive}(\.{"scantokens"},\39\\{scan\_tokens},\390)$;\6
+$\\{primitive}(\.{"shipout"},\39\\{ship\_out\_command},\390)$;\6
+$\\{primitive}(\.{"skipto"},\39\\{skip\_to},\390)$;\6
+$\\{primitive}(\.{"step"},\39\\{step\_token},\390)$;\6
+$\\{primitive}(\.{"str"},\39\\{str\_op},\390)$;\6
+$\\{primitive}(\.{"tension"},\39\\{tension},\390)$;\6
+$\\{primitive}(\.{"to"},\39\\{to\_token},\390)$;\6
+$\\{primitive}(\.{"until"},\39\\{until\_token},\390)$;\par
+\fi
+
+\M212. Each primitive has a corresponding inverse, so that it is possible to
+display the cryptic numeric contents of \\{eqtb} in symbolic form.
+Every call of \\{primitive} in this program is therefore accompanied by some
+straightforward code that forms part of the \\{print\_cmd\_mod} routine
+explained below.
+
+\Y\P$\4\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of primitives\X%
+\S$\6
+\4\\{add\_to\_command}: \37$\\{print}(\.{"addto"})$;\6
+\4\\{assignment}: \37$\\{print}(\.{":="})$;\6
+\4\\{at\_least}: \37$\\{print}(\.{"atleast"})$;\6
+\4\\{at\_token}: \37$\\{print}(\.{"at"})$;\6
+\4\\{bchar\_label}: \37$\\{print}(\.{"||:"})$;\6
+\4\\{begin\_group}: \37$\\{print}(\.{"begingroup"})$;\6
+\4\\{colon}: \37$\\{print}(\.{":"})$;\6
+\4\\{comma}: \37$\\{print}(\.{","})$;\6
+\4\\{controls}: \37$\\{print}(\.{"controls"})$;\6
+\4\\{cull\_command}: \37$\\{print}(\.{"cull"})$;\6
+\4\\{curl\_command}: \37$\\{print}(\.{"curl"})$;\6
+\4\\{delimiters}: \37$\\{print}(\.{"delimiters"})$;\6
+\4\\{display\_command}: \37$\\{print}(\.{"display"})$;\6
+\4\\{double\_colon}: \37$\\{print}(\.{"::"})$;\6
+\4\\{end\_group}: \37$\\{print}(\.{"endgroup"})$;\6
+\4\\{every\_job\_command}: \37$\\{print}(\.{"everyjob"})$;\6
+\4\\{exit\_test}: \37$\\{print}(\.{"exitif"})$;\6
+\4\\{expand\_after}: \37$\\{print}(\.{"expandafter"})$;\6
+\4\\{from\_token}: \37$\\{print}(\.{"from"})$;\6
+\4\\{in\_window}: \37$\\{print}(\.{"inwindow"})$;\6
+\4\\{interim\_command}: \37$\\{print}(\.{"interim"})$;\6
+\4\\{left\_brace}: \37$\\{print}(\.{"\{"})$;\6
+\4\\{left\_bracket}: \37$\\{print}(\.{"["})$;\6
+\4\\{let\_command}: \37$\\{print}(\.{"let"})$;\6
+\4\\{new\_internal}: \37$\\{print}(\.{"newinternal"})$;\6
+\4\\{of\_token}: \37$\\{print}(\.{"of"})$;\6
+\4\\{open\_window}: \37$\\{print}(\.{"openwindow"})$;\6
+\4\\{path\_join}: \37$\\{print}(\.{".."})$;\6
+\4\\{random\_seed}: \37$\\{print}(\.{"randomseed"})$;\6
+\4\\{relax}: \37$\\{print\_char}(\.{"\\"})$;\6
+\4\\{right\_brace}: \37$\\{print}(\.{"\}"})$;\6
+\4\\{right\_bracket}: \37$\\{print}(\.{"]"})$;\6
+\4\\{save\_command}: \37$\\{print}(\.{"save"})$;\6
+\4\\{scan\_tokens}: \37$\\{print}(\.{"scantokens"})$;\6
+\4\\{semicolon}: \37$\\{print}(\.{";"})$;\6
+\4\\{ship\_out\_command}: \37$\\{print}(\.{"shipout"})$;\6
+\4\\{skip\_to}: \37$\\{print}(\.{"skipto"})$;\6
+\4\\{step\_token}: \37$\\{print}(\.{"step"})$;\6
+\4\\{str\_op}: \37$\\{print}(\.{"str"})$;\6
+\4\\{tension}: \37$\\{print}(\.{"tension"})$;\6
+\4\\{to\_token}: \37$\\{print}(\.{"to"})$;\6
+\4\\{until\_token}: \37$\\{print}(\.{"until"})$;\par
+\As684, 689, 696, 710, 741, 894, 1014, 1019, 1025, 1028, 1038, 1043, 1053,
+1080, 1102, 1109\ETs1180.
+\U625.\fi
+
+\M213. We will deal with the other primitives later, at some point in the
+program
+where their \\{eq\_type} and \\{equiv} values are more meaningful. For
+example,
+the primitives for macro definitions will be loaded when we consider the
+routines that define macros.
+It is easy to find where each particular
+primitive was treated by looking in the index at the end; for example, the
+section where \.{"def"} entered \\{eqtb} is listed under `\&{def} primitive'.
+
+\fi
+
+\N214. \[14] Token lists.
+A \MF\ token is either symbolic or numeric or a string, or it denotes
+a macro parameter or capsule; so there are five corresponding ways to encode it
+internally: (1)~A symbolic token whose hash code is~\|p
+is represented by the number \|p, in the \\{info} field of a single-word
+node in~\\{mem}. (2)~A numeric token whose \\{scaled} value is~\|v is
+represented in a two-word node of~\\{mem}; the \\{type} field is \\{known},
+the \\{name\_type} field is \\{token}, and the \\{value} field holds~\|v.
+The fact that this token appears in a two-word node rather than a
+one-word node is, of course, clear from the node address.
+(3)~A string token is also represented in a two-word node; the \\{type}
+field is \\{string\_type}, the \\{name\_type} field is \\{token}, and the
+\\{value} field holds the corresponding \\{str\_number}. (4)~Capsules have
+$\\{name\_type}=\\{capsule}$, and their \\{type} and \\{value} fields represent
+arbitrary values (in ways to be explained later). (5)~Macro parameters
+are like symbolic tokens in that they appear in \\{info} fields of
+one-word nodes. The $k$th parameter is represented by $\\{expr\_base}+\|k$ if
+it
+is of type \&{expr}, or by $\\{suffix\_base}+\|k$ if it is of type \&{suffix},
+or
+by $\\{text\_base}+\|k$ if it is of type \&{text}. (Here $0\L\|k<\\{param%
+\_size}$.)
+Actual values of these parameters are kept in a separate stack, as we will
+see later. The constants \\{expr\_base}, \\{suffix\_base}, and \\{text\_base}
+are,
+of course, chosen so that there will be no confusion between symbolic
+tokens and parameters of various types.
+
+It turns out that $\\{value}(\\{null})=0$, because $\\{null}=\\{null\_coords}$;
+we will make use of this coincidence later.
+
+Incidentally, while we're speaking of coincidences, we might note that
+the `\\{type}' field of a node has nothing to do with ``type'' in a
+printer's sense. It's curious that the same word is used in such different
+ways.
+
+\Y\P\D \37$\\{type}(\#)\S\\{mem}[\#].\\{hh}.\\{b0}$\C{identifies what kind of
+value this is}\par
+\P\D \37$\\{name\_type}(\#)\S\\{mem}[\#].\\{hh}.\\{b1}$\C{a clue to the name of
+this value}\par
+\P\D \37$\\{token\_node\_size}=2$\C{the number of words in a large token node}%
+\par
+\P\D \37$\\{value\_loc}(\#)\S\#+1$\C{the word that contains the \\{value}
+field}\par
+\P\D \37$\\{value}(\#)\S\\{mem}[\\{value\_loc}(\#)].\\{int}$\C{the value stored
+in a large token node}\par
+\P\D \37$\\{expr\_base}\S\\{hash\_end}+1$\C{code for the zeroth \&{expr}
+parameter}\par
+\P\D \37$\\{suffix\_base}\S\\{expr\_base}+\\{param\_size}$\C{code for the
+zeroth \&{suffix} parameter}\par
+\P\D \37$\\{text\_base}\S\\{suffix\_base}+\\{param\_size}$\C{code for the
+zeroth \&{text} parameter}\par
+\Y\P$\4\X14:Check the ``constant'' values for consistency\X\mathrel{+}\S$\6
+\&{if} $\\{text\_base}+\\{param\_size}>\\{max\_halfword}$ \1\&{then}\5
+$\\{bad}\K22$;\2\par
+\fi
+
+\M215. A numeric token is created by the following trivial routine.
+
+\Y\P\4\&{function}\1\ \37$\\{new\_num\_tok}(\|v:\\{scaled})$: \37\\{pointer};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the new node}\2\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{token\_node\_size})$;\5
+$\\{value}(\|p)\K\|v$;\5
+$\\{type}(\|p)\K\\{known}$;\5
+$\\{name\_type}(\|p)\K\\{token}$;\5
+$\\{new\_num\_tok}\K\|p$;\6
+\&{end};\par
+\fi
+
+\M216. A token list is a singly linked list of nodes in \\{mem}, where
+each node contains a token and a link. Here's a subroutine that gets rid
+of a token list when it is no longer needed.
+
+\Y\P\4\&{procedure}\1\ \37\\{token\_recycle};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37$\\{flush\_token\_list}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the node being recycled}\2\6
+\&{begin} \37\&{while} $\|p\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\|q\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{if} $\|q\G\\{hi\_mem\_min}$ \1\&{then}\5
+$\\{free\_avail}(\|q)$\6
+\4\&{else} \&{begin} \37\&{case} $\\{type}(\|q)$ \1\&{of}\6
+\4$\\{vacuous},\39\\{boolean\_type},\39\\{known}$: \37\\{do\_nothing};\6
+\4\\{string\_type}: \37$\\{delete\_str\_ref}(\\{value}(\|q))$;\6
+\4$\\{unknown\_types},\39\\{pen\_type},\39\\{path\_type},\39\\{future\_pen},\39%
+\\{picture\_type},\39\\{pair\_type},\39\\{transform\_type},\39\\{dependent},\39%
+\\{proto\_dependent},\39\\{independent}$: \37\&{begin} \37$\\{g\_pointer}\K%
+\|q$;\5
+\\{token\_recycle};\6
+\&{end};\6
+\4\&{othercases} \37$\\{confusion}(\.{"token"})$\2\6
+\&{endcases};\6
+$\\{free\_node}(\|q,\39\\{token\_node\_size})$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M217. The procedure \\{show\_token\_list}, which prints a symbolic form of
+the token list that starts at a given node \|p, illustrates these
+conventions. The token list being displayed should not begin with a reference
+count. However, the procedure is intended to be fairly robust, so that if the
+memory links are awry or if \|p is not really a pointer to a token list,
+almost nothing catastrophic can happen.
+
+An additional parameter \|q is also given; this parameter is either null
+or it points to a node in the token list where a certain magic computation
+takes place that will be explained later. (Basically, \|q is non-null when
+we are printing the two-line context information at the time of an error
+message; \|q marks the place corresponding to where the second line
+should begin.)
+
+The generation will stop, and `\.{\char`\ ETC.}' will be printed, if the length
+of printing exceeds a given limit~\|l; the length of printing upon entry is
+assumed to be a given amount called \\{null\_tally}. (Note that
+\\{show\_token\_list} sometimes uses itself recursively to print
+variable names within a capsule.)
+
+Unusual entries are printed in the form of all-caps tokens
+preceded by a space, e.g., `\.{\char`\ BAD}'.
+
+\Y\P$\4\X217:Declare the procedure called \\{show\_token\_list}\X\S$\6
+\4\&{procedure}\1\ \37\\{print\_capsule};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37$\\{show\_token\_list}(\|p,\39\|q:\\{integer};\,\35\|l,%
+\39\\{null\_tally}:\\{integer})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\\{class},\39\|c$: \37\\{small\_number};\C{the \\{char\_class} of
+previous and new tokens}\6
+$\|r,\39\|v$: \37\\{integer};\C{temporary registers}\2\6
+\&{begin} \37$\\{class}\K\\{percent\_class}$;\5
+$\\{tally}\K\\{null\_tally}$;\6
+\&{while} $(\|p\I\\{null})\W(\\{tally}<\|l)$ \1\&{do}\6
+\&{begin} \37\&{if} $\|p=\|q$ \1\&{then}\5
+\X646:Do magic computation\X;\2\6
+\X218:Display token \|p and set \|c to its class; but \&{return} if there are
+problems\X;\6
+$\\{class}\K\|c$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\&{if} $\|p\I\\{null}$ \1\&{then}\5
+$\\{print}(\.{"\ ETC."})$;\2\6
+\4\\{exit}: \37\&{end};\par
+\U162.\fi
+
+\M218. \P$\X218:Display token \|p and set \|c to its class; but \&{return} if
+there are problems\X\S$\6
+$\|c\K\\{letter\_class}$;\C{the default}\6
+\&{if} $(\|p<\\{mem\_min})\V(\|p>\\{mem\_end})$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"\ CLOBBERED"})$;\5
+\&{return};\6
+\&{end};\2\6
+\&{if} $\|p<\\{hi\_mem\_min}$ \1\&{then}\5
+\X219:Display two-word token\X\6
+\4\&{else} \&{begin} \37$\|r\K\\{info}(\|p)$;\6
+\&{if} $\|r\G\\{expr\_base}$ \1\&{then}\5
+\X222:Display a parameter token\X\6
+\4\&{else} \&{if} $\|r<1$ \1\&{then}\6
+\&{if} $\|r=0$ \1\&{then}\5
+\X221:Display a collective subscript\X\6
+\4\&{else} $\\{print}(\.{"\ IMPOSSIBLE"})$\2\6
+\4\&{else} \&{begin} \37$\|r\K\\{text}(\|r)$;\6
+\&{if} $(\|r<0)\V(\|r\G\\{str\_ptr})$ \1\&{then}\5
+$\\{print}(\.{"\ NONEXISTENT"})$\6
+\4\&{else} \X223:Print string \|r as a symbolic token and set \|c to its class%
+\X;\2\6
+\&{end};\2\2\6
+\&{end}\2\par
+\U217.\fi
+
+\M219. \P$\X219:Display two-word token\X\S$\6
+\&{if} $\\{name\_type}(\|p)=\\{token}$ \1\&{then}\6
+\&{if} $\\{type}(\|p)=\\{known}$ \1\&{then}\5
+\X220:Display a numeric token\X\6
+\4\&{else} \&{if} $\\{type}(\|p)\I\\{string\_type}$ \1\&{then}\5
+$\\{print}(\.{"\ BAD"})$\6
+\4\&{else} \&{begin} \37$\\{print\_char}(\.{""}\.{""})$;\5
+$\\{slow\_print}(\\{value}(\|p))$;\5
+$\\{print\_char}(\.{""}\.{""})$;\5
+$\|c\K\\{string\_class}$;\6
+\&{end}\2\2\6
+\4\&{else} \&{if} $(\\{name\_type}(\|p)\I\\{capsule})\V(\\{type}(\|p)<%
+\\{vacuous})\V(\\{type}(\|p)>\\{independent})$ \1\&{then}\5
+$\\{print}(\.{"\ BAD"})$\6
+\4\&{else} \&{begin} \37$\\{g\_pointer}\K\|p$;\5
+\\{print\_capsule};\5
+$\|c\K\\{right\_paren\_class}$;\6
+\&{end}\2\2\par
+\U218.\fi
+
+\M220. \P$\X220:Display a numeric token\X\S$\6
+\&{begin} \37\&{if} $\\{class}=\\{digit\_class}$ \1\&{then}\5
+$\\{print\_char}(\.{"\ "})$;\2\6
+$\|v\K\\{value}(\|p)$;\6
+\&{if} $\|v<0$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{class}=\\{left\_bracket\_class}$ \1\&{then}\5
+$\\{print\_char}(\.{"\ "})$;\2\6
+$\\{print\_char}(\.{"["})$;\5
+$\\{print\_scaled}(\|v)$;\5
+$\\{print\_char}(\.{"]"})$;\5
+$\|c\K\\{right\_bracket\_class}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print\_scaled}(\|v)$;\5
+$\|c\K\\{digit\_class}$;\6
+\&{end};\2\6
+\&{end}\par
+\U219.\fi
+
+\M221. Strictly speaking, a genuine token will never have $\\{info}(\|p)=0$.
+But we will see later (in the \\{print\_variable\_name} routine) that
+it is convenient to let $\\{info}(\|p)=0$ stand for `\.{[]}'.
+
+\Y\P$\4\X221:Display a collective subscript\X\S$\6
+\&{begin} \37\&{if} $\\{class}=\\{left\_bracket\_class}$ \1\&{then}\5
+$\\{print\_char}(\.{"\ "})$;\2\6
+$\\{print}(\.{"[]"})$;\5
+$\|c\K\\{right\_bracket\_class}$;\6
+\&{end}\par
+\U218.\fi
+
+\M222. \P$\X222:Display a parameter token\X\S$\6
+\&{begin} \37\&{if} $\|r<\\{suffix\_base}$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"(EXPR"})$;\5
+$\|r\K\|r-(\\{expr\_base})$;\6
+\&{end}\6
+\4\&{else} \&{if} $\|r<\\{text\_base}$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"(SUFFIX"})$;\5
+$\|r\K\|r-(\\{suffix\_base})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print}(\.{"(TEXT"})$;\5
+$\|r\K\|r-(\\{text\_base})$;\6
+\&{end};\2\2\6
+$\\{print\_int}(\|r)$;\5
+$\\{print\_char}(\.{")"})$;\5
+$\|c\K\\{right\_paren\_class}$;\6
+\&{end}\par
+\U218.\fi
+
+\M223. \P$\X223:Print string \|r as a symbolic token and set \|c to its class\X%
+\S$\6
+\&{begin} \37$\|c\K\\{char\_class}[\\{so}(\\{str\_pool}[\\{str\_start}[%
+\|r]])]$;\6
+\&{if} $\|c=\\{class}$ \1\&{then}\6
+\&{case} $\|c$ \1\&{of}\6
+\4\\{letter\_class}: \37$\\{print\_char}(\.{"."})$;\6
+\4\\{isolated\_classes}: \37\\{do\_nothing};\6
+\4\&{othercases} \37$\\{print\_char}(\.{"\ "})$\2\6
+\&{endcases};\2\6
+$\\{slow\_print}(\|r)$;\6
+\&{end}\par
+\U218.\fi
+
+\M224. The following procedures have been declared \\{forward} with no
+parameters,
+because the author dislikes \PASCAL's convention about \\{forward} procedures
+with parameters. It was necessary to do something, because \\{show\_token%
+\_list}
+is recursive (although the recursion is limited to one level), and because
+\\{flush\_token\_list} is syntactically (but not semantically) recursive.
+
+\Y\P$\4\X224:Declare miscellaneous procedures that were declared \\{forward}\X%
+\S$\6
+\4\&{procedure}\1\ \37\\{print\_capsule};\2\6
+\&{begin} \37$\\{print\_char}(\.{"("})$;\5
+$\\{print\_exp}(\\{g\_pointer},\390)$;\5
+$\\{print\_char}(\.{")"})$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37\\{token\_recycle};\2\6
+\&{begin} \37$\\{recycle\_value}(\\{g\_pointer})$;\6
+\&{end};\par
+\U1202.\fi
+
+\M225. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{g\_pointer}: \37\\{pointer};\C{(global) parameter to the \\{forward}
+procedures}\par
+\fi
+
+\M226. Macro definitions are kept in \MF's memory in the form of token lists
+that have a few extra one-word nodes at the beginning.
+
+The first node contains a reference count that is used to tell when the
+list is no longer needed. To emphasize the fact that a reference count is
+present, we shall refer to the \\{info} field of this special node as the
+\\{ref\_count} field.
+
+The next node or nodes after the reference count serve to describe the
+formal parameters. They either contain a code word that specifies all
+of the parameters, or they contain zero or more parameter tokens followed
+by the code `\\{general\_macro}'.
+
+\Y\P\D \37$\\{ref\_count}\S\\{info}$\C{reference count preceding a macro
+definition or pen header}\par
+\P\D \37$\\{add\_mac\_ref}(\#)\S\\{incr}(\\{ref\_count}(\#))$\C{make a new
+reference to a macro list}\par
+\P\D \37$\\{general\_macro}=0$\C{preface to a macro defined with a parameter
+list}\par
+\P\D \37$\\{primary\_macro}=1$\C{preface to a macro with a \&{primary}
+parameter}\par
+\P\D \37$\\{secondary\_macro}=2$\C{preface to a macro with a \&{secondary}
+parameter}\par
+\P\D \37$\\{tertiary\_macro}=3$\C{preface to a macro with a \&{tertiary}
+parameter}\par
+\P\D \37$\\{expr\_macro}=4$\C{preface to a macro with an undelimited \&{expr}
+parameter}\par
+\P\D \37$\\{of\_macro}=5$\C{preface to a macro with undelimited `\&{expr} \|x
+\&{of}~\|y' parameters}\par
+\P\D \37$\\{suffix\_macro}=6$\C{preface to a macro with an undelimited %
+\&{suffix} parameter}\par
+\P\D \37$\\{text\_macro}=7$\C{preface to a macro with an undelimited \&{text}
+parameter}\par
+\Y\P\4\&{procedure}\1\ \37$\\{delete\_mac\_ref}(\|p:\\{pointer})$;\C{\|p
+points to the reference count of a macro list that is losing one reference}%
+\2\6
+\&{begin} \37\&{if} $\\{ref\_count}(\|p)=\\{null}$ \1\&{then}\5
+$\\{flush\_token\_list}(\|p)$\6
+\4\&{else} $\\{decr}(\\{ref\_count}(\|p))$;\2\6
+\&{end};\par
+\fi
+
+\M227. The following subroutine displays a macro, given a pointer to its
+reference count.
+
+\Y\P\hbox{\4}\X625:Declare the procedure called \\{print\_cmd\_mod}\X\6
+\4\&{procedure}\1\ \37$\\{show\_macro}(\|p:\\{pointer};\,\35\|q,\39\|l:%
+\\{integer})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|r: \37\\{pointer};\C{temporary storage}\2\6
+\&{begin} \37$\|p\K\\{link}(\|p)$;\C{bypass the reference count}\6
+\&{while} $\\{info}(\|p)>\\{text\_macro}$ \1\&{do}\6
+\&{begin} \37$\|r\K\\{link}(\|p)$;\5
+$\\{link}(\|p)\K\\{null}$;\5
+$\\{show\_token\_list}(\|p,\39\\{null},\39\|l,\390)$;\5
+$\\{link}(\|p)\K\|r$;\5
+$\|p\K\|r$;\6
+\&{if} $\|l>0$ \1\&{then}\5
+$\|l\K\|l-\\{tally}$\ \&{else} \&{return};\2\6
+\&{end};\C{control printing of `\.{ETC.}'}\2\6
+$\\{tally}\K0$;\6
+\&{case} $\\{info}(\|p)$ \1\&{of}\6
+\4\\{general\_macro}: \37$\\{print}(\.{"->"})$;\6
+\4$\\{primary\_macro},\39\\{secondary\_macro},\39\\{tertiary\_macro}$: \37%
+\&{begin} \37$\\{print\_char}(\.{"<"})$;\5
+$\\{print\_cmd\_mod}(\\{param\_type},\39\\{info}(\|p))$;\5
+$\\{print}(\.{">->"})$;\6
+\&{end};\6
+\4\\{expr\_macro}: \37$\\{print}(\.{"<expr>->"})$;\6
+\4\\{of\_macro}: \37$\\{print}(\.{"<expr>of<primary>->"})$;\6
+\4\\{suffix\_macro}: \37$\\{print}(\.{"<suffix>->"})$;\6
+\4\\{text\_macro}: \37$\\{print}(\.{"<text>->"})$;\2\6
+\&{end};\C{there are no other cases}\6
+$\\{show\_token\_list}(\\{link}(\|p),\39\|q,\39\|l-\\{tally},\390)$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\N228. \[15] Data structures for variables.
+The variables of \MF\ programs can be simple, like `\.x', or they can
+combine the structural properties of arrays and records, like `\.{x20a.b}'.
+A \MF\ user assigns a type to a variable like \.{x20a.b} by saying, for
+example, `\.{boolean} \.{x20a.b}'. It's time for us to study how such
+things are represented inside of the computer.
+
+Each variable value occupies two consecutive words, either in a two-word
+node called a value node, or as a two-word subfield of a larger node. One
+of those two words is called the \\{value} field; it is an integer,
+containing either a \\{scaled} numeric value or the representation of some
+other type of quantity. (It might also be subdivided into halfwords, in
+which case it is referred to by other names instead of \\{value}.) The other
+word is broken into subfields called \\{type}, \\{name\_type}, and \\{link}.
+The
+\\{type} field is a quarterword that specifies the variable's type, and
+\\{name\_type} is a quarterword from which \MF\ can reconstruct the
+variable's name (sometimes by using the \\{link} field as well). Thus, only
+1.25 words are actually devoted to the value itself; the other
+three-quarters of a word are overhead, but they aren't wasted because they
+allow \MF\ to deal with sparse arrays and to provide meaningful diagnostics.
+
+In this section we shall be concerned only with the structural aspects of
+variables, not their values. Later parts of the program will change the
+\\{type} and \\{value} fields, but we shall treat those fields as black boxes
+whose contents should not be touched.
+
+However, if the \\{type} field is \\{structured}, there is no \\{value} field,
+and the second word is broken into two pointer fields called \\{attr\_head}
+and \\{subscr\_head}. Those fields point to additional nodes that
+contain structural information, as we shall see.
+
+\Y\P\D \37$\\{subscr\_head\_loc}(\#)\S\#+1$\C{where \\{value}, \\{subscr%
+\_head}, and \\{attr\_head} are}\par
+\P\D \37$\\{attr\_head}(\#)\S\\{info}(\\{subscr\_head\_loc}(\#))$\C{pointer to
+attribute info}\par
+\P\D \37$\\{subscr\_head}(\#)\S\\{link}(\\{subscr\_head\_loc}(\#))$\C{pointer
+to subscript info}\par
+\P\D \37$\\{value\_node\_size}=2$\C{the number of words in a value node}\par
+\fi
+
+\M229. An attribute node is three words long. Two of these words contain %
+\\{type}
+and \\{value} fields as described above, and the third word contains
+additional information: There is an \\{attr\_loc} field, which contains the
+hash address of the token that names this attribute; and there's also a
+\\{parent} field, which points to the value node of \\{structured} type at the
+next higher level (i.e., at the level to which this attribute is
+subsidiary). The \\{name\_type} in an attribute node is `\\{attr}'. The
+\\{link} field points to the next attribute with the same parent; these are
+arranged in increasing order, so that $\\{attr\_loc}(\\{link}(\|p))>\\{attr%
+\_loc}(\|p)$. The
+final attribute node links to the constant \\{end\_attr}, whose \\{attr\_loc}
+field is greater than any legal hash address. The \\{attr\_head} in the
+parent points to a node whose \\{name\_type} is \\{structured\_root}; this
+node represents the null attribute, i.e., the variable that is relevant
+when no attributes are attached to the parent. The \\{attr\_head} node is
+either
+a value node, a subscript node, or an attribute node, depending on what
+the parent would be if it were not structured; but the subscript and
+attribute fields are ignored, so it effectively contains only the data of
+a value node. The \\{link} field in this special node points to an attribute
+node whose \\{attr\_loc} field is zero; the latter node represents a collective
+subscript `\.{[]}' attached to the parent, and its \\{link} field points to
+the first non-special attribute node (or to \\{end\_attr} if there are none).
+
+A subscript node likewise occupies three words, with \\{type} and \\{value}
+fields
+plus extra information; its \\{name\_type} is \\{subscr}. In this case the
+third word is called the \\{subscript} field, which is a \\{scaled} integer.
+The \\{link} field points to the subscript node with the next larger
+subscript, if any; otherwise the \\{link} points to the attribute node
+for collective subscripts at this level. We have seen that the latter node
+contains an upward pointer, so that the parent can be deduced.
+
+The \\{name\_type} in a parent-less value node is \\{root}, and the \\{link}
+is the hash address of the token that names this value.
+
+In other words, variables have a hierarchical structure that includes
+enough threads running around so that the program is able to move easily
+between siblings, parents, and children. An example should be helpful:
+(The reader is advised to draw a picture while reading the following
+description, since that will help to firm up the ideas.)
+Suppose that `\.x' and `\.{x.a}' and `\.{x[]b}' and `\.{x5}'
+and `\.{x20b}' have been mentioned in a user's program, where
+\.{x[]b} has been declared to be of \&{boolean} type. Let $\|h(\|x)$, $\|h(%
+\|a)$,
+and $\|h(\|b)$ be the hash addresses of \.x, \.a, and~\.b. Then
+$\\{eq\_type}(\|h(\|x))=\\{tag\_token}$ and $\\{equiv}(\|h(\|x))=\|p$, where %
+\|p~is a two-word value
+node with $\\{name\_type}(\|p)=\\{root}$ and $\\{link}(\|p)=\|h(\|x)$. We have
+$\\{type}(\|p)=\\{structured}$,
+$\\{attr\_head}(\|p)=\|q$, and $\\{subscr\_head}(\|p)=\|r$, where \|q points to
+a value
+node and \|r to a subscript node. (Are you still following this? Use
+a pencil to draw a diagram.) The lone variable `\.x' is represented by
+$\\{type}(\|q)$ and $\\{value}(\|q)$; furthermore
+$\\{name\_type}(\|q)=\\{structured\_root}$ and $\\{link}(\|q)=\\{q1}$, where %
+\\{q1} points
+to an attribute node representing `\.{x[]}'. Thus $\\{name\_type}(\\{q1})=%
+\\{attr}$,
+$\\{attr\_loc}(\\{q1})=\\{collective\_subscript}=0$, $\\{parent}(\\{q1})=\|p$,
+$\\{type}(\\{q1})=\\{structured}$, $\\{attr\_head}(\\{q1})=\\{qq}$, and $%
+\\{subscr\_head}(\\{q1})=\\{qq1}$;
+\\{qq} is a value node with $\\{type}(\\{qq})=\\{numeric\_type}$ (assuming that
+\.{x5} is
+numeric, because \\{qq} represents `\.{x[]}' with no further attributes),
+$\\{name\_type}(\\{qq})=\\{structured\_root}$, and
+$\\{link}(\\{qq})=\\{qq1}$. (Now pay attention to the next part.) Node \\{qq1}
+is
+an attribute node representing `\.{x[][]}', which has never yet
+occurred; its \\{type} field is \\{undefined}, and its \\{value} field is
+undefined. We have $\\{name\_type}(\\{qq1})=\\{attr}$, $\\{attr\_loc}(\\{qq1})=%
+\\{collective\_subscript}$,
+$\\{parent}(\\{qq1})=\\{q1}$, and $\\{link}(\\{qq1})=\\{qq2}$. Since \\{qq2}
+represents
+`\.{x[]b}', $\\{type}(\\{qq2})=\\{unknown\_boolean}$; also $\\{attr\_loc}(%
+\\{qq2})=\|h(\|b)$,
+$\\{parent}(\\{qq2})=\\{q1}$, $\\{name\_type}(\\{qq2})=\\{attr}$, $\\{link}(%
+\\{qq2})=\\{end\_attr}$.
+(Maybe colored lines will help untangle your picture.)
+Node \|r is a subscript node with \\{type} and \\{value}
+representing `\.{x5}'; $\\{name\_type}(\|r)=\\{subscr}$, $\\{subscript}(%
+\|r)=5.0$,
+and $\\{link}(\|r)=\\{r1}$ is another subscript node. To complete the picture,
+see if you can guess what $\\{link}(\\{r1})$ is; give up? It's~\\{q1}.
+Furthermore $\\{subscript}(\\{r1})=20.0$, $\\{name\_type}(\\{r1})=\\{subscr}$,
+$\\{type}(\\{r1})=\\{structured}$, $\\{attr\_head}(\\{r1})=\\{qqq}$, $\\{subscr%
+\_head}(\\{r1})=\\{qqq1}$,
+and we finish things off with three more nodes
+\\{qqq}, \\{qqq1}, and \\{qqq2} hung onto~\\{r1}. (Perhaps you should start
+again
+with a larger sheet of paper.) The value of variable \.{x20b}
+appears in node~\\{qqq2}, as you can well imagine.
+
+If the example in the previous paragraph doesn't make things crystal
+clear, a glance at some of the simpler subroutines below will reveal how
+things work out in practice.
+
+The only really unusual thing about these conventions is the use of
+collective subscript attributes. The idea is to avoid repeating a lot of
+type information when many elements of an array are identical macros
+(for which distinct values need not be stored) or when they don't have
+all of the possible attributes. Branches of the structure below collective
+subscript attributes do not carry actual values except for macro identifiers;
+branches of the structure below subscript nodes do not carry significant
+information in their collective subscript attributes.
+
+\Y\P\D \37$\\{attr\_loc\_loc}(\#)\S\#+2$\C{where the \\{attr\_loc} and %
+\\{parent} fields are}\par
+\P\D \37$\\{attr\_loc}(\#)\S\\{info}(\\{attr\_loc\_loc}(\#))$\C{hash address of
+this attribute}\par
+\P\D \37$\\{parent}(\#)\S\\{link}(\\{attr\_loc\_loc}(\#))$\C{pointer to %
+\\{structured} variable}\par
+\P\D \37$\\{subscript\_loc}(\#)\S\#+2$\C{where the \\{subscript} field lives}%
+\par
+\P\D \37$\\{subscript}(\#)\S\\{mem}[\\{subscript\_loc}(\#)].\\{sc}$\C{subscript
+of this variable}\par
+\P\D \37$\\{attr\_node\_size}=3$\C{the number of words in an attribute node}\par
+\P\D \37$\\{subscr\_node\_size}=3$\C{the number of words in a subscript node}%
+\par
+\P\D \37$\\{collective\_subscript}=0$\C{code for the attribute `\.{[]}'}\par
+\Y\P$\4\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}\S$\6
+$\\{attr\_loc}(\\{end\_attr})\K\\{hash\_end}+1$;\5
+$\\{parent}(\\{end\_attr})\K\\{null}$;\par
+\fi
+
+\M230. Variables of type \&{pair} will have values that point to four-word
+nodes containing two numeric values. The first of these values has
+$\\{name\_type}=\\{x\_part\_sector}$ and the second has $\\{name\_type}=\\{y%
+\_part\_sector}$;
+the \\{link} in the first points back to the node whose \\{value} points
+to this four-word node.
+
+Variables of type \&{transform} are similar, but in this case their
+\\{value} points to a 12-word node containing six values, identified by
+\\{x\_part\_sector}, \\{y\_part\_sector}, \\{xx\_part\_sector}, \\{xy\_part%
+\_sector},
+\\{yx\_part\_sector}, and \\{yy\_part\_sector}.
+
+When an entire structured variable is saved, the \\{root} indication
+is temporarily replaced by \\{saved\_root}.
+
+Some variables have no name; they just are used for temporary storage
+while expressions are being evaluated. We call them {\sl capsules}.
+
+\Y\P\D \37$\\{x\_part\_loc}(\#)\S\#$\C{where the \&{xpart} is found in a pair
+or transform node}\par
+\P\D \37$\\{y\_part\_loc}(\#)\S\#+2$\C{where the \&{ypart} is found in a pair
+or transform node}\par
+\P\D \37$\\{xx\_part\_loc}(\#)\S\#+4$\C{where the \&{xxpart} is found in a
+transform node}\par
+\P\D \37$\\{xy\_part\_loc}(\#)\S\#+6$\C{where the \&{xypart} is found in a
+transform node}\par
+\P\D \37$\\{yx\_part\_loc}(\#)\S\#+8$\C{where the \&{yxpart} is found in a
+transform node}\par
+\P\D \37$\\{yy\_part\_loc}(\#)\S\#+10$\C{where the \&{yypart} is found in a
+transform node}\Y\par
+\P\D \37$\\{pair\_node\_size}=4$\C{the number of words in a pair node}\par
+\P\D \37$\\{transform\_node\_size}=12$\C{the number of words in a transform
+node}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{big\_node\_size}: \37\&{array} $[\\{transform\_type}\to\\{pair\_type}]$ \1%
+\&{of}\5
+\\{small\_number};\2\par
+\fi
+
+\M231. The \\{big\_node\_size} array simply contains two constants that \MF\
+occasionally needs to know.
+
+\Y\P$\4\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{big\_node\_size}[\\{transform\_type}]\K\\{transform\_node\_size}$;\5
+$\\{big\_node\_size}[\\{pair\_type}]\K\\{pair\_node\_size}$;\par
+\fi
+
+\M232. If $\\{type}(\|p)=\\{pair\_type}$ or \\{transform\_type} and if $%
+\\{value}(\|p)=\\{null}$, the
+procedure call $\\{init\_big\_node}(\|p)$ will allocate a pair or transform
+node
+for~\|p. The individual parts of such nodes are initially of type
+\\{independent}.
+
+\Y\P\4\&{procedure}\1\ \37$\\{init\_big\_node}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the new node}\6
+\|s: \37\\{small\_number};\C{its size}\2\6
+\&{begin} \37$\|s\K\\{big\_node\_size}[\\{type}(\|p)]$;\5
+$\|q\K\\{get\_node}(\|s)$;\6
+\1\&{repeat} \37$\|s\K\|s-2$;\5
+\X586:Make variable $\|q+\|s$ newly independent\X;\6
+$\\{name\_type}(\|q+\|s)\K\\{half}(\|s)+\\{x\_part\_sector}$;\5
+$\\{link}(\|q+\|s)\K\\{null}$;\6
+\4\&{until}\5
+$\|s=0$;\2\6
+$\\{link}(\|q)\K\|p$;\5
+$\\{value}(\|p)\K\|q$;\6
+\&{end};\par
+\fi
+
+\M233. The \\{id\_transform} function creates a capsule for the
+identity transformation.
+
+\Y\P\4\&{function}\1\ \37\\{id\_transform}: \37\\{pointer};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{list manipulation
+registers}\2\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{type}(\|p)\K\\{transform\_type}$;\5
+$\\{name\_type}(\|p)\K\\{capsule}$;\5
+$\\{value}(\|p)\K\\{null}$;\5
+$\\{init\_big\_node}(\|p)$;\5
+$\|q\K\\{value}(\|p)$;\5
+$\|r\K\|q+\\{transform\_node\_size}$;\6
+\1\&{repeat} \37$\|r\K\|r-2$;\5
+$\\{type}(\|r)\K\\{known}$;\5
+$\\{value}(\|r)\K0$;\6
+\4\&{until}\5
+$\|r=\|q$;\2\6
+$\\{value}(\\{xx\_part\_loc}(\|q))\K\\{unity}$;\5
+$\\{value}(\\{yy\_part\_loc}(\|q))\K\\{unity}$;\5
+$\\{id\_transform}\K\|p$;\6
+\&{end};\par
+\fi
+
+\M234. Tokens are of type \\{tag\_token} when they first appear, but they point
+to \\{null} until they are first used as the root of a variable.
+The following subroutine establishes the root node on such grand occasions.
+
+\Y\P\4\&{procedure}\1\ \37$\\{new\_root}(\|x:\\{pointer})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the new node}\2\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{type}(\|p)\K\\{undefined}$;\5
+$\\{name\_type}(\|p)\K\\{root}$;\5
+$\\{link}(\|p)\K\|x$;\5
+$\\{equiv}(\|x)\K\|p$;\6
+\&{end};\par
+\fi
+
+\M235. These conventions for variable representation are illustrated by the
+\\{print\_variable\_name} routine, which displays the full name of a
+variable given only a pointer to its two-word value packet.
+
+\Y\P\4\&{procedure}\1\ \37$\\{print\_variable\_name}(\|p:\\{pointer})$;\6
+\4\&{label} \37$\\{found},\39\\{exit}$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{a token list that will name the variable's
+suffix}\6
+\|r: \37\\{pointer};\C{temporary for token list creation}\2\6
+\&{begin} \37\&{while} $\\{name\_type}(\|p)\G\\{x\_part\_sector}$ \1\&{do}\5
+\X237:Preface the output with a part specifier; \&{return} in the case of a
+capsule\X;\2\6
+$\|q\K\\{null}$;\6
+\&{while} $\\{name\_type}(\|p)>\\{saved\_root}$ \1\&{do}\5
+\X236:Ascend one level, pushing a token onto list \|q and replacing \|p by its
+parent\X;\2\6
+$\|r\K\\{get\_avail}$;\5
+$\\{info}(\|r)\K\\{link}(\|p)$;\5
+$\\{link}(\|r)\K\|q$;\6
+\&{if} $\\{name\_type}(\|p)=\\{saved\_root}$ \1\&{then}\5
+$\\{print}(\.{"(SAVED)"})$;\2\6
+$\\{show\_token\_list}(\|r,\39\\{null},\39\\{el\_gordo},\39\\{tally})$;\5
+$\\{flush\_token\_list}(\|r)$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M236. \P$\X236:Ascend one level, pushing a token onto list \|q and replacing %
+\|p by its parent\X\S$\6
+\&{begin} \37\&{if} $\\{name\_type}(\|p)=\\{subscr}$ \1\&{then}\6
+\&{begin} \37$\|r\K\\{new\_num\_tok}(\\{subscript}(\|p))$;\6
+\1\&{repeat} \37$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\\{name\_type}(\|p)=\\{attr}$;\2\6
+\&{end}\6
+\4\&{else} \&{if} $\\{name\_type}(\|p)=\\{structured\_root}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{link}(\|p)$;\5
+\&{goto} \37\\{found};\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{name\_type}(\|p)\I\\{attr}$ \1\&{then}\5
+$\\{confusion}(\.{"var"})$;\2\6
+$\|r\K\\{get\_avail}$;\5
+$\\{info}(\|r)\K\\{attr\_loc}(\|p)$;\6
+\&{end};\2\2\6
+$\\{link}(\|r)\K\|q$;\5
+$\|q\K\|r$;\6
+\4\\{found}: \37$\|p\K\\{parent}(\|p)$;\6
+\&{end}\par
+\U235.\fi
+
+\M237. \P$\X237:Preface the output with a part specifier; \&{return} in the
+case of a capsule\X\S$\6
+\&{begin} \37\&{case} $\\{name\_type}(\|p)$ \1\&{of}\6
+\4\\{x\_part\_sector}: \37$\\{print\_char}(\.{"x"})$;\6
+\4\\{y\_part\_sector}: \37$\\{print\_char}(\.{"y"})$;\6
+\4\\{xx\_part\_sector}: \37$\\{print}(\.{"xx"})$;\6
+\4\\{xy\_part\_sector}: \37$\\{print}(\.{"xy"})$;\6
+\4\\{yx\_part\_sector}: \37$\\{print}(\.{"yx"})$;\6
+\4\\{yy\_part\_sector}: \37$\\{print}(\.{"yy"})$;\6
+\4\\{capsule}: \37\&{begin} \37$\\{print}(\.{"\%CAPSULE"})$;\5
+$\\{print\_int}(\|p-\\{null})$;\5
+\&{return};\6
+\&{end};\2\6
+\&{end};\C{there are no other cases}\6
+$\\{print}(\.{"part\ "})$;\5
+$\|p\K\\{link}(\|p-2\ast(\\{name\_type}(\|p)-\\{x\_part\_sector}))$;\6
+\&{end}\par
+\U235.\fi
+
+\M238. The \\{interesting} function returns \\{true} if a given variable is not
+in a capsule, or if the user wants to trace capsules.
+
+\Y\P\4\&{function}\1\ \37$\\{interesting}(\|p:\\{pointer})$: \37\\{boolean};\6
+\4\&{var} \37\|t: \37\\{small\_number};\C{a \\{name\_type}}\2\6
+\&{begin} \37\&{if} $\\{internal}[\\{tracing\_capsules}]>0$ \1\&{then}\5
+$\\{interesting}\K\\{true}$\6
+\4\&{else} \&{begin} \37$\|t\K\\{name\_type}(\|p)$;\6
+\&{if} $\|t\G\\{x\_part\_sector}$ \1\&{then}\6
+\&{if} $\|t\I\\{capsule}$ \1\&{then}\5
+$\|t\K\\{name\_type}(\\{link}(\|p-2\ast(\|t-\\{x\_part\_sector})))$;\2\2\6
+$\\{interesting}\K(\|t\I\\{capsule})$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M239. Now here is a subroutine that converts an unstructured type into an
+equivalent structured type, by inserting a \\{structured} node that is
+capable of growing. This operation is done only when $\\{name\_type}(\|p)=%
+\\{root}$,
+\\{subscr}, or \\{attr}.
+
+The procedure returns a pointer to the new node that has taken node~\|p's
+place in the structure. Node~\|p itself does not move, nor are its
+\\{value} or \\{type} fields changed in any way.
+
+\Y\P\4\&{function}\1\ \37$\\{new\_structure}(\|p:\\{pointer})$: \37%
+\\{pointer};\6
+\4\&{var} \37$\|q,\39\|r$: \37\\{pointer};\C{list manipulation registers}\2\6
+\&{begin} \37\&{case} $\\{name\_type}(\|p)$ \1\&{of}\6
+\4\\{root}: \37\&{begin} \37$\|q\K\\{link}(\|p)$;\5
+$\|r\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{equiv}(\|q)\K\|r$;\6
+\&{end};\6
+\4\\{subscr}: \37\X240:Link a new subscript node \|r in place of node \|p\X;\6
+\4\\{attr}: \37\X241:Link a new attribute node \|r in place of node \|p\X;\6
+\4\&{othercases} \37$\\{confusion}(\.{"struct"})$\2\6
+\&{endcases};\6
+$\\{link}(\|r)\K\\{link}(\|p)$;\5
+$\\{type}(\|r)\K\\{structured}$;\5
+$\\{name\_type}(\|r)\K\\{name\_type}(\|p)$;\5
+$\\{attr\_head}(\|r)\K\|p$;\5
+$\\{name\_type}(\|p)\K\\{structured\_root}$;\6
+$\|q\K\\{get\_node}(\\{attr\_node\_size})$;\5
+$\\{link}(\|p)\K\|q$;\5
+$\\{subscr\_head}(\|r)\K\|q$;\5
+$\\{parent}(\|q)\K\|r$;\5
+$\\{type}(\|q)\K\\{undefined}$;\5
+$\\{name\_type}(\|q)\K\\{attr}$;\5
+$\\{link}(\|q)\K\\{end\_attr}$;\5
+$\\{attr\_loc}(\|q)\K\\{collective\_subscript}$;\5
+$\\{new\_structure}\K\|r$;\6
+\&{end};\par
+\fi
+
+\M240. \P$\X240:Link a new subscript node \|r in place of node \|p\X\S$\6
+\&{begin} \37$\|q\K\|p$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\\{name\_type}(\|q)=\\{attr}$;\2\6
+$\|q\K\\{parent}(\|q)$;\5
+$\|r\K\\{subscr\_head\_loc}(\|q)$;\C{$\\{link}(\|r)=\\{subscr\_head}(\|q)$}\6
+\1\&{repeat} \37$\|q\K\|r$;\5
+$\|r\K\\{link}(\|r)$;\6
+\4\&{until}\5
+$\|r=\|p$;\2\6
+$\|r\K\\{get\_node}(\\{subscr\_node\_size})$;\5
+$\\{link}(\|q)\K\|r$;\5
+$\\{subscript}(\|r)\K\\{subscript}(\|p)$;\6
+\&{end}\par
+\U239.\fi
+
+\M241. If the attribute is \\{collective\_subscript}, there are two pointers to
+node~\|p, so we must change both of them.
+
+\Y\P$\4\X241:Link a new attribute node \|r in place of node \|p\X\S$\6
+\&{begin} \37$\|q\K\\{parent}(\|p)$;\5
+$\|r\K\\{attr\_head}(\|q)$;\6
+\1\&{repeat} \37$\|q\K\|r$;\5
+$\|r\K\\{link}(\|r)$;\6
+\4\&{until}\5
+$\|r=\|p$;\2\6
+$\|r\K\\{get\_node}(\\{attr\_node\_size})$;\5
+$\\{link}(\|q)\K\|r$;\6
+$\\{mem}[\\{attr\_loc\_loc}(\|r)]\K\\{mem}[\\{attr\_loc\_loc}(\|p)]$;\C{copy %
+\\{attr\_loc} and \\{parent}}\6
+\&{if} $\\{attr\_loc}(\|p)=\\{collective\_subscript}$ \1\&{then}\6
+\&{begin} \37$\|q\K\\{subscr\_head\_loc}(\\{parent}(\|p))$;\6
+\&{while} $\\{link}(\|q)\I\|p$ \1\&{do}\5
+$\|q\K\\{link}(\|q)$;\2\6
+$\\{link}(\|q)\K\|r$;\6
+\&{end};\2\6
+\&{end}\par
+\U239.\fi
+
+\M242. The \\{find\_variable} routine is given a pointer~\|t to a nonempty
+token
+list of suffixes; it returns a pointer to the corresponding two-word
+value. For example, if \|t points to token \.x followed by a numeric
+token containing the value~7, \\{find\_variable} finds where the value of
+\.{x7} is stored in memory. This may seem a simple task, and it
+usually is, except when \.{x7} has never been referenced before.
+Indeed, \.x may never have even been subscripted before; complexities
+arise with respect to updating the collective subscript information.
+
+If a macro type is detected anywhere along path~\|t, or if the first
+item on \|t isn't a \\{tag\_token}, the value \\{null} is returned.
+Otherwise \|p will be a non-null pointer to a node such that
+$\\{undefined}<\\{type}(\|p)<\\{structured}$.
+
+\Y\P\D \37$\\{abort\_find}\S$\1\6
+\&{begin} \37$\\{find\_variable}\K\\{null}$;\5
+\&{return};\ \&{end}\2\par
+\Y\P\4\&{function}\1\ \37$\\{find\_variable}(\|t:\\{pointer})$: \37%
+\\{pointer};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{nodes in the
+``value'' line}\6
+$\\{pp},\39\\{qq},\39\\{rr},\39\\{ss}$: \37\\{pointer};\C{nodes in the
+``collective'' line}\6
+\|n: \37\\{integer};\C{subscript or attribute}\6
+\\{save\_word}: \37\\{memory\_word};\C{temporary storage for a word of \\{mem}}%
+\2\6
+\&{begin} \37$\|p\K\\{info}(\|t)$;\5
+$\|t\K\\{link}(\|t)$;\6
+\&{if} $\\{eq\_type}(\|p)\mathbin{\&{mod}}\\{outer\_tag}\I\\{tag\_token}$ \1%
+\&{then}\5
+\\{abort\_find};\2\6
+\&{if} $\\{equiv}(\|p)=\\{null}$ \1\&{then}\5
+$\\{new\_root}(\|p)$;\2\6
+$\|p\K\\{equiv}(\|p)$;\5
+$\\{pp}\K\|p$;\6
+\&{while} $\|t\I\\{null}$ \1\&{do}\6
+\&{begin} \37\X243:Make sure that both nodes \|p and \\{pp} are of %
+\\{structured} type\X;\6
+\&{if} $\|t<\\{hi\_mem\_min}$ \1\&{then}\5
+\X244:Descend one level for the subscript $\\{value}(\|t)$\X\6
+\4\&{else} \X245:Descend one level for the attribute $\\{info}(\|t)$\X;\2\6
+$\|t\K\\{link}(\|t)$;\6
+\&{end};\2\6
+\&{if} $\\{type}(\\{pp})\G\\{structured}$ \1\&{then}\6
+\&{if} $\\{type}(\\{pp})=\\{structured}$ \1\&{then}\5
+$\\{pp}\K\\{attr\_head}(\\{pp})$\ \&{else} \\{abort\_find};\2\2\6
+\&{if} $\\{type}(\|p)=\\{structured}$ \1\&{then}\5
+$\|p\K\\{attr\_head}(\|p)$;\2\6
+\&{if} $\\{type}(\|p)=\\{undefined}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{type}(\\{pp})=\\{undefined}$ \1\&{then}\6
+\&{begin} \37$\\{type}(\\{pp})\K\\{numeric\_type}$;\5
+$\\{value}(\\{pp})\K\\{null}$;\6
+\&{end};\2\6
+$\\{type}(\|p)\K\\{type}(\\{pp})$;\5
+$\\{value}(\|p)\K\\{null}$;\6
+\&{end};\2\6
+$\\{find\_variable}\K\|p$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M243. Although \\{pp} and \|p begin together, they diverge when a subscript
+occurs;
+\\{pp}~stays in the collective line while \|p~goes through actual subscript
+values.
+
+\Y\P$\4\X243:Make sure that both nodes \|p and \\{pp} are of \\{structured}
+type\X\S$\6
+\&{if} $\\{type}(\\{pp})\I\\{structured}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{type}(\\{pp})>\\{structured}$ \1\&{then}\5
+\\{abort\_find};\2\6
+$\\{ss}\K\\{new\_structure}(\\{pp})$;\6
+\&{if} $\|p=\\{pp}$ \1\&{then}\5
+$\|p\K\\{ss}$;\2\6
+$\\{pp}\K\\{ss}$;\6
+\&{end};\C{now $\\{type}(\\{pp})=\\{structured}$}\2\6
+\&{if} $\\{type}(\|p)\I\\{structured}$ \1\&{then}\C{it cannot be $>%
+\\{structured}$}\6
+$\|p\K\\{new\_structure}(\|p)$\C{now $\\{type}(\|p)=\\{structured}$}\2\par
+\U242.\fi
+
+\M244. We want this part of the program to be reasonably fast, in case there
+are
+lots of subscripts at the same level of the data structure. Therefore
+we store an ``infinite'' value in the word that appears at the end of the
+subscript list, even though that word isn't part of a subscript node.
+
+\Y\P$\4\X244:Descend one level for the subscript $\\{value}(\|t)$\X\S$\6
+\&{begin} \37$\|n\K\\{value}(\|t)$;\5
+$\\{pp}\K\\{link}(\\{attr\_head}(\\{pp}))$;\C{now $\\{attr\_loc}(\\{pp})=%
+\\{collective\_subscript}$}\6
+$\|q\K\\{link}(\\{attr\_head}(\|p))$;\5
+$\\{save\_word}\K\\{mem}[\\{subscript\_loc}(\|q)]$;\5
+$\\{subscript}(\|q)\K\\{el\_gordo}$;\5
+$\|s\K\\{subscr\_head\_loc}(\|p)$;\C{$\\{link}(\|s)=\\{subscr\_head}(\|p)$}\6
+\1\&{repeat} \37$\|r\K\|s$;\5
+$\|s\K\\{link}(\|s)$;\6
+\4\&{until}\5
+$\|n\L\\{subscript}(\|s)$;\2\6
+\&{if} $\|n=\\{subscript}(\|s)$ \1\&{then}\5
+$\|p\K\|s$\6
+\4\&{else} \&{begin} \37$\|p\K\\{get\_node}(\\{subscr\_node\_size})$;\5
+$\\{link}(\|r)\K\|p$;\5
+$\\{link}(\|p)\K\|s$;\5
+$\\{subscript}(\|p)\K\|n$;\5
+$\\{name\_type}(\|p)\K\\{subscr}$;\5
+$\\{type}(\|p)\K\\{undefined}$;\6
+\&{end};\2\6
+$\\{mem}[\\{subscript\_loc}(\|q)]\K\\{save\_word}$;\6
+\&{end}\par
+\U242.\fi
+
+\M245. \P$\X245:Descend one level for the attribute $\\{info}(\|t)$\X\S$\6
+\&{begin} \37$\|n\K\\{info}(\|t)$;\5
+$\\{ss}\K\\{attr\_head}(\\{pp})$;\6
+\1\&{repeat} \37$\\{rr}\K\\{ss}$;\5
+$\\{ss}\K\\{link}(\\{ss})$;\6
+\4\&{until}\5
+$\|n\L\\{attr\_loc}(\\{ss})$;\2\6
+\&{if} $\|n<\\{attr\_loc}(\\{ss})$ \1\&{then}\6
+\&{begin} \37$\\{qq}\K\\{get\_node}(\\{attr\_node\_size})$;\5
+$\\{link}(\\{rr})\K\\{qq}$;\5
+$\\{link}(\\{qq})\K\\{ss}$;\5
+$\\{attr\_loc}(\\{qq})\K\|n$;\5
+$\\{name\_type}(\\{qq})\K\\{attr}$;\5
+$\\{type}(\\{qq})\K\\{undefined}$;\5
+$\\{parent}(\\{qq})\K\\{pp}$;\5
+$\\{ss}\K\\{qq}$;\6
+\&{end};\2\6
+\&{if} $\|p=\\{pp}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{ss}$;\5
+$\\{pp}\K\\{ss}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{pp}\K\\{ss}$;\5
+$\|s\K\\{attr\_head}(\|p)$;\6
+\1\&{repeat} \37$\|r\K\|s$;\5
+$\|s\K\\{link}(\|s)$;\6
+\4\&{until}\5
+$\|n\L\\{attr\_loc}(\|s)$;\2\6
+\&{if} $\|n=\\{attr\_loc}(\|s)$ \1\&{then}\5
+$\|p\K\|s$\6
+\4\&{else} \&{begin} \37$\|q\K\\{get\_node}(\\{attr\_node\_size})$;\5
+$\\{link}(\|r)\K\|q$;\5
+$\\{link}(\|q)\K\|s$;\5
+$\\{attr\_loc}(\|q)\K\|n$;\5
+$\\{name\_type}(\|q)\K\\{attr}$;\5
+$\\{type}(\|q)\K\\{undefined}$;\5
+$\\{parent}(\|q)\K\|p$;\5
+$\|p\K\|q$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end}\par
+\U242.\fi
+
+\M246. Variables lose their former values when they appear in a type
+declaration,
+or when they are defined to be macros or \&{let} equal to something else.
+A subroutine will be defined later that recycles the storage associated
+with any particular \\{type} or \\{value}; our goal now is to study a higher
+level process called \\{flush\_variable}, which selectively frees parts of a
+variable structure.
+
+This routine has some complexity because of examples such as
+`\hbox{\tt numeric x[]a[]b}',
+which recycles all variables of the form \.{x[i]a[j]b} (and no others), while
+`\hbox{\tt vardef x[]a[]=...}'
+discards all variables of the form \.{x[i]a[j]} followed by an arbitrary
+suffix, except for the collective node \.{x[]a[]} itself. The obvious way
+to handle such examples is to use recursion; so that's what we~do.
+
+Parameter \|p points to the root information of the variable;
+parameter \|t points to a list of one-word nodes that represent
+suffixes, with $\\{info}=\\{collective\_subscript}$ for subscripts.
+
+\Y\P\hbox{\4}\X257:Declare subroutines for printing expressions\X\6
+\hbox{\4}\X594:Declare basic dependency-list subroutines\X\6
+\hbox{\4}\X268:Declare the recycling subroutines\X\6
+\hbox{\4}\X808:Declare the procedure called \\{flush\_cur\_exp}\X\6
+\hbox{\4}\X247:Declare the procedure called \\{flush\_below\_variable}\X\6
+\4\&{procedure}\1\ \37$\\{flush\_variable}(\|p,\39\|t:\\{pointer};\,\35%
+\\{discard\_suffixes}:\\{boolean})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\|q,\39\|r$: \37\\{pointer};\C{list manipulation}\6
+\|n: \37\\{halfword};\C{attribute to match}\2\6
+\&{begin} \37\&{while} $\|t\I\\{null}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{type}(\|p)\I\\{structured}$ \1\&{then}\5
+\&{return};\2\6
+$\|n\K\\{info}(\|t)$;\5
+$\|t\K\\{link}(\|t)$;\6
+\&{if} $\|n=\\{collective\_subscript}$ \1\&{then}\6
+\&{begin} \37$\|r\K\\{subscr\_head\_loc}(\|p)$;\5
+$\|q\K\\{link}(\|r)$;\C{$\|q=\\{subscr\_head}(\|p)$}\6
+\&{while} $\\{name\_type}(\|q)=\\{subscr}$ \1\&{do}\6
+\&{begin} \37$\\{flush\_variable}(\|q,\39\|t,\39\\{discard\_suffixes})$;\6
+\&{if} $\|t=\\{null}$ \1\&{then}\6
+\&{if} $\\{type}(\|q)=\\{structured}$ \1\&{then}\5
+$\|r\K\|q$\6
+\4\&{else} \&{begin} \37$\\{link}(\|r)\K\\{link}(\|q)$;\5
+$\\{free\_node}(\|q,\39\\{subscr\_node\_size})$;\6
+\&{end}\2\6
+\4\&{else} $\|r\K\|q$;\2\6
+$\|q\K\\{link}(\|r)$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\|p\K\\{attr\_head}(\|p)$;\6
+\1\&{repeat} \37$\|r\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\\{attr\_loc}(\|p)\G\|n$;\2\6
+\&{if} $\\{attr\_loc}(\|p)\I\|n$ \1\&{then}\5
+\&{return};\2\6
+\&{end};\2\6
+\&{if} $\\{discard\_suffixes}$ \1\&{then}\5
+$\\{flush\_below\_variable}(\|p)$\6
+\4\&{else} \&{begin} \37\&{if} $\\{type}(\|p)=\\{structured}$ \1\&{then}\5
+$\|p\K\\{attr\_head}(\|p)$;\2\6
+$\\{recycle\_value}(\|p)$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M247. The next procedure is simpler; it wipes out everything but \|p itself,
+which becomes undefined.
+
+\Y\P$\4\X247:Declare the procedure called \\{flush\_below\_variable}\X\S$\6
+\4\&{procedure}\1\ \37$\\{flush\_below\_variable}(\|p:\\{pointer})$;\6
+\4\&{var} \37$\|q,\39\|r$: \37\\{pointer};\C{list manipulation registers}\2\6
+\&{begin} \37\&{if} $\\{type}(\|p)\I\\{structured}$ \1\&{then}\5
+$\\{recycle\_value}(\|p)$\C{this sets $\\{type}(\|p)=\\{undefined}$}\6
+\4\&{else} \&{begin} \37$\|q\K\\{subscr\_head}(\|p)$;\6
+\&{while} $\\{name\_type}(\|q)=\\{subscr}$ \1\&{do}\6
+\&{begin} \37$\\{flush\_below\_variable}(\|q)$;\5
+$\|r\K\|q$;\5
+$\|q\K\\{link}(\|q)$;\5
+$\\{free\_node}(\|r,\39\\{subscr\_node\_size})$;\6
+\&{end};\2\6
+$\|r\K\\{attr\_head}(\|p)$;\5
+$\|q\K\\{link}(\|r)$;\5
+$\\{recycle\_value}(\|r)$;\6
+\&{if} $\\{name\_type}(\|p)\L\\{saved\_root}$ \1\&{then}\5
+$\\{free\_node}(\|r,\39\\{value\_node\_size})$\6
+\4\&{else} $\\{free\_node}(\|r,\39\\{subscr\_node\_size})$;\C{we assume that $%
+\\{subscr\_node\_size}=\\{attr\_node\_size}$}\2\6
+\1\&{repeat} \37$\\{flush\_below\_variable}(\|q)$;\5
+$\|r\K\|q$;\5
+$\|q\K\\{link}(\|q)$;\5
+$\\{free\_node}(\|r,\39\\{attr\_node\_size})$;\6
+\4\&{until}\5
+$\|q=\\{end\_attr}$;\2\6
+$\\{type}(\|p)\K\\{undefined}$;\6
+\&{end};\2\6
+\&{end};\par
+\U246.\fi
+
+\M248. Just before assigning a new value to a variable, we will recycle the
+old value and make the old value undefined. The \\{und\_type} routine
+determines what type of undefined value should be given, based on
+the current type before recycling.
+
+\Y\P\4\&{function}\1\ \37$\\{und\_type}(\|p:\\{pointer})$: \37\\{small%
+\_number};\2\6
+\&{begin} \37\&{case} $\\{type}(\|p)$ \1\&{of}\6
+\4$\\{undefined},\39\\{vacuous}$: \37$\\{und\_type}\K\\{undefined}$;\6
+\4$\\{boolean\_type},\39\\{unknown\_boolean}$: \37$\\{und\_type}\K\\{unknown%
+\_boolean}$;\6
+\4$\\{string\_type},\39\\{unknown\_string}$: \37$\\{und\_type}\K\\{unknown%
+\_string}$;\6
+\4$\\{pen\_type},\39\\{unknown\_pen},\39\\{future\_pen}$: \37$\\{und\_type}\K%
+\\{unknown\_pen}$;\6
+\4$\\{path\_type},\39\\{unknown\_path}$: \37$\\{und\_type}\K\\{unknown\_path}$;%
+\6
+\4$\\{picture\_type},\39\\{unknown\_picture}$: \37$\\{und\_type}\K\\{unknown%
+\_picture}$;\6
+\4$\\{transform\_type},\39\\{pair\_type},\39\\{numeric\_type}$: \37$\\{und%
+\_type}\K\\{type}(\|p)$;\6
+\4$\\{known},\39\\{dependent},\39\\{proto\_dependent},\39\\{independent}$: \37$%
+\\{und\_type}\K\\{numeric\_type}$;\2\6
+\&{end};\C{there are no other cases}\6
+\&{end};\par
+\fi
+
+\M249. The \\{clear\_symbol} routine is used when we want to redefine the
+equivalent
+of a symbolic token. It must remove any variable structure or macro
+definition that is currently attached to that symbol. If the \\{saving}
+parameter is true, a subsidiary structure is saved instead of destroyed.
+
+\Y\P\4\&{procedure}\1\ \37$\\{clear\_symbol}(\|p:\\{pointer};\,\35\\{saving}:%
+\\{boolean})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{$\\{equiv}(\|p)$}\2\6
+\&{begin} \37$\|q\K\\{equiv}(\|p)$;\6
+\&{case} $\\{eq\_type}(\|p)\mathbin{\&{mod}}\\{outer\_tag}$ \1\&{of}\6
+\4$\\{defined\_macro},\39\\{secondary\_primary\_macro},\39\\{tertiary%
+\_secondary\_macro},\39\\{expression\_tertiary\_macro}$: \37\&{if} $\R%
+\\{saving}$ \1\&{then}\5
+$\\{delete\_mac\_ref}(\|q)$;\2\6
+\4\\{tag\_token}: \37\&{if} $\|q\I\\{null}$ \1\&{then}\6
+\&{if} $\\{saving}$ \1\&{then}\5
+$\\{name\_type}(\|q)\K\\{saved\_root}$\6
+\4\&{else} \&{begin} \37$\\{flush\_below\_variable}(\|q)$;\5
+$\\{free\_node}(\|q,\39\\{value\_node\_size})$;\6
+\&{end};\2\6
+\4\&{othercases} \\{do\_nothing}\2\2\6
+\&{endcases};\6
+$\\{eqtb}[\|p]\K\\{eqtb}[\\{frozen\_undefined}]$;\6
+\&{end};\par
+\fi
+
+\N250. \[16] Saving and restoring equivalents.
+The nested structure provided by \&{begingroup} and \&{endgroup}
+allows \\{eqtb} entries to be saved and restored, so that temporary changes
+can be made without difficulty. When the user requests a current value to
+be saved, \MF\ puts that value into its ``save stack.'' An appearance of
+\&{endgroup} ultimately causes the old values to be removed from the save
+stack and put back in their former places.
+
+The save stack is a linked list containing three kinds of entries,
+distinguished by their \\{info} fields. If \|p points to a saved item,
+then
+
+\smallskip\hang
+$\\{info}(\|p)=0$ stands for a group boundary; each \&{begingroup} contributes
+such an item to the save stack and each \&{endgroup} cuts back the stack
+until the most recent such entry has been removed.
+
+\smallskip\hang
+$\\{info}(\|p)=\|q$, where $1\L\|q\L\\{hash\_end}$, means that $\\{mem}[\|p+1]$
+holds the former
+contents of $\\{eqtb}[\|q]$. Such save stack entries are generated by \&{save}
+commands or suitable \&{interim} commands.
+
+\smallskip\hang
+$\\{info}(\|p)=\\{hash\_end}+\|q$, where $\|q>0$, means that $\\{value}(\|p)$
+is a \\{scaled}
+integer to be restored to internal parameter number~\|q. Such entries
+are generated by \&{interim} commands.
+
+\smallskip\noindent
+The global variable \\{save\_ptr} points to the top item on the save stack.
+
+\Y\P\D \37$\\{save\_node\_size}=2$\C{number of words per non-boundary
+save-stack node}\par
+\P\D \37$\\{saved\_equiv}(\#)\S\\{mem}[\#+1].\\{hh}$\C{where an \\{eqtb} entry
+gets saved}\par
+\P\D \37$\\{save\_boundary\_item}(\#)\S$\1\6
+\&{begin} \37$\#\K\\{get\_avail}$;\5
+$\\{info}(\#)\K0$;\5
+$\\{link}(\#)\K\\{save\_ptr}$;\5
+$\\{save\_ptr}\K\#$;\6
+\&{end}\2\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{save\_ptr}: \37\\{pointer};\C{the most recently saved item}\par
+\fi
+
+\M251. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{save\_ptr}\K\\{null}$;\par
+\fi
+
+\M252. The \\{save\_variable} routine is given a hash address \|q; it salts
+this
+address in the save stack, together with its current equivalent,
+then makes token~\|q behave as though it were brand new.
+
+Nothing is stacked when $\\{save\_ptr}=\\{null}$, however; there's no way to
+remove
+things from the stack when the program is not inside a group, so there's
+no point in wasting the space.
+
+\Y\P\4\&{procedure}\1\ \37$\\{save\_variable}(\|q:\\{pointer})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\\{save\_ptr}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{save\_node\_size})$;\5
+$\\{info}(\|p)\K\|q$;\5
+$\\{link}(\|p)\K\\{save\_ptr}$;\5
+$\\{saved\_equiv}(\|p)\K\\{eqtb}[\|q]$;\5
+$\\{save\_ptr}\K\|p$;\6
+\&{end};\2\6
+$\\{clear\_symbol}(\|q,\39(\\{save\_ptr}\I\\{null}))$;\6
+\&{end};\par
+\fi
+
+\M253. Similarly, \\{save\_internal} is given the location \|q of an internal
+quantity like \\{tracing\_pens}. It creates a save stack entry of the
+third kind.
+
+\Y\P\4\&{procedure}\1\ \37$\\{save\_internal}(\|q:\\{halfword})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{new item for the save stack}\2\6
+\&{begin} \37\&{if} $\\{save\_ptr}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{save\_node\_size})$;\5
+$\\{info}(\|p)\K\\{hash\_end}+\|q$;\5
+$\\{link}(\|p)\K\\{save\_ptr}$;\5
+$\\{value}(\|p)\K\\{internal}[\|q]$;\5
+$\\{save\_ptr}\K\|p$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M254. At the end of a group, the \\{unsave} routine restores all of the saved
+equivalents in reverse order. This routine will be called only when there
+is at least one boundary item on the save stack.
+
+\Y\P\4\&{procedure}\1\ \37\\{unsave};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{index to saved item}\6
+\|p: \37\\{pointer};\C{temporary register}\2\6
+\&{begin} \37\&{while} $\\{info}(\\{save\_ptr})\I0$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{info}(\\{save\_ptr})$;\6
+\&{if} $\|q>\\{hash\_end}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{internal}[\\{tracing\_restores}]>0$ \1\&{then}\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{restoring\ "})$;\5
+$\\{slow\_print}(\\{int\_name}[\|q-(\\{hash\_end})])$;\5
+$\\{print\_char}(\.{"="})$;\5
+$\\{print\_scaled}(\\{value}(\\{save\_ptr}))$;\5
+$\\{print\_char}(\.{"\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end};\2\6
+$\\{internal}[\|q-(\\{hash\_end})]\K\\{value}(\\{save\_ptr})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{internal}[\\{tracing\_restores}]>0$ \1%
+\&{then}\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{restoring\ "})$;\5
+$\\{slow\_print}(\\{text}(\|q))$;\5
+$\\{print\_char}(\.{"\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end};\2\6
+$\\{clear\_symbol}(\|q,\39\\{false})$;\5
+$\\{eqtb}[\|q]\K\\{saved\_equiv}(\\{save\_ptr})$;\6
+\&{if} $\\{eq\_type}(\|q)\mathbin{\&{mod}}\\{outer\_tag}=\\{tag\_token}$ \1%
+\&{then}\6
+\&{begin} \37$\|p\K\\{equiv}(\|q)$;\6
+\&{if} $\|p\I\\{null}$ \1\&{then}\5
+$\\{name\_type}(\|p)\K\\{root}$;\2\6
+\&{end};\2\6
+\&{end};\2\6
+$\|p\K\\{link}(\\{save\_ptr})$;\5
+$\\{free\_node}(\\{save\_ptr},\39\\{save\_node\_size})$;\5
+$\\{save\_ptr}\K\|p$;\6
+\&{end};\2\6
+$\|p\K\\{link}(\\{save\_ptr})$;\5
+$\\{free\_avail}(\\{save\_ptr})$;\5
+$\\{save\_ptr}\K\|p$;\6
+\&{end};\par
+\fi
+
+\N255. \[17] Data structures for paths.
+When a \MF\ user specifies a path, \MF\ will create a list of knots
+and control points for the associated cubic spline curves. If the
+knots are $z_0$, $z_1$, \dots, $z_n$, there are control points
+$z_k^+$ and $z_{k+1}^-$ such that the cubic splines between knots
+$z_k$ and $z_{k+1}$ are defined by B\'ezier's formula
+$$\eqalign{z(t)&=B(z_k,z_k^+,z_{k+1}^-,z_{k+1};t)\cr
+&=(1-t)^3z_k+3(1-t)^2tz_k^++3(1-t)t^2z_{k+1}^-+t^3z_{k+1}\cr}$$
+for $0\L\|t\L1$.
+
+There is a 7-word node for each knot $z_k$, containing one word of
+control information and six words for the \|x and \|y coordinates
+of $z_k^-$ and $z_k$ and~$z_k^+$. The control information appears
+in the \\{left\_type} and \\{right\_type} fields, which each occupy
+a quarter of the first word in the node; they specify properties
+of the curve as it enters and leaves the knot. There's also a
+halfword \\{link} field, which points to the following knot.
+
+If the path is a closed contour, knots 0 and \|n are identical;
+i.e., the \\{link} in knot $\|n-1$ points to knot~0. But if the path
+is not closed, the \\{left\_type} of knot~0 and the \\{right\_type} of knot~\|n
+are equal to \\{endpoint}. In the latter case the \\{link} in knot~\|n points
+to knot~0, and the control points $z_0^-$ and $z_n^+$ are not used.
+
+\Y\P\D \37$\\{left\_type}(\#)\S\\{mem}[\#].\\{hh}.\\{b0}$\C{characterizes the
+path entering this knot}\par
+\P\D \37$\\{right\_type}(\#)\S\\{mem}[\#].\\{hh}.\\{b1}$\C{characterizes the
+path leaving this knot}\par
+\P\D \37$\\{endpoint}=0$\C{\\{left\_type} at path beginning and \\{right\_type}
+at path end}\par
+\P\D \37$\\{x\_coord}(\#)\S\\{mem}[\#+1].\\{sc}$\C{the \|x coordinate of this
+knot}\par
+\P\D \37$\\{y\_coord}(\#)\S\\{mem}[\#+2].\\{sc}$\C{the \|y coordinate of this
+knot}\par
+\P\D \37$\\{left\_x}(\#)\S\\{mem}[\#+3].\\{sc}$\C{the \|x coordinate of
+previous control point}\par
+\P\D \37$\\{left\_y}(\#)\S\\{mem}[\#+4].\\{sc}$\C{the \|y coordinate of
+previous control point}\par
+\P\D \37$\\{right\_x}(\#)\S\\{mem}[\#+5].\\{sc}$\C{the \|x coordinate of next
+control point}\par
+\P\D \37$\\{right\_y}(\#)\S\\{mem}[\#+6].\\{sc}$\C{the \|y coordinate of next
+control point}\par
+\P\D \37$\\{knot\_node\_size}=7$\C{number of words in a knot node}\par
+\fi
+
+\M256. Before the B\'ezier control points have been calculated, the memory
+space they will ultimately occupy is taken up by information that can be
+used to compute them. There are four cases:
+
+\yskip
+\textindent{$\bullet$} If $\\{right\_type}=\\{open}$, the curve should leave
+the knot in the same direction it entered; \MF\ will figure out a
+suitable direction.
+
+\yskip
+\textindent{$\bullet$} If $\\{right\_type}=\\{curl}$, the curve should leave
+the
+knot in a direction depending on the angle at which it enters the next
+knot and on the curl parameter stored in \\{right\_curl}.
+
+\yskip
+\textindent{$\bullet$} If $\\{right\_type}=\\{given}$, the curve should leave
+the
+knot in a nonzero direction stored as an \\{angle} in \\{right\_given}.
+
+\yskip
+\textindent{$\bullet$} If $\\{right\_type}=\\{explicit}$, the B\'ezier control
+point for leaving this knot has already been computed; it is in the
+\\{right\_x} and \\{right\_y} fields.
+
+\yskip\noindent
+The rules for \\{left\_type} are similar, but they refer to the curve entering
+the knot, and to \\{left} fields instead of \\{right} fields.
+
+Non-\\{explicit} control points will be chosen based on ``tension'' parameters
+in the \\{left\_tension} and \\{right\_tension} fields. The
+`\&{atleast}' option is represented by negative tension values.
+
+For example, the \MF\ path specification
+$$\.{z0..z1..tension atleast 1..\{curl 2\}z2..z3\{-1,-2\}..tension
+3 and 4..p},$$
+where \.p is the path `\.{z4..controls z45 and z54..z5}', will be represented
+by the six knots
+\def\lodash{\hbox to 1.1em{\thinspace\hrulefill\thinspace}}
+$$\vbox{\halign{#\hfil&&\qquad#\hfil\cr
+\\{left\_type}&\\{left} info&$\\{x\_coord},\\{y\_coord}$&\\{right\_type}&%
+\\{right} info\cr
+\noalign{\yskip}
+\\{endpoint}&\lodash$,\,$\lodash&$x_0,y_0$&\\{curl}&$1.0,1.0$\cr
+\\{open}&\lodash$,1.0$&$x_1,y_1$&\\{open}&\lodash$,-1.0$\cr
+\\{curl}&$2.0,-1.0$&$x_2,y_2$&\\{curl}&$2.0,1.0$\cr
+\\{given}&$d,1.0$&$x_3,y_3$&\\{given}&$d,3.0$\cr
+\\{open}&\lodash$,4.0$&$x_4,y_4$&\\{explicit}&$x_{45},y_{45}$\cr
+\\{explicit}&$x_{54},y_{54}$&$x_5,y_5$&\\{endpoint}&\lodash$,\,$\lodash\cr}}$$
+Here \|d is the \\{angle} obtained by calling $\\{n\_arg}(-\\{unity},-%
+\\{two})$.
+Of course, this example is more complicated than anything a normal user
+would ever write.
+
+These types must satisfy certain restrictions because of the form of \MF's
+path syntax:
+(i)~\\{open} type never appears in the same node together with \\{endpoint},
+\\{given}, or \\{curl}.
+(ii)~The \\{right\_type} of a node is \\{explicit} if and only if the
+\\{left\_type} of the following node is \\{explicit}.
+(iii)~\\{endpoint} types occur only at the ends, as mentioned above.
+
+\Y\P\D \37$\\{left\_curl}\S\\{left\_x}$\C{curl information when entering this
+knot}\par
+\P\D \37$\\{left\_given}\S\\{left\_x}$\C{given direction when entering this
+knot}\par
+\P\D \37$\\{left\_tension}\S\\{left\_y}$\C{tension information when entering
+this knot}\par
+\P\D \37$\\{right\_curl}\S\\{right\_x}$\C{curl information when leaving this
+knot}\par
+\P\D \37$\\{right\_given}\S\\{right\_x}$\C{given direction when leaving this
+knot}\par
+\P\D \37$\\{right\_tension}\S\\{right\_y}$\C{tension information when leaving
+this knot}\par
+\P\D \37$\\{explicit}=1$\C{\\{left\_type} or \\{right\_type} when control
+points are known}\par
+\P\D \37$\\{given}=2$\C{\\{left\_type} or \\{right\_type} when a direction is
+given}\par
+\P\D \37$\\{curl}=3$\C{\\{left\_type} or \\{right\_type} when a curl is
+desired}\par
+\P\D \37$\\{open}=4$\C{\\{left\_type} or \\{right\_type} when \MF\ should
+choose the direction}\par
+\fi
+
+\M257. Here is a diagnostic routine that prints a given knot list
+in symbolic form. It illustrates the conventions discussed above,
+and checks for anomalies that might arise while \MF\ is being debugged.
+
+\Y\P$\4\X257:Declare subroutines for printing expressions\X\S$\6
+\4\&{procedure}\1\ \37$\\{print\_path}(\|h:\\{pointer};\,\35\|s:\\{str%
+\_number};\,\35\\{nuline}:\\{boolean})$;\6
+\4\&{label} \37$\\{done},\39\\{done1}$;\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{for list traversal}\2\6
+\&{begin} \37$\\{print\_diagnostic}(\.{"Path"},\39\|s,\39\\{nuline})$;\5
+\\{print\_ln};\5
+$\|p\K\|h$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|p)$;\6
+\&{if} $(\|p=\\{null})\V(\|q=\\{null})$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"???"})$;\5
+\&{goto} \37\\{done};\C{this won't happen}\6
+\&{end};\2\6
+\X258:Print information for adjacent knots \|p and \|q\X;\6
+$\|p\K\|q$;\6
+\&{if} $(\|p\I\|h)\V(\\{left\_type}(\|h)\I\\{endpoint})$ \1\&{then}\5
+\X259:Print two dots, followed by \\{given} or \\{curl} if present\X;\2\6
+\4\&{until}\5
+$\|p=\|h$;\2\6
+\&{if} $\\{left\_type}(\|h)\I\\{endpoint}$ \1\&{then}\5
+$\\{print}(\.{"cycle"})$;\2\6
+\4\\{done}: \37$\\{end\_diagnostic}(\\{true})$;\6
+\&{end};\par
+\As332, 388, 473, 589, 801\ETs807.
+\U246.\fi
+
+\M258. \P$\X258:Print information for adjacent knots \|p and \|q\X\S$\6
+$\\{print\_two}(\\{x\_coord}(\|p),\39\\{y\_coord}(\|p))$;\6
+\&{case} $\\{right\_type}(\|p)$ \1\&{of}\6
+\4\\{endpoint}: \37\&{begin} \37\&{if} $\\{left\_type}(\|p)=\\{open}$ \1%
+\&{then}\5
+$\\{print}(\.{"\{open?\}"})$;\C{can't happen}\2\6
+\&{if} $(\\{left\_type}(\|q)\I\\{endpoint})\V(\|q\I\|h)$ \1\&{then}\5
+$\|q\K\\{null}$;\C{force an error}\2\6
+\&{goto} \37\\{done1};\6
+\&{end};\6
+\4\\{explicit}: \37\X261:Print control points between \|p and \|q, then %
+\&{goto} \\{done1}\X;\6
+\4\\{open}: \37\X262:Print information for a curve that begins \\{open}\X;\6
+\4$\\{curl},\39\\{given}$: \37\X263:Print information for a curve that begins %
+\\{curl} or \\{given}\X;\6
+\4\&{othercases} \37$\\{print}(\.{"???"})$\C{can't happen}\2\6
+\&{endcases};\6
+\&{if} $\\{left\_type}(\|q)\L\\{explicit}$ \1\&{then}\5
+$\\{print}(\.{"..control?"})$\C{can't happen}\6
+\4\&{else} \&{if} $(\\{right\_tension}(\|p)\I\\{unity})\V(\\{left\_tension}(%
+\|q)\I\\{unity})$ \1\&{then}\5
+\X260:Print tension between \|p and \|q\X;\2\2\6
+\4\\{done1}: \37\par
+\U257.\fi
+
+\M259. Since \\{n\_sin\_cos} produces \\{fraction} results, which we will print
+as if they
+were \\{scaled}, the magnitude of a \\{given} direction vector will be~4096.
+
+\Y\P$\4\X259:Print two dots, followed by \\{given} or \\{curl} if present\X\S$\6
+\&{begin} \37$\\{print\_nl}(\.{"\ .."})$;\6
+\&{if} $\\{left\_type}(\|p)=\\{given}$ \1\&{then}\6
+\&{begin} \37$\\{n\_sin\_cos}(\\{left\_given}(\|p))$;\5
+$\\{print\_char}(\.{"\{"})$;\5
+$\\{print\_scaled}(\\{n\_cos})$;\5
+$\\{print\_char}(\.{","})$;\5
+$\\{print\_scaled}(\\{n\_sin})$;\5
+$\\{print\_char}(\.{"\}"})$;\6
+\&{end}\6
+\4\&{else} \&{if} $\\{left\_type}(\|p)=\\{curl}$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"\{curl\ "})$;\5
+$\\{print\_scaled}(\\{left\_curl}(\|p))$;\5
+$\\{print\_char}(\.{"\}"})$;\6
+\&{end};\2\2\6
+\&{end}\par
+\U257.\fi
+
+\M260. \P$\X260:Print tension between \|p and \|q\X\S$\6
+\&{begin} \37$\\{print}(\.{"..tension\ "})$;\6
+\&{if} $\\{right\_tension}(\|p)<0$ \1\&{then}\5
+$\\{print}(\.{"atleast"})$;\2\6
+$\\{print\_scaled}(\\{abs}(\\{right\_tension}(\|p)))$;\6
+\&{if} $\\{right\_tension}(\|p)\I\\{left\_tension}(\|q)$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"\ and\ "})$;\6
+\&{if} $\\{left\_tension}(\|q)<0$ \1\&{then}\5
+$\\{print}(\.{"atleast"})$;\2\6
+$\\{print\_scaled}(\\{abs}(\\{left\_tension}(\|q)))$;\6
+\&{end};\2\6
+\&{end}\par
+\U258.\fi
+
+\M261. \P$\X261:Print control points between \|p and \|q, then \&{goto} %
+\\{done1}\X\S$\6
+\&{begin} \37$\\{print}(\.{"..controls\ "})$;\5
+$\\{print\_two}(\\{right\_x}(\|p),\39\\{right\_y}(\|p))$;\5
+$\\{print}(\.{"\ and\ "})$;\6
+\&{if} $\\{left\_type}(\|q)\I\\{explicit}$ \1\&{then}\5
+$\\{print}(\.{"??"})$\C{can't happen}\6
+\4\&{else} $\\{print\_two}(\\{left\_x}(\|q),\39\\{left\_y}(\|q))$;\2\6
+\&{goto} \37\\{done1};\6
+\&{end}\par
+\U258.\fi
+
+\M262. \P$\X262:Print information for a curve that begins \\{open}\X\S$\6
+\&{if} $(\\{left\_type}(\|p)\I\\{explicit})\W(\\{left\_type}(\|p)\I\\{open})$ %
+\1\&{then}\5
+$\\{print}(\.{"\{open?\}"})$\C{can't happen}\2\par
+\U258.\fi
+
+\M263. A curl of 1 is shown explicitly, so that the user sees clearly that
+\MF's default curl is present.
+
+The code here uses the fact that $\\{left\_curl}\S\\{left\_given}$ and
+$\\{right\_curl}\S\\{right\_given}$.
+
+\Y\P$\4\X263:Print information for a curve that begins \\{curl} or \\{given}\X%
+\S$\6
+\&{begin} \37\&{if} $\\{left\_type}(\|p)=\\{open}$ \1\&{then}\5
+$\\{print}(\.{"??"})$;\C{can't happen}\2\6
+\&{if} $\\{right\_type}(\|p)=\\{curl}$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"\{curl\ "})$;\5
+$\\{print\_scaled}(\\{right\_curl}(\|p))$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{n\_sin\_cos}(\\{right\_given}(\|p))$;\5
+$\\{print\_char}(\.{"\{"})$;\5
+$\\{print\_scaled}(\\{n\_cos})$;\5
+$\\{print\_char}(\.{","})$;\5
+$\\{print\_scaled}(\\{n\_sin})$;\6
+\&{end};\2\6
+$\\{print\_char}(\.{"\}"})$;\6
+\&{end}\par
+\U258.\fi
+
+\M264. If we want to duplicate a knot node, we can say \\{copy\_knot}:
+
+\Y\P\4\&{function}\1\ \37$\\{copy\_knot}(\|p:\\{pointer})$: \37\\{pointer};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the copy}\6
+\|k: \37$0\to\\{knot\_node\_size}-1$;\C{runs through the words of a knot node}%
+\2\6
+\&{begin} \37$\|q\K\\{get\_node}(\\{knot\_node\_size})$;\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{knot\_node\_size}-1$ \1\&{do}\5
+$\\{mem}[\|q+\|k]\K\\{mem}[\|p+\|k]$;\2\6
+$\\{copy\_knot}\K\|q$;\6
+\&{end};\par
+\fi
+
+\M265. The \\{copy\_path} routine makes a clone of a given path.
+
+\Y\P\4\&{function}\1\ \37$\\{copy\_path}(\|p:\\{pointer})$: \37\\{pointer};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\|q,\39\\{pp},\39\\{qq}$: \37\\{pointer};\C{for list
+manipulation}\2\6
+\&{begin} \37$\|q\K\\{get\_node}(\\{knot\_node\_size})$;\C{this will correspond
+to \|p}\6
+$\\{qq}\K\|q$;\5
+$\\{pp}\K\|p$;\6
+\~ \1\&{loop}\ \&{begin} \37$\\{left\_type}(\\{qq})\K\\{left\_type}(\\{pp})$;\5
+$\\{right\_type}(\\{qq})\K\\{right\_type}(\\{pp})$;\6
+$\\{x\_coord}(\\{qq})\K\\{x\_coord}(\\{pp})$;\5
+$\\{y\_coord}(\\{qq})\K\\{y\_coord}(\\{pp})$;\6
+$\\{left\_x}(\\{qq})\K\\{left\_x}(\\{pp})$;\5
+$\\{left\_y}(\\{qq})\K\\{left\_y}(\\{pp})$;\6
+$\\{right\_x}(\\{qq})\K\\{right\_x}(\\{pp})$;\5
+$\\{right\_y}(\\{qq})\K\\{right\_y}(\\{pp})$;\6
+\&{if} $\\{link}(\\{pp})=\|p$ \1\&{then}\6
+\&{begin} \37$\\{link}(\\{qq})\K\|q$;\5
+$\\{copy\_path}\K\|q$;\5
+\&{return};\6
+\&{end};\2\6
+$\\{link}(\\{qq})\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{qq}\K\\{link}(\\{qq})$;\5
+$\\{pp}\K\\{link}(\\{pp})$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M266. Similarly, there's a way to copy the {\sl reverse\/} of a path. This
+procedure
+returns a pointer to the first node of the copy, if the path is a cycle,
+but to the final node of a non-cyclic copy. The global
+variable \\{path\_tail} will point to the final node of the original path;
+this trick makes it easier to implement `\&{doublepath}'.
+
+All node types are assumed to be \\{endpoint} or \\{explicit} only.
+
+\Y\P\4\&{function}\1\ \37$\\{htap\_ypoc}(\|p:\\{pointer})$: \37\\{pointer};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\|q,\39\\{pp},\39\\{qq},\39\\{rr}$: \37\\{pointer};\C{for list
+manipulation}\2\6
+\&{begin} \37$\|q\K\\{get\_node}(\\{knot\_node\_size})$;\C{this will correspond
+to \|p}\6
+$\\{qq}\K\|q$;\5
+$\\{pp}\K\|p$;\6
+\~ \1\&{loop}\ \&{begin} \37$\\{right\_type}(\\{qq})\K\\{left\_type}(\\{pp})$;\5
+$\\{left\_type}(\\{qq})\K\\{right\_type}(\\{pp})$;\6
+$\\{x\_coord}(\\{qq})\K\\{x\_coord}(\\{pp})$;\5
+$\\{y\_coord}(\\{qq})\K\\{y\_coord}(\\{pp})$;\6
+$\\{right\_x}(\\{qq})\K\\{left\_x}(\\{pp})$;\5
+$\\{right\_y}(\\{qq})\K\\{left\_y}(\\{pp})$;\6
+$\\{left\_x}(\\{qq})\K\\{right\_x}(\\{pp})$;\5
+$\\{left\_y}(\\{qq})\K\\{right\_y}(\\{pp})$;\6
+\&{if} $\\{link}(\\{pp})=\|p$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|q)\K\\{qq}$;\5
+$\\{path\_tail}\K\\{pp}$;\5
+$\\{htap\_ypoc}\K\|q$;\5
+\&{return};\6
+\&{end};\2\6
+$\\{rr}\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{link}(\\{rr})\K\\{qq}$;\5
+$\\{qq}\K\\{rr}$;\5
+$\\{pp}\K\\{link}(\\{pp})$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M267. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{path\_tail}: \37\\{pointer};\C{the node that links to the beginning of a
+path}\par
+\fi
+
+\M268. When a cyclic list of knot nodes is no longer needed, it can be recycled
+by
+calling the following subroutine.
+
+\Y\P$\4\X268:Declare the recycling subroutines\X\S$\6
+\4\&{procedure}\1\ \37$\\{toss\_knot\_list}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the node being freed}\6
+\|r: \37\\{pointer};\C{the next node}\2\6
+\&{begin} \37$\|q\K\|p$;\6
+\1\&{repeat} \37$\|r\K\\{link}(\|q)$;\5
+$\\{free\_node}(\|q,\39\\{knot\_node\_size})$;\5
+$\|q\K\|r$;\6
+\4\&{until}\5
+$\|q=\|p$;\2\6
+\&{end};\par
+\As385, 487, 620\ETs809.
+\U246.\fi
+
+\N269. \[18] Choosing control points.
+Now we must actually delve into one of \MF's more difficult routines,
+the \\{make\_choices} procedure that chooses angles and control points for
+the splines of a curve when the user has not specified them explicitly.
+The parameter to \\{make\_choices} points to a list of knots and
+path information, as described above.
+
+A path decomposes into independent segments at ``breakpoint'' knots,
+which are knots whose left and right angles are both prespecified in
+some way (i.e., their \\{left\_type} and \\{right\_type} aren't both open).
+
+\Y\P\hbox{\4}\X284:Declare the procedure called \\{solve\_choices}\X\6
+\4\&{procedure}\1\ \37$\\{make\_choices}(\\{knots}:\\{pointer})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|h: \37\\{pointer};\C{the first breakpoint}\6
+$\|p,\39\|q$: \37\\{pointer};\C{consecutive breakpoints being processed}\6
+\X280:Other local variables for \\{make\_choices}\X\2\6
+\&{begin} \37\\{check\_arith};\C{make sure that $\\{arith\_error}=\\{false}$}\6
+\&{if} $\\{internal}[\\{tracing\_choices}]>0$ \1\&{then}\5
+$\\{print\_path}(\\{knots},\39\.{",\ before\ choices"},\39\\{true})$;\2\6
+\X271:If consecutive knots are equal, join them explicitly\X;\6
+\X272:Find the first breakpoint, \|h, on the path; insert an artificial
+breakpoint if the path is an unbroken cycle\X;\6
+$\|p\K\|h$;\6
+\1\&{repeat} \37\X273:Fill in the control points between \|p and the next
+breakpoint, then advance \|p to that breakpoint\X;\6
+\4\&{until}\5
+$\|p=\|h$;\2\6
+\&{if} $\\{internal}[\\{tracing\_choices}]>0$ \1\&{then}\5
+$\\{print\_path}(\\{knots},\39\.{",\ after\ choices"},\39\\{true})$;\2\6
+\&{if} $\\{arith\_error}$ \1\&{then}\5
+\X270:Report an unexpected problem during the choice-making\X;\2\6
+\&{end};\par
+\fi
+
+\M270. \P$\X270:Report an unexpected problem during the choice-making\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Some\ number\ got\ too\ big"})$;\5
+$\\{help2}(\.{"The\ path\ that\ I\ just\ computed\ is\ out\ of\ range."})$\6
+$(\.{"So\ it\ will\ probably\ look\ funny.\ Proceed,\ for\ a\ laugh."})$;\5
+\\{put\_get\_error};\5
+$\\{arith\_error}\K\\{false}$;\6
+\&{end}\par
+\U269.\fi
+
+\M271. Two knots in a row with the same coordinates will always be joined
+by an explicit ``curve'' whose control points are identical with the
+knots.
+
+\Y\P$\4\X271:If consecutive knots are equal, join them explicitly\X\S$\6
+$\|p\K\\{knots}$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|p)$;\6
+\&{if} $\\{x\_coord}(\|p)=\\{x\_coord}(\|q)$ \1\&{then}\6
+\&{if} $\\{y\_coord}(\|p)=\\{y\_coord}(\|q)$ \1\&{then}\6
+\&{if} $\\{right\_type}(\|p)>\\{explicit}$ \1\&{then}\6
+\&{begin} \37$\\{right\_type}(\|p)\K\\{explicit}$;\6
+\&{if} $\\{left\_type}(\|p)=\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{left\_type}(\|p)\K\\{curl}$;\5
+$\\{left\_curl}(\|p)\K\\{unity}$;\6
+\&{end};\2\6
+$\\{left\_type}(\|q)\K\\{explicit}$;\6
+\&{if} $\\{right\_type}(\|q)=\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{right\_type}(\|q)\K\\{curl}$;\5
+$\\{right\_curl}(\|q)\K\\{unity}$;\6
+\&{end};\2\6
+$\\{right\_x}(\|p)\K\\{x\_coord}(\|p)$;\5
+$\\{left\_x}(\|q)\K\\{x\_coord}(\|p)$;\6
+$\\{right\_y}(\|p)\K\\{y\_coord}(\|p)$;\5
+$\\{left\_y}(\|q)\K\\{y\_coord}(\|p)$;\6
+\&{end};\2\2\2\6
+$\|p\K\|q$;\6
+\4\&{until}\5
+$\|p=\\{knots}$\2\par
+\U269.\fi
+
+\M272. If there are no breakpoints, it is necessary to compute the direction
+angles around an entire cycle. In this case the \\{left\_type} of the first
+node is temporarily changed to \\{end\_cycle}.
+
+\Y\P\D \37$\\{end\_cycle}=\\{open}+1$\par
+\Y\P$\4\X272:Find the first breakpoint, \|h, on the path; insert an artificial
+breakpoint if the path is an unbroken cycle\X\S$\6
+$\|h\K\\{knots}$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\\{left\_type}(\|h)\I\\{open}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\\{right\_type}(\|h)\I\\{open}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|h\K\\{link}(\|h)$;\6
+\&{if} $\|h=\\{knots}$ \1\&{then}\6
+\&{begin} \37$\\{left\_type}(\|h)\K\\{end\_cycle}$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\&{end};\2\6
+\4\\{done}: \37\par
+\U269.\fi
+
+\M273. If $\\{right\_type}(\|p)<\\{given}$ and $\|q=\\{link}(\|p)$, we must
+have
+$\\{right\_type}(\|p)=\\{left\_type}(\|q)=\\{explicit}$ or \\{endpoint}.
+
+\Y\P$\4\X273:Fill in the control points between \|p and the next breakpoint,
+then advance \|p to that breakpoint\X\S$\6
+$\|q\K\\{link}(\|p)$;\6
+\&{if} $\\{right\_type}(\|p)\G\\{given}$ \1\&{then}\6
+\&{begin} \37\&{while} $(\\{left\_type}(\|q)=\\{open})\W(\\{right\_type}(\|q)=%
+\\{open})$ \1\&{do}\5
+$\|q\K\\{link}(\|q)$;\2\6
+\X278:Fill in the control information between consecutive breakpoints \|p and %
+\|q\X;\6
+\&{end};\2\6
+$\|p\K\|q$\par
+\U269.\fi
+
+\M274. Before we can go further into the way choices are made, we need to
+consider the underlying theory. The basic ideas implemented in \\{make%
+\_choices}
+are due to John Hobby, who introduced the notion of ``mock curvature''
+at a knot. Angles are chosen so that they preserve mock curvature when
+a knot is passed, and this has been found to produce excellent results.
+
+It is convenient to introduce some notations that simplify the necessary
+formulas. Let $d_{k,k+1}=\vert z\k-z_k\vert$ be the (nonzero) distance
+between knots \|k and $\|k+1$; and let
+$${z\k-z_k\over z_k-z_{k-1}}={d_{k,k+1}\over d_{k-1,k}}e^{i\psi_k}$$
+so that a polygonal line from $z_{k-1}$ to $z_k$ to $z\k$ turns left
+through an angle of~$\psi_k$. We assume that $\vert\psi_k\vert\L180^\circ$.
+The control points for the spline from $z_k$ to $z\k$ will be denoted by
+$$\eqalign{z_k^+&=z_k+
+\textstyle{1\over3}\rho_k e^{i\theta_k}(z\k-z_k),\cr
+z\k^-&=z\k-
+\textstyle{1\over3}\sigma\k e^{-i\phi\k}(z\k-z_k),\cr}$$
+where $\rho_k$ and $\sigma\k$ are nonnegative ``velocity ratios'' at the
+beginning and end of the curve, while $\theta_k$ and $\phi\k$ are the
+corresponding ``offset angles.'' These angles satisfy the condition
+$$\theta_k+\phi_k+\psi_k=0,\eqno(*)$$
+whenever the curve leaves an intermediate knot~\|k in the direction that
+it enters.
+
+\fi
+
+\M275. Let $\alpha_k$ and $\beta\k$ be the reciprocals of the ``tension'' of
+the curve at its beginning and ending points. This means that
+$\rho_k=\alpha_k f(\theta_k,\phi\k)$ and $\sigma\k=\beta\k f(\phi\k,\theta_k)$,
+where $f(\theta,\phi)$ is \MF's standard velocity function defined in
+the \\{velocity} subroutine. The cubic spline $B(z_k^{\phantom+},z_k^+,
+z\k^-,z\k^{\phantom+};t)$
+has curvature
+$${2\sigma\k\sin(\theta_k+\phi\k)-6\sin\theta_k\over\rho_k^2d_{k,k+1}}
+\qquad{\rm and}\qquad
+{2\rho_k\sin(\theta_k+\phi\k)-6\sin\phi\k\over\sigma\k^2d_{k,k+1}}$$
+at $\|t=0$ and $\|t=1$, respectively. The mock curvature is the linear
+approximation to this true curvature that arises in the limit for
+small $\theta_k$ and~$\phi\k$, if second-order terms are discarded.
+The standard velocity function satisfies
+$$f(\theta,\phi)=1+O(\theta^2+\theta\phi+\phi^2);$$
+hence the mock curvatures are respectively
+$${2\beta\k(\theta_k+\phi\k)-6\theta_k\over\alpha_k^2d_{k,k+1}}
+\qquad{\rm and}\qquad
+{2\alpha_k(\theta_k+\phi\k)-6\phi\k\over\beta\k^2d_{k,k+1}}.\eqno(**)$$
+
+\fi
+
+\M276. The turning angles $\psi_k$ are given, and equation $(*)$ above
+determines $\phi_k$ when $\theta_k$ is known, so the task of
+angle selection is essentially to choose appropriate values for each
+$\theta_k$. When equation~$(*)$ is used to eliminate $\phi$~variables
+from $(**)$, we obtain a system of linear equations of the form
+$$A_k\theta_{k-1}+(B_k+C_k)\theta_k+D_k\theta\k=-B_k\psi_k-D_k\psi\k,$$
+where
+$$A_k={\alpha_{k-1}\over\beta_k^2d_{k-1,k}},
+\qquad B_k={3-\alpha_{k-1}\over\beta_k^2d_{k-1,k}},
+\qquad C_k={3-\beta\k\over\alpha_k^2d_{k,k+1}},
+\qquad D_k={\beta\k\over\alpha_k^2d_{k,k+1}}.$$
+The tensions are always $3\over4$ or more, hence each $\alpha$ and~$\beta$
+will be at most $4\over3$. It follows that $B_k\G{5\over4}A_k$ and
+$C_k\G{5\over4}D_k$; hence the equations are diagonally dominant;
+hence they have a unique solution. Moreover, in most cases the tensions
+are equal to~1, so that $B_k=2A_k$ and $C_k=2D_k$. This makes the
+solution numerically stable, and there is an exponential damping
+effect: The data at knot $k\pm j$ affects the angle at knot~$k$ by
+a factor of~$O(2^{-j})$.
+
+\fi
+
+\M277. However, we still must consider the angles at the starting and ending
+knots of a non-cyclic path. These angles might be given explicitly, or
+they might be specified implicitly in terms of an amount of ``curl.''
+
+Let's assume that angles need to be determined for a non-cyclic path
+starting at $z_0$ and ending at~$z_n$. Then equations of the form
+$$A_k\theta_{k-1}+(B_k+C_k)\theta_k+D_k\theta_{k+1}=R_k$$
+have been given for $0<k<n$, and it will be convenient to introduce
+equations of the same form for $k=0$ and $k=n$, where
+$$A_0=B_0=C_n=D_n=0.$$
+If $\theta_0$ is supposed to have a given value $E_0$, we simply
+define $C_0=0$, $D_0=0$, and $R_0=E_0$. Otherwise a curl
+parameter, $\gamma_0$, has been specified at~$z_0$; this means
+that the mock curvature at $z_0$ should be $\gamma_0$ times the
+mock curvature at $z_1$; i.e.,
+$${2\beta_1(\theta_0+\phi_1)-6\theta_0\over\alpha_0^2d_{01}}
+=\gamma_0{2\alpha_0(\theta_0+\phi_1)-6\phi_1\over\beta_1^2d_{01}}.$$
+This equation simplifies to
+$$(\alpha_0\chi_0+3-\beta_1)\theta_0+
+\bigl((3-\alpha_0)\chi_0+\beta_1\bigr)\theta_1=
+-\bigl((3-\alpha_0)\chi_0+\beta_1\bigr)\psi_1,$$
+where $\chi_0=\alpha_0^2\gamma_0/\beta_1^2$; so we can set $C_0=
+\chi_0\alpha_0+3-\beta_1$, $D_0=(3-\alpha_0)\chi_0+\beta_1$, $R_0=-D_0\psi_1$.
+It can be shown that $C_0>0$ and $C_0B_1-A_1D_0>0$ when $\gamma_0\G0$,
+hence the linear equations remain nonsingular.
+
+Similar considerations apply at the right end, when the final angle $\phi_n$
+may or may not need to be determined. It is convenient to let $\psi_n=0$,
+hence $\theta_n=-\phi_n$. We either have an explicit equation $\theta_n=E_n$,
+or we have
+$$\bigl((3-\beta_n)\chi_n+\alpha_{n-1}\bigr)\theta_{n-1}+
+(\beta_n\chi_n+3-\alpha_{n-1})\theta_n=0,\qquad
+\chi_n={\beta_n^2\gamma_n\over\alpha_{n-1}^2}.$$
+
+When \\{make\_choices} chooses angles, it must compute the coefficients of
+these linear equations, then solve the equations. To compute the coefficients,
+it is necessary to compute arctangents of the given turning angles~$\psi_k$.
+When the equations are solved, the chosen directions $\theta_k$ are put
+back into the form of control points by essentially computing sines and
+cosines.
+
+\fi
+
+\M278. OK, we are ready to make the hard choices of \\{make\_choices}.
+Most of the work is relegated to an auxiliary procedure
+called \\{solve\_choices}, which has been introduced to keep
+\\{make\_choices} from being extremely long.
+
+\Y\P$\4\X278:Fill in the control information between consecutive breakpoints %
+\|p and \|q\X\S$\6
+\X281:Calculate the turning angles $\psi_k$ and the distances $d_{k,k+1}$; set
+$n$ to the length of the path\X;\6
+\X282:Remove \\{open} types at the breakpoints\X;\6
+$\\{solve\_choices}(\|p,\39\|q,\39\|n)$\par
+\U273.\fi
+
+\M279. It's convenient to precompute quantities that will be needed several
+times later. The values of $\\{delta\_x}[\|k]$ and $\\{delta\_y}[\|k]$ will be
+the
+coordinates of $z\k-z_k$, and the magnitude of this vector will be
+$\\{delta}[\|k]=\hbox{$d_{k,k+1}$}$. The path angle $\psi_k$ between
+$z_k-z_{k-1}$
+and $z\k-z_k$ will be stored in $\\{psi}[\|k]$.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{delta\_x},\39\\{delta\_y},\39\\{delta}$: \37\&{array} $[0\to\\{path%
+\_size}]$ \1\&{of}\5
+\\{scaled};\C{knot differences}\2\6
+\4\\{psi}: \37\&{array} $[1\to\\{path\_size}]$ \1\&{of}\5
+\\{angle};\C{turning angles}\2\par
+\fi
+
+\M280. \P$\X280:Other local variables for \\{make\_choices}\X\S$\6
+\4$\|k,\39\|n$: \37$0\to\\{path\_size}$;\C{current and final knot numbers}\6
+\4$\|s,\39\|t$: \37\\{pointer};\C{registers for list traversal}\6
+\4$\\{delx},\39\\{dely}$: \37\\{scaled};\C{directions where \\{open} meets %
+\\{explicit}}\6
+\4$\\{sine},\39\\{cosine}$: \37\\{fraction};\C{trig functions of various
+angles}\par
+\U269.\fi
+
+\M281. \P$\X281:Calculate the turning angles $\psi_k$ and the distances
+$d_{k,k+1}$; set $n$ to the length of the path\X\S$\6
+$\|k\K0$;\5
+$\|s\K\|p$;\5
+$\|n\K\\{path\_size}$;\6
+\1\&{repeat} \37$\|t\K\\{link}(\|s)$;\5
+$\\{delta\_x}[\|k]\K\\{x\_coord}(\|t)-\\{x\_coord}(\|s)$;\5
+$\\{delta\_y}[\|k]\K\\{y\_coord}(\|t)-\\{y\_coord}(\|s)$;\5
+$\\{delta}[\|k]\K\\{pyth\_add}(\\{delta\_x}[\|k],\39\\{delta\_y}[\|k])$;\6
+\&{if} $\|k>0$ \1\&{then}\6
+\&{begin} \37$\\{sine}\K\\{make\_fraction}(\\{delta\_y}[\|k-1],\39\\{delta}[%
+\|k-1])$;\5
+$\\{cosine}\K\\{make\_fraction}(\\{delta\_x}[\|k-1],\39\\{delta}[\|k-1])$;\5
+$\\{psi}[\|k]\K\\{n\_arg}(\\{take\_fraction}(\\{delta\_x}[\|k],\39\\{cosine})+%
+\\{take\_fraction}(\\{delta\_y}[\|k],\39\\{sine}),\39\\{take\_fraction}(%
+\\{delta\_y}[\|k],\39\\{cosine})-\\{take\_fraction}(\\{delta\_x}[\|k],\39%
+\\{sine}))$;\6
+\&{end};\2\6
+$\\{incr}(\|k)$;\5
+$\|s\K\|t$;\6
+\&{if} $\|k=\\{path\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"path\ size"},\39\\{path\_size})$;\2\6
+\&{if} $\|s=\|q$ \1\&{then}\5
+$\|n\K\|k$;\2\6
+\4\&{until}\5
+$(\|k\G\|n)\W(\\{left\_type}(\|s)\I\\{end\_cycle})$;\2\6
+\&{if} $\|k=\|n$ \1\&{then}\5
+$\\{psi}[\|n]\K0$\ \&{else} $\\{psi}[\|k]\K\\{psi}[1]$\2\par
+\U278.\fi
+
+\M282. When we get to this point of the code, $\\{right\_type}(\|p)$ is either
+\\{given} or \\{curl} or \\{open}. If it is \\{open}, we must have
+$\\{left\_type}(\|p)=\\{end\_cycle}$ or $\\{left\_type}(\|p)=\\{explicit}$. In
+the latter
+case, the \\{open} type is converted to \\{given}; however, if the
+velocity coming into this knot is zero, the \\{open} type is
+converted to a \\{curl}, since we don't know the incoming direction.
+
+Similarly, $\\{left\_type}(\|q)$ is either \\{given} or \\{curl} or \\{open} or
+\\{end\_cycle}. The \\{open} possibility is reduced either to \\{given} or to %
+\\{curl}.
+
+\Y\P$\4\X282:Remove \\{open} types at the breakpoints\X\S$\6
+\&{if} $\\{left\_type}(\|q)=\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{delx}\K\\{right\_x}(\|q)-\\{x\_coord}(\|q)$;\5
+$\\{dely}\K\\{right\_y}(\|q)-\\{y\_coord}(\|q)$;\6
+\&{if} $(\\{delx}=0)\W(\\{dely}=0)$ \1\&{then}\6
+\&{begin} \37$\\{left\_type}(\|q)\K\\{curl}$;\5
+$\\{left\_curl}(\|q)\K\\{unity}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{left\_type}(\|q)\K\\{given}$;\5
+$\\{left\_given}(\|q)\K\\{n\_arg}(\\{delx},\39\\{dely})$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{if} $(\\{right\_type}(\|p)=\\{open})\W(\\{left\_type}(\|p)=\\{explicit})$ \1%
+\&{then}\6
+\&{begin} \37$\\{delx}\K\\{x\_coord}(\|p)-\\{left\_x}(\|p)$;\5
+$\\{dely}\K\\{y\_coord}(\|p)-\\{left\_y}(\|p)$;\6
+\&{if} $(\\{delx}=0)\W(\\{dely}=0)$ \1\&{then}\6
+\&{begin} \37$\\{right\_type}(\|p)\K\\{curl}$;\5
+$\\{right\_curl}(\|p)\K\\{unity}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{right\_type}(\|p)\K\\{given}$;\5
+$\\{right\_given}(\|p)\K\\{n\_arg}(\\{delx},\39\\{dely})$;\6
+\&{end};\2\6
+\&{end}\2\par
+\U278.\fi
+
+\M283. Linear equations need to be solved whenever $\|n>1$; and also when $%
+\|n=1$
+and exactly one of the breakpoints involves a curl. The simplest case occurs
+when $\|n=1$ and there is a curl at both breakpoints; then we simply draw
+a straight line.
+
+But before coding up the simple cases, we might as well face the general case,
+since we must deal with it sooner or later, and since the general case
+is likely to give some insight into the way simple cases can be handled best.
+
+When there is no cycle, the linear equations to be solved form a tri-diagonal
+system, and we can apply the standard technique of Gaussian elimination
+to convert that system to a sequence of equations of the form
+$$\theta_0+u_0\theta_1=v_0,\quad
+\theta_1+u_1\theta_2=v_1,\quad\ldots,\quad
+\theta_{n-1}+u_{n-1}\theta_n=v_{n-1},\quad
+\theta_n=v_n.$$
+It is possible to do this diagonalization while generating the equations.
+Once $\theta_n$ is known, it is easy to determine $\theta_{n-1}$, \dots,
+$\theta_1$, $\theta_0$; thus, the equations will be solved.
+
+The procedure is slightly more complex when there is a cycle, but the
+basic idea will be nearly the same. In the cyclic case the right-hand
+sides will be $v_k+w_k\theta_0$ instead of simply $v_k$, and we will start
+the process off with $u_0=v_0=0$, $w_0=1$. The final equation will be not
+$\theta_n=v_n$ but $\theta_n+u_n\theta_1=v_n+w_n\theta_0$; an appropriate
+ending routine will take account of the fact that $\theta_n=\theta_0$ and
+eliminate the $w$'s from the system, after which the solution can be
+obtained as before.
+
+When $u_k$, $v_k$, and $w_k$ are being computed, the three pointer
+variables \|r, \|s,~\|t will point respectively to knots $\|k-1$, \|k,
+and~$\|k+1$. The $u$'s and $w$'s are scaled by $2^{28}$, i.e., they are
+of type \\{fraction}; the $\theta$'s and $v$'s are of type \\{angle}.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{theta}: \37\&{array} $[0\to\\{path\_size}]$ \1\&{of}\5
+\\{angle};\C{values of $\theta_k$}\2\6
+\4\\{uu}: \37\&{array} $[0\to\\{path\_size}]$ \1\&{of}\5
+\\{fraction};\C{values of $u_k$}\2\6
+\4\\{vv}: \37\&{array} $[0\to\\{path\_size}]$ \1\&{of}\5
+\\{angle};\C{values of $v_k$}\2\6
+\4\\{ww}: \37\&{array} $[0\to\\{path\_size}]$ \1\&{of}\5
+\\{fraction};\C{values of $w_k$}\2\par
+\fi
+
+\M284. Our immediate problem is to get the ball rolling by setting up the
+first equation or by realizing that no equations are needed, and to fit
+this initialization into a framework suitable for the overall computation.
+
+\Y\P$\4\X284:Declare the procedure called \\{solve\_choices}\X\S$\6
+\hbox{\4}\X296:Declare subroutines needed by \\{solve\_choices}\X\6
+\4\&{procedure}\1\ \37$\\{solve\_choices}(\|p,\39\|q:\\{pointer};\,\35\|n:%
+\\{halfword})$;\6
+\4\&{label} \37$\\{found},\39\\{exit}$;\6
+\4\&{var} \37\|k: \37$0\to\\{path\_size}$;\C{current knot number}\6
+$\|r,\39\|s,\39\|t$: \37\\{pointer};\C{registers for list traversal}\6
+\X286:Other local variables for \\{solve\_choices}\X\2\6
+\&{begin} \37$\|k\K0$;\5
+$\|s\K\|p$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|t\K\\{link}(\|s)$;\6
+\&{if} $\|k=0$ \1\&{then}\5
+\X285:Get the linear equations started; or \&{return} with the control points
+in place, if linear equations needn't be solved\X\6
+\4\&{else} \&{case} $\\{left\_type}(\|s)$ \1\&{of}\6
+\4$\\{end\_cycle},\39\\{open}$: \37\X287:Set up equation to match mock
+curvatures at $z_k$; then \&{goto} \\{found} with $\theta_n$ adjusted to equal
+$\theta_0$, if a cycle has ended\X;\6
+\4\\{curl}: \37\X295:Set up equation for a curl at $\theta_n$ and \&{goto} %
+\\{found}\X;\6
+\4\\{given}: \37\X292:Calculate the given value of $\theta_n$ and \&{goto} %
+\\{found}\X;\2\6
+\&{end};\C{there are no other cases}\2\6
+$\|r\K\|s$;\5
+$\|s\K\|t$;\5
+$\\{incr}(\|k)$;\6
+\&{end};\2\6
+\4\\{found}: \37\X297:Finish choosing angles and assigning control points\X;\6
+\4\\{exit}: \37\&{end};\par
+\U269.\fi
+
+\M285. On the first time through the loop, we have $\|k=0$ and \|r is not yet
+defined. The first linear equation, if any, will have $A_0=B_0=0$.
+
+\Y\P$\4\X285:Get the linear equations started; or \&{return} with the control
+points in place, if linear equations needn't be solved\X\S$\6
+\&{case} $\\{right\_type}(\|s)$ \1\&{of}\6
+\4\\{given}: \37\&{if} $\\{left\_type}(\|t)=\\{given}$ \1\&{then}\5
+\X301:Reduce to simple case of two givens and \&{return}\X\6
+\4\&{else} \X293:Set up the equation for a given value of $\theta_0$\X;\2\6
+\4\\{curl}: \37\&{if} $\\{left\_type}(\|t)=\\{curl}$ \1\&{then}\5
+\X302:Reduce to simple case of straight line and \&{return}\X\6
+\4\&{else} \X294:Set up the equation for a curl at $\theta_0$\X;\2\6
+\4\\{open}: \37\&{begin} \37$\\{uu}[0]\K0$;\5
+$\\{vv}[0]\K0$;\5
+$\\{ww}[0]\K\\{fraction\_one}$;\6
+\&{end};\C{this begins a cycle}\2\6
+\&{end}\C{there are no other cases}\par
+\U284.\fi
+
+\M286. The general equation that specifies equality of mock curvature at $z_k$
+is
+$$A_k\theta_{k-1}+(B_k+C_k)\theta_k+D_k\theta\k=-B_k\psi_k-D_k\psi\k,$$
+as derived above. We want to combine this with the already-derived equation
+$\theta_{k-1}+u_{k-1}\theta_k=v_{k-1}+w_{k-1}\theta_0$ in order to obtain
+a new equation
+$\theta_k+u_k\theta\k=v_k+w_k\theta_0$. This can be done by dividing the
+equation
+$$(B_k-u_{k-1}A_k+C_k)\theta_k+D_k\theta\k=-B_k\psi_k-D_k\psi\k-A_kv_{k-1}
+-A_kw_{k-1}\theta_0$$
+by $B_k-u_{k-1}A_k+C_k$. The trick is to do this carefully with
+fixed-point arithmetic, avoiding the chance of overflow while retaining
+suitable precision.
+
+The calculations will be performed in several registers that
+provide temporary storage for intermediate quantities.
+
+\Y\P$\4\X286:Other local variables for \\{solve\_choices}\X\S$\6
+\4$\\{aa},\39\\{bb},\39\\{cc},\39\\{ff},\39\\{acc}$: \37\\{fraction};%
+\C{temporary registers}\6
+\4$\\{dd},\39\\{ee}$: \37\\{scaled};\C{likewise, but \\{scaled}}\6
+\4$\\{lt},\39\\{rt}$: \37\\{scaled};\C{tension values}\par
+\U284.\fi
+
+\M287. \P$\X287:Set up equation to match mock curvatures at $z_k$; then %
+\&{goto} \\{found} with $\theta_n$ adjusted to equal $\theta_0$, if a cycle has
+ended\X\S$\6
+\&{begin} \37\X288:Calculate the values $\\{aa}=A_k/B_k$, $\\{bb}=D_k/C_k$, $%
+\\{dd}=(3-\alpha_{k-1})d_{k,k+1}$, $\\{ee}=(3-\beta\k)d_{k-1,k}$, and $%
+\\{cc}=(B_k-u_{k-1}A_k)/B_k$\X;\6
+\X289:Calculate the ratio $\\{ff}=C_k/(C_k+B_k-u_{k-1}A_k)$\X;\6
+$\\{uu}[\|k]\K\\{take\_fraction}(\\{ff},\39\\{bb})$;\5
+\X290:Calculate the values of $v_k$ and $w_k$\X;\6
+\&{if} $\\{left\_type}(\|s)=\\{end\_cycle}$ \1\&{then}\5
+\X291:Adjust $\theta_n$ to equal $\theta_0$ and \&{goto} \\{found}\X;\2\6
+\&{end}\par
+\U284.\fi
+
+\M288. Since tension values are never less than 3/4, the values \\{aa} and
+\\{bb} computed here are never more than 4/5.
+
+\Y\P$\4\X288:Calculate the values $\\{aa}=A_k/B_k$, $\\{bb}=D_k/C_k$, $%
+\\{dd}=(3-\alpha_{k-1})d_{k,k+1}$, $\\{ee}=(3-\beta\k)d_{k-1,k}$, and $%
+\\{cc}=(B_k-u_{k-1}A_k)/B_k$\X\S$\6
+\&{if} $\\{abs}(\\{right\_tension}(\|r))=\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{aa}\K\\{fraction\_half}$;\5
+$\\{dd}\K2\ast\\{delta}[\|k]$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{aa}\K\\{make\_fraction}(\\{unity},\393\ast\\{abs}(%
+\\{right\_tension}(\|r))-\\{unity})$;\5
+$\\{dd}\K\\{take\_fraction}(\\{delta}[\|k],\39\\{fraction\_three}-\\{make%
+\_fraction}(\\{unity},\39\\{abs}(\\{right\_tension}(\|r))))$;\6
+\&{end};\2\6
+\&{if} $\\{abs}(\\{left\_tension}(\|t))=\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{bb}\K\\{fraction\_half}$;\5
+$\\{ee}\K2\ast\\{delta}[\|k-1]$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{bb}\K\\{make\_fraction}(\\{unity},\393\ast\\{abs}(%
+\\{left\_tension}(\|t))-\\{unity})$;\5
+$\\{ee}\K\\{take\_fraction}(\\{delta}[\|k-1],\39\\{fraction\_three}-\\{make%
+\_fraction}(\\{unity},\39\\{abs}(\\{left\_tension}(\|t))))$;\6
+\&{end};\2\6
+$\\{cc}\K\\{fraction\_one}-\\{take\_fraction}(\\{uu}[\|k-1],\39\\{aa})$\par
+\U287.\fi
+
+\M289. The ratio to be calculated in this step can be written in the form
+$$\beta_k^2\cdot\\{ee}\over\beta_k^2\cdot\\{ee}+\alpha_k^2\cdot
+\\{cc}\cdot\\{dd},$$
+because of the quantities just calculated. The values of \\{dd} and \\{ee}
+will not be needed after this step has been performed.
+
+\Y\P$\4\X289:Calculate the ratio $\\{ff}=C_k/(C_k+B_k-u_{k-1}A_k)$\X\S$\6
+$\\{dd}\K\\{take\_fraction}(\\{dd},\39\\{cc})$;\5
+$\\{lt}\K\\{abs}(\\{left\_tension}(\|s))$;\5
+$\\{rt}\K\\{abs}(\\{right\_tension}(\|s))$;\6
+\&{if} $\\{lt}\I\\{rt}$ \1\&{then}\C{$\beta_k^{-1}\ne\alpha_k^{-1}$}\6
+\&{if} $\\{lt}<\\{rt}$ \1\&{then}\6
+\&{begin} \37$\\{ff}\K\\{make\_fraction}(\\{lt},\39\\{rt})$;\5
+$\\{ff}\K\\{take\_fraction}(\\{ff},\39\\{ff})$;\C{$\alpha_k^2/\beta_k^2$}\6
+$\\{dd}\K\\{take\_fraction}(\\{dd},\39\\{ff})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{ff}\K\\{make\_fraction}(\\{rt},\39\\{lt})$;\5
+$\\{ff}\K\\{take\_fraction}(\\{ff},\39\\{ff})$;\C{$\beta_k^2/\alpha_k^2$}\6
+$\\{ee}\K\\{take\_fraction}(\\{ee},\39\\{ff})$;\6
+\&{end};\2\2\6
+$\\{ff}\K\\{make\_fraction}(\\{ee},\39\\{ee}+\\{dd})$\par
+\U287.\fi
+
+\M290. The value of $u_{k-1}$ will be $\L1$ except when $k=1$ and the previous
+equation was specified by a curl. In that case we must use a special
+method of computation to prevent overflow.
+
+Fortunately, the calculations turn out to be even simpler in this ``hard''
+case. The curl equation makes $w_0=0$ and $v_0=-u_0\psi_1$, hence
+$-B_1\psi_1-A_1v_0=-(B_1-u_0A_1)\psi_1=-\\{cc}\cdot B_1\psi_1$.
+
+\Y\P$\4\X290:Calculate the values of $v_k$ and $w_k$\X\S$\6
+$\\{acc}\K-\\{take\_fraction}(\\{psi}[\|k+1],\39\\{uu}[\|k])$;\6
+\&{if} $\\{right\_type}(\|r)=\\{curl}$ \1\&{then}\6
+\&{begin} \37$\\{ww}[\|k]\K0$;\5
+$\\{vv}[\|k]\K\\{acc}-\\{take\_fraction}(\\{psi}[1],\39\\{fraction\_one}-%
+\\{ff})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{ff}\K\\{make\_fraction}(\\{fraction\_one}-\\{ff},%
+\39\\{cc})$;\C{this is $B_k/(C_k+B_k-u_{k-1}A_k)<5$}\6
+$\\{acc}\K\\{acc}-\\{take\_fraction}(\\{psi}[\|k],\39\\{ff})$;\5
+$\\{ff}\K\\{take\_fraction}(\\{ff},\39\\{aa})$;\C{this is
+$A_k/(C_k+B_k-u_{k-1}A_k)$}\6
+$\\{vv}[\|k]\K\\{acc}-\\{take\_fraction}(\\{vv}[\|k-1],\39\\{ff})$;\6
+\&{if} $\\{ww}[\|k-1]=0$ \1\&{then}\5
+$\\{ww}[\|k]\K0$\6
+\4\&{else} $\\{ww}[\|k]\K-\\{take\_fraction}(\\{ww}[\|k-1],\39\\{ff})$;\2\6
+\&{end}\2\par
+\U287.\fi
+
+\M291. When a complete cycle has been traversed, we have $\theta_k+u_k\theta\k=
+v_k+w_k\theta_0$, for $1\L\|k\L\|n$. We would like to determine the value of
+$\theta_n$ and reduce the system to the form $\theta_k+u_k\theta\k=v_k$
+for $0\L\|k<\|n$, so that the cyclic case can be finished up just as if there
+were no cycle.
+
+The idea in the following code is to observe that
+$$\eqalign{\theta_n&=v_n+w_n\theta_0-u_n\theta_1=\cdots\cr
+&=v_n+w_n\theta_0-u_n\bigl(v_1+w_1\theta_0-u_1(v_2+\cdots
+-u_{n-2}(v_{n-1}+w_{n-1}\theta_0-u_{n-1}\theta_0)\ldots{})\bigr),\cr}$$
+so we can solve for $\theta_n=\theta_0$.
+
+\Y\P$\4\X291:Adjust $\theta_n$ to equal $\theta_0$ and \&{goto} \\{found}\X\S$\6
+\&{begin} \37$\\{aa}\K0$;\5
+$\\{bb}\K\\{fraction\_one}$;\C{we have $\|k=\|n$}\6
+\1\&{repeat} \37$\\{decr}(\|k)$;\6
+\&{if} $\|k=0$ \1\&{then}\5
+$\|k\K\|n$;\2\6
+$\\{aa}\K\\{vv}[\|k]-\\{take\_fraction}(\\{aa},\39\\{uu}[\|k])$;\5
+$\\{bb}\K\\{ww}[\|k]-\\{take\_fraction}(\\{bb},\39\\{uu}[\|k])$;\6
+\4\&{until}\5
+$\|k=\|n$;\C{now $\theta_n=\\{aa}+\\{bb}\cdot\theta_n$}\2\6
+$\\{aa}\K\\{make\_fraction}(\\{aa},\39\\{fraction\_one}-\\{bb})$;\5
+$\\{theta}[\|n]\K\\{aa}$;\5
+$\\{vv}[0]\K\\{aa}$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}\|n-1$ \1\&{do}\5
+$\\{vv}[\|k]\K\\{vv}[\|k]+\\{take\_fraction}(\\{aa},\39\\{ww}[\|k])$;\2\6
+\&{goto} \37\\{found};\6
+\&{end}\par
+\U287.\fi
+
+\M292. \P\D \37$\\{reduce\_angle}(\#)\S$\1\6
+\&{if} $\\{abs}(\#)>\\{one\_eighty\_deg}$ \1\&{then}\6
+\&{if} $\#>0$ \1\&{then}\5
+$\#\K\#-\\{three\_sixty\_deg}$\ \&{else} $\#\K\#+\\{three\_sixty\_deg}$\2\2\2%
+\par
+\Y\P$\4\X292:Calculate the given value of $\theta_n$ and \&{goto} \\{found}\X%
+\S$\6
+\&{begin} \37$\\{theta}[\|n]\K\\{left\_given}(\|s)-\\{n\_arg}(\\{delta\_x}[%
+\|n-1],\39\\{delta\_y}[\|n-1])$;\5
+$\\{reduce\_angle}(\\{theta}[\|n])$;\5
+\&{goto} \37\\{found};\6
+\&{end}\par
+\U284.\fi
+
+\M293. \P$\X293:Set up the equation for a given value of $\theta_0$\X\S$\6
+\&{begin} \37$\\{vv}[0]\K\\{right\_given}(\|s)-\\{n\_arg}(\\{delta\_x}[0],\39%
+\\{delta\_y}[0])$;\5
+$\\{reduce\_angle}(\\{vv}[0])$;\5
+$\\{uu}[0]\K0$;\5
+$\\{ww}[0]\K0$;\6
+\&{end}\par
+\U285.\fi
+
+\M294. \P$\X294:Set up the equation for a curl at $\theta_0$\X\S$\6
+\&{begin} \37$\\{cc}\K\\{right\_curl}(\|s)$;\5
+$\\{lt}\K\\{abs}(\\{left\_tension}(\|t))$;\5
+$\\{rt}\K\\{abs}(\\{right\_tension}(\|s))$;\6
+\&{if} $(\\{rt}=\\{unity})\W(\\{lt}=\\{unity})$ \1\&{then}\5
+$\\{uu}[0]\K\\{make\_fraction}(\\{cc}+\\{cc}+\\{unity},\39\\{cc}+\\{two})$\6
+\4\&{else} $\\{uu}[0]\K\\{curl\_ratio}(\\{cc},\39\\{rt},\39\\{lt})$;\2\6
+$\\{vv}[0]\K-\\{take\_fraction}(\\{psi}[1],\39\\{uu}[0])$;\5
+$\\{ww}[0]\K0$;\6
+\&{end}\par
+\U285.\fi
+
+\M295. \P$\X295:Set up equation for a curl at $\theta_n$ and \&{goto} \\{found}%
+\X\S$\6
+\&{begin} \37$\\{cc}\K\\{left\_curl}(\|s)$;\5
+$\\{lt}\K\\{abs}(\\{left\_tension}(\|s))$;\5
+$\\{rt}\K\\{abs}(\\{right\_tension}(\|r))$;\6
+\&{if} $(\\{rt}=\\{unity})\W(\\{lt}=\\{unity})$ \1\&{then}\5
+$\\{ff}\K\\{make\_fraction}(\\{cc}+\\{cc}+\\{unity},\39\\{cc}+\\{two})$\6
+\4\&{else} $\\{ff}\K\\{curl\_ratio}(\\{cc},\39\\{lt},\39\\{rt})$;\2\6
+$\\{theta}[\|n]\K-\\{make\_fraction}(\\{take\_fraction}(\\{vv}[\|n-1],\39%
+\\{ff}),\39\\{fraction\_one}-\\{take\_fraction}(\\{ff},\39\\{uu}[\|n-1]))$;\5
+\&{goto} \37\\{found};\6
+\&{end}\par
+\U284.\fi
+
+\M296. The \\{curl\_ratio} subroutine has three arguments, which our previous
+notation
+encourages us to call $\gamma$, $\alpha^{-1}$, and $\beta^{-1}$. It is
+a somewhat tedious program to calculate
+$${(3-\alpha)\alpha^2\gamma+\beta^3\over
+\alpha^3\gamma+(3-\beta)\beta^2},$$
+with the result reduced to 4 if it exceeds 4. (This reduction of curl
+is necessary only if the curl and tension are both large.)
+The values of $\alpha$ and $\beta$ will be at most~4/3.
+
+\Y\P$\4\X296:Declare subroutines needed by \\{solve\_choices}\X\S$\6
+\4\&{function}\1\ \37$\\{curl\_ratio}(\\{gamma},\39\\{a\_tension},\39\\{b%
+\_tension}:\\{scaled})$: \37\\{fraction};\6
+\4\&{var} \37$\\{alpha},\39\\{beta},\39\\{num},\39\\{denom},\39\\{ff}$: \37%
+\\{fraction};\C{registers}\2\6
+\&{begin} \37$\\{alpha}\K\\{make\_fraction}(\\{unity},\39\\{a\_tension})$;\5
+$\\{beta}\K\\{make\_fraction}(\\{unity},\39\\{b\_tension})$;\6
+\&{if} $\\{alpha}\L\\{beta}$ \1\&{then}\6
+\&{begin} \37$\\{ff}\K\\{make\_fraction}(\\{alpha},\39\\{beta})$;\5
+$\\{ff}\K\\{take\_fraction}(\\{ff},\39\\{ff})$;\5
+$\\{gamma}\K\\{take\_fraction}(\\{gamma},\39\\{ff})$;\6
+$\\{beta}\K\\{beta}\mathbin{\&{div}}\O{10000}$;\C{convert \\{fraction} to %
+\\{scaled}}\6
+$\\{denom}\K\\{take\_fraction}(\\{gamma},\39\\{alpha})+\\{three}-\\{beta}$;\5
+$\\{num}\K\\{take\_fraction}(\\{gamma},\39\\{fraction\_three}-\\{alpha})+%
+\\{beta}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{ff}\K\\{make\_fraction}(\\{beta},\39\\{alpha})$;\5
+$\\{ff}\K\\{take\_fraction}(\\{ff},\39\\{ff})$;\5
+$\\{beta}\K\\{take\_fraction}(\\{beta},\39\\{ff})\mathbin{\&{div}}\O{10000}$;%
+\C{convert \\{fraction} to \\{scaled}}\6
+$\\{denom}\K\\{take\_fraction}(\\{gamma},\39\\{alpha})+(\\{ff}\mathbin{%
+\&{div}}1365)-\\{beta}$;\C{$1365\approx 2^{12}/3$}\6
+$\\{num}\K\\{take\_fraction}(\\{gamma},\39\\{fraction\_three}-\\{alpha})+%
+\\{beta}$;\6
+\&{end};\2\6
+\&{if} $\\{num}\G\\{denom}+\\{denom}+\\{denom}+\\{denom}$ \1\&{then}\5
+$\\{curl\_ratio}\K\\{fraction\_four}$\6
+\4\&{else} $\\{curl\_ratio}\K\\{make\_fraction}(\\{num},\39\\{denom})$;\2\6
+\&{end};\par
+\A299.
+\U284.\fi
+
+\M297. We're in the home stretch now.
+
+\Y\P$\4\X297:Finish choosing angles and assigning control points\X\S$\6
+\&{for} $\|k\K\|n-1\mathrel{\&{downto}}0$ \1\&{do}\5
+$\\{theta}[\|k]\K\\{vv}[\|k]-\\{take\_fraction}(\\{theta}[\|k+1],\39\\{uu}[%
+\|k])$;\2\6
+$\|s\K\|p$;\5
+$\|k\K0$;\6
+\1\&{repeat} \37$\|t\K\\{link}(\|s)$;\6
+$\\{n\_sin\_cos}(\\{theta}[\|k])$;\5
+$\\{st}\K\\{n\_sin}$;\5
+$\\{ct}\K\\{n\_cos}$;\6
+$\\{n\_sin\_cos}(-\\{psi}[\|k+1]-\\{theta}[\|k+1])$;\5
+$\\{sf}\K\\{n\_sin}$;\5
+$\\{cf}\K\\{n\_cos}$;\6
+$\\{set\_controls}(\|s,\39\|t,\39\|k)$;\6
+$\\{incr}(\|k)$;\5
+$\|s\K\|t$;\6
+\4\&{until}\5
+$\|k=\|n$\2\par
+\U284.\fi
+
+\M298. The \\{set\_controls} routine actually puts the control points into
+a pair of consecutive nodes \|p and~\|q. Global variables are used to
+record the values of $\sin\theta$, $\cos\theta$, $\sin\phi$, and
+$\cos\phi$ needed in this calculation.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{st},\39\\{ct},\39\\{sf},\39\\{cf}$: \37\\{fraction};\C{sines and cosines}%
+\par
+\fi
+
+\M299. \P$\X296:Declare subroutines needed by \\{solve\_choices}\X\mathrel{+}%
+\S$\6
+\4\&{procedure}\1\ \37$\\{set\_controls}(\|p,\39\|q:\\{pointer};\,\35\|k:%
+\\{integer})$;\6
+\4\&{var} \37$\\{rr},\39\\{ss}$: \37\\{fraction};\C{velocities, divided by
+thrice the tension}\6
+$\\{lt},\39\\{rt}$: \37\\{scaled};\C{tensions}\6
+\\{sine}: \37\\{fraction};\C{$\sin(\theta+\phi)$}\2\6
+\&{begin} \37$\\{lt}\K\\{abs}(\\{left\_tension}(\|q))$;\5
+$\\{rt}\K\\{abs}(\\{right\_tension}(\|p))$;\5
+$\\{rr}\K\\{velocity}(\\{st},\39\\{ct},\39\\{sf},\39\\{cf},\39\\{rt})$;\5
+$\\{ss}\K\\{velocity}(\\{sf},\39\\{cf},\39\\{st},\39\\{ct},\39\\{lt})$;\6
+\&{if} $(\\{right\_tension}(\|p)<0)\V(\\{left\_tension}(\|q)<0)$ \1\&{then}\5
+\X300:Decrease the velocities, if necessary, to stay inside the bounding
+triangle\X;\2\6
+$\\{right\_x}(\|p)\K\\{x\_coord}(\|p)+\\{take\_fraction}(\\{take\_fraction}(%
+\\{delta\_x}[\|k],\39\\{ct})-\\{take\_fraction}(\\{delta\_y}[\|k],\39\\{st}),%
+\39\\{rr})$;\5
+$\\{right\_y}(\|p)\K\\{y\_coord}(\|p)+\\{take\_fraction}(\\{take\_fraction}(%
+\\{delta\_y}[\|k],\39\\{ct})+\\{take\_fraction}(\\{delta\_x}[\|k],\39\\{st}),%
+\39\\{rr})$;\5
+$\\{left\_x}(\|q)\K\\{x\_coord}(\|q)-\\{take\_fraction}(\\{take\_fraction}(%
+\\{delta\_x}[\|k],\39\\{cf})+\\{take\_fraction}(\\{delta\_y}[\|k],\39\\{sf}),%
+\39\\{ss})$;\5
+$\\{left\_y}(\|q)\K\\{y\_coord}(\|q)-\\{take\_fraction}(\\{take\_fraction}(%
+\\{delta\_y}[\|k],\39\\{cf})-\\{take\_fraction}(\\{delta\_x}[\|k],\39\\{sf}),%
+\39\\{ss})$;\5
+$\\{right\_type}(\|p)\K\\{explicit}$;\5
+$\\{left\_type}(\|q)\K\\{explicit}$;\6
+\&{end};\par
+\fi
+
+\M300. The boundedness conditions $\\{rr}\L\sin\phi\,/\sin(\theta+\phi)$ and
+$\\{ss}\L\sin\theta\,/\sin(\theta+\phi)$ are to be enforced if $\sin\theta$,
+$\sin\phi$, and $\sin(\theta+\phi)$ all have the same sign. Otherwise
+there is no ``bounding triangle.''
+
+\Y\P$\4\X300:Decrease the velocities, if necessary, to stay inside the bounding
+triangle\X\S$\6
+\&{if} $((\\{st}\G0)\W(\\{sf}\G0))\V((\\{st}\L0)\W(\\{sf}\L0))$ \1\&{then}\6
+\&{begin} \37$\\{sine}\K\\{take\_fraction}(\\{abs}(\\{st}),\39\\{cf})+\\{take%
+\_fraction}(\\{abs}(\\{sf}),\39\\{ct})$;\6
+\&{if} $\\{sine}>0$ \1\&{then}\6
+\&{begin} \37$\\{sine}\K\\{take\_fraction}(\\{sine},\39\\{fraction\_one}+%
+\\{unity})$;\C{safety factor}\6
+\&{if} $\\{right\_tension}(\|p)<0$ \1\&{then}\6
+\&{if} $\\{ab\_vs\_cd}(\\{abs}(\\{sf}),\39\\{fraction\_one},\39\\{rr},\39%
+\\{sine})<0$ \1\&{then}\5
+$\\{rr}\K\\{make\_fraction}(\\{abs}(\\{sf}),\39\\{sine})$;\2\2\6
+\&{if} $\\{left\_tension}(\|q)<0$ \1\&{then}\6
+\&{if} $\\{ab\_vs\_cd}(\\{abs}(\\{st}),\39\\{fraction\_one},\39\\{ss},\39%
+\\{sine})<0$ \1\&{then}\5
+$\\{ss}\K\\{make\_fraction}(\\{abs}(\\{st}),\39\\{sine})$;\2\2\6
+\&{end};\2\6
+\&{end}\2\par
+\U299.\fi
+
+\M301. Only the simple cases remain to be handled.
+
+\Y\P$\4\X301:Reduce to simple case of two givens and \&{return}\X\S$\6
+\&{begin} \37$\\{aa}\K\\{n\_arg}(\\{delta\_x}[0],\39\\{delta\_y}[0])$;\6
+$\\{n\_sin\_cos}(\\{right\_given}(\|p)-\\{aa})$;\5
+$\\{ct}\K\\{n\_cos}$;\5
+$\\{st}\K\\{n\_sin}$;\6
+$\\{n\_sin\_cos}(\\{left\_given}(\|q)-\\{aa})$;\5
+$\\{cf}\K\\{n\_cos}$;\5
+$\\{sf}\K-\\{n\_sin}$;\6
+$\\{set\_controls}(\|p,\39\|q,\390)$;\5
+\&{return};\6
+\&{end}\par
+\U285.\fi
+
+\M302. \P$\X302:Reduce to simple case of straight line and \&{return}\X\S$\6
+\&{begin} \37$\\{right\_type}(\|p)\K\\{explicit}$;\5
+$\\{left\_type}(\|q)\K\\{explicit}$;\5
+$\\{lt}\K\\{abs}(\\{left\_tension}(\|q))$;\5
+$\\{rt}\K\\{abs}(\\{right\_tension}(\|p))$;\6
+\&{if} $\\{rt}=\\{unity}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{delta\_x}[0]\G0$ \1\&{then}\5
+$\\{right\_x}(\|p)\K\\{x\_coord}(\|p)+((\\{delta\_x}[0]+1)\mathbin{\&{div}}3)$\6
+\4\&{else} $\\{right\_x}(\|p)\K\\{x\_coord}(\|p)+((\\{delta\_x}[0]-1)\mathbin{%
+\&{div}}3)$;\2\6
+\&{if} $\\{delta\_y}[0]\G0$ \1\&{then}\5
+$\\{right\_y}(\|p)\K\\{y\_coord}(\|p)+((\\{delta\_y}[0]+1)\mathbin{\&{div}}3)$\6
+\4\&{else} $\\{right\_y}(\|p)\K\\{y\_coord}(\|p)+((\\{delta\_y}[0]-1)\mathbin{%
+\&{div}}3)$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{ff}\K\\{make\_fraction}(\\{unity},\393\ast\\{rt})$;%
+\C{$\alpha/3$}\6
+$\\{right\_x}(\|p)\K\\{x\_coord}(\|p)+\\{take\_fraction}(\\{delta\_x}[0],\39%
+\\{ff})$;\5
+$\\{right\_y}(\|p)\K\\{y\_coord}(\|p)+\\{take\_fraction}(\\{delta\_y}[0],\39%
+\\{ff})$;\6
+\&{end};\2\6
+\&{if} $\\{lt}=\\{unity}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{delta\_x}[0]\G0$ \1\&{then}\5
+$\\{left\_x}(\|q)\K\\{x\_coord}(\|q)-((\\{delta\_x}[0]+1)\mathbin{\&{div}}3)$\6
+\4\&{else} $\\{left\_x}(\|q)\K\\{x\_coord}(\|q)-((\\{delta\_x}[0]-1)\mathbin{%
+\&{div}}3)$;\2\6
+\&{if} $\\{delta\_y}[0]\G0$ \1\&{then}\5
+$\\{left\_y}(\|q)\K\\{y\_coord}(\|q)-((\\{delta\_y}[0]+1)\mathbin{\&{div}}3)$\6
+\4\&{else} $\\{left\_y}(\|q)\K\\{y\_coord}(\|q)-((\\{delta\_y}[0]-1)\mathbin{%
+\&{div}}3)$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{ff}\K\\{make\_fraction}(\\{unity},\393\ast\\{lt})$;%
+\C{$\beta/3$}\6
+$\\{left\_x}(\|q)\K\\{x\_coord}(\|q)-\\{take\_fraction}(\\{delta\_x}[0],\39%
+\\{ff})$;\5
+$\\{left\_y}(\|q)\K\\{y\_coord}(\|q)-\\{take\_fraction}(\\{delta\_y}[0],\39%
+\\{ff})$;\6
+\&{end};\2\6
+\&{return};\6
+\&{end}\par
+\U285.\fi
+
+\N303. \[19] Generating discrete moves.
+The purpose of the next part of \MF\ is to compute discrete approximations
+to curves described as parametric polynomial functions $z(t)$.
+We shall start with the low level first, because an efficient ``engine''
+is needed to support the high-level constructions.
+
+Most of the subroutines are based on variations of a single theme,
+namely the idea of {\sl bisection}. Given a Bernshte{\u\i}n polynomial
+$$B(z_0,z_1,\ldots,z_n;t)=\sum_k{n\choose k}t^k(1-t)^{n-k}z_k,$$
+we can conveniently bisect its range as follows:
+
+\smallskip
+\textindent{1)} Let $z_k^{(0)}=z_k$, for $0\L\|k\L\|n$.
+
+\smallskip
+\textindent{2)} Let $z_k^{(j+1)}={1\over2}(z_k^{(j)}+z\k^{(j)})$, for
+$0\L\|k<\|n-\|j$, for $0\L\|j<\|n$.
+
+\smallskip\noindent
+Then
+$$B(z_0,z_1,\ldots,z_n;t)=B(z_0^{(0)},z_0^{(1)},\ldots,z_0^{(n)};2t)
+=B(z_0^{(n)},z_1^{(n-1)},\ldots,z_n^{(0)};2t-1).$$
+This formula gives us the coefficients of polynomials to use over the ranges
+$0\L t\L{1\over2}$ and ${1\over2}\L t\L1$.
+
+In our applications it will usually be possible to work indirectly with
+numbers that allow us to deduce relevant properties of the polynomials
+without actually computing the polynomial values. We will deal with
+coefficients $Z_k=2^l(z_k-z_{k-1})$ for $1\L\|k\L\|n$, instead of
+the actual numbers $z_0$, $z_1$, \dots,~$z_n$, and the value of~\|l will
+increase by~1 at each bisection step. This technique reduces the
+amount of calculation needed for bisection and also increases the
+accuracy of evaluation (since one bit of precision is gained at each
+bisection). Indeed, the bisection process now becomes one level shorter:
+
+\smallskip
+\textindent{$1'$)} Let $Z_k^{(1)}=Z_k$, for $1\L\|k\L\|n$.
+
+\smallskip
+\textindent{$2'$)} Let $Z_k^{(j+1)}={1\over2}(Z_k^{(j)}+Z\k^{(j)})$, for
+$1\L\|k\L\|n-\|j$, for $1\L\|j<\|n$.
+
+\smallskip\noindent
+The relevant coefficients $(Z'_1,\ldots,Z'_n)$ and $(Z''_1,\ldots,Z''_n)$
+for the two subintervals after bisection are respectively
+$(Z_1^{(1)},Z_1^{(2)},\ldots,Z_1^{(n)})$ and
+$(Z_1^{(n)},Z_2^{(n-1)},\ldots,Z_n^{(1)})$.
+And the values of $z_0$ appropriate for the bisected interval are $z'_0=z_0$
+and $z''_0=z_0+(Z_1+Z_2+\cdots+Z_n)/2^{l+1}$.
+
+Step $2'$ involves division by~2, which introduces computational errors
+of at most $1\over2$ at each step; thus after $l$~levels of bisection the
+integers $Z_k$ will differ from their true values by at most $(n-1)l/2$.
+This error rate is quite acceptable, considering that we have $l$~more
+bits of precision in the $Z$'s by comparison with the~$z$'s. Note also
+that the $Z$'s remain bounded; there's no danger of integer overflow, even
+though we have the identity $Z_k=2^l(z_k-z_{k-1})$ for arbitrarily large~$l$.
+
+In fact, we can show not only that the $Z$'s remain bounded, but also that
+they become nearly equal, since they are control points for a polynomial
+of one less degree. If $\vert Z\k-Z_k\vert\L M$ initially, it is possible
+to prove that $\vert Z\k-Z_k\vert\L\lceil M/2^l\rceil$ after $l$~levels
+of bisection, even in the presence of rounding errors. Here's the
+proof [cf.~Lane and Riesenfeld, {\sl IEEE Trans.\ on Pattern Analysis
+and Machine Intelligence\/ \bf PAMI-2} (1980), 35--46]: Assuming that
+$\vert Z\k-Z_k\vert\L M$ before bisection, we want to prove that
+$\vert Z\k-Z_k\vert\L\lceil M/2\rceil$ afterward. First we show that
+$\vert Z\k^{(j)}-Z_k^{(j)}\vert\L M$ for all $j$ and~$k$, by induction
+on~$j$; this follows from the fact that
+$$\bigl\vert\\{half}(a+b)-\\{half}(b+c)\bigr\vert\L
+\max\bigl(\vert a-b\vert,\vert b-c\vert\bigr)$$
+holds for both of the rounding rules $\\{half}(x)=\lfloor x/2\rfloor$
+and $\\{half}(x)={\rm sign}(x)\lfloor\vert x/2\vert\rfloor$.
+(If $\vert a-b\vert$ and $\vert b-c\vert$ are equal, then
+$a+b$ and $b+c$ are both even or both odd. The rounding errors either
+cancel or round the numbers toward each other; hence
+$$\eqalign{\bigl\vert\\{half}(a+b)-\\{half}(b+c)\bigr\vert
+&\L\textstyle\bigl\vert{1\over2}(a+b)-{1\over2}(b+c)\bigr\vert\cr
+&=\textstyle\bigl\vert{1\over2}(a-b)+{1\over2}(b-c)\bigr\vert
+\L\max\bigl(\vert a-b\vert,\vert b-c\vert\bigr),\cr}$$
+as required. A simpler argument applies if $\vert a-b\vert$ and
+$\vert b-c\vert$ are unequal.) Now it is easy to see that
+$\vert Z_1^{(j+1)}-Z_1^{(j)}\vert\L\bigl\lfloor{1\over2}
+\vert Z_2^{(j)}-Z_1^{(j)}\vert+{1\over2}\bigr\rfloor
+\L\bigl\lfloor{1\over2}(M+1)\bigr\rfloor=\lceil M/2\rceil$.
+
+Another interesting fact about bisection is the identity
+$$Z_1'+\cdots+Z_n'+Z_1''+\cdots+Z_n''=2(Z_1+\cdots+Z_n+E),$$
+where $E$ is the sum of the rounding errors in all of the halving
+operations ($\vert E\vert\L n(n-1)/4$).
+
+\fi
+
+\M304. We will later reduce the problem of digitizing a complex cubic
+$z(t)=B(z_0,z_1,z_2,z_3;t)$ to the following simpler problem:
+Given two real cubics
+$x(t)=B(x_0,x_1,x_2,x_3;t)$
+and $y(t)=B(y_0,y_1,y_2,y_3;t)$ that are monotone nondecreasing,
+determine the set of integer points
+$$P=\bigl\{\bigl(\lfloor x(t)\rfloor,\lfloor y(t)\rfloor\bigr)
+\bigm\vert 0\L t\L 1\bigr\}.$$
+Well, the problem isn't actually quite so clean as this; when the path
+goes very near an integer point $(a,b)$, computational errors may
+make us think that $P$ contains $(a-1,b)$ while in reality it should
+contain $(a,b-1)$. Furthermore, if the path goes {\sl exactly\/}
+through the integer points $(a-1,b-1)$ and
+$(a,b)$, we will want $P$ to contain one
+of the two points $(a-1,b)$ or $(a,b-1)$, so that $P$ can be described
+entirely by ``rook moves'' upwards or to the right; no diagonal
+moves from $(a-1,b-1)$ to~$(a,b)$ will be allowed.
+
+Thus, the set $P$ we wish to compute will merely be an approximation
+to the set described in the formula above. It will consist of
+$\lfloor x(1)\rfloor-\lfloor x(0)\rfloor$ rightward moves and
+$\lfloor y(1)\rfloor-\lfloor y(0)\rfloor$ upward moves, intermixed
+in some order. Our job will be to figure out a suitable order.
+
+The following recursive strategy suggests itself, when we recall that
+$x(0)=x_0$, $x(1)=x_3$, $y(0)=y_0$, and $y(1)=y_3$:
+
+\smallskip
+If $\lfloor x_0\rfloor=\lfloor x_3\rfloor$ then take
+$\lfloor y_3\rfloor-\lfloor y_0\rfloor$ steps up.
+
+Otherwise if $\lfloor y_0\rfloor=\lfloor y_3\rfloor$ then take
+$\lfloor x_3\rfloor-\lfloor x_0\rfloor$ steps to the right.
+
+Otherwise bisect the current cubics and repeat the process on both halves.
+
+\yskip\noindent
+This intuitively appealing formulation does not quite solve the problem,
+because it may never terminate. For example, it's not hard to see that
+no steps will {\sl ever\/} be taken if $(x_0,x_1,x_2,x_3)=(y_0,y_1,y_2,y_3)$!
+However, we can surmount this difficulty with a bit of care; so let's
+proceed to flesh out the algorithm as stated, before worrying about
+such details.
+
+The bisect-and-double strategy discussed above suggests that we represent
+$(x_0,x_1,x_2,x_3)$ by $(X_1,X_2,X_3)$, where $X_k=2^l(x_k-x_{k-1})$
+for some~$l$. Initially $l=16$, since the $x$'s are \\{scaled}.
+In order to deal with other aspects of the algorithm we will want to
+maintain also the quantities $m=\lfloor x_3\rfloor-\lfloor x_0\rfloor$
+and $R=2^l(x_0\bmod 1)$. Similarly,
+$(y_0,y_1,y_2,y_3)$ will be represented by $(Y_1,Y_2,Y_3)$,
+$n=\lfloor y_3\rfloor-\lfloor y_0\rfloor$,
+and $S=2^l(y_0\bmod 1)$. The algorithm now takes the following form:
+
+\smallskip
+If $m=0$ then take $n$ steps up.
+
+Otherwise if $n=0$ then take $m$ steps to the right.
+
+Otherwise bisect the current cubics and repeat the process on both halves.
+
+\smallskip\noindent
+The bisection process for $(X_1,X_2,X_3,m,R,l)$ reduces, in essence,
+to the following formulas:
+$$\vbox{\halign{$#\hfil$\cr
+X_2'=\\{half}(X_1+X_2),\quad
+X_2''=\\{half}(X_2+X_3),\quad
+X_3'=\\{half}(X_2'+X_2''),\cr
+X_1'=X_1,\quad
+X_1''=X_3',\quad
+X_3''=X_3,\cr
+R'=2R,\quad
+T=X_1'+X_2'+X_3'+R',\quad
+R''=T\bmod 2^{l+1},\cr
+m'=\lfloor T/2^{l+1}\rfloor,\quad
+m''=m-m'.\cr}}$$
+
+\fi
+
+\M305. When $m=n=1$, the computation can be speeded up because we simply
+need to decide between two alternatives, (up,\thinspace right)
+versus (right,\thinspace up). There appears to be no simple, direct
+way to make the correct decision by looking at the values of
+$(X_1,X_2,X_3,R)$ and
+$(Y_1,Y_2,Y_3,S)$; but we can streamline the bisection process, and
+we can use the fact that only one of the two descendants needs to
+be examined after each bisection. Furthermore, we observed earlier
+that after several levels of bisection the $X$'s and $Y$'s will be nearly
+equal; so we will be justified in assuming that the curve is essentially a
+straight line. (This, incidentally, solves the problem of infinite
+recursion mentioned earlier.)
+
+It is possible to show that
+$$m=\bigl\lfloor(X_1+X_2+X_3+R+E)\,/\,2^l\bigr\rfloor,$$
+where $E$ is an accumulated rounding error that is at most
+$3\cdot(2^{l-16}-1)$ in absolute value. We will make sure that
+the $X$'s are less than $2^{28}$; hence when $l=30$ we must
+have $\|m\L1$. This proves that the special case $m=n=1$ is
+bound to be reached by the time $l=30$. Furthermore $l=30$ is
+a suitable time to make the straight line approximation,
+if the recursion hasn't already died out, because the maximum
+difference between $X$'s will then be $<2^{14}$; this corresponds
+to an error of $<1$ with respect to the original scaling.
+(Stating this another way, each bisection makes the curve two bits
+closer to a straight line, hence 14 bisections are sufficient for
+28-bit accuracy.)
+
+In the case of a straight line, the curve goes first right, then up,
+if and only if $(T-2^l)(2^l-S)>(U-2^l)(2^l-R)$, where
+$T=X_1+X_2+X_3+R$ and $U=Y_1+Y_2+Y_3+S$. For the actual curve
+essentially runs from $(R/2^l,S/2^l)$ to $(T/2^l,U/2^l)$, and
+we are testing whether or not $(1,1)$ is above the straight
+line connecting these two points. (This formula assumes that $(1,1)$
+is not exactly on the line.)
+
+\fi
+
+\M306. We have glossed over the problem of tie-breaking in ambiguous
+cases when the cubic curve passes exactly through integer points.
+\MF\ finesses this problem by assuming that coordinates
+$(x,y)$ actually stand for slightly perturbed values $(x+\xi,y+\eta)$,
+where $\xi$ and~$\eta$ are infinitesimals whose signs will determine
+what to do when $x$ and/or~$y$ are exact integers. The quantities
+$\lfloor x\rfloor$ and~$\lfloor y\rfloor$ in the formulas above
+should actually read $\lfloor x+\xi\rfloor$ and $\lfloor y+\eta\rfloor$.
+
+If $x$ is a \\{scaled} value, we have $\lfloor x+\xi\rfloor=\lfloor x\rfloor$
+if $\xi>0$, and $\lfloor x+\xi\rfloor=\lfloor x-2^{-16}\rfloor$ if
+$\xi<0$. It is convenient to represent $\xi$ by the integer \\{xi\_corr},
+defined to be 0~if $\xi>0$ and 1~if $\xi<0$; then, for example, the
+integer $\lfloor x+\xi\rfloor$ can be computed as
+$\\{floor\_unscaled}(\|x-\\{xi\_corr})$. Similarly, $\eta$ is conveniently
+represented by~\\{eta\_corr}.
+
+In our applications the sign of $\xi-\eta$ will always be the same as
+the sign of $\xi$. Therefore it turns out that the rule for straight
+lines, as stated above, should be modified as follows in the case of
+ties: The line goes first right, then up, if and only if
+$(T-2^l)(2^l-S)+\xi>(U-2^l)(2^l-R)$. And this relation holds iff
+$\\{ab\_vs\_cd}(T-2^l,2^l-S,U-2^l,2^l-R)-\\{xi\_corr}\ge0$.
+
+These conventions for rounding are symmetrical, in the sense that the
+digitized moves obtained from $(x_0,x_1,x_2,x_3,y_0,y_1,y_2,y_3,\xi,\eta)$
+will be exactly complementary to the moves that would be obtained from
+$(-x_3,-x_2,-x_1,-x_0,-y_3,-y_2,-y_1,-y_0,-\xi,-\eta)$, if arithmetic
+is exact. However, truncation errors in the bisection process might
+upset the symmetry. We can restore much of the lost symmetry by adding
+\\{xi\_corr} or \\{eta\_corr} when halving the data.
+
+\fi
+
+\M307. One further possibility needs to be mentioned: The algorithm
+will be applied only to cubic polynomials $B(x_0,x_1,x_2,x_3;t)$ that
+are nondecreasing as $t$~varies from 0 to~1; this condition turns
+out to hold if and only if $x_0\L x_1$, $x_2\L x_3$, and either
+$x_1\L x_2$ or $(x_1-x_2)^2\L(x_1-x_0)(x_3-x_2)$. If bisection were
+carried out with perfect accuracy, these relations would remain
+invariant. But rounding errors can creep in, hence the bisection
+algorithm can produce non-monotonic subproblems from monotonic
+initial conditions. This leads to the potential danger that $m$ or~$n$
+could become negative in the algorithm described above.
+
+For example, if we start with $(x_1-x_0,x_2-x_1,x_3-x_2)=
+(X_1,X_2,X_3)=(7,-16,58)$, the corresponding polynomial is
+monotonic, because $16^2<7\cdot39$. But the bisection algorithm
+produces the left descendant $(7,-5,3)$, which is nonmonotonic;
+its right descendant is~$(0,-1,3)$.
+
+\def\xt{{\tilde x}}
+Fortunately we can prove that such rounding errors will never cause
+the algorithm to make a tragic mistake. At every stage we are working
+with numbers corresponding to a cubic polynomial $B(\xt_0,
+\xt_1,\xt_2,\xt_3)$ that approximates some
+monotonic polynomial $B(x_0,x_1,x_2,x_3)$. The accumulated errors are
+controlled so that $\vert x_k-\xt_k\vert<\epsilon=3\cdot2^{-16}$.
+If bisection is done at some stage of the recursion, we have
+$m=\lfloor\xt_3\rfloor-\lfloor\xt_0\rfloor>0$, and the algorithm
+computes a bisection value $\bar x$ such that $m'=\lfloor\bar x\rfloor-
+\lfloor\xt_0\rfloor$
+and $m''=\lfloor\xt_3\rfloor-\lfloor\bar x\rfloor$. We want to prove
+that neither $m'$ nor $m''$ can be negative. Since $\bar x$ is an
+approximation to a value in the interval $[x_0,x_3]$, we have
+$\bar x>x_0-\epsilon$ and $\bar x<x_3+\epsilon$, hence $\bar x>
+\xt_0-2\epsilon$ and $\bar x<\xt_3+2\epsilon$.
+If $m'$ is negative we must have $\xt_0\bmod 1<2\epsilon$;
+if $m''$ is negative we must have $\xt_3\bmod 1>1-2\epsilon$.
+In either case the condition $\lfloor\xt_3\rfloor-\lfloor\xt_0\rfloor>0$
+implies that $\xt_3-\xt_0>1-2\epsilon$, hence $x_3-x_0>1-4\epsilon$.
+But it can be shown that if $B(x_0,x_1,x_2,x_3;t)$ is a monotonic
+cubic, then $B(x_0,x_1,x_2,x_3;{1\over2})$ is always between
+$.14[x_0,x_3]$ and $.86[x_0,x_3]$; and it is impossible for $\bar x$
+to be within~$\epsilon$ of such a number. Contradiction!
+(The constant .14 is actually $(7-\sqrt{28}\,)/12$; the worst case
+occurs for polynomials like $B(0,28-4\sqrt{28},14-5\sqrt{28},42;t)$.)
+
+\fi
+
+\M308. OK, now that a long theoretical preamble has justified the
+bisection-and-doubling algorithm, we are ready to proceed with
+its actual coding. But we still haven't discussed the
+form of the output.
+
+For reasons to be discussed later, we shall find it convenient to
+record the output as follows: Moving one step up is represented by
+appending a `1' to a list; moving one step right is represented by
+adding unity to the element at the end of the list. Thus, for example,
+the net effect of ``(up, right, right, up, right)'' is to append
+$(3,2)$.
+
+The list is kept in a global array called \\{move}. Before starting the
+algorithm, \MF\ should check that $\\{move\_ptr}+\lfloor y_3\rfloor
+-\lfloor y_0\rfloor\L\\{move\_size}$, so that the list won't exceed
+the bounds of this array.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{move}: \37\&{array} $[0\to\\{move\_size}]$ \1\&{of}\5
+\\{integer};\C{the recorded moves}\2\6
+\4\\{move\_ptr}: \37$0\to\\{move\_size}$;\C{the number of items in the \\{move}
+list}\par
+\fi
+
+\M309. When bisection occurs, we ``push'' the subproblem corresponding
+to the right-hand subinterval onto the \\{bisect\_stack} while
+we continue to work on the left-hand subinterval. Thus, the \\{bisect\_stack}
+will hold $(X_1,X_2,X_3,R,m,Y_1,Y_2,Y_3,S,n,l)$ values for
+subproblems yet to be tackled.
+
+At most 15 subproblems will be on the stack at once (namely, for
+$l=15$,~16, \dots,~29); but the stack is bigger than this, because
+it is used also for more complicated bisection algorithms.
+
+\Y\P\D \37$\\{stack\_x1}\S\\{bisect\_stack}[\\{bisect\_ptr}]$\C{stacked value
+of $X_1$}\par
+\P\D \37$\\{stack\_x2}\S\\{bisect\_stack}[\\{bisect\_ptr}+1]$\C{stacked value
+of $X_2$}\par
+\P\D \37$\\{stack\_x3}\S\\{bisect\_stack}[\\{bisect\_ptr}+2]$\C{stacked value
+of $X_3$}\par
+\P\D \37$\\{stack\_r}\S\\{bisect\_stack}[\\{bisect\_ptr}+3]$\C{stacked value of
+$R$}\par
+\P\D \37$\\{stack\_m}\S\\{bisect\_stack}[\\{bisect\_ptr}+4]$\C{stacked value of
+$m$}\par
+\P\D \37$\\{stack\_y1}\S\\{bisect\_stack}[\\{bisect\_ptr}+5]$\C{stacked value
+of $Y_1$}\par
+\P\D \37$\\{stack\_y2}\S\\{bisect\_stack}[\\{bisect\_ptr}+6]$\C{stacked value
+of $Y_2$}\par
+\P\D \37$\\{stack\_y3}\S\\{bisect\_stack}[\\{bisect\_ptr}+7]$\C{stacked value
+of $Y_3$}\par
+\P\D \37$\\{stack\_s}\S\\{bisect\_stack}[\\{bisect\_ptr}+8]$\C{stacked value of
+$S$}\par
+\P\D \37$\\{stack\_n}\S\\{bisect\_stack}[\\{bisect\_ptr}+9]$\C{stacked value of
+$n$}\par
+\P\D \37$\\{stack\_l}\S\\{bisect\_stack}[\\{bisect\_ptr}+10]$\C{stacked value
+of $l$}\par
+\P\D \37$\\{move\_increment}=11$\C{number of items pushed by \\{make\_moves}}%
+\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{bisect\_stack}: \37\&{array} $[0\to\\{bistack\_size}]$ \1\&{of}\5
+\\{integer};\2\6
+\4\\{bisect\_ptr}: \37$0\to\\{bistack\_size}$;\par
+\fi
+
+\M310. \P$\X14:Check the ``constant'' values for consistency\X\mathrel{+}\S$\6
+\&{if} $15\ast\\{move\_increment}>\\{bistack\_size}$ \1\&{then}\5
+$\\{bad}\K31$;\2\par
+\fi
+
+\M311. The \\{make\_moves} subroutine is given \\{scaled} values
+$(x_0,x_1,x_2,x_3)$
+and $(y_0,y_1,y_2,y_3)$ that represent monotone-nondecreasing polynomials;
+it makes $\lfloor x_3+\xi\rfloor-\lfloor x_0+\xi\rfloor$ rightward moves
+and $\lfloor y_3+\eta\rfloor-\lfloor y_0+\eta\rfloor$ upward moves, as
+explained earlier. (Here $\lfloor x+\xi\rfloor$ actually stands for
+$\lfloor x/2^{16}-\\{xi\_corr}\rfloor$, if $x$ is regarded as an integer
+without scaling.) The unscaled integers $x_k$ and~$y_k$ should be less
+than $2^{28}$ in magnitude.
+
+It is assumed that $\\{move\_ptr} + \lfloor y_3+\eta\rfloor -
+\lfloor y_0+\eta\rfloor < \\{move\_size}$ when this procedure is called,
+so that the capacity of the \\{move} array will not be exceeded.
+
+The variables \|r and \|s in this procedure stand respectively for
+$R-\\{xi\_corr}$ and $S-\\{eta\_corr}$ in the theory discussed above.
+
+\Y\P\4\&{procedure}\1\ \37$\\{make\_moves}(\\{xx0},\39\\{xx1},\39\\{xx2},\39%
+\\{xx3},\39\\{yy0},\39\\{yy1},\39\\{yy2},\39\\{yy3}:\\{scaled};\,\35\\{xi%
+\_corr},\39\\{eta\_corr}:\\{small\_number})$;\6
+\4\&{label} \37$\\{continue},\39\\{done},\39\\{exit}$;\6
+\4\&{var} \37$\\{x1},\39\\{x2},\39\\{x3},\39\|m,\39\|r,\39\\{y1},\39\\{y2},\39%
+\\{y3},\39\|n,\39\|s,\39\|l$: \37\\{integer};\C{bisection variables explained
+above}\6
+$\|q,\39\|t,\39\|u,\39\\{x2a},\39\\{x3a},\39\\{y2a},\39\\{y3a}$: \37%
+\\{integer};\C{additional temporary registers}\2\6
+\&{begin} \37\&{if} $(\\{xx3}<\\{xx0})\V(\\{yy3}<\\{yy0})$ \1\&{then}\5
+$\\{confusion}(\.{"m"})$;\2\6
+$\|l\K16$;\5
+$\\{bisect\_ptr}\K0$;\6
+$\\{x1}\K\\{xx1}-\\{xx0}$;\5
+$\\{x2}\K\\{xx2}-\\{xx1}$;\5
+$\\{x3}\K\\{xx3}-\\{xx2}$;\6
+\&{if} $\\{xx0}\G\\{xi\_corr}$ \1\&{then}\5
+$\|r\K(\\{xx0}-\\{xi\_corr})\mathbin{\&{mod}}\\{unity}$\6
+\4\&{else} $\|r\K\\{unity}-1-((-\\{xx0}+\\{xi\_corr}-1)\mathbin{\&{mod}}%
+\\{unity})$;\2\6
+$\|m\K(\\{xx3}-\\{xx0}+\|r)\mathbin{\&{div}}\\{unity}$;\6
+$\\{y1}\K\\{yy1}-\\{yy0}$;\5
+$\\{y2}\K\\{yy2}-\\{yy1}$;\5
+$\\{y3}\K\\{yy3}-\\{yy2}$;\6
+\&{if} $\\{yy0}\G\\{eta\_corr}$ \1\&{then}\5
+$\|s\K(\\{yy0}-\\{eta\_corr})\mathbin{\&{mod}}\\{unity}$\6
+\4\&{else} $\|s\K\\{unity}-1-((-\\{yy0}+\\{eta\_corr}-1)\mathbin{\&{mod}}%
+\\{unity})$;\2\6
+$\|n\K(\\{yy3}-\\{yy0}+\|s)\mathbin{\&{div}}\\{unity}$;\6
+\&{if} $(\\{xx3}-\\{xx0}\G\\{fraction\_one})\V(\\{yy3}-\\{yy0}\G\\{fraction%
+\_one})$ \1\&{then}\5
+\X313:Divide the variables by two, to avoid overflow problems\X;\2\6
+\~ \1\&{loop}\ \&{begin} \37\\{continue}: \37\X314:Make moves for current
+subinterval; if bisection is necessary, push the second subinterval onto the
+stack, and \&{goto} \\{continue} in order to handle the first subinterval\X;\6
+\&{if} $\\{bisect\_ptr}=0$ \1\&{then}\5
+\&{return};\2\6
+\X312:Remove a subproblem for \\{make\_moves} from the stack\X;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M312. \P$\X312:Remove a subproblem for \\{make\_moves} from the stack\X\S$\6
+$\\{bisect\_ptr}\K\\{bisect\_ptr}-\\{move\_increment}$;\6
+$\\{x1}\K\\{stack\_x1}$;\5
+$\\{x2}\K\\{stack\_x2}$;\5
+$\\{x3}\K\\{stack\_x3}$;\5
+$\|r\K\\{stack\_r}$;\5
+$\|m\K\\{stack\_m}$;\6
+$\\{y1}\K\\{stack\_y1}$;\5
+$\\{y2}\K\\{stack\_y2}$;\5
+$\\{y3}\K\\{stack\_y3}$;\5
+$\|s\K\\{stack\_s}$;\5
+$\|n\K\\{stack\_n}$;\6
+$\|l\K\\{stack\_l}$\par
+\U311.\fi
+
+\M313. Our variables $(\\{x1},\\{x2},\\{x3})$ correspond to $(X_1,X_2,X_3)$ in
+the notation
+of the theory developed above. We need to keep them less than $2^{28}$
+in order to avoid integer overflow in weird circumstances.
+For example, data like $x_0=-2^{28}+2^{16}-1$ and $x_1=x_2=x_3=2^{28}-1$
+would otherwise be problematical. Hence this part of the code is
+needed, if only to thwart malicious users.
+
+\Y\P$\4\X313:Divide the variables by two, to avoid overflow problems\X\S$\6
+\&{begin} \37$\\{x1}\K\\{half}(\\{x1}+\\{xi\_corr})$;\5
+$\\{x2}\K\\{half}(\\{x2}+\\{xi\_corr})$;\5
+$\\{x3}\K\\{half}(\\{x3}+\\{xi\_corr})$;\5
+$\|r\K\\{half}(\|r+\\{xi\_corr})$;\6
+$\\{y1}\K\\{half}(\\{y1}+\\{eta\_corr})$;\5
+$\\{y2}\K\\{half}(\\{y2}+\\{eta\_corr})$;\5
+$\\{y3}\K\\{half}(\\{y3}+\\{eta\_corr})$;\5
+$\|s\K\\{half}(\|s+\\{eta\_corr})$;\6
+$\|l\K15$;\6
+\&{end}\par
+\U311.\fi
+
+\M314. \P$\X314:Make moves for current subinterval; if bisection is necessary,
+push the second subinterval onto the stack, and \&{goto} \\{continue} in order
+to handle the first subinterval\X\S$\6
+\&{if} $\|m=0$ \1\&{then}\5
+\X315:Move upward \|n steps\X\6
+\4\&{else} \&{if} $\|n=0$ \1\&{then}\5
+\X316:Move to the right \|m steps\X\6
+\4\&{else} \&{if} $\|m+\|n=2$ \1\&{then}\5
+\X317:Make one move of each kind\X\6
+\4\&{else} \&{begin} \37$\\{incr}(\|l)$;\5
+$\\{stack\_l}\K\|l$;\6
+$\\{stack\_x3}\K\\{x3}$;\5
+$\\{stack\_x2}\K\\{half}(\\{x2}+\\{x3}+\\{xi\_corr})$;\5
+$\\{x2}\K\\{half}(\\{x1}+\\{x2}+\\{xi\_corr})$;\5
+$\\{x3}\K\\{half}(\\{x2}+\\{stack\_x2}+\\{xi\_corr})$;\5
+$\\{stack\_x1}\K\\{x3}$;\6
+$\|r\K\|r+\|r+\\{xi\_corr}$;\5
+$\|t\K\\{x1}+\\{x2}+\\{x3}+\|r$;\6
+$\|q\K\|t\mathbin{\&{div}}\\{two\_to\_the}[\|l]$;\5
+$\\{stack\_r}\K\|t\mathbin{\&{mod}}\\{two\_to\_the}[\|l]$;\6
+$\\{stack\_m}\K\|m-\|q$;\5
+$\|m\K\|q$;\6
+$\\{stack\_y3}\K\\{y3}$;\5
+$\\{stack\_y2}\K\\{half}(\\{y2}+\\{y3}+\\{eta\_corr})$;\5
+$\\{y2}\K\\{half}(\\{y1}+\\{y2}+\\{eta\_corr})$;\5
+$\\{y3}\K\\{half}(\\{y2}+\\{stack\_y2}+\\{eta\_corr})$;\5
+$\\{stack\_y1}\K\\{y3}$;\6
+$\|s\K\|s+\|s+\\{eta\_corr}$;\5
+$\|u\K\\{y1}+\\{y2}+\\{y3}+\|s$;\6
+$\|q\K\|u\mathbin{\&{div}}\\{two\_to\_the}[\|l]$;\5
+$\\{stack\_s}\K\|u\mathbin{\&{mod}}\\{two\_to\_the}[\|l]$;\6
+$\\{stack\_n}\K\|n-\|q$;\5
+$\|n\K\|q$;\6
+$\\{bisect\_ptr}\K\\{bisect\_ptr}+\\{move\_increment}$;\5
+\&{goto} \37\\{continue};\6
+\&{end}\2\2\2\par
+\U311.\fi
+
+\M315. \P$\X315:Move upward \|n steps\X\S$\6
+\&{while} $\|n>0$ \1\&{do}\6
+\&{begin} \37$\\{incr}(\\{move\_ptr})$;\5
+$\\{move}[\\{move\_ptr}]\K1$;\5
+$\\{decr}(\|n)$;\6
+\&{end}\2\par
+\U314.\fi
+
+\M316. \P$\X316:Move to the right \|m steps\X\S$\6
+$\\{move}[\\{move\_ptr}]\K\\{move}[\\{move\_ptr}]+\|m$\par
+\U314.\fi
+
+\M317. \P$\X317:Make one move of each kind\X\S$\6
+\&{begin} \37$\|r\K\\{two\_to\_the}[\|l]-\|r$;\5
+$\|s\K\\{two\_to\_the}[\|l]-\|s$;\6
+\&{while} $\|l<30$ \1\&{do}\6
+\&{begin} \37$\\{x3a}\K\\{x3}$;\5
+$\\{x2a}\K\\{half}(\\{x2}+\\{x3}+\\{xi\_corr})$;\5
+$\\{x2}\K\\{half}(\\{x1}+\\{x2}+\\{xi\_corr})$;\5
+$\\{x3}\K\\{half}(\\{x2}+\\{x2a}+\\{xi\_corr})$;\5
+$\|t\K\\{x1}+\\{x2}+\\{x3}$;\5
+$\|r\K\|r+\|r-\\{xi\_corr}$;\6
+$\\{y3a}\K\\{y3}$;\5
+$\\{y2a}\K\\{half}(\\{y2}+\\{y3}+\\{eta\_corr})$;\5
+$\\{y2}\K\\{half}(\\{y1}+\\{y2}+\\{eta\_corr})$;\5
+$\\{y3}\K\\{half}(\\{y2}+\\{y2a}+\\{eta\_corr})$;\5
+$\|u\K\\{y1}+\\{y2}+\\{y3}$;\5
+$\|s\K\|s+\|s-\\{eta\_corr}$;\6
+\&{if} $\|t<\|r$ \1\&{then}\6
+\&{if} $\|u<\|s$ \1\&{then}\5
+\X318:Switch to the right subinterval\X\6
+\4\&{else} \&{begin} \37\X320:Move up then right\X;\6
+\&{goto} \37\\{done};\6
+\&{end}\2\6
+\4\&{else} \&{if} $\|u<\|s$ \1\&{then}\6
+\&{begin} \37\X319:Move right then up\X;\6
+\&{goto} \37\\{done};\6
+\&{end};\2\2\6
+$\\{incr}(\|l)$;\6
+\&{end};\2\6
+$\|r\K\|r-\\{xi\_corr}$;\5
+$\|s\K\|s-\\{eta\_corr}$;\6
+\&{if} $\\{ab\_vs\_cd}(\\{x1}+\\{x2}+\\{x3},\39\|s,\39\\{y1}+\\{y2}+\\{y3},\39%
+\|r)-\\{xi\_corr}\G0$ \1\&{then}\5
+\X319:Move right then up\X\6
+\4\&{else} \X320:Move up then right\X;\2\6
+\4\\{done}: \37\&{end}\par
+\U314.\fi
+
+\M318. \P$\X318:Switch to the right subinterval\X\S$\6
+\&{begin} \37$\\{x1}\K\\{x3}$;\5
+$\\{x2}\K\\{x2a}$;\5
+$\\{x3}\K\\{x3a}$;\5
+$\|r\K\|r-\|t$;\5
+$\\{y1}\K\\{y3}$;\5
+$\\{y2}\K\\{y2a}$;\5
+$\\{y3}\K\\{y3a}$;\5
+$\|s\K\|s-\|u$;\6
+\&{end}\par
+\U317.\fi
+
+\M319. \P$\X319:Move right then up\X\S$\6
+\&{begin} \37$\\{incr}(\\{move}[\\{move\_ptr}])$;\5
+$\\{incr}(\\{move\_ptr})$;\5
+$\\{move}[\\{move\_ptr}]\K1$;\6
+\&{end}\par
+\Us317\ET317.\fi
+
+\M320. \P$\X320:Move up then right\X\S$\6
+\&{begin} \37$\\{incr}(\\{move\_ptr})$;\5
+$\\{move}[\\{move\_ptr}]\K2$;\6
+\&{end}\par
+\Us317\ET317.\fi
+
+\M321. After \\{make\_moves} has acted, possibly for several curves that move
+toward
+the same octant, a ``smoothing'' operation might be done on the \\{move} array.
+This removes optical glitches that can arise even when the curve has been
+digitized without rounding errors.
+
+The smoothing process replaces the integers $a_0\ldots a_n$ in
+$\\{move}[\|b\to\|t]$ by ``smoothed'' integers $a_0'\ldots a_n'$ defined as
+follows:
+$$a_k'=a_k+\delta\k-\delta_k;\qquad
+\delta_k=\cases{+1,&if $1<k<n$ and $a_{k-2}\G a_{k-1}\ll a_k\G a\k$;\cr
+-1,&if $1<k<n$ and $a_{k-2}\L a_{k-1}\gg a_k\L a\k$;\cr
+0,&otherwise.\cr}$$
+Here $a\ll b$ means that $a\L b-2$, and $a\gg b$ means that $a\G b+2$.
+
+The smoothing operation is symmetric in the sense that, if $a_0\ldots a_n$
+smoothes to $a_0'\ldots a_n'$, then the reverse sequence $a_n\ldots a_0$
+smoothes to $a_n'\ldots a_0'$; also the complementary sequence
+$(m-a_0)\ldots(m-a_n)$ smoothes to $(m-a_0')\ldots(m-a_n')$.
+We have $a_0'+\cdots+a_n'=a_0+\cdots+a_n$ because $\delta_0=\delta_{n+1}=0$.
+
+\Y\P\4\&{procedure}\1\ \37$\\{smooth\_moves}(\|b,\39\|t:\\{integer})$;\6
+\4\&{var} \37\|k: \37$1\to\\{move\_size}$;\C{index into \\{move}}\6
+$\|a,\39\\{aa},\39\\{aaa}$: \37\\{integer};\C{original values of $\\{move}[%
+\|k],\\{move}[\|k-1],\\{move}[\|k-2]$}\2\6
+\&{begin} \37\&{if} $\|t-\|b\G3$ \1\&{then}\6
+\&{begin} \37$\|k\K\|b+2$;\5
+$\\{aa}\K\\{move}[\|k-1]$;\5
+$\\{aaa}\K\\{move}[\|k-2]$;\6
+\1\&{repeat} \37$\|a\K\\{move}[\|k]$;\6
+\&{if} $\\{abs}(\|a-\\{aa})>1$ \1\&{then}\5
+\X322:Increase and decrease $\\{move}[\|k-1]$ and $\\{move}[\|k]$ by $\delta_k$%
+\X;\2\6
+$\\{incr}(\|k)$;\5
+$\\{aaa}\K\\{aa}$;\5
+$\\{aa}\K\|a$;\6
+\4\&{until}\5
+$\|k=\|t$;\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M322. \P$\X322:Increase and decrease $\\{move}[\|k-1]$ and $\\{move}[\|k]$ by
+$\delta_k$\X\S$\6
+\&{if} $\|a>\\{aa}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{aaa}\G\\{aa}$ \1\&{then}\6
+\&{if} $\|a\G\\{move}[\|k+1]$ \1\&{then}\6
+\&{begin} \37$\\{incr}(\\{move}[\|k-1])$;\5
+$\\{move}[\|k]\K\|a-1$;\6
+\&{end};\2\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{aaa}\L\\{aa}$ \1\&{then}\6
+\&{if} $\|a\L\\{move}[\|k+1]$ \1\&{then}\6
+\&{begin} \37$\\{decr}(\\{move}[\|k-1])$;\5
+$\\{move}[\|k]\K\|a+1$;\6
+\&{end};\2\2\6
+\&{end}\2\par
+\U321.\fi
+
+\N323. \[20] Edge structures.
+Now we come to \MF's internal scheme for representing what the user can
+actually ``see,'' the edges between pixels. Each pixel has an integer
+weight, obtained by summing the weights on all edges to its left. \MF\
+represents only the nonzero edge weights, since most of the edges are
+weightless; in this way, the data storage requirements grow only linearly
+with respect to the number of pixels per point, even though two-dimensional
+data is being represented. (Well, the actual dependence on the underlying
+resolution is order $n\log n$, but the the $\log n$ factor is buried in our
+implicit restriction on the maximum raster size.) The sum of all edge
+weights in each row should be zero.
+
+The data structure for edge weights must be compact and flexible,
+yet it should support efficient updating and display operations. We
+want to be able to have many different edge structures in memory at
+once, and we want the computer to be able to translate them, reflect them,
+and/or merge them together with relative ease.
+
+\MF's solution to this problem requires one single-word node per
+nonzero edge weight, plus one two-word node for each row in a contiguous
+set of rows. There's also a header node that provides global information
+about the entire structure.
+
+\fi
+
+\M324. Let's consider the edge-weight nodes first. The \\{info} field of such
+nodes contains both an $m$~value and a weight~$w$, in the form
+$8m+w+c$, where $c$ is a constant that depends on data found in the header.
+We shall consider $c$ in detail later; for now, it's best just to think
+of it as a way to compensate for the fact that $m$ and~$w$ can be negative,
+together with the fact that an \\{info} field must have a value between
+\\{min\_halfword} and \\{max\_halfword}. The $m$ value is an unscaled
+$x$~coordinate,
+so it satisfies $\vert m\vert<
+4096$; the $w$ value is always in the range $1\L\vert w\vert\L3$. We can
+unpack the data in the \\{info} field by fetching $\\{ho}(\\{info}(\|p))=%
+\\{info}(\|p)-\\{min\_halfword}$ and dividing this nonnegative number by~8;
+the constant~$c$ will be chosen so that the remainder of this division
+is $4+w$. Thus, for example, a remainder of~3 will correspond to
+the edge weight $w=-1$.
+
+Every row of an edge structure contains two lists of such edge-weight
+nodes, called the \\{sorted} and \\{unsorted} lists, linked together by their
+\\{link} fields in the normal way. The difference between them is that we
+always have $\\{info}(\|p)\L\\{info}(\\{link}(\|p))$ in the \\{sorted} list,
+but there's no
+such restriction on the elements of the \\{unsorted} list. The reason for
+this distinction is that it would take unnecessarily long to maintain
+edge-weight lists in sorted order while they're being updated; but when we
+need to process an entire row from left to right in order of the
+$m$~values, it's fairly easy and quick to sort a short list of unsorted
+elements and to merge them into place among their sorted cohorts.
+Furthermore, the fact that the \\{unsorted} list is empty can sometimes be
+used to good advantage, because it allows us to conclude that a particular
+row has not changed since the last time we sorted it.
+
+The final \\{link} of the \\{sorted} list will be \\{sentinel}, which points to
+a special one-word node whose \\{info} field is essentially infinite; this
+facilitates the sorting and merging operations. The final \\{link} of the
+\\{unsorted} list will be either \\{null} or \\{void}, where $\\{void}=%
+\\{null}+1$
+is used to avoid redisplaying data that has not changed:
+A \\{void} value is stored at the head of the
+unsorted list whenever the corresponding row has been displayed.
+
+\Y\P\D \37$\\{zero\_w}=4$\par
+\P\D \37$\\{void}\S\\{null}+1$\par
+\Y\P$\4\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}\S$\6
+$\\{info}(\\{sentinel})\K\\{max\_halfword}$;\C{$\\{link}(\\{sentinel})=%
+\\{null}$}\par
+\fi
+
+\M325. The rows themselves are represented by row-header nodes that
+contain four link fields. Two of these four, \\{sorted} and \\{unsorted},
+point to the first items of the edge-weight lists just mentioned.
+The other two, \\{link} and \\{knil}, point to the headers of the two
+adjacent rows. If \|p points to the header for row number~\|n, then
+$\\{link}(\|p)$ points up to the header for row~$\|n+1$, and $\\{knil}(\|p)$
+points
+down to the header for row~$\|n-1$. This double linking makes it
+convenient to move through consecutive rows either upward or downward;
+as usual, we have $\\{link}(\\{knil}(\|p))=\\{knil}(\\{link}(\|p))=\|p$ for all
+row headers~\|p.
+
+The row associated with a given value of \|n contains weights for
+edges that run between the lattice points $(\|m,\|n)$ and $(\|m,\|n+1)$.
+
+\Y\P\D \37$\\{knil}\S\\{info}$\C{inverse of the \\{link} field, in a doubly
+linked list}\par
+\P\D \37$\\{sorted\_loc}(\#)\S\#+1$\C{where the \\{sorted} link field resides}%
+\par
+\P\D \37$\\{sorted}(\#)\S\\{link}(\\{sorted\_loc}(\#))$\C{beginning of the list
+of sorted edge weights}\par
+\P\D \37$\\{unsorted}(\#)\S\\{info}(\#+1)$\C{beginning of the list of unsorted
+edge weights}\par
+\P\D \37$\\{row\_node\_size}=2$\C{number of words in a row header node}\par
+\fi
+
+\M326. The main header node \|h for an edge structure has \\{link} and \\{knil}
+fields that link it above the topmost row and below the bottommost row.
+It also has fields called \\{m\_min}, \\{m\_max}, \\{n\_min}, and \\{n\_max}
+that
+bound the current extent of the edge data: All \|m values in edge-weight
+nodes should lie between $\\{m\_min}(\|h)-4096$ and $\\{m\_max}(\|h)-4096$,
+inclusive.
+Furthermore the topmost row header, pointed to by $\\{knil}(\|h)$,
+is for row number $\\{n\_max}(\|h)-4096$; the bottommost row header, pointed to
+by
+$\\{link}(\|h)$, is for row number $\\{n\_min}(\|h)-4096$.
+
+The offset constant \|c that's used in all of the edge-weight data is
+represented implicitly in $\\{m\_offset}(\|h)$; its actual value is
+$$\hbox{$\|c=\\{min\_halfword}+\\{zero\_w}+8\ast\\{m\_offset}(\|h)$.}$$
+Notice that it's possible to shift an entire edge structure by an
+amount $(\Delta m,\Delta n)$ by adding $\Delta n$ to $\\{n\_min}(\|h)$ and $%
+\\{n\_max}(\|h)$,
+adding $\Delta m$ to $\\{m\_min}(\|h)$ and $\\{m\_max}(\|h)$, and subtracting
+$\Delta m$ from $\\{m\_offset}(\|h)$;
+none of the other edge data needs to be modified. Initially the \\{m\_offset}
+field is~4096, but it will change if the user requests such a shift.
+The contents of these five fields should always be positive and less than
+8192; \\{n\_max} should, in fact, be less than 8191. Furthermore
+$\\{m\_min}+\\{m\_offset}-4096$ and $\\{m\_max}+\\{m\_offset}-4096$ must also
+lie strictly
+between 0 and 8192, so that the \\{info} fields of edge-weight nodes will
+fit in a halfword.
+
+The header node of an edge structure also contains two somewhat unusual
+fields that are called $\\{last\_window}(\|h)$ and $\\{last\_window\_time}(%
+\|h)$. When this
+structure is displayed in window~\|k of the user's screen, after that
+window has been updated \|t times, \MF\ sets $\\{last\_window}(\|h)\K\|k$ and
+$\\{last\_window\_time}(\|h)\K\|t$; it also sets $\\{unsorted}(\|p)\K\\{void}$
+for all row
+headers~\|p, after merging any existing unsorted weights with the sorted
+ones. A subsequent display in the same window will be able to avoid
+redisplaying rows whose \\{unsorted} list is still \\{void}, if the window
+hasn't been used for something else in the meantime.
+
+A pointer to the row header of row $\\{n\_pos}(\|h)-4096$ is provided in
+$\\{n\_rover}(\|h)$. Most of the algorithms that update an edge structure
+are able to get by without random row references; they usually
+access rows that are neighbors of each other or of the current \\{n\_pos} row.
+Exception: If $\\{link}(\|h)=\|h$ (so that the edge structure contains
+no rows), we have $\\{n\_rover}(\|h)=\|h$, and $\\{n\_pos}(\|h)$ is irrelevant.
+
+\Y\P\D \37$\\{zero\_field}=4096$\C{amount added to coordinates to make them
+positive}\par
+\P\D \37$\\{n\_min}(\#)\S\\{info}(\#+1)$\C{minimum row number present, plus %
+\\{zero\_field}}\par
+\P\D \37$\\{n\_max}(\#)\S\\{link}(\#+1)$\C{maximum row number present, plus %
+\\{zero\_field}}\par
+\P\D \37$\\{m\_min}(\#)\S\\{info}(\#+2)$\C{minimum column number present, plus %
+\\{zero\_field}}\par
+\P\D \37$\\{m\_max}(\#)\S\\{link}(\#+2)$\C{maximum column number present, plus %
+\\{zero\_field}}\par
+\P\D \37$\\{m\_offset}(\#)\S\\{info}(\#+3)$\C{translation of $m$ data in
+edge-weight nodes}\par
+\P\D \37$\\{last\_window}(\#)\S\\{link}(\#+3)$\C{the last display went into
+this window}\par
+\P\D \37$\\{last\_window\_time}(\#)\S\\{mem}[\#+4].\\{int}$\C{after this many
+window updates}\par
+\P\D \37$\\{n\_pos}(\#)\S\\{info}(\#+5)$\C{the row currently in \\{n\_rover},
+plus \\{zero\_field}}\par
+\P\D \37$\\{n\_rover}(\#)\S\\{link}(\#+5)$\C{a row recently referenced}\par
+\P\D \37$\\{edge\_header\_size}=6$\C{number of words in an edge-structure
+header}\par
+\P\D \37$\\{valid\_range}(\#)\S(\\{abs}(\#-4096)<4096)$\C{is $\#$ strictly
+between 0 and 8192?}\par
+\P\D \37$\\{empty\_edges}(\#)\S\\{link}(\#)=\#$\C{are there no rows in this
+edge header?}\par
+\Y\P\4\&{procedure}\1\ \37$\\{init\_edges}(\|h:\\{pointer})$;\C{initialize an
+edge header to null values}\2\6
+\&{begin} \37$\\{knil}(\|h)\K\|h$;\5
+$\\{link}(\|h)\K\|h$;\6
+$\\{n\_min}(\|h)\K\\{zero\_field}+4095$;\5
+$\\{n\_max}(\|h)\K\\{zero\_field}-4095$;\5
+$\\{m\_min}(\|h)\K\\{zero\_field}+4095$;\5
+$\\{m\_max}(\|h)\K\\{zero\_field}-4095$;\5
+$\\{m\_offset}(\|h)\K\\{zero\_field}$;\6
+$\\{last\_window}(\|h)\K0$;\5
+$\\{last\_window\_time}(\|h)\K0$;\6
+$\\{n\_rover}(\|h)\K\|h$;\5
+$\\{n\_pos}(\|h)\K0$;\6
+\&{end};\par
+\fi
+
+\M327. When a lot of work is being done on a particular edge structure, we
+plant
+a pointer to its main header in the global variable \\{cur\_edges}.
+This saves us from having to pass this pointer as a parameter over and
+over again between subroutines.
+
+Similarly, \\{cur\_wt} is a global weight that is being used by several
+procedures at once.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{cur\_edges}: \37\\{pointer};\C{the edge structure of current interest}\6
+\4\\{cur\_wt}: \37\\{integer};\C{the edge weight of current interest}\par
+\fi
+
+\M328. The \\{fix\_offset} routine goes through all the edge-weight nodes of
+\\{cur\_edges} and adds a constant to their \\{info} fields, so that
+$\\{m\_offset}(\\{cur\_edges})$ can be brought back to \\{zero\_field}. (This
+is necessary only in unusual cases when the offset has gotten too
+large or too small.)
+
+\Y\P\4\&{procedure}\1\ \37\\{fix\_offset};\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{list traversers}\6
+\\{delta}: \37\\{integer};\C{the amount of change}\2\6
+\&{begin} \37$\\{delta}\K8\ast(\\{m\_offset}(\\{cur\_edges})-\\{zero\_field})$;%
+\5
+$\\{m\_offset}(\\{cur\_edges})\K\\{zero\_field}$;\5
+$\|q\K\\{link}(\\{cur\_edges})$;\6
+\&{while} $\|q\I\\{cur\_edges}$ \1\&{do}\6
+\&{begin} \37$\|p\K\\{sorted}(\|q)$;\6
+\&{while} $\|p\I\\{sentinel}$ \1\&{do}\6
+\&{begin} \37$\\{info}(\|p)\K\\{info}(\|p)-\\{delta}$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\|p\K\\{unsorted}(\|q)$;\6
+\&{while} $\|p>\\{void}$ \1\&{do}\6
+\&{begin} \37$\\{info}(\|p)\K\\{info}(\|p)-\\{delta}$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M329. The \\{edge\_prep} routine makes the \\{cur\_edges} structure ready to
+accept new data whose coordinates satisfy $\\{ml}\L\|m\L\\{mr}$ and $\\{nl}\L%
+\|n\L\\{nr}-1$,
+assuming that $-4096<\\{ml}\L\\{mr}<4096$ and $-4096<\\{nl}\L\\{nr}<4096$. It
+makes
+appropriate adjustments to \\{m\_min}, \\{m\_max}, \\{n\_min}, and \\{n\_max},
+adding new empty rows if necessary.
+
+\Y\P\4\&{procedure}\1\ \37$\\{edge\_prep}(\\{ml},\39\\{mr},\39\\{nl},\39%
+\\{nr}:\\{integer})$;\6
+\4\&{var} \37\\{delta}: \37\\{halfword};\C{amount of change}\6
+$\|p,\39\|q$: \37\\{pointer};\C{for list manipulation}\2\6
+\&{begin} \37$\\{ml}\K\\{ml}+\\{zero\_field}$;\5
+$\\{mr}\K\\{mr}+\\{zero\_field}$;\5
+$\\{nl}\K\\{nl}+\\{zero\_field}$;\5
+$\\{nr}\K\\{nr}-1+\\{zero\_field}$;\6
+\&{if} $\\{ml}<\\{m\_min}(\\{cur\_edges})$ \1\&{then}\5
+$\\{m\_min}(\\{cur\_edges})\K\\{ml}$;\2\6
+\&{if} $\\{mr}>\\{m\_max}(\\{cur\_edges})$ \1\&{then}\5
+$\\{m\_max}(\\{cur\_edges})\K\\{mr}$;\2\6
+\&{if} $\R\\{valid\_range}(\\{m\_min}(\\{cur\_edges})+\\{m\_offset}(\\{cur%
+\_edges})-\\{zero\_field})\V\30\R\\{valid\_range}(\\{m\_max}(\\{cur\_edges})+%
+\\{m\_offset}(\\{cur\_edges})-\\{zero\_field})$ \1\&{then}\5
+\\{fix\_offset};\2\6
+\&{if} $\\{empty\_edges}(\\{cur\_edges})$ \1\&{then}\C{there are no rows}\6
+\&{begin} \37$\\{n\_min}(\\{cur\_edges})\K\\{nr}+1$;\5
+$\\{n\_max}(\\{cur\_edges})\K\\{nr}$;\6
+\&{end};\2\6
+\&{if} $\\{nl}<\\{n\_min}(\\{cur\_edges})$ \1\&{then}\5
+\X330:Insert exactly $\\{n\_min}(\\{cur\_edges})-\\{nl}$ empty rows at the
+bottom\X;\2\6
+\&{if} $\\{nr}>\\{n\_max}(\\{cur\_edges})$ \1\&{then}\5
+\X331:Insert exactly $\\{nr}-\\{n\_max}(\\{cur\_edges})$ empty rows at the top%
+\X;\2\6
+\&{end};\par
+\fi
+
+\M330. \P$\X330:Insert exactly $\\{n\_min}(\\{cur\_edges})-\\{nl}$ empty rows
+at the bottom\X\S$\6
+\&{begin} \37$\\{delta}\K\\{n\_min}(\\{cur\_edges})-\\{nl}$;\5
+$\\{n\_min}(\\{cur\_edges})\K\\{nl}$;\5
+$\|p\K\\{link}(\\{cur\_edges})$;\6
+\1\&{repeat} \37$\|q\K\\{get\_node}(\\{row\_node\_size})$;\5
+$\\{sorted}(\|q)\K\\{sentinel}$;\5
+$\\{unsorted}(\|q)\K\\{void}$;\5
+$\\{knil}(\|p)\K\|q$;\5
+$\\{link}(\|q)\K\|p$;\5
+$\|p\K\|q$;\5
+$\\{decr}(\\{delta})$;\6
+\4\&{until}\5
+$\\{delta}=0$;\2\6
+$\\{knil}(\|p)\K\\{cur\_edges}$;\5
+$\\{link}(\\{cur\_edges})\K\|p$;\6
+\&{if} $\\{n\_rover}(\\{cur\_edges})=\\{cur\_edges}$ \1\&{then}\5
+$\\{n\_pos}(\\{cur\_edges})\K\\{nl}-1$;\2\6
+\&{end}\par
+\U329.\fi
+
+\M331. \P$\X331:Insert exactly $\\{nr}-\\{n\_max}(\\{cur\_edges})$ empty rows
+at the top\X\S$\6
+\&{begin} \37$\\{delta}\K\\{nr}-\\{n\_max}(\\{cur\_edges})$;\5
+$\\{n\_max}(\\{cur\_edges})\K\\{nr}$;\5
+$\|p\K\\{knil}(\\{cur\_edges})$;\6
+\1\&{repeat} \37$\|q\K\\{get\_node}(\\{row\_node\_size})$;\5
+$\\{sorted}(\|q)\K\\{sentinel}$;\5
+$\\{unsorted}(\|q)\K\\{void}$;\5
+$\\{link}(\|p)\K\|q$;\5
+$\\{knil}(\|q)\K\|p$;\5
+$\|p\K\|q$;\5
+$\\{decr}(\\{delta})$;\6
+\4\&{until}\5
+$\\{delta}=0$;\2\6
+$\\{link}(\|p)\K\\{cur\_edges}$;\5
+$\\{knil}(\\{cur\_edges})\K\|p$;\6
+\&{if} $\\{n\_rover}(\\{cur\_edges})=\\{cur\_edges}$ \1\&{then}\5
+$\\{n\_pos}(\\{cur\_edges})\K\\{nr}+1$;\2\6
+\&{end}\par
+\U329.\fi
+
+\M332. The \\{print\_edges} subroutine gives a symbolic rendition of an edge
+structure, for use in `\&{show}' commands. A rather terse output
+format has been chosen since edge structures can grow quite large.
+
+\Y\P$\4\X257:Declare subroutines for printing expressions\X\mathrel{+}\S$\6
+\hbox{\4}\X333:Declare the procedure called \\{print\_weight}\X\6
+\4\&{procedure}\1\ \37$\\{print\_edges}(\|s:\\{str\_number};\,\35\\{nuline}:%
+\\{boolean};\,\35\\{x\_off},\39\\{y\_off}:\\{integer})$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{for list traversal}\6
+\|n: \37\\{integer};\C{row number}\2\6
+\&{begin} \37$\\{print\_diagnostic}(\.{"Edge\ structure"},\39\|s,\39%
+\\{nuline})$;\5
+$\|p\K\\{knil}(\\{cur\_edges})$;\5
+$\|n\K\\{n\_max}(\\{cur\_edges})-\\{zero\_field}$;\6
+\&{while} $\|p\I\\{cur\_edges}$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{unsorted}(\|p)$;\5
+$\|r\K\\{sorted}(\|p)$;\6
+\&{if} $(\|q>\\{void})\V(\|r\I\\{sentinel})$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"row\ "})$;\5
+$\\{print\_int}(\|n+\\{y\_off})$;\5
+$\\{print\_char}(\.{":"})$;\6
+\&{while} $\|q>\\{void}$ \1\&{do}\6
+\&{begin} \37$\\{print\_weight}(\|q,\39\\{x\_off})$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+$\\{print}(\.{"\ |"})$;\6
+\&{while} $\|r\I\\{sentinel}$ \1\&{do}\6
+\&{begin} \37$\\{print\_weight}(\|r,\39\\{x\_off})$;\5
+$\|r\K\\{link}(\|r)$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\|p\K\\{knil}(\|p)$;\5
+$\\{decr}(\|n)$;\6
+\&{end};\2\6
+$\\{end\_diagnostic}(\\{true})$;\6
+\&{end};\par
+\fi
+
+\M333. \P$\X333:Declare the procedure called \\{print\_weight}\X\S$\6
+\4\&{procedure}\1\ \37$\\{print\_weight}(\|q:\\{pointer};\,\35\\{x\_off}:%
+\\{integer})$;\6
+\4\&{var} \37$\|w,\39\|m$: \37\\{integer};\C{unpacked weight and coordinate}\6
+\|d: \37\\{integer};\C{temporary data register}\2\6
+\&{begin} \37$\|d\K\\{ho}(\\{info}(\|q))$;\5
+$\|w\K\|d\mathbin{\&{mod}}8$;\5
+$\|m\K(\|d\mathbin{\&{div}}8)-\\{m\_offset}(\\{cur\_edges})$;\6
+\&{if} $\\{file\_offset}>\\{max\_print\_line}-9$ \1\&{then}\5
+$\\{print\_nl}(\.{"\ "})$\6
+\4\&{else} $\\{print\_char}(\.{"\ "})$;\2\6
+$\\{print\_int}(\|m+\\{x\_off})$;\6
+\&{while} $\|w>\\{zero\_w}$ \1\&{do}\6
+\&{begin} \37$\\{print\_char}(\.{"+"})$;\5
+$\\{decr}(\|w)$;\6
+\&{end};\2\6
+\&{while} $\|w<\\{zero\_w}$ \1\&{do}\6
+\&{begin} \37$\\{print\_char}(\.{"-"})$;\5
+$\\{incr}(\|w)$;\6
+\&{end};\2\6
+\&{end};\par
+\U332.\fi
+
+\M334. Here's a trivial subroutine that copies an edge structure. (Let's hope
+that the given structure isn't too gigantic.)
+
+\Y\P\4\&{function}\1\ \37$\\{copy\_edges}(\|h:\\{pointer})$: \37\\{pointer};\6
+\4\&{var} \37$\|p,\39\|r$: \37\\{pointer};\C{variables that traverse the given
+structure}\6
+$\\{hh},\39\\{pp},\39\\{qq},\39\\{rr},\39\\{ss}$: \37\\{pointer};\C{variables
+that traverse the new structure}\2\6
+\&{begin} \37$\\{hh}\K\\{get\_node}(\\{edge\_header\_size})$;\5
+$\\{mem}[\\{hh}+1]\K\\{mem}[\|h+1]$;\5
+$\\{mem}[\\{hh}+2]\K\\{mem}[\|h+2]$;\5
+$\\{mem}[\\{hh}+3]\K\\{mem}[\|h+3]$;\5
+$\\{mem}[\\{hh}+4]\K\\{mem}[\|h+4]$;\C{we've now copied \\{n\_min}, \\{n\_max},
+ \\{m\_min}, \\{m\_max}, \\{m\_offset}, \\{last\_window}, and \\{last\_window%
+\_time}}\6
+$\\{n\_pos}(\\{hh})\K\\{n\_max}(\\{hh})+1$;\5
+$\\{n\_rover}(\\{hh})\K\\{hh}$;\6
+$\|p\K\\{link}(\|h)$;\5
+$\\{qq}\K\\{hh}$;\6
+\&{while} $\|p\I\|h$ \1\&{do}\6
+\&{begin} \37$\\{pp}\K\\{get\_node}(\\{row\_node\_size})$;\5
+$\\{link}(\\{qq})\K\\{pp}$;\5
+$\\{knil}(\\{pp})\K\\{qq}$;\5
+\X335:Copy both \\{sorted} and \\{unsorted} lists of \|p to \\{pp}\X;\6
+$\|p\K\\{link}(\|p)$;\5
+$\\{qq}\K\\{pp}$;\6
+\&{end};\2\6
+$\\{link}(\\{qq})\K\\{hh}$;\5
+$\\{knil}(\\{hh})\K\\{qq}$;\5
+$\\{copy\_edges}\K\\{hh}$;\6
+\&{end};\par
+\fi
+
+\M335. \P$\X335:Copy both \\{sorted} and \\{unsorted} lists of \|p to \\{pp}\X%
+\S$\6
+$\|r\K\\{sorted}(\|p)$;\5
+$\\{rr}\K\\{sorted\_loc}(\\{pp})$;\C{$\\{link}(\\{rr})=\\{sorted}(\\{pp})$}\6
+\&{while} $\|r\I\\{sentinel}$ \1\&{do}\6
+\&{begin} \37$\\{ss}\K\\{get\_avail}$;\5
+$\\{link}(\\{rr})\K\\{ss}$;\5
+$\\{rr}\K\\{ss}$;\5
+$\\{info}(\\{rr})\K\\{info}(\|r)$;\6
+$\|r\K\\{link}(\|r)$;\6
+\&{end};\2\6
+$\\{link}(\\{rr})\K\\{sentinel}$;\6
+$\|r\K\\{unsorted}(\|p)$;\5
+$\\{rr}\K\\{temp\_head}$;\6
+\&{while} $\|r>\\{void}$ \1\&{do}\6
+\&{begin} \37$\\{ss}\K\\{get\_avail}$;\5
+$\\{link}(\\{rr})\K\\{ss}$;\5
+$\\{rr}\K\\{ss}$;\5
+$\\{info}(\\{rr})\K\\{info}(\|r)$;\6
+$\|r\K\\{link}(\|r)$;\6
+\&{end};\2\6
+$\\{link}(\\{rr})\K\|r$;\5
+$\\{unsorted}(\\{pp})\K\\{link}(\\{temp\_head})$\par
+\Us334\ET341.\fi
+
+\M336. Another trivial routine flips \\{cur\_edges} about the \|x-axis
+(i.e., negates all the \|y coordinates), assuming that at least
+one row is present.
+
+\Y\P\4\&{procedure}\1\ \37\\{y\_reflect\_edges};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{list manipulation
+registers}\2\6
+\&{begin} \37$\|p\K\\{n\_min}(\\{cur\_edges})$;\5
+$\\{n\_min}(\\{cur\_edges})\K\\{zero\_field}+\\{zero\_field}-1-\\{n\_max}(%
+\\{cur\_edges})$;\5
+$\\{n\_max}(\\{cur\_edges})\K\\{zero\_field}+\\{zero\_field}-1-\|p$;\5
+$\\{n\_pos}(\\{cur\_edges})\K\\{zero\_field}+\\{zero\_field}-1-\\{n\_pos}(%
+\\{cur\_edges})$;\6
+$\|p\K\\{link}(\\{cur\_edges})$;\5
+$\|q\K\\{cur\_edges}$;\C{we assume that $\|p\I\|q$}\6
+\1\&{repeat} \37$\|r\K\\{link}(\|p)$;\5
+$\\{link}(\|p)\K\|q$;\5
+$\\{knil}(\|q)\K\|p$;\5
+$\|q\K\|p$;\5
+$\|p\K\|r$;\6
+\4\&{until}\5
+$\|q=\\{cur\_edges}$;\2\6
+$\\{last\_window\_time}(\\{cur\_edges})\K0$;\6
+\&{end};\par
+\fi
+
+\M337. It's somewhat more difficult, yet not too hard, to reflect about the %
+\|y-axis.
+
+\Y\P\4\&{procedure}\1\ \37\\{x\_reflect\_edges};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{list manipulation
+registers}\6
+\|m: \37\\{integer};\C{\\{info} fields will be reflected with respect to this
+number}\2\6
+\&{begin} \37$\|p\K\\{m\_min}(\\{cur\_edges})$;\5
+$\\{m\_min}(\\{cur\_edges})\K\\{zero\_field}+\\{zero\_field}-\\{m\_max}(\\{cur%
+\_edges})$;\5
+$\\{m\_max}(\\{cur\_edges})\K\\{zero\_field}+\\{zero\_field}-\|p$;\5
+$\|m\K(\\{zero\_field}+\\{m\_offset}(\\{cur\_edges}))\ast8+\\{zero\_w}+\\{min%
+\_halfword}+\\{zero\_w}+\\{min\_halfword}$;\5
+$\\{m\_offset}(\\{cur\_edges})\K\\{zero\_field}$;\5
+$\|p\K\\{link}(\\{cur\_edges})$;\6
+\1\&{repeat} \37\X339:Reflect the edge-and-weight data in $\\{sorted}(\|p)$\X;\6
+\X338:Reflect the edge-and-weight data in $\\{unsorted}(\|p)$\X;\6
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\|p=\\{cur\_edges}$;\2\6
+$\\{last\_window\_time}(\\{cur\_edges})\K0$;\6
+\&{end};\par
+\fi
+
+\M338. We want to change the sign of the weight as we change the sign of the
+\|x~coordinate. Fortunately, it's easier to do this than to negate
+one without the other.
+
+\Y\P$\4\X338:Reflect the edge-and-weight data in $\\{unsorted}(\|p)$\X\S$\6
+$\|q\K\\{unsorted}(\|p)$;\6
+\&{while} $\|q>\\{void}$ \1\&{do}\6
+\&{begin} \37$\\{info}(\|q)\K\|m-\\{info}(\|q)$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end}\2\par
+\U337.\fi
+
+\M339. Reversing the order of a linked list is best thought of as the process
+of
+popping nodes off one stack and pushing them on another. In this case we
+pop from stack~\|q and push to stack~\|r.
+
+\Y\P$\4\X339:Reflect the edge-and-weight data in $\\{sorted}(\|p)$\X\S$\6
+$\|q\K\\{sorted}(\|p)$;\5
+$\|r\K\\{sentinel}$;\6
+\&{while} $\|q\I\\{sentinel}$ \1\&{do}\6
+\&{begin} \37$\|s\K\\{link}(\|q)$;\5
+$\\{link}(\|q)\K\|r$;\5
+$\|r\K\|q$;\5
+$\\{info}(\|r)\K\|m-\\{info}(\|q)$;\5
+$\|q\K\|s$;\6
+\&{end};\2\6
+$\\{sorted}(\|p)\K\|r$\par
+\U337.\fi
+
+\M340. Now let's multiply all the $y$~coordinates of a nonempty edge structure
+by a small integer $s>1$:
+
+\Y\P\4\&{procedure}\1\ \37$\\{y\_scale\_edges}(\|s:\\{integer})$;\6
+\4\&{var} \37$\|p,\39\|q,\39\\{pp},\39\|r,\39\\{rr},\39\\{ss}$: \37\\{pointer};%
+\C{list manipulation registers}\6
+\|t: \37\\{integer};\C{replication counter}\2\6
+\&{begin} \37\&{if} $(\|s\ast(\\{n\_max}(\\{cur\_edges})+1-\\{zero\_field})%
+\G4096)\V\30(\|s\ast(\\{n\_min}(\\{cur\_edges})-\\{zero\_field})\L-4096)$ \1%
+\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Scaled\ picture\ would\ be\ too\ big"})$;\5
+$\\{help3}(\.{"I\ can\'t\ yscale\ the\ picture\ as\ requested---it\ would"})$\6
+$(\.{"make\ some\ coordinates\ too\ large\ or\ too\ small."})$\6
+$(\.{"Proceed,\ and\ I\'ll\ omit\ the\ transformation."})$;\5
+\\{put\_get\_error};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{n\_max}(\\{cur\_edges})\K\|s\ast(\\{n\_max}(\\{cur%
+\_edges})+1-\\{zero\_field})-1+\\{zero\_field}$;\5
+$\\{n\_min}(\\{cur\_edges})\K\|s\ast(\\{n\_min}(\\{cur\_edges})-\\{zero%
+\_field})+\\{zero\_field}$;\5
+\X341:Replicate every row exactly $s$ times\X;\6
+$\\{last\_window\_time}(\\{cur\_edges})\K0$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M341. \P$\X341:Replicate every row exactly $s$ times\X\S$\6
+$\|p\K\\{cur\_edges}$;\6
+\1\&{repeat} \37$\|q\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{for} $\|t\K2\mathrel{\&{to}}\|s$ \1\&{do}\6
+\&{begin} \37$\\{pp}\K\\{get\_node}(\\{row\_node\_size})$;\5
+$\\{link}(\|q)\K\\{pp}$;\5
+$\\{knil}(\|p)\K\\{pp}$;\5
+$\\{link}(\\{pp})\K\|p$;\5
+$\\{knil}(\\{pp})\K\|q$;\5
+$\|q\K\\{pp}$;\5
+\X335:Copy both \\{sorted} and \\{unsorted} lists of \|p to \\{pp}\X;\6
+\&{end};\2\6
+\4\&{until}\5
+$\\{link}(\|p)=\\{cur\_edges}$\2\par
+\U340.\fi
+
+\M342. Scaling the $x$~coordinates is, of course, our next task.
+
+\Y\P\4\&{procedure}\1\ \37$\\{x\_scale\_edges}(\|s:\\{integer})$;\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{list manipulation registers}\6
+\|t: \37$0\to65535$;\C{unpacked \\{info} field}\6
+\|w: \37$0\to7$;\C{unpacked weight}\6
+\\{delta}: \37\\{integer};\C{amount added to scaled \\{info}}\2\6
+\&{begin} \37\&{if} $(\|s\ast(\\{m\_max}(\\{cur\_edges})-\\{zero\_field})%
+\G4096)\V\30(\|s\ast(\\{m\_min}(\\{cur\_edges})-\\{zero\_field})\L-4096)$ \1%
+\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Scaled\ picture\ would\ be\ too\ big"})$;\5
+$\\{help3}(\.{"I\ can\'t\ xscale\ the\ picture\ as\ requested---it\ would"})$\6
+$(\.{"make\ some\ coordinates\ too\ large\ or\ too\ small."})$\6
+$(\.{"Proceed,\ and\ I\'ll\ omit\ the\ transformation."})$;\5
+\\{put\_get\_error};\6
+\&{end}\6
+\4\&{else} \&{if} $(\\{m\_max}(\\{cur\_edges})\I\\{zero\_field})\V(\\{m\_min}(%
+\\{cur\_edges})\I\\{zero\_field})$ \1\&{then}\6
+\&{begin} \37$\\{m\_max}(\\{cur\_edges})\K\|s\ast(\\{m\_max}(\\{cur\_edges})-%
+\\{zero\_field})+\\{zero\_field}$;\5
+$\\{m\_min}(\\{cur\_edges})\K\|s\ast(\\{m\_min}(\\{cur\_edges})-\\{zero%
+\_field})+\\{zero\_field}$;\5
+$\\{delta}\K8\ast(\\{zero\_field}-\|s\ast\\{m\_offset}(\\{cur\_edges}))+\\{min%
+\_halfword}$;\5
+$\\{m\_offset}(\\{cur\_edges})\K\\{zero\_field}$;\6
+\X343:Scale the $x$~coordinates of each row by $s$\X;\6
+$\\{last\_window\_time}(\\{cur\_edges})\K0$;\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M343. The multiplications cannot overflow because we know that $\|s<4096$.
+
+\Y\P$\4\X343:Scale the $x$~coordinates of each row by $s$\X\S$\6
+$\|q\K\\{link}(\\{cur\_edges})$;\6
+\1\&{repeat} \37$\|p\K\\{sorted}(\|q)$;\6
+\&{while} $\|p\I\\{sentinel}$ \1\&{do}\6
+\&{begin} \37$\|t\K\\{ho}(\\{info}(\|p))$;\5
+$\|w\K\|t\mathbin{\&{mod}}8$;\5
+$\\{info}(\|p)\K(\|t-\|w)\ast\|s+\|w+\\{delta}$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\|p\K\\{unsorted}(\|q)$;\6
+\&{while} $\|p>\\{void}$ \1\&{do}\6
+\&{begin} \37$\|t\K\\{ho}(\\{info}(\|p))$;\5
+$\|w\K\|t\mathbin{\&{mod}}8$;\5
+$\\{info}(\|p)\K(\|t-\|w)\ast\|s+\|w+\\{delta}$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\|q\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\|q=\\{cur\_edges}$\2\par
+\U342.\fi
+
+\M344. Here is a routine that changes the signs of all the weights, without
+changing anything else.
+
+\Y\P\4\&{procedure}\1\ \37$\\{negate\_edges}(\|h:\\{pointer})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s,\39\|t,\39\|u$: \37\\{pointer};%
+\C{structure traversers}\2\6
+\&{begin} \37$\|p\K\\{link}(\|h)$;\6
+\&{while} $\|p\I\|h$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{unsorted}(\|p)$;\6
+\&{while} $\|q>\\{void}$ \1\&{do}\6
+\&{begin} \37$\\{info}(\|q)\K8-2\ast((\\{ho}(\\{info}(\|q)))\mathbin{%
+\&{mod}}8)+\\{info}(\|q)$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+$\|q\K\\{sorted}(\|p)$;\6
+\&{if} $\|q\I\\{sentinel}$ \1\&{then}\6
+\&{begin} \37\1\&{repeat} \37$\\{info}(\|q)\K8-2\ast((\\{ho}(\\{info}(\|q)))%
+\mathbin{\&{mod}}8)+\\{info}(\|q)$;\5
+$\|q\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\|q=\\{sentinel}$;\2\6
+\X345:Put the list $\\{sorted}(\|p)$ back into sort\X;\6
+\&{end};\2\6
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\\{last\_window\_time}(\|h)\K0$;\6
+\&{end};\par
+\fi
+
+\M345. \MF\ would work even if the code in this section were omitted, because
+a list of edge-and-weight data that is sorted only by
+\|m but not~\|w turns out to be good enough for correct operation.
+However, the author decided not to make the program even trickier than
+it is already, since \\{negate\_edges} isn't needed very often.
+The simpler-to-state condition, ``keep the \\{sorted} list fully sorted,''
+is therefore being preserved at the cost of extra computation.
+
+\Y\P$\4\X345:Put the list $\\{sorted}(\|p)$ back into sort\X\S$\6
+$\|u\K\\{sorted\_loc}(\|p)$;\5
+$\|q\K\\{link}(\|u)$;\5
+$\|r\K\|q$;\5
+$\|s\K\\{link}(\|r)$;\C{$\|q=\\{sorted}(\|p)$}\6
+\~ \1\&{loop}\ \&{if} $\\{info}(\|s)>\\{info}(\|r)$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|u)\K\|q$;\6
+\&{if} $\|s=\\{sentinel}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|u\K\|r$;\5
+$\|q\K\|s$;\5
+$\|r\K\|q$;\5
+$\|s\K\\{link}(\|r)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|t\K\|s$;\5
+$\|s\K\\{link}(\|t)$;\5
+$\\{link}(\|t)\K\|q$;\5
+$\|q\K\|t$;\6
+\&{end};\2\2\6
+\4\\{done}: \37$\\{link}(\|r)\K\\{sentinel}$\par
+\U344.\fi
+
+\M346. The \\{unsorted} edges of a row are merged into the \\{sorted} ones by
+a subroutine called \\{sort\_edges}. It uses simple insertion sort,
+followed by a merge, because the unsorted list is supposedly quite short.
+However, the unsorted list is assumed to be nonempty.
+
+\Y\P\4\&{procedure}\1\ \37$\\{sort\_edges}(\|h:\\{pointer})$;\C{\|h is a row
+header}\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|k: \37\\{halfword};\C{key register that we compare to $\\{info}(%
+\|q)$}\6
+$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\2\6
+\&{begin} \37$\|r\K\\{unsorted}(\|h)$;\5
+$\\{unsorted}(\|h)\K\\{null}$;\5
+$\|p\K\\{link}(\|r)$;\5
+$\\{link}(\|r)\K\\{sentinel}$;\5
+$\\{link}(\\{temp\_head})\K\|r$;\6
+\&{while} $\|p>\\{void}$ \1\&{do}\C{sort node \|p into the list that starts at %
+\\{temp\_head}}\6
+\&{begin} \37$\|k\K\\{info}(\|p)$;\5
+$\|q\K\\{temp\_head}$;\6
+\1\&{repeat} \37$\|r\K\|q$;\5
+$\|q\K\\{link}(\|r)$;\6
+\4\&{until}\5
+$\|k\L\\{info}(\|q)$;\2\6
+$\\{link}(\|r)\K\|p$;\5
+$\|r\K\\{link}(\|p)$;\5
+$\\{link}(\|p)\K\|q$;\5
+$\|p\K\|r$;\6
+\&{end};\2\6
+\X347:Merge the \\{temp\_head} list into $\\{sorted}(\|h)$\X;\6
+\&{end};\par
+\fi
+
+\M347. In this step we use the fact that $\\{sorted}(\|h)=\\{link}(\\{sorted%
+\_loc}(\|h))$.
+
+\Y\P$\4\X347:Merge the \\{temp\_head} list into $\\{sorted}(\|h)$\X\S$\6
+\&{begin} \37$\|r\K\\{sorted\_loc}(\|h)$;\5
+$\|q\K\\{link}(\|r)$;\5
+$\|p\K\\{link}(\\{temp\_head})$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|k\K\\{info}(\|p)$;\6
+\&{while} $\|k>\\{info}(\|q)$ \1\&{do}\6
+\&{begin} \37$\|r\K\|q$;\5
+$\|q\K\\{link}(\|r)$;\6
+\&{end};\2\6
+$\\{link}(\|r)\K\|p$;\5
+$\|s\K\\{link}(\|p)$;\5
+$\\{link}(\|p)\K\|q$;\6
+\&{if} $\|s=\\{sentinel}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|r\K\|p$;\5
+$\|p\K\|s$;\6
+\&{end};\2\6
+\4\\{done}: \37\&{end}\par
+\U346.\fi
+
+\M348. The \\{cull\_edges} procedure ``optimizes'' an edge structure by making
+all
+the pixel weights either \\{w\_out} or~\\{w\_in}. The weight will be~\\{w\_in}
+after the
+operation if and only if it was in the closed interval $[\\{w\_lo},\\{w\_hi}]$
+before, where $\\{w\_lo}\L\\{w\_hi}$. Either \\{w\_out} or \\{w\_in} is zero,
+while the other is
+$\pm1$, $\pm2$, or $\pm3$. The parameters will be such that zero-weight
+pixels will remain of weight zero. (This is fortunate,
+because there are infinitely many of them.)
+
+The procedure also computes the tightest possible bounds on the resulting
+data, by updating \\{m\_min}, \\{m\_max}, \\{n\_min}, and~\\{n\_max}.
+
+\Y\P\4\&{procedure}\1\ \37$\\{cull\_edges}(\\{w\_lo},\39\\{w\_hi},\39\\{w%
+\_out},\39\\{w\_in}:\\{integer})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{for list
+manipulation}\6
+\|w: \37\\{integer};\C{new weight after culling}\6
+\|d: \37\\{integer};\C{data register for unpacking}\6
+\|m: \37\\{integer};\C{the previous column number, including \\{m\_offset}}\6
+\\{mm}: \37\\{integer};\C{the next column number, including \\{m\_offset}}\6
+\\{ww}: \37\\{integer};\C{accumulated weight before culling}\6
+\\{prev\_w}: \37\\{integer};\C{value of \|w before column \|m}\6
+$\|n,\39\\{min\_n},\39\\{max\_n}$: \37\\{pointer};\C{current and extreme row
+numbers}\6
+$\\{min\_d},\39\\{max\_d}$: \37\\{pointer};\C{extremes of the new
+edge-and-weight data}\2\6
+\&{begin} \37$\\{min\_d}\K\\{max\_halfword}$;\5
+$\\{max\_d}\K\\{min\_halfword}$;\5
+$\\{min\_n}\K\\{max\_halfword}$;\5
+$\\{max\_n}\K\\{min\_halfword}$;\6
+$\|p\K\\{link}(\\{cur\_edges})$;\5
+$\|n\K\\{n\_min}(\\{cur\_edges})$;\6
+\&{while} $\|p\I\\{cur\_edges}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{unsorted}(\|p)>\\{void}$ \1\&{then}\5
+$\\{sort\_edges}(\|p)$;\2\6
+\&{if} $\\{sorted}(\|p)\I\\{sentinel}$ \1\&{then}\5
+\X349:Cull superfluous edge-weight entries from $\\{sorted}(\|p)$\X;\2\6
+$\|p\K\\{link}(\|p)$;\5
+$\\{incr}(\|n)$;\6
+\&{end};\2\6
+\X352:Delete empty rows at the top and/or bottom; update the boundary values in
+the header\X;\6
+$\\{last\_window\_time}(\\{cur\_edges})\K0$;\6
+\&{end};\par
+\fi
+
+\M349. The entire \\{sorted} list is returned to available memory in this step;
+a new list is built starting (temporarily) at \\{temp\_head}.
+Since several edges can occur at the same column, we need to be looking
+ahead of where the actual culling takes place. This means that it's
+slightly tricky to get the iteration started and stopped.
+
+\Y\P$\4\X349:Cull superfluous edge-weight entries from $\\{sorted}(\|p)$\X\S$\6
+\&{begin} \37$\|r\K\\{temp\_head}$;\5
+$\|q\K\\{sorted}(\|p)$;\5
+$\\{ww}\K0$;\5
+$\|m\K1000000$;\5
+$\\{prev\_w}\K0$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\|q=\\{sentinel}$ \1\&{then}\5
+$\\{mm}\K1000000$\6
+\4\&{else} \&{begin} \37$\|d\K\\{ho}(\\{info}(\|q))$;\5
+$\\{mm}\K\|d\mathbin{\&{div}}8$;\5
+$\\{ww}\K\\{ww}+(\|d\mathbin{\&{mod}}8)-\\{zero\_w}$;\6
+\&{end};\2\6
+\&{if} $\\{mm}>\|m$ \1\&{then}\6
+\&{begin} \37\X350:Insert an edge-weight for edge \|m, if the new pixel weight
+has changed\X;\6
+\&{if} $\|q=\\{sentinel}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{end};\2\6
+$\|m\K\\{mm}$;\6
+\&{if} $\\{ww}\G\\{w\_lo}$ \1\&{then}\6
+\&{if} $\\{ww}\L\\{w\_hi}$ \1\&{then}\5
+$\|w\K\\{w\_in}$\6
+\4\&{else} $\|w\K\\{w\_out}$\2\6
+\4\&{else} $\|w\K\\{w\_out}$;\2\6
+$\|s\K\\{link}(\|q)$;\5
+$\\{free\_avail}(\|q)$;\5
+$\|q\K\|s$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{link}(\|r)\K\\{sentinel}$;\5
+$\\{sorted}(\|p)\K\\{link}(\\{temp\_head})$;\6
+\&{if} $\|r\I\\{temp\_head}$ \1\&{then}\5
+\X351:Update the max/min amounts\X;\2\6
+\&{end}\par
+\U348.\fi
+
+\M350. \P$\X350:Insert an edge-weight for edge \|m, if the new pixel weight has
+changed\X\S$\6
+\&{if} $\|w\I\\{prev\_w}$ \1\&{then}\6
+\&{begin} \37$\|s\K\\{get\_avail}$;\5
+$\\{link}(\|r)\K\|s$;\5
+$\\{info}(\|s)\K8\ast\|m+\\{min\_halfword}+\\{zero\_w}+\|w-\\{prev\_w}$;\5
+$\|r\K\|s$;\5
+$\\{prev\_w}\K\|w$;\6
+\&{end}\2\par
+\U349.\fi
+
+\M351. \P$\X351:Update the max/min amounts\X\S$\6
+\&{begin} \37\&{if} $\\{min\_n}=\\{max\_halfword}$ \1\&{then}\5
+$\\{min\_n}\K\|n$;\2\6
+$\\{max\_n}\K\|n$;\6
+\&{if} $\\{min\_d}>\\{info}(\\{link}(\\{temp\_head}))$ \1\&{then}\5
+$\\{min\_d}\K\\{info}(\\{link}(\\{temp\_head}))$;\2\6
+\&{if} $\\{max\_d}<\\{info}(\|r)$ \1\&{then}\5
+$\\{max\_d}\K\\{info}(\|r)$;\2\6
+\&{end}\par
+\U349.\fi
+
+\M352. \P$\X352:Delete empty rows at the top and/or bottom; update the boundary
+values in the header\X\S$\6
+\&{if} $\\{min\_n}>\\{max\_n}$ \1\&{then}\5
+\X353:Delete all the row headers\X\6
+\4\&{else} \&{begin} \37$\|n\K\\{n\_min}(\\{cur\_edges})$;\5
+$\\{n\_min}(\\{cur\_edges})\K\\{min\_n}$;\6
+\&{while} $\\{min\_n}>\|n$ \1\&{do}\6
+\&{begin} \37$\|p\K\\{link}(\\{cur\_edges})$;\5
+$\\{link}(\\{cur\_edges})\K\\{link}(\|p)$;\5
+$\\{knil}(\\{link}(\|p))\K\\{cur\_edges}$;\5
+$\\{free\_node}(\|p,\39\\{row\_node\_size})$;\5
+$\\{incr}(\|n)$;\6
+\&{end};\2\6
+$\|n\K\\{n\_max}(\\{cur\_edges})$;\5
+$\\{n\_max}(\\{cur\_edges})\K\\{max\_n}$;\5
+$\\{n\_pos}(\\{cur\_edges})\K\\{max\_n}+1$;\5
+$\\{n\_rover}(\\{cur\_edges})\K\\{cur\_edges}$;\6
+\&{while} $\\{max\_n}<\|n$ \1\&{do}\6
+\&{begin} \37$\|p\K\\{knil}(\\{cur\_edges})$;\5
+$\\{knil}(\\{cur\_edges})\K\\{knil}(\|p)$;\5
+$\\{link}(\\{knil}(\|p))\K\\{cur\_edges}$;\5
+$\\{free\_node}(\|p,\39\\{row\_node\_size})$;\5
+$\\{decr}(\|n)$;\6
+\&{end};\2\6
+$\\{m\_min}(\\{cur\_edges})\K((\\{ho}(\\{min\_d}))\mathbin{\&{div}}8)-\\{m%
+\_offset}(\\{cur\_edges})+\\{zero\_field}$;\5
+$\\{m\_max}(\\{cur\_edges})\K((\\{ho}(\\{max\_d}))\mathbin{\&{div}}8)-\\{m%
+\_offset}(\\{cur\_edges})+\\{zero\_field}$;\6
+\&{end}\2\par
+\U348.\fi
+
+\M353. We get here if the edges have been entirely culled away.
+
+\Y\P$\4\X353:Delete all the row headers\X\S$\6
+\&{begin} \37$\|p\K\\{link}(\\{cur\_edges})$;\6
+\&{while} $\|p\I\\{cur\_edges}$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{link}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{row\_node\_size})$;\5
+$\|p\K\|q$;\6
+\&{end};\2\6
+$\\{init\_edges}(\\{cur\_edges})$;\6
+\&{end}\par
+\U352.\fi
+
+\M354. The last and most difficult routine for transforming an edge
+structure---and
+the most interesting one!---is \\{xy\_swap\_edges}, which interchanges the
+r\^^Doles of rows and columns. Its task can be viewed as the job of
+creating an edge structure that contains only horizontal edges, linked
+together in columns, given an edge structure that contains only
+vertical edges linked together in rows; we must do this without changing
+the implied pixel weights.
+
+Given any two adjacent rows of an edge structure, it is not difficult to
+determine the horizontal edges that lie ``between'' them: We simply look
+for vertically adjacent pixels that have different weight, and insert
+a horizontal edge containing the difference in weights. Every horizontal
+edge determined in this way should be put into an appropriate linked
+list. Since random access to these linked lists is desirable, we use
+the \\{move} array to hold the list heads. If we work through the given
+edge structure from top to bottom, the constructed lists will not need
+to be sorted, since they will already be in order.
+
+The following algorithm makes use of some ideas suggested by John Hobby.
+It assumes that the edge structure is non-null, i.e., that $\\{link}(\\{cur%
+\_edges})\I\\{cur\_edges}$, hence $\\{m\_max}(\\{cur\_edges})\G\\{m\_min}(%
+\\{cur\_edges})$.
+
+\Y\P\4\&{procedure}\1\ \37\\{xy\_swap\_edges};\C{interchange \|x and \|y in %
+\\{cur\_edges}}\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\\{m\_magic},\39\\{n\_magic}$: \37\\{integer};\C{special values
+that account for offsets}\6
+$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{pointers that traverse the given
+structure}\6
+\X357:Other local variables for \\{xy\_swap\_edges}\X\2\6
+\&{begin} \37\X356:Initialize the array of new edge list heads\X;\6
+\X355:Insert blank rows at the top and bottom, and set \|p to the new top row%
+\X;\6
+\X365:Compute the magic offset values\X;\6
+\1\&{repeat} \37$\|q\K\\{knil}(\|p)$;\ \&{if} $\\{unsorted}(\|q)>\\{void}$ \1%
+\&{then}\5
+$\\{sort\_edges}(\|q)$;\2\6
+\X358:Insert the horizontal edges defined by adjacent rows $\|p,\|q$, and
+destroy row~\|p\X;\6
+$\|p\K\|q$;\5
+$\\{n\_magic}\K\\{n\_magic}-8$;\6
+\4\&{until}\5
+$\\{knil}(\|p)=\\{cur\_edges}$;\2\6
+$\\{free\_node}(\|p,\39\\{row\_node\_size})$;\C{now all original rows have been
+recycled}\6
+\X364:Adjust the header to reflect the new edges\X;\6
+\&{end};\par
+\fi
+
+\M355. Here we don't bother to keep the \\{link} entries up to date, since the
+procedure looks only at the \\{knil} fields as it destroys the former
+edge structure.
+
+\Y\P$\4\X355:Insert blank rows at the top and bottom, and set \|p to the new
+top row\X\S$\6
+$\|p\K\\{get\_node}(\\{row\_node\_size})$;\5
+$\\{sorted}(\|p)\K\\{sentinel}$;\5
+$\\{unsorted}(\|p)\K\\{null}$;\6
+$\\{knil}(\|p)\K\\{cur\_edges}$;\5
+$\\{knil}(\\{link}(\\{cur\_edges}))\K\|p$;\C{the new bottom row}\6
+$\|p\K\\{get\_node}(\\{row\_node\_size})$;\5
+$\\{sorted}(\|p)\K\\{sentinel}$;\5
+$\\{knil}(\|p)\K\\{knil}(\\{cur\_edges})$;\C{the new top row}\par
+\U354.\fi
+
+\M356. The new lists will become \\{sorted} lists later, so we initialize
+empty lists to \\{sentinel}.
+
+\Y\P$\4\X356:Initialize the array of new edge list heads\X\S$\6
+$\\{m\_spread}\K\\{m\_max}(\\{cur\_edges})-\\{m\_min}(\\{cur\_edges})$;\C{this
+is $\G0$ by assumption}\6
+\&{if} $\\{m\_spread}>\\{move\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"move\ table\ size"},\39\\{move\_size})$;\2\6
+\&{for} $\|j\K0\mathrel{\&{to}}\\{m\_spread}$ \1\&{do}\5
+$\\{move}[\|j]\K\\{sentinel}$\2\par
+\U354.\fi
+
+\M357. \P$\X357:Other local variables for \\{xy\_swap\_edges}\X\S$\6
+\4\\{m\_spread}: \37\\{integer};\C{the difference between \\{m\_max} and \\{m%
+\_min}}\6
+\4$\|j,\39\\{jj}$: \37$0\to\\{move\_size}$;\C{indices into \\{move}}\6
+\4$\|m,\39\\{mm}$: \37\\{integer};\C{\|m values at vertical edges}\6
+\4$\\{pd},\39\\{rd}$: \37\\{integer};\C{data fields from edge-and-weight nodes}%
+\6
+\4$\\{pm},\39\\{rm}$: \37\\{integer};\C{\|m values from edge-and-weight nodes}\6
+\4\|w: \37\\{integer};\C{the difference in accumulated weight}\6
+\4\\{ww}: \37\\{integer};\C{as much of \|w that can be stored in a single node}%
+\6
+\4\\{dw}: \37\\{integer};\C{an increment to be added to \|w}\par
+\A363.
+\U354.\fi
+
+\M358. At the point where we test $\|w\I0$, variable \|w contains
+the accumulated weight from edges already passed in
+row~\|p minus the accumulated weight from edges already passed in row~\|q.
+
+\Y\P$\4\X358:Insert the horizontal edges defined by adjacent rows $\|p,\|q$,
+and destroy row~\|p\X\S$\6
+$\|r\K\\{sorted}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{row\_node\_size})$;\5
+$\|p\K\|r$;\6
+$\\{pd}\K\\{ho}(\\{info}(\|p))$;\5
+$\\{pm}\K\\{pd}\mathbin{\&{div}}8$;\6
+$\|r\K\\{sorted}(\|q)$;\5
+$\\{rd}\K\\{ho}(\\{info}(\|r))$;\5
+$\\{rm}\K\\{rd}\mathbin{\&{div}}8$;\5
+$\|w\K0$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\\{pm}<\\{rm}$ \1\&{then}\5
+$\\{mm}\K\\{pm}$\ \&{else} $\\{mm}\K\\{rm}$;\2\6
+\&{if} $\|w\I0$ \1\&{then}\5
+\X362:Insert horizontal edges of weight \|w between \|m and~\\{mm}\X;\2\6
+\&{if} $\\{pd}<\\{rd}$ \1\&{then}\6
+\&{begin} \37$\\{dw}\K(\\{pd}\mathbin{\&{mod}}8)-\\{zero\_w}$;\5
+\X360:Advance pointer \|p to the next vertical edge, after destroying the
+previous one\X;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\|r=\\{sentinel}$ \1\&{then}\5
+\&{goto} \37\\{done};\C{$\\{rd}=\\{pd}=\\{ho}(\\{max\_halfword})$}\2\6
+$\\{dw}\K-((\\{rd}\mathbin{\&{mod}}8)-\\{zero\_w})$;\5
+\X359:Advance pointer \|r to the next vertical edge\X;\6
+\&{end};\2\6
+$\|m\K\\{mm}$;\5
+$\|w\K\|w+\\{dw}$;\6
+\&{end};\2\6
+\4\\{done}: \37\par
+\U354.\fi
+
+\M359. \P$\X359:Advance pointer \|r to the next vertical edge\X\S$\6
+$\|r\K\\{link}(\|r)$;\5
+$\\{rd}\K\\{ho}(\\{info}(\|r))$;\5
+$\\{rm}\K\\{rd}\mathbin{\&{div}}8$\par
+\U358.\fi
+
+\M360. \P$\X360:Advance pointer \|p to the next vertical edge, after destroying
+the previous one\X\S$\6
+$\|s\K\\{link}(\|p)$;\5
+$\\{free\_avail}(\|p)$;\5
+$\|p\K\|s$;\5
+$\\{pd}\K\\{ho}(\\{info}(\|p))$;\5
+$\\{pm}\K\\{pd}\mathbin{\&{div}}8$\par
+\U358.\fi
+
+\M361. Certain ``magic'' values are needed to make the following code work,
+because of the various offsets in our data structure. For now, let's not
+worry about their precise values; we shall compute \\{m\_magic} and \\{n%
+\_magic}
+later, after we see what the code looks like.
+
+\fi
+
+\M362. \P$\X362:Insert horizontal edges of weight \|w between \|m and~\\{mm}\X%
+\S$\6
+\&{if} $\|m\I\\{mm}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{mm}-\\{m\_magic}\G\\{move\_size}$ \1\&{then}\5
+$\\{confusion}(\.{"xy"})$;\2\6
+$\\{extras}\K(\\{abs}(\|w)-1)\mathbin{\&{div}}3$;\6
+\&{if} $\\{extras}>0$ \1\&{then}\6
+\&{begin} \37\&{if} $\|w>0$ \1\&{then}\5
+$\\{xw}\K+3$\ \&{else} $\\{xw}\K-3$;\2\6
+$\\{ww}\K\|w-\\{extras}\ast\\{xw}$;\6
+\&{end}\6
+\4\&{else} $\\{ww}\K\|w$;\2\6
+\1\&{repeat} \37$\|j\K\|m-\\{m\_magic}$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}\\{extras}$ \1\&{do}\6
+\&{begin} \37$\|s\K\\{get\_avail}$;\5
+$\\{info}(\|s)\K\\{n\_magic}+\\{xw}$;\5
+$\\{link}(\|s)\K\\{move}[\|j]$;\5
+$\\{move}[\|j]\K\|s$;\6
+\&{end};\2\6
+$\|s\K\\{get\_avail}$;\5
+$\\{info}(\|s)\K\\{n\_magic}+\\{ww}$;\5
+$\\{link}(\|s)\K\\{move}[\|j]$;\5
+$\\{move}[\|j]\K\|s$;\6
+$\\{incr}(\|m)$;\6
+\4\&{until}\5
+$\|m=\\{mm}$;\2\6
+\&{end}\2\par
+\U358.\fi
+
+\M363. \P$\X357:Other local variables for \\{xy\_swap\_edges}\X\mathrel{+}\S$\6
+\4\\{extras}: \37\\{integer};\C{the number of additional nodes to make weights
+$>3$}\6
+\4\\{xw}: \37$-3\to3$;\C{the additional weight in extra nodes}\6
+\4\|k: \37\\{integer};\C{loop counter for inserting extra nodes}\par
+\fi
+
+\M364. At the beginning of this step, $\\{move}[\\{m\_spread}]=\\{sentinel}$,
+because no
+horizontal edges will extend to the right of column $\\{m\_max}(\\{cur%
+\_edges})$.
+
+\Y\P$\4\X364:Adjust the header to reflect the new edges\X\S$\6
+$\\{move}[\\{m\_spread}]\K0$;\5
+$\|j\K0$;\6
+\&{while} $\\{move}[\|j]=\\{sentinel}$ \1\&{do}\5
+$\\{incr}(\|j)$;\2\6
+\&{if} $\|j=\\{m\_spread}$ \1\&{then}\5
+$\\{init\_edges}(\\{cur\_edges})$\C{all edge weights are zero}\6
+\4\&{else} \&{begin} \37$\\{mm}\K\\{m\_min}(\\{cur\_edges})$;\5
+$\\{m\_min}(\\{cur\_edges})\K\\{n\_min}(\\{cur\_edges})$;\5
+$\\{m\_max}(\\{cur\_edges})\K\\{n\_max}(\\{cur\_edges})+1$;\5
+$\\{m\_offset}(\\{cur\_edges})\K\\{zero\_field}$;\5
+$\\{jj}\K\\{m\_spread}-1$;\6
+\&{while} $\\{move}[\\{jj}]=\\{sentinel}$ \1\&{do}\5
+$\\{decr}(\\{jj})$;\2\6
+$\\{n\_min}(\\{cur\_edges})\K\|j+\\{mm}$;\5
+$\\{n\_max}(\\{cur\_edges})\K\\{jj}+\\{mm}$;\5
+$\|q\K\\{cur\_edges}$;\6
+\1\&{repeat} \37$\|p\K\\{get\_node}(\\{row\_node\_size})$;\5
+$\\{link}(\|q)\K\|p$;\5
+$\\{knil}(\|p)\K\|q$;\5
+$\\{sorted}(\|p)\K\\{move}[\|j]$;\5
+$\\{unsorted}(\|p)\K\\{null}$;\5
+$\\{incr}(\|j)$;\5
+$\|q\K\|p$;\6
+\4\&{until}\5
+$\|j>\\{jj}$;\2\6
+$\\{link}(\|q)\K\\{cur\_edges}$;\5
+$\\{knil}(\\{cur\_edges})\K\|q$;\5
+$\\{n\_pos}(\\{cur\_edges})\K\\{n\_max}(\\{cur\_edges})+1$;\5
+$\\{n\_rover}(\\{cur\_edges})\K\\{cur\_edges}$;\5
+$\\{last\_window\_time}(\\{cur\_edges})\K0$;\6
+\&{end};\2\par
+\U354.\fi
+
+\M365. The values of \\{m\_magic} and \\{n\_magic} can be worked out by trying
+the
+code above on a small example; if they work correctly in simple cases,
+they should work in general.
+
+\Y\P$\4\X365:Compute the magic offset values\X\S$\6
+$\\{m\_magic}\K\\{m\_min}(\\{cur\_edges})+\\{m\_offset}(\\{cur\_edges})-\\{zero%
+\_field}$;\5
+$\\{n\_magic}\K8\ast\\{n\_max}(\\{cur\_edges})+8+\\{zero\_w}+\\{min\_halfword}$%
+\par
+\U354.\fi
+
+\M366. Now let's look at the subroutine that merges the edges from a given
+edge structure into \\{cur\_edges}. The given edge structure loses all its
+edges.
+
+\Y\P\4\&{procedure}\1\ \37$\\{merge\_edges}(\|h:\\{pointer})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\\{pp},\39\\{qq},\39\\{rr}$: \37\\{pointer};%
+\C{list manipulation registers}\6
+\|n: \37\\{integer};\C{row number}\6
+\|k: \37\\{halfword};\C{key register that we compare to $\\{info}(\|q)$}\6
+\\{delta}: \37\\{integer};\C{change to the edge/weight data}\2\6
+\&{begin} \37\&{if} $\\{link}(\|h)\I\|h$ \1\&{then}\6
+\&{begin} \37\&{if} $(\\{m\_min}(\|h)<\\{m\_min}(\\{cur\_edges}))\V(\\{m\_max}(%
+\|h)>\\{m\_max}(\\{cur\_edges}))\V\30(\\{n\_min}(\|h)<\\{n\_min}(\\{cur%
+\_edges}))\V(\\{n\_max}(\|h)>\\{n\_max}(\\{cur\_edges}))$ \1\&{then}\5
+$\\{edge\_prep}(\\{m\_min}(\|h)-\\{zero\_field},\39\\{m\_max}(\|h)-\\{zero%
+\_field},\39\\{n\_min}(\|h)-\\{zero\_field},\39\\{n\_max}(\|h)-\\{zero%
+\_field}+1)$;\2\6
+\&{if} $\\{m\_offset}(\|h)\I\\{m\_offset}(\\{cur\_edges})$ \1\&{then}\5
+\X367:Adjust the data of \|h to account for a difference of offsets\X;\2\6
+$\|n\K\\{n\_min}(\\{cur\_edges})$;\5
+$\|p\K\\{link}(\\{cur\_edges})$;\5
+$\\{pp}\K\\{link}(\|h)$;\6
+\&{while} $\|n<\\{n\_min}(\|h)$ \1\&{do}\6
+\&{begin} \37$\\{incr}(\|n)$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\1\&{repeat} \37\X368:Merge row \\{pp} into row \|p\X;\6
+$\\{pp}\K\\{link}(\\{pp})$;\5
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\\{pp}=\|h$;\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M367. \P$\X367:Adjust the data of \|h to account for a difference of offsets\X%
+\S$\6
+\&{begin} \37$\\{pp}\K\\{link}(\|h)$;\5
+$\\{delta}\K8\ast(\\{m\_offset}(\\{cur\_edges})-\\{m\_offset}(\|h))$;\6
+\1\&{repeat} \37$\\{qq}\K\\{sorted}(\\{pp})$;\6
+\&{while} $\\{qq}\I\\{sentinel}$ \1\&{do}\6
+\&{begin} \37$\\{info}(\\{qq})\K\\{info}(\\{qq})+\\{delta}$;\5
+$\\{qq}\K\\{link}(\\{qq})$;\6
+\&{end};\2\6
+$\\{qq}\K\\{unsorted}(\\{pp})$;\6
+\&{while} $\\{qq}>\\{void}$ \1\&{do}\6
+\&{begin} \37$\\{info}(\\{qq})\K\\{info}(\\{qq})+\\{delta}$;\5
+$\\{qq}\K\\{link}(\\{qq})$;\6
+\&{end};\2\6
+$\\{pp}\K\\{link}(\\{pp})$;\6
+\4\&{until}\5
+$\\{pp}=\|h$;\2\6
+\&{end}\par
+\U366.\fi
+
+\M368. The \\{sorted} and \\{unsorted} lists are merged separately. After this
+step, row~\\{pp} will have no edges remaining, since they will all have
+been merged into row~\|p.
+
+\Y\P$\4\X368:Merge row \\{pp} into row \|p\X\S$\6
+$\\{qq}\K\\{unsorted}(\\{pp})$;\6
+\&{if} $\\{qq}>\\{void}$ \1\&{then}\6
+\&{if} $\\{unsorted}(\|p)\L\\{void}$ \1\&{then}\5
+$\\{unsorted}(\|p)\K\\{qq}$\6
+\4\&{else} \&{begin} \37\&{while} $\\{link}(\\{qq})>\\{void}$ \1\&{do}\5
+$\\{qq}\K\\{link}(\\{qq})$;\2\6
+$\\{link}(\\{qq})\K\\{unsorted}(\|p)$;\5
+$\\{unsorted}(\|p)\K\\{unsorted}(\\{pp})$;\6
+\&{end};\2\2\6
+$\\{unsorted}(\\{pp})\K\\{null}$;\5
+$\\{qq}\K\\{sorted}(\\{pp})$;\6
+\&{if} $\\{qq}\I\\{sentinel}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{unsorted}(\|p)=\\{void}$ \1\&{then}\5
+$\\{unsorted}(\|p)\K\\{null}$;\2\6
+$\\{sorted}(\\{pp})\K\\{sentinel}$;\5
+$\|r\K\\{sorted\_loc}(\|p)$;\5
+$\|q\K\\{link}(\|r)$;\C{$\|q=\\{sorted}(\|p)$}\6
+\&{if} $\|q=\\{sentinel}$ \1\&{then}\5
+$\\{sorted}(\|p)\K\\{qq}$\6
+\4\&{else} \~ \1\&{loop}\ \&{begin} \37$\|k\K\\{info}(\\{qq})$;\6
+\&{while} $\|k>\\{info}(\|q)$ \1\&{do}\6
+\&{begin} \37$\|r\K\|q$;\5
+$\|q\K\\{link}(\|r)$;\6
+\&{end};\2\6
+$\\{link}(\|r)\K\\{qq}$;\5
+$\\{rr}\K\\{link}(\\{qq})$;\5
+$\\{link}(\\{qq})\K\|q$;\6
+\&{if} $\\{rr}=\\{sentinel}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|r\K\\{qq}$;\5
+$\\{qq}\K\\{rr}$;\6
+\&{end};\2\2\6
+\&{end};\2\6
+\4\\{done}: \37\par
+\U366.\fi
+
+\M369. The \\{total\_weight} routine computes the total of all pixel weights
+in a given edge structure. It's not difficult to prove that this is
+the sum of $(-w)$ times $x$ taken over all edges,
+where $w$ and~$x$ are the weight and $x$~coordinates stored in an edge.
+It's not necessary to worry that this quantity will overflow the
+size of an \\{integer} register, because it will be less than~$2^{31}$
+unless the edge structure has more than 174,762 edges. However, we had
+better not try to compute it as a \\{scaled} integer, because a total
+weight of almost $12\times 2^{12}$ can be produced by only four edges.
+
+\Y\P\4\&{function}\1\ \37$\\{total\_weight}(\|h:\\{pointer})$: \37\\{integer};%
+\C{\|h is an edge header}\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{variables that traverse the given
+structure}\6
+\|n: \37\\{integer};\C{accumulated total so far}\6
+\|m: \37$0\to65535$;\C{packed $x$ and $w$ values, including offsets}\2\6
+\&{begin} \37$\|n\K0$;\5
+$\|p\K\\{link}(\|h)$;\6
+\&{while} $\|p\I\|h$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{sorted}(\|p)$;\6
+\&{while} $\|q\I\\{sentinel}$ \1\&{do}\5
+\X370:Add the contribution of node \|q to the total weight, and set $\|q\K%
+\\{link}(\|q)$\X;\2\6
+$\|q\K\\{unsorted}(\|p)$;\6
+\&{while} $\|q>\\{void}$ \1\&{do}\5
+\X370:Add the contribution of node \|q to the total weight, and set $\|q\K%
+\\{link}(\|q)$\X;\2\6
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\\{total\_weight}\K\|n$;\6
+\&{end};\par
+\fi
+
+\M370. It's not necessary to add the offsets to the $x$ coordinates, because
+an entire edge structure can be shifted without affecting its total weight.
+Similarly, we don't need to subtract \\{zero\_field}.
+
+\Y\P$\4\X370:Add the contribution of node \|q to the total weight, and set $\|q%
+\K\\{link}(\|q)$\X\S$\6
+\&{begin} \37$\|m\K\\{ho}(\\{info}(\|q))$;\5
+$\|n\K\|n-((\|m\mathbin{\&{mod}}8)-\\{zero\_w})\ast(\|m\mathbin{\&{div}}8)$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end}\par
+\Us369\ET369.\fi
+
+\M371. So far we've done lots of things to edge structures assuming that
+edges are actually present, but we haven't seen how edges get created
+in the first place. Let's turn now to the problem of generating new edges.
+
+\MF\ will display new edges as they are being computed, if \\{tracing\_edges}
+is positive. In order to keep such data reasonably compact, only the
+points at which the path makes a $90^\circ$ or $180^\circ$ turn are listed.
+
+The tracing algorithm must remember some past history in order to suppress
+unnecessary data. Three variables \\{trace\_x}, \\{trace\_y}, and \\{trace\_yy}
+provide this history: The last coordinates printed were $(\\{trace\_x},\\{trace%
+\_y})$,
+and the previous edge traced ended at $(\\{trace\_x},\\{trace\_yy})$. Before
+anything
+at all has been traced, $\\{trace\_x}=-4096$.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{trace\_x}: \37\\{integer};\C{$x$~coordinate most recently shown in a
+trace}\6
+\4\\{trace\_y}: \37\\{integer};\C{$y$~coordinate most recently shown in a
+trace}\6
+\4\\{trace\_yy}: \37\\{integer};\C{$y$~coordinate most recently encountered}\par
+\fi
+
+\M372. Edge tracing is initiated by the \\{begin\_edge\_tracing} routine,
+continued by the \\{trace\_a\_corner} routine, and terminated by the
+\\{end\_edge\_tracing} routine.
+
+\Y\P\4\&{procedure}\1\ \37\\{begin\_edge\_tracing};\2\6
+\&{begin} \37$\\{print\_diagnostic}(\.{"Tracing\ edges"},\39\.{""},\39%
+\\{true})$;\5
+$\\{print}(\.{"\ (weight\ "})$;\5
+$\\{print\_int}(\\{cur\_wt})$;\5
+$\\{print\_char}(\.{")"})$;\5
+$\\{trace\_x}\K-4096$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37\\{trace\_a\_corner};\2\6
+\&{begin} \37\&{if} $\\{file\_offset}>\\{max\_print\_line}-13$ \1\&{then}\5
+$\\{print\_nl}(\.{""})$;\2\6
+$\\{print\_char}(\.{"("})$;\5
+$\\{print\_int}(\\{trace\_x})$;\5
+$\\{print\_char}(\.{","})$;\5
+$\\{print\_int}(\\{trace\_yy})$;\5
+$\\{print\_char}(\.{")"})$;\5
+$\\{trace\_y}\K\\{trace\_yy}$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37\\{end\_edge\_tracing};\2\6
+\&{begin} \37\&{if} $\\{trace\_x}=-4096$ \1\&{then}\5
+$\\{print\_nl}(\.{"(No\ new\ edges\ added.)"})$\6
+\4\&{else} \&{begin} \37\\{trace\_a\_corner};\5
+$\\{print\_char}(\.{"."})$;\6
+\&{end};\2\6
+$\\{end\_diagnostic}(\\{true})$;\6
+\&{end};\par
+\fi
+
+\M373. Just after a new edge weight has been put into the \\{info} field of
+node~\|r, in row~\|n, the following routine continues an ongoing trace.
+
+\Y\P\4\&{procedure}\1\ \37$\\{trace\_new\_edge}(\|r:\\{pointer};\,\35\|n:%
+\\{integer})$;\6
+\4\&{var} \37\|d: \37\\{integer};\C{temporary data register}\6
+\|w: \37$-3\to3$;\C{weight associated with an edge transition}\6
+$\|m,\39\\{n0},\39\\{n1}$: \37\\{integer};\C{column and row numbers}\2\6
+\&{begin} \37$\|d\K\\{ho}(\\{info}(\|r))$;\5
+$\|w\K(\|d\mathbin{\&{mod}}8)-\\{zero\_w}$;\5
+$\|m\K(\|d\mathbin{\&{div}}8)-\\{m\_offset}(\\{cur\_edges})$;\6
+\&{if} $\|w=\\{cur\_wt}$ \1\&{then}\6
+\&{begin} \37$\\{n0}\K\|n+1$;\5
+$\\{n1}\K\|n$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{n0}\K\|n$;\5
+$\\{n1}\K\|n+1$;\6
+\&{end};\C{the edges run from $(\|m,\\{n0})$ to $(\|m,\\{n1})$}\2\6
+\&{if} $\|m\I\\{trace\_x}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{trace\_x}=-4096$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{""})$;\5
+$\\{trace\_yy}\K\\{n0}$;\6
+\&{end}\6
+\4\&{else} \&{if} $\\{trace\_yy}\I\\{n0}$ \1\&{then}\5
+$\\{print\_char}(\.{"?"})$\C{shouldn't happen}\6
+\4\&{else} \\{trace\_a\_corner};\2\2\6
+$\\{trace\_x}\K\|m$;\5
+\\{trace\_a\_corner};\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{n0}\I\\{trace\_yy}$ \1\&{then}\5
+$\\{print\_char}(\.{"!"})$;\C{shouldn't happen}\2\6
+\&{if} $((\\{n0}<\\{n1})\W(\\{trace\_y}>\\{trace\_yy}))\V((\\{n0}>\\{n1})\W(%
+\\{trace\_y}<\\{trace\_yy}))$ \1\&{then}\5
+\\{trace\_a\_corner};\2\6
+\&{end};\2\6
+$\\{trace\_yy}\K\\{n1}$;\6
+\&{end};\par
+\fi
+
+\M374. One way to put new edge weights into an edge structure is to use the
+following routine, which simply draws a straight line from $(\\{x0},\\{y0})$ to
+$(\\{x1},\\{y1})$. More precisely, it introduces weights for the edges of the
+discrete path $\bigl(\lfloor t[x_0,x_1]+{1\over2}+\epsilon\rfloor,
+\lfloor t[y_0,y_1]+{1\over2}+\epsilon\delta\rfloor\bigr)$,
+as $t$ varies from 0 to~1, where $\epsilon$ and $\delta$ are extremely small
+positive numbers.
+
+The structure header is assumed to be \\{cur\_edges}; downward edge weights
+will be \\{cur\_wt}, while upward ones will be $-\\{cur\_wt}$.
+
+Of course, this subroutine will be called only in connection with others
+that eventually draw a complete cycle, so that the sum of the edge weights
+in each row will be zero whenever the row is displayed.
+
+\Y\P\4\&{procedure}\1\ \37$\\{line\_edges}(\\{x0},\39\\{y0},\39\\{x1},\39%
+\\{y1}:\\{scaled})$;\6
+\4\&{label} \37$\\{done},\39\\{done1}$;\6
+\4\&{var} \37$\\{m0},\39\\{n0},\39\\{m1},\39\\{n1}$: \37\\{integer};\C{rounded
+and unscaled coordinates}\6
+$\\{delx},\39\\{dely}$: \37\\{scaled};\C{the coordinate differences of the
+line}\6
+\\{yt}: \37\\{scaled};\C{smallest \|y coordinate that rounds the same as %
+\\{y0}}\6
+\\{tx}: \37\\{scaled};\C{tentative change in \|x}\6
+$\|p,\39\|r$: \37\\{pointer};\C{list manipulation registers}\6
+\\{base}: \37\\{integer};\C{amount added to edge-and-weight data}\6
+\|n: \37\\{integer};\C{current row number}\2\6
+\&{begin} \37$\\{n0}\K\\{round\_unscaled}(\\{y0})$;\5
+$\\{n1}\K\\{round\_unscaled}(\\{y1})$;\6
+\&{if} $\\{n0}\I\\{n1}$ \1\&{then}\6
+\&{begin} \37$\\{m0}\K\\{round\_unscaled}(\\{x0})$;\5
+$\\{m1}\K\\{round\_unscaled}(\\{x1})$;\5
+$\\{delx}\K\\{x1}-\\{x0}$;\5
+$\\{dely}\K\\{y1}-\\{y0}$;\5
+$\\{yt}\K\\{n0}\ast\\{unity}-\\{half\_unit}$;\5
+$\\{y0}\K\\{y0}-\\{yt}$;\5
+$\\{y1}\K\\{y1}-\\{yt}$;\6
+\&{if} $\\{n0}<\\{n1}$ \1\&{then}\5
+\X375:Insert upward edges for a line\X\6
+\4\&{else} \X376:Insert downward edges for a line\X;\2\6
+$\\{n\_rover}(\\{cur\_edges})\K\|p$;\5
+$\\{n\_pos}(\\{cur\_edges})\K\|n+\\{zero\_field}$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M375. Here we are careful to cancel any effect of rounding error.
+
+\Y\P$\4\X375:Insert upward edges for a line\X\S$\6
+\&{begin} \37$\\{base}\K8\ast\\{m\_offset}(\\{cur\_edges})+\\{min\_halfword}+%
+\\{zero\_w}-\\{cur\_wt}$;\6
+\&{if} $\\{m0}\L\\{m1}$ \1\&{then}\5
+$\\{edge\_prep}(\\{m0},\39\\{m1},\39\\{n0},\39\\{n1})$\ \&{else} $\\{edge%
+\_prep}(\\{m1},\39\\{m0},\39\\{n0},\39\\{n1})$;\2\6
+\X377:Move to row \\{n0}, pointed to by \|p\X;\6
+$\\{y0}\K\\{unity}-\\{y0}$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|r\K\\{get\_avail}$;\5
+$\\{link}(\|r)\K\\{unsorted}(\|p)$;\5
+$\\{unsorted}(\|p)\K\|r$;\6
+$\\{tx}\K\\{take\_fraction}(\\{delx},\39\\{make\_fraction}(\\{y0},\39%
+\\{dely}))$;\6
+\&{if} $\\{ab\_vs\_cd}(\\{delx},\39\\{y0},\39\\{dely},\39\\{tx})<0$ \1\&{then}\5
+$\\{decr}(\\{tx})$;\C{now $\\{tx}=\lfloor\\{y0}\cdot\\{delx}/\\{dely}\rfloor$}%
+\2\6
+$\\{info}(\|r)\K8\ast\\{round\_unscaled}(\\{x0}+\\{tx})+\\{base}$;\6
+$\\{y1}\K\\{y1}-\\{unity}$;\6
+\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+$\\{trace\_new\_edge}(\|r,\39\|n)$;\2\6
+\&{if} $\\{y1}<\\{unity}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|p\K\\{link}(\|p)$;\5
+$\\{y0}\K\\{y0}+\\{unity}$;\5
+$\\{incr}(\|n)$;\6
+\&{end};\2\6
+\4\\{done}: \37\&{end}\par
+\U374.\fi
+
+\M376. \P$\X376:Insert downward edges for a line\X\S$\6
+\&{begin} \37$\\{base}\K8\ast\\{m\_offset}(\\{cur\_edges})+\\{min\_halfword}+%
+\\{zero\_w}+\\{cur\_wt}$;\6
+\&{if} $\\{m0}\L\\{m1}$ \1\&{then}\5
+$\\{edge\_prep}(\\{m0},\39\\{m1},\39\\{n1},\39\\{n0})$\ \&{else} $\\{edge%
+\_prep}(\\{m1},\39\\{m0},\39\\{n1},\39\\{n0})$;\2\6
+$\\{decr}(\\{n0})$;\5
+\X377:Move to row \\{n0}, pointed to by \|p\X;\6
+\~ \1\&{loop}\ \&{begin} \37$\|r\K\\{get\_avail}$;\5
+$\\{link}(\|r)\K\\{unsorted}(\|p)$;\5
+$\\{unsorted}(\|p)\K\|r$;\6
+$\\{tx}\K\\{take\_fraction}(\\{delx},\39\\{make\_fraction}(\\{y0},\39%
+\\{dely}))$;\6
+\&{if} $\\{ab\_vs\_cd}(\\{delx},\39\\{y0},\39\\{dely},\39\\{tx})<0$ \1\&{then}\5
+$\\{incr}(\\{tx})$;\C{now $\\{tx}=\lceil\\{y0}\cdot\\{delx}/\\{dely}\rceil$,
+since $\\{dely}<0$}\2\6
+$\\{info}(\|r)\K8\ast\\{round\_unscaled}(\\{x0}-\\{tx})+\\{base}$;\6
+$\\{y1}\K\\{y1}+\\{unity}$;\6
+\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+$\\{trace\_new\_edge}(\|r,\39\|n)$;\2\6
+\&{if} $\\{y1}\G0$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+$\|p\K\\{knil}(\|p)$;\5
+$\\{y0}\K\\{y0}+\\{unity}$;\5
+$\\{decr}(\|n)$;\6
+\&{end};\2\6
+\4\\{done1}: \37\&{end}\par
+\U374.\fi
+
+\M377. \P$\X377:Move to row \\{n0}, pointed to by \|p\X\S$\6
+$\|n\K\\{n\_pos}(\\{cur\_edges})-\\{zero\_field}$;\5
+$\|p\K\\{n\_rover}(\\{cur\_edges})$;\6
+\&{if} $\|n\I\\{n0}$ \1\&{then}\6
+\&{if} $\|n<\\{n0}$ \1\&{then}\6
+\1\&{repeat} \37$\\{incr}(\|n)$;\5
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\|n=\\{n0}$\2\6
+\4\&{else} \1\&{repeat} \37$\\{decr}(\|n)$;\5
+$\|p\K\\{knil}(\|p)$;\6
+\4\&{until}\5
+$\|n=\\{n0}$\2\2\2\par
+\Us375, 376, 381, 382, 383\ETs384.\fi
+
+\M378. \MF\ inserts most of its edges into edge structures via the
+\\{move\_to\_edges} subroutine, which uses the data stored in the \\{move}
+array
+to specify a sequence of ``rook moves.'' The starting point $(\\{m0},\\{n0})$
+and finishing point $(\\{m1},\\{n1})$ of these moves, as seen from the
+standpoint
+of the first octant, are supplied as parameters; the moves should, however,
+be rotated into a given octant. (We're going to study octant
+transformations in great detail later; the reader may wish to come back to
+this part of the program after mastering the mysteries of octants.)
+
+The rook moves themselves are defined as follows, from a \\{first\_octant}
+point of view: ``Go right $\\{move}[\|k]$ steps, then go up one, for $0\L\|k<%
+\\{n1}-\\{n0}$;
+then go right $\\{move}[\\{n1}-\\{n0}]$ steps and stop.'' The sum of $\\{move}[%
+\|k]$
+for $0\L\|k\L\\{n1}-\\{n0}$ will be equal to $\\{m1}-\\{m0}$.
+
+As in the \\{line\_edges} routine, we use $+\\{cur\_wt}$ as the weight of
+all downward edges and $-\\{cur\_wt}$ as the weight of all upward edges,
+after the moves have been rotated to the proper octant direction.
+
+There are two main cases to consider: \\{fast\_case} is for moves that
+travel in the direction of octants 1, 4, 5, and~8, while \\{slow\_case}
+is for moves that travel toward octants 2, 3, 6, and~7. The latter directions
+are comparatively cumbersome because they generate more upward or downward
+edges; a curve that travels horizontally doesn't produce any edges at all,
+but a curve that travels vertically touches lots of rows.
+
+\Y\P\D \37$\\{fast\_case\_up}=60$\C{for octants 1 and 4}\par
+\P\D \37$\\{fast\_case\_down}=61$\C{for octants 5 and 8}\par
+\P\D \37$\\{slow\_case\_up}=62$\C{for octants 2 and 3}\par
+\P\D \37$\\{slow\_case\_down}=63$\C{for octants 6 and 7}\par
+\Y\P\4\&{procedure}\1\ \37$\\{move\_to\_edges}(\\{m0},\39\\{n0},\39\\{m1},\39%
+\\{n1}:\\{integer})$;\6
+\4\&{label} \37$\\{fast\_case\_up},\39\\{fast\_case\_down},\39\\{slow\_case%
+\_up},\39\\{slow\_case\_down},\39\\{done}$;\6
+\4\&{var} \37\\{delta}: \37$0\to\\{move\_size}$;\C{extent of \\{move} data}\6
+\|k: \37$0\to\\{move\_size}$;\C{index into \\{move}}\6
+$\|p,\39\|r$: \37\\{pointer};\C{list manipulation registers}\6
+\\{dx}: \37\\{integer};\C{change in edge-weight \\{info} when \|x changes by 1}%
+\6
+\\{edge\_and\_weight}: \37\\{integer};\C{\\{info} to insert}\6
+\|j: \37\\{integer};\C{number of consecutive vertical moves}\6
+\|n: \37\\{integer};\C{the current row pointed to by \|p}\2\6
+\&{debug} \37\\{sum}: \37\\{integer};\ \&{gubed}\6
+\&{begin} \37$\\{delta}\K\\{n1}-\\{n0}$;\6
+\&{debug} \37$\\{sum}\K\\{move}[0]$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}\\{delta}$ \1\&{do}\5
+$\\{sum}\K\\{sum}+\\{abs}(\\{move}[\|k])$;\2\6
+\&{if} $\\{sum}\I\\{m1}-\\{m0}$ \1\&{then}\5
+$\\{confusion}(\.{"0"})$;\ \2\6
+\&{gubed}\6
+\X380:Prepare for and switch to the appropriate case, based on \\{octant}\X;\6
+\4\\{fast\_case\_up}: \37\X381:Add edges for first or fourth octants, then %
+\&{goto} \\{done}\X;\6
+\4\\{fast\_case\_down}: \37\X382:Add edges for fifth or eighth octants, then %
+\&{goto} \\{done}\X;\6
+\4\\{slow\_case\_up}: \37\X383:Add edges for second or third octants, then %
+\&{goto} \\{done}\X;\6
+\4\\{slow\_case\_down}: \37\X384:Add edges for sixth or seventh octants, then %
+\&{goto} \\{done}\X;\6
+\4\\{done}: \37$\\{n\_pos}(\\{cur\_edges})\K\|n+\\{zero\_field}$;\5
+$\\{n\_rover}(\\{cur\_edges})\K\|p$;\6
+\&{end};\par
+\fi
+
+\M379. The current octant code appears in a global variable. If, for example,
+we have $\\{octant}=\\{third\_octant}$, it means that a curve traveling in a
+north to
+north-westerly direction has been rotated for the purposes of internal
+calculations so that the \\{move} data travels in an east to north-easterly
+direction. We want to unrotate as we update the edge structure.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{octant}: \37$\\{first\_octant}\to\\{sixth\_octant}$;\C{the current octant
+of interest}\par
+\fi
+
+\M380. \P$\X380:Prepare for and switch to the appropriate case, based on %
+\\{octant}\X\S$\6
+\&{case} $\\{octant}$ \1\&{of}\6
+\4\\{first\_octant}: \37\&{begin} \37$\\{dx}\K8$;\5
+$\\{edge\_prep}(\\{m0},\39\\{m1},\39\\{n0},\39\\{n1})$;\5
+\&{goto} \37\\{fast\_case\_up};\6
+\&{end};\6
+\4\\{second\_octant}: \37\&{begin} \37$\\{dx}\K8$;\5
+$\\{edge\_prep}(\\{n0},\39\\{n1},\39\\{m0},\39\\{m1})$;\5
+\&{goto} \37\\{slow\_case\_up};\6
+\&{end};\6
+\4\\{third\_octant}: \37\&{begin} \37$\\{dx}\K-8$;\5
+$\\{edge\_prep}(-\\{n1},\39-\\{n0},\39\\{m0},\39\\{m1})$;\5
+$\\{negate}(\\{n0})$;\5
+\&{goto} \37\\{slow\_case\_up};\6
+\&{end};\6
+\4\\{fourth\_octant}: \37\&{begin} \37$\\{dx}\K-8$;\5
+$\\{edge\_prep}(-\\{m1},\39-\\{m0},\39\\{n0},\39\\{n1})$;\5
+$\\{negate}(\\{m0})$;\5
+\&{goto} \37\\{fast\_case\_up};\6
+\&{end};\6
+\4\\{fifth\_octant}: \37\&{begin} \37$\\{dx}\K-8$;\5
+$\\{edge\_prep}(-\\{m1},\39-\\{m0},\39-\\{n1},\39-\\{n0})$;\5
+$\\{negate}(\\{m0})$;\5
+\&{goto} \37\\{fast\_case\_down};\6
+\&{end};\6
+\4\\{sixth\_octant}: \37\&{begin} \37$\\{dx}\K-8$;\5
+$\\{edge\_prep}(-\\{n1},\39-\\{n0},\39-\\{m1},\39-\\{m0})$;\5
+$\\{negate}(\\{n0})$;\5
+\&{goto} \37\\{slow\_case\_down};\6
+\&{end};\6
+\4\\{seventh\_octant}: \37\&{begin} \37$\\{dx}\K8$;\5
+$\\{edge\_prep}(\\{n0},\39\\{n1},\39-\\{m1},\39-\\{m0})$;\5
+\&{goto} \37\\{slow\_case\_down};\6
+\&{end};\6
+\4\\{eighth\_octant}: \37\&{begin} \37$\\{dx}\K8$;\5
+$\\{edge\_prep}(\\{m0},\39\\{m1},\39-\\{n1},\39-\\{n0})$;\5
+\&{goto} \37\\{fast\_case\_down};\6
+\&{end};\2\6
+\&{end};\C{there are only eight octants}\par
+\U378.\fi
+
+\M381. \P$\X381:Add edges for first or fourth octants, then \&{goto} \\{done}\X%
+\S$\6
+\X377:Move to row \\{n0}, pointed to by \|p\X;\6
+\&{if} $\\{delta}>0$ \1\&{then}\6
+\&{begin} \37$\|k\K0$;\5
+$\\{edge\_and\_weight}\K8\ast(\\{m0}+\\{m\_offset}(\\{cur\_edges}))+\\{min%
+\_halfword}+\\{zero\_w}-\\{cur\_wt}$;\6
+\1\&{repeat} \37$\\{edge\_and\_weight}\K\\{edge\_and\_weight}+\\{dx}\ast%
+\\{move}[\|k]$;\5
+$\\{fast\_get\_avail}(\|r)$;\5
+$\\{link}(\|r)\K\\{unsorted}(\|p)$;\5
+$\\{info}(\|r)\K\\{edge\_and\_weight}$;\6
+\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+$\\{trace\_new\_edge}(\|r,\39\|n)$;\2\6
+$\\{unsorted}(\|p)\K\|r$;\5
+$\|p\K\\{link}(\|p)$;\5
+$\\{incr}(\|k)$;\5
+$\\{incr}(\|n)$;\6
+\4\&{until}\5
+$\|k=\\{delta}$;\2\6
+\&{end};\2\6
+\&{goto} \37\\{done}\par
+\U378.\fi
+
+\M382. \P$\X382:Add edges for fifth or eighth octants, then \&{goto} \\{done}\X%
+\S$\6
+$\\{n0}\K-\\{n0}-1$;\5
+\X377:Move to row \\{n0}, pointed to by \|p\X;\6
+\&{if} $\\{delta}>0$ \1\&{then}\6
+\&{begin} \37$\|k\K0$;\5
+$\\{edge\_and\_weight}\K8\ast(\\{m0}+\\{m\_offset}(\\{cur\_edges}))+\\{min%
+\_halfword}+\\{zero\_w}+\\{cur\_wt}$;\6
+\1\&{repeat} \37$\\{edge\_and\_weight}\K\\{edge\_and\_weight}+\\{dx}\ast%
+\\{move}[\|k]$;\5
+$\\{fast\_get\_avail}(\|r)$;\5
+$\\{link}(\|r)\K\\{unsorted}(\|p)$;\5
+$\\{info}(\|r)\K\\{edge\_and\_weight}$;\6
+\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+$\\{trace\_new\_edge}(\|r,\39\|n)$;\2\6
+$\\{unsorted}(\|p)\K\|r$;\5
+$\|p\K\\{knil}(\|p)$;\5
+$\\{incr}(\|k)$;\5
+$\\{decr}(\|n)$;\6
+\4\&{until}\5
+$\|k=\\{delta}$;\2\6
+\&{end};\2\6
+\&{goto} \37\\{done}\par
+\U378.\fi
+
+\M383. \P$\X383:Add edges for second or third octants, then \&{goto} \\{done}\X%
+\S$\6
+$\\{edge\_and\_weight}\K8\ast(\\{n0}+\\{m\_offset}(\\{cur\_edges}))+\\{min%
+\_halfword}+\\{zero\_w}-\\{cur\_wt}$;\5
+$\\{n0}\K\\{m0}$;\5
+$\|k\K0$;\5
+\X377:Move to row \\{n0}, pointed to by \|p\X;\6
+\1\&{repeat} \37$\|j\K\\{move}[\|k]$;\6
+\&{while} $\|j>0$ \1\&{do}\6
+\&{begin} \37$\\{fast\_get\_avail}(\|r)$;\5
+$\\{link}(\|r)\K\\{unsorted}(\|p)$;\5
+$\\{info}(\|r)\K\\{edge\_and\_weight}$;\6
+\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+$\\{trace\_new\_edge}(\|r,\39\|n)$;\2\6
+$\\{unsorted}(\|p)\K\|r$;\5
+$\|p\K\\{link}(\|p)$;\5
+$\\{decr}(\|j)$;\5
+$\\{incr}(\|n)$;\6
+\&{end};\2\6
+$\\{edge\_and\_weight}\K\\{edge\_and\_weight}+\\{dx}$;\5
+$\\{incr}(\|k)$;\6
+\4\&{until}\5
+$\|k>\\{delta}$;\2\6
+\&{goto} \37\\{done}\par
+\U378.\fi
+
+\M384. \P$\X384:Add edges for sixth or seventh octants, then \&{goto} \\{done}%
+\X\S$\6
+$\\{edge\_and\_weight}\K8\ast(\\{n0}+\\{m\_offset}(\\{cur\_edges}))+\\{min%
+\_halfword}+\\{zero\_w}+\\{cur\_wt}$;\5
+$\\{n0}\K-\\{m0}-1$;\5
+$\|k\K0$;\5
+\X377:Move to row \\{n0}, pointed to by \|p\X;\6
+\1\&{repeat} \37$\|j\K\\{move}[\|k]$;\6
+\&{while} $\|j>0$ \1\&{do}\6
+\&{begin} \37$\\{fast\_get\_avail}(\|r)$;\5
+$\\{link}(\|r)\K\\{unsorted}(\|p)$;\5
+$\\{info}(\|r)\K\\{edge\_and\_weight}$;\6
+\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+$\\{trace\_new\_edge}(\|r,\39\|n)$;\2\6
+$\\{unsorted}(\|p)\K\|r$;\5
+$\|p\K\\{knil}(\|p)$;\5
+$\\{decr}(\|j)$;\5
+$\\{decr}(\|n)$;\6
+\&{end};\2\6
+$\\{edge\_and\_weight}\K\\{edge\_and\_weight}+\\{dx}$;\5
+$\\{incr}(\|k)$;\6
+\4\&{until}\5
+$\|k>\\{delta}$;\2\6
+\&{goto} \37\\{done}\par
+\U378.\fi
+
+\M385. All the hard work of building an edge structure is undone by the
+following
+subroutine.
+
+\Y\P$\4\X268:Declare the recycling subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{toss\_edges}(\|h:\\{pointer})$;\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{for list manipulation}\2\6
+\&{begin} \37$\|q\K\\{link}(\|h)$;\6
+\&{while} $\|q\I\|h$ \1\&{do}\6
+\&{begin} \37$\\{flush\_list}(\\{sorted}(\|q))$;\6
+\&{if} $\\{unsorted}(\|q)>\\{void}$ \1\&{then}\5
+$\\{flush\_list}(\\{unsorted}(\|q))$;\2\6
+$\|p\K\|q$;\5
+$\|q\K\\{link}(\|q)$;\5
+$\\{free\_node}(\|p,\39\\{row\_node\_size})$;\6
+\&{end};\2\6
+$\\{free\_node}(\|h,\39\\{edge\_header\_size})$;\6
+\&{end};\par
+\fi
+
+\N386. \[21] Subdivision into octants.
+When \MF\ digitizes a path, it reduces the problem to the special
+case of paths that travel in ``first octant'' directions; i.e.,
+each cubic $z(t)=\bigl(x(t),y(t)\bigr)$ being digitized will have the property
+that $0\L y'(t)\L x'(t)$. This assumption makes digitizing simpler
+and faster than if the direction of motion has to be tested repeatedly.
+
+When $z(t)$ is cubic, $x'(t)$ and $y'(t)$ are quadratic, hence the four
+polynomials $x'(t)$, $y'(t)$, $x'(t)-y'(t)$, and $x'(t)+y'(t)$ cross
+through~0 at most twice each. If we subdivide the given cubic at these
+places, we get at most nine subintervals in each of which
+$x'(t)$, $y'(t)$, $x'(t)-y'(t)$, and $x'(t)+y'(t)$ all have a constant
+sign. The curve can be transformed in each of these subintervals so that
+it travels entirely in first octant directions, if we reflect $x\swap-x$,
+$y\swap-y$, and/or $x\swap y$ as necessary. (Incidentally, it can be
+shown that a cubic such that $x'(t)=16(2t-1)^2+2(2t-1)-1$ and
+$y'(t)=8(2t-1)^2+4(2t-1)$ does indeed split into nine subintervals.)
+
+\fi
+
+\M387. The transformation that rotates coordinates, so that first octant motion
+can be assumed, is defined by the \\{skew} subroutine, which sets global
+variables \\{cur\_x} and \\{cur\_y} to the values that are appropriate in a
+given octant. (Octants are encoded as they were in the \\{n\_arg} subroutine.)
+
+This transformation is ``skewed'' by replacing $(\|x,\|y)$ by $(\|x-\|y,\|y)$,
+once first octant motion has been established. It turns out that
+skewed coordinates are somewhat better to work with when curves are
+actually digitized.
+
+\Y\P\D \37$\\{set\_two\_end}(\#)\S\\{cur\_y}\K\#$;\ \&{end} \par
+\P\D $\\{set\_two}(\#)\S$ \6
+\&{begin} \37$\\{cur\_x}\K\#$;\5
+\\{set\_two\_end}\par
+\Y\P\4\&{procedure}\1\ \37$\\{skew}(\|x,\39\|y:\\{scaled};\,\35\\{octant}:%
+\\{small\_number})$;\2\6
+\&{begin} \37\&{case} $\\{octant}$ \1\&{of}\6
+\4\\{first\_octant}: \37$\\{set\_two}(\|x-\|y)(\|y)$;\6
+\4\\{second\_octant}: \37$\\{set\_two}(\|y-\|x)(\|x)$;\6
+\4\\{third\_octant}: \37$\\{set\_two}(\|y+\|x)(-\|x)$;\6
+\4\\{fourth\_octant}: \37$\\{set\_two}(-\|x-\|y)(\|y)$;\6
+\4\\{fifth\_octant}: \37$\\{set\_two}(-\|x+\|y)(-\|y)$;\6
+\4\\{sixth\_octant}: \37$\\{set\_two}(-\|y+\|x)(-\|x)$;\6
+\4\\{seventh\_octant}: \37$\\{set\_two}(-\|y-\|x)(\|x)$;\6
+\4\\{eighth\_octant}: \37$\\{set\_two}(\|x+\|y)(-\|y)$;\2\6
+\&{end};\C{there are no other cases}\6
+\&{end};\par
+\fi
+
+\M388. Conversely, the following subroutine sets \\{cur\_x} and
+\\{cur\_y} to the original coordinate values of a point, given an octant
+code and the point's coordinates $(\|x,\|y)$ after they have been mapped into
+the first octant and skewed.
+
+\Y\P$\4\X257:Declare subroutines for printing expressions\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{unskew}(\|x,\39\|y:\\{scaled};\,\35\\{octant}:%
+\\{small\_number})$;\2\6
+\&{begin} \37\&{case} $\\{octant}$ \1\&{of}\6
+\4\\{first\_octant}: \37$\\{set\_two}(\|x+\|y)(\|y)$;\6
+\4\\{second\_octant}: \37$\\{set\_two}(\|y)(\|x+\|y)$;\6
+\4\\{third\_octant}: \37$\\{set\_two}(-\|y)(\|x+\|y)$;\6
+\4\\{fourth\_octant}: \37$\\{set\_two}(-\|x-\|y)(\|y)$;\6
+\4\\{fifth\_octant}: \37$\\{set\_two}(-\|x-\|y)(-\|y)$;\6
+\4\\{sixth\_octant}: \37$\\{set\_two}(-\|y)(-\|x-\|y)$;\6
+\4\\{seventh\_octant}: \37$\\{set\_two}(\|y)(-\|x-\|y)$;\6
+\4\\{eighth\_octant}: \37$\\{set\_two}(\|x+\|y)(-\|y)$;\2\6
+\&{end};\C{there are no other cases}\6
+\&{end};\par
+\fi
+
+\M389. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{cur\_x},\39\\{cur\_y}$: \37\\{scaled};\C{outputs of \\{rotate}, %
+\\{unrotate}, and a few other routines}\par
+\fi
+
+\M390. The conversion to skewed and rotated coordinates takes place in
+stages, and at one point in the transformation we will have negated the
+$x$ and/or $y$ coordinates so as to make curves travel in the first
+{\sl quadrant}. At this point the relevant ``octant'' code will be
+either \\{first\_octant} (when no transformation has been done),
+or $\\{fourth\_octant}=\\{first\_octant}+\\{negate\_x}$ (when $x$ has been
+negated),
+or $\\{fifth\_octant}=\\{first\_octant}+\\{negate\_x}+\\{negate\_y}$ (when both
+have been
+negated), or $\\{eighth\_octant}=\\{first\_octant}+\\{negate\_y}$ (when $y$ has
+been
+negated). The \\{abnegate} routine is sometimes needed to convert
+from one of these transformations to another.
+
+\Y\P\4\&{procedure}\1\ \37$\\{abnegate}(\|x,\39\|y:\\{scaled};\,\35\\{octant%
+\_before},\39\\{octant\_after}:\\{small\_number})$;\2\6
+\&{begin} \37\&{if} $\\{odd}(\\{octant\_before})=\\{odd}(\\{octant\_after})$ \1%
+\&{then}\5
+$\\{cur\_x}\K\|x$\6
+\4\&{else} $\\{cur\_x}\K-\|x$;\2\6
+\&{if} $(\\{octant\_before}>\\{negate\_y})=(\\{octant\_after}>\\{negate\_y})$ %
+\1\&{then}\5
+$\\{cur\_y}\K\|y$\6
+\4\&{else} $\\{cur\_y}\K-\|y$;\2\6
+\&{end};\par
+\fi
+
+\M391. Now here's a subroutine that's handy for subdivision: Given a
+quadratic polynomial $B(a,b,c;t)$, the \\{crossing\_point} function
+returns the unique \\{fraction} value \|t between 0 and~1 at which
+$B(a,b,c;t)$ changes from positive to negative, or returns
+$\|t=\\{fraction\_one}+1$ if no such value exists. If $\|a<0$ (so that
+$B(a,b,c;t)$
+is already negative at $\|t=0$), \\{crossing\_point} returns the value zero.
+
+\Y\P\D \37$\\{no\_crossing}\S$\1\6
+\&{begin} \37$\\{crossing\_point}\K\\{fraction\_one}+1$;\5
+\&{return};\6
+\&{end}\2\par
+\P\D \37$\\{one\_crossing}\S$\1\6
+\&{begin} \37$\\{crossing\_point}\K\\{fraction\_one}$;\5
+\&{return};\6
+\&{end}\2\par
+\P\D \37$\\{zero\_crossing}\S$\1\6
+\&{begin} \37$\\{crossing\_point}\K0$;\5
+\&{return};\6
+\&{end}\2\par
+\Y\P\4\&{function}\1\ \37$\\{crossing\_point}(\|a,\39\|b,\39\|c:\\{integer})$:
+\37\\{fraction};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|d: \37\\{integer};\C{recursive counter}\6
+$\|x,\39\\{xx},\39\\{x0},\39\\{x1},\39\\{x2}$: \37\\{integer};\C{temporary
+registers for bisection}\2\6
+\&{begin} \37\&{if} $\|a<0$ \1\&{then}\5
+\\{zero\_crossing};\2\6
+\&{if} $\|c\G0$ \1\&{then}\6
+\&{begin} \37\&{if} $\|b\G0$ \1\&{then}\6
+\&{if} $\|c>0$ \1\&{then}\5
+\\{no\_crossing}\6
+\4\&{else} \&{if} $(\|a=0)\W(\|b=0)$ \1\&{then}\5
+\\{no\_crossing}\6
+\4\&{else} \\{one\_crossing};\2\2\2\6
+\&{if} $\|a=0$ \1\&{then}\5
+\\{zero\_crossing};\2\6
+\&{end}\6
+\4\&{else} \&{if} $\|a=0$ \1\&{then}\6
+\&{if} $\|b\L0$ \1\&{then}\5
+\\{zero\_crossing};\2\2\2\6
+\X392:Use bisection to find the crossing point, if one exists\X;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M392. The general bisection method is quite simple when $n=2$, hence
+\\{crossing\_point} does not take much time. At each stage in the
+recursion we have a subinterval defined by \|l and~\|j such that
+$B(a,b,c;2^{-l}(j+t))=B(x_0,x_1,x_2;t)$, and we want to ``zero in'' on
+the subinterval where $x_0\G0$ and $\min(x_1,x_2)<0$.
+
+It is convenient for purposes of calculation to combine the values
+of \|l and~\|j in a single variable $d=2^l+j$, because the operation
+of bisection then corresponds simply to doubling $d$ and possibly
+adding~1. Furthermore it proves to be convenient to modify
+our previous conventions for bisection slightly, maintaining the
+variables $X_0=2^lx_0$, $X_1=2^l(x_0-x_1)$, and $X_2=2^l(x_1-x_2)$.
+With these variables the conditions $x_0\ge0$ and $\min(x_1,x_2)<0$ are
+equivalent to $\max(X_1,X_1+X_2)>X_0\ge0$.
+
+The following code maintains the invariant relations
+$0\L\\{x0}<\max(\\{x1},\\{x1}+\\{x2})$,
+$\vert\\{x1}\vert<2^{30}$, $\vert\\{x2}\vert<2^{30}$;
+it has been constructed in such a way that no arithmetic overflow
+will occur if the inputs satisfy
+$a<2^{30}$, $\vert a-b\vert<2^{30}$, and $\vert b-c\vert<2^{30}$.
+
+\Y\P$\4\X392:Use bisection to find the crossing point, if one exists\X\S$\6
+$\|d\K1$;\5
+$\\{x0}\K\|a$;\5
+$\\{x1}\K\|a-\|b$;\5
+$\\{x2}\K\|b-\|c$;\6
+\1\&{repeat} \37$\|x\K\\{half}(\\{x1}+\\{x2})$;\6
+\&{if} $\\{x1}-\\{x0}>\\{x0}$ \1\&{then}\6
+\&{begin} \37$\\{x2}\K\|x$;\5
+$\\{double}(\\{x0})$;\5
+$\\{double}(\|d)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{xx}\K\\{x1}+\|x-\\{x0}$;\6
+\&{if} $\\{xx}>\\{x0}$ \1\&{then}\6
+\&{begin} \37$\\{x2}\K\|x$;\5
+$\\{double}(\\{x0})$;\5
+$\\{double}(\|d)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{x0}\K\\{x0}-\\{xx}$;\6
+\&{if} $\|x\L\\{x0}$ \1\&{then}\6
+\&{if} $\|x+\\{x2}\L\\{x0}$ \1\&{then}\5
+\\{no\_crossing};\2\2\6
+$\\{x1}\K\|x$;\5
+$\|d\K\|d+\|d+1$;\6
+\&{end};\2\6
+\&{end};\2\6
+\4\&{until}\5
+$\|d\G\\{fraction\_one}$;\2\6
+$\\{crossing\_point}\K\|d-\\{fraction\_one}$\par
+\U391.\fi
+
+\M393. Octant subdivision is applied only to cycles, i.e., to closed paths.
+A ``cycle spec'' is a data structure that contains specifications of
+cubic curves and octant mappings for the cycle that has been subdivided
+into segments belonging to single octants. It is composed entirely of
+knot nodes, similar to those in the representation of paths; but the
+\\{explicit} type indications have been replaced by positive numbers
+that give further information. Additional \\{endpoint} data is also
+inserted at the octant boundaries.
+
+Recall that a cubic polynomial is represented by four control points
+that appear in adjacent nodes \|p and~\|q of a knot list. The \|x~coordinates
+are $\\{x\_coord}(\|p)$, $\\{right\_x}(\|p)$, $\\{left\_x}(\|q)$, and $\\{x%
+\_coord}(\|q)$; the
+\|y~coordinates are similar. We shall call this ``the cubic following~\|p''
+or ``the cubic between \|p and~\|q'' or ``the cubic preceding~\|q.''
+
+Cycle specs are circular lists of cubic curves mixed with octant
+boundaries. Like cubics, the octant boundaries are represented in
+consecutive knot nodes \|p and~\|q. In such cases $\\{right\_type}(\|p)=\\{left%
+\_type}(\|q)=\\{endpoint}$, and the fields $\\{right\_x}(\|p)$, $\\{right\_y}(%
+\|p)$,
+$\\{left\_x}(\|q)$, and $\\{left\_y}(\|q)$ are replaced by other fields called
+$\\{right\_octant}(\|p)$, $\\{right\_transition}(\|p)$, $\\{left\_octant}(%
+\|q)$, and
+$\\{left\_transition}(\|q)$, respectively. For example, when the curve
+direction
+moves from the third octant to the fourth octant, the boundary nodes say
+$\\{right\_octant}(\|p)=\\{third\_octant}$, $\\{left\_octant}(\|q)=\\{fourth%
+\_octant}$,
+and $\\{right\_transition}(\|p)=\\{left\_transition}(\|q)=\\{diagonal}$. A %
+\\{diagonal}
+transition occurs when moving between octants 1~\AM~2, 3~\AM~4, 5~\AM~6, or
+7~\AM~8; an \\{axis} transition occurs when moving between octants 8~\AM~1,
+2~\AM~3, 4~\AM~5, 6~\AM~7. (Such transition information is redundant
+but convenient.) Fields $\\{x\_coord}(\|p)$ and $\\{y\_coord}(\|p)$ will
+contain
+coordinates of the transition point after rotation from third octant
+to first octant; i.e., if the true coordinates are $(x,y)$, the
+coordinates $(y,-x)$ will appear in node~\|p. Similarly, a fourth-octant
+transformation will have been applied after the transition, so
+we will have $\\{x\_coord}(\|q)=\hbox{$-x$}$ and $\\{y\_coord}(\|q)=\|y$.
+
+The cubic between \|p and \|q will contain positive numbers in the
+fields $\\{right\_type}(\|p)$ and $\\{left\_type}(\|q)$; this makes cubics
+distinguishable from octant boundaries, because $\\{endpoint}=0$.
+The value of $\\{right\_type}(\|p)$ will be the current octant code,
+during the time that cycle specs are being constructed; it will
+refer later to a pen offset position, if the envelope of a cycle is
+being computed. A cubic that comes from some subinterval of the $k$th
+step in the original cyclic path will have $\\{left\_type}(\|q)=\|k$.
+
+\Y\P\D \37$\\{right\_octant}\S\\{right\_x}$\C{the octant code before a
+transition}\par
+\P\D \37$\\{left\_octant}\S\\{left\_x}$\C{the octant after a transition}\par
+\P\D \37$\\{right\_transition}\S\\{right\_y}$\C{the type of transition}\par
+\P\D \37$\\{left\_transition}\S\\{left\_y}$\C{ditto, either \\{axis} or %
+\\{diagonal}}\par
+\P\D \37$\\{axis}=0$\C{a transition across the $x'$- or $y'$-axis}\par
+\P\D \37$\\{diagonal}=1$\C{a transition where $y'=\pm x'$}\par
+\fi
+
+\M394. Here's a routine that prints a cycle spec in symbolic form, so that it
+is possible to see what subdivision has been made. The point coordinates
+are converted back from \MF's internal ``rotated'' form to the external
+``true'' form. The global variable~\\{cur\_spec} should point to a knot just
+after the beginning of an octant boundary, i.e., such that
+$\\{left\_type}(\\{cur\_spec})=\\{endpoint}$.
+
+\Y\P\D \37$\\{print\_two\_true}(\#)\S\\{unskew}(\#,\39\\{octant})$;\5
+$\\{print\_two}(\\{cur\_x},\39\\{cur\_y})$\par
+\Y\P\4\&{procedure}\1\ \37$\\{print\_spec}(\|s:\\{str\_number})$;\6
+\4\&{label} \37$\\{not\_found},\39\\{done}$;\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{for list traversal}\6
+\\{octant}: \37\\{small\_number};\C{the current octant code}\2\6
+\&{begin} \37$\\{print\_diagnostic}(\.{"Cycle\ spec"},\39\|s,\39\\{true})$;\5
+$\|p\K\\{cur\_spec}$;\5
+$\\{octant}\K\\{left\_octant}(\|p)$;\5
+\\{print\_ln};\5
+$\\{print\_two\_true}(\\{x\_coord}(\\{cur\_spec}),\39\\{y\_coord}(\\{cur%
+\_spec}))$;\5
+$\\{print}(\.{"\ \%\ beginning\ in\ octant\ \`"})$;\6
+\~ \1\&{loop}\ \&{begin} \37$\\{print}(\\{octant\_dir}[\\{octant}])$;\5
+$\\{print\_char}(\.{"\'"})$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|q\K\\{link}(\|p)$;\6
+\&{if} $\\{right\_type}(\|p)=\\{endpoint}$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\X397:Print the cubic between \|p and \|q\X;\6
+$\|p\K\|q$;\6
+\&{end};\2\6
+\4\\{not\_found}: \37\&{if} $\|q=\\{cur\_spec}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|p\K\|q$;\5
+$\\{octant}\K\\{left\_octant}(\|p)$;\5
+$\\{print\_nl}(\.{"\%\ entering\ octant\ \`"})$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{print\_nl}(\.{"\ \&\ cycle"})$;\5
+$\\{end\_diagnostic}(\\{true})$;\6
+\&{end};\par
+\fi
+
+\M395. Symbolic octant direction names are kept in the \\{octant\_dir} array.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{octant\_dir}: \37\&{array} $[\\{first\_octant}\to\\{sixth\_octant}]$ \1%
+\&{of}\5
+\\{str\_number};\2\par
+\fi
+
+\M396. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{octant\_dir}[\\{first\_octant}]\K\.{"ENE"}$;\5
+$\\{octant\_dir}[\\{second\_octant}]\K\.{"NNE"}$;\5
+$\\{octant\_dir}[\\{third\_octant}]\K\.{"NNW"}$;\5
+$\\{octant\_dir}[\\{fourth\_octant}]\K\.{"WNW"}$;\5
+$\\{octant\_dir}[\\{fifth\_octant}]\K\.{"WSW"}$;\5
+$\\{octant\_dir}[\\{sixth\_octant}]\K\.{"SSW"}$;\5
+$\\{octant\_dir}[\\{seventh\_octant}]\K\.{"SSE"}$;\5
+$\\{octant\_dir}[\\{eighth\_octant}]\K\.{"ESE"}$;\par
+\fi
+
+\M397. \P$\X397:Print the cubic between \|p and \|q\X\S$\6
+\&{begin} \37$\\{print\_nl}(\.{"\ \ \ ..controls\ "})$;\5
+$\\{print\_two\_true}(\\{right\_x}(\|p),\39\\{right\_y}(\|p))$;\5
+$\\{print}(\.{"\ and\ "})$;\5
+$\\{print\_two\_true}(\\{left\_x}(\|q),\39\\{left\_y}(\|q))$;\5
+$\\{print\_nl}(\.{"\ .."})$;\5
+$\\{print\_two\_true}(\\{x\_coord}(\|q),\39\\{y\_coord}(\|q))$;\5
+$\\{print}(\.{"\ \%\ segment\ "})$;\5
+$\\{print\_int}(\\{left\_type}(\|q)-1)$;\6
+\&{end}\par
+\U394.\fi
+
+\M398. A much more compact version of a spec is printed to help users identify
+``strange paths.''
+
+\Y\P\4\&{procedure}\1\ \37$\\{print\_strange}(\|s:\\{str\_number})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{for list traversal}\6
+\|f: \37\\{pointer};\C{starting point in the cycle}\6
+\|q: \37\\{pointer};\C{octant boundary to be printed}\6
+\|t: \37\\{integer};\C{segment number, plus 1}\2\6
+\&{begin} \37\&{if} $\\{interaction}=\\{error\_stop\_mode}$ \1\&{then}\5
+\\{wake\_up\_terminal};\2\6
+$\\{print\_nl}(\.{">"})$;\5
+\X399:Find the starting point, \|f\X;\6
+\X400:Determine the octant boundary \|q that precedes \|f\X;\6
+$\|t\K0$;\6
+\1\&{repeat} \37\&{if} $\\{left\_type}(\|p)\I\\{endpoint}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{left\_type}(\|p)\I\|t$ \1\&{then}\6
+\&{begin} \37$\|t\K\\{left\_type}(\|p)$;\5
+$\\{print\_char}(\.{"\ "})$;\5
+$\\{print\_int}(\|t-1)$;\6
+\&{end};\2\6
+\&{if} $\|q\I\\{null}$ \1\&{then}\6
+\&{begin} \37\X401:Print the turns, if any, that start at \|q, and advance \|q%
+\X;\6
+$\\{print\_char}(\.{"\ "})$;\5
+$\\{print}(\\{octant\_dir}[\\{left\_octant}(\|q)])$;\5
+$\|q\K\\{null}$;\6
+\&{end};\2\6
+\&{end}\6
+\4\&{else} \&{if} $\|q=\\{null}$ \1\&{then}\5
+$\|q\K\|p$;\2\2\6
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\|p=\|f$;\2\6
+$\\{print\_char}(\.{"\ "})$;\5
+$\\{print\_int}(\\{left\_type}(\|p)-1)$;\6
+\&{if} $\|q\I\\{null}$ \1\&{then}\5
+\X401:Print the turns, if any, that start at \|q, and advance \|q\X;\2\6
+$\\{print\_err}(\|s)$;\6
+\&{end};\par
+\fi
+
+\M399. If the segment numbers on the cycle are $t_1$, $t_2$, \dots, $t_m$,
+we have $t_{k-1}\L t_k$ except for at most one value of~$k$. If there are
+no exceptions, $f$ will point to $t_1$; otherwise it will point to the
+exceptional~$t_k$.
+
+There is at least one segment number (i.e., we always have $m>0$), because
+\\{print\_strange} is never called upon to display an entirely ``dead'' cycle.
+
+\Y\P$\4\X399:Find the starting point, \|f\X\S$\6
+$\|p\K\\{cur\_spec}$;\5
+$\|t\K\\{max\_quarterword}+1$;\6
+\1\&{repeat} \37$\|p\K\\{link}(\|p)$;\6
+\&{if} $\\{left\_type}(\|p)\I\\{endpoint}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{left\_type}(\|p)<\|t$ \1\&{then}\5
+$\|f\K\|p$;\2\6
+$\|t\K\\{left\_type}(\|p)$;\6
+\&{end};\2\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$\2\par
+\U398.\fi
+
+\M400. \P$\X400:Determine the octant boundary \|q that precedes \|f\X\S$\6
+$\|p\K\\{cur\_spec}$;\5
+$\|q\K\|p$;\6
+\1\&{repeat} \37$\|p\K\\{link}(\|p)$;\6
+\&{if} $\\{left\_type}(\|p)=\\{endpoint}$ \1\&{then}\5
+$\|q\K\|p$;\2\6
+\4\&{until}\5
+$\|p=\|f$\2\par
+\U398.\fi
+
+\M401. When two octant boundaries are adjacent, the path is simply changing
+direction
+without moving. Such octant directions are shown in parentheses.
+
+\Y\P$\4\X401:Print the turns, if any, that start at \|q, and advance \|q\X\S$\6
+\&{if} $\\{left\_type}(\\{link}(\|q))=\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"\ ("})$;\5
+$\\{print}(\\{octant\_dir}[\\{left\_octant}(\|q)])$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{while} $\\{left\_type}(\\{link}(\|q))=\\{endpoint}$ \1\&{do}\6
+\&{begin} \37$\\{print\_char}(\.{"\ "})$;\5
+$\\{print}(\\{octant\_dir}[\\{left\_octant}(\|q)])$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+$\\{print\_char}(\.{")"})$;\6
+\&{end}\2\par
+\Us398\ET398.\fi
+
+\M402. The \\{make\_spec} routine is what subdivides paths into octants:
+Given a pointer \\{cur\_spec} to a cyclic path, \\{make\_spec} mungs the path
+data
+and returns a pointer to the corresponding cyclic spec.
+All ``dead'' cubics (i.e., cubics that don't move at all from
+their starting points) will have been removed from the result.
+
+The idea of \\{make\_spec} is fairly simple: Each cubic is first
+subdivided, if necessary, into pieces belonging to single octants;
+then the octant boundaries are inserted. But some of the details of
+this transformation are not quite obvious.
+
+If $\\{autorounding}>0$, the path will be adjusted so that critical tangent
+directions occur at ``good'' points with respect to the pen called \\{cur%
+\_pen}.
+
+The resulting spec will have all \|x and \|y coordinates at most
+$2^{28}-\\{half\_unit}-1-\\{safety\_margin}$ in absolute value. The pointer
+that is returned will start some octant, as required by \\{print\_spec}.
+
+\Y\P\hbox{\4}\X405:Declare subroutines needed by \\{make\_spec}\X\6
+\4\&{function}\1\ \37$\\{make\_spec}(\|h:\\{pointer};\,\35\\{safety\_margin}:%
+\\{scaled};\,\35\\{tracing}:\\{integer})$: \37\\{pointer};\C{converts a path to
+a cycle spec}\6
+\4\&{label} \37$\\{continue},\39\\{done}$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{for traversing the
+lists}\6
+\|k: \37\\{integer};\C{serial number of path segment, or octant code}\6
+\\{chopped}: \37\\{integer};\C{positive if data truncated, negative
+if data dangerously large}\6
+\X453:Other local variables for \\{make\_spec}\X\2\6
+\&{begin} \37$\\{cur\_spec}\K\|h$;\6
+\&{if} $\\{tracing}>0$ \1\&{then}\5
+$\\{print\_path}(\\{cur\_spec},\39\.{",\ before\ subdivision\ into\ octants"},%
+\39\\{true})$;\2\6
+$\\{max\_allowed}\K\\{fraction\_one}-\\{half\_unit}-1-\\{safety\_margin}$;\5
+\X404:Truncate the values of all coordinates that exceed \\{max\_allowed}, and
+stamp segment numbers in each \\{left\_type} field\X;\6
+\\{quadrant\_subdivide};\C{subdivide each cubic into pieces belonging to
+quadrants}\6
+\&{if} $(\\{internal}[\\{autorounding}]>0)\W(\\{chopped}=0)$ \1\&{then}\5
+\\{xy\_round};\2\6
+\\{octant\_subdivide};\C{complete the subdivision}\6
+\&{if} $(\\{internal}[\\{autorounding}]>\\{unity})\W(\\{chopped}=0)$ \1\&{then}%
+\5
+\\{diag\_round};\2\6
+\X447:Remove dead cubics\X;\6
+\X450:Insert octant boundaries and compute the turning number\X;\6
+\&{while} $\\{left\_type}(\\{cur\_spec})\I\\{endpoint}$ \1\&{do}\5
+$\\{cur\_spec}\K\\{link}(\\{cur\_spec})$;\2\6
+\&{if} $\\{tracing}>0$ \1\&{then}\6
+\&{if} $(\\{internal}[\\{autorounding}]\L0)\V(\\{chopped}\I0)$ \1\&{then}\5
+$\\{print\_spec}(\.{",\ after\ subdivision"})$\6
+\4\&{else} \&{if} $\\{internal}[\\{autorounding}]>\\{unity}$ \1\&{then}\5
+$\\{print\_spec}(\.{",\ after\ subdivision\ and\ double\ autorounding"})$\6
+\4\&{else} $\\{print\_spec}(\.{",\ after\ subdivision\ and\ autorounding"})$;\2%
+\2\2\6
+$\\{make\_spec}\K\\{cur\_spec}$;\6
+\&{end};\par
+\fi
+
+\M403. The \\{make\_spec} routine has an interesting side effect, namely to set
+the global variable \\{turning\_number} to the number of times the tangent
+vector of the given cyclic path winds around the origin.
+
+Another global variable \\{cur\_spec} points to the specification as it is
+being made, since several subroutines must go to work on it.
+
+And there are two global variables that affect the rounding
+decisions, as we'll see later; they are called \\{cur\_pen} and \\{cur\_path%
+\_type}.
+The latter will be \\{double\_path\_code} if \\{make\_spec} is being
+applied to a double path.
+
+\Y\P\D \37$\\{double\_path\_code}=0$\C{command modifier for `\&{doublepath}'}%
+\par
+\P\D \37$\\{contour\_code}=1$\C{command modifier for `\&{contour}'}\par
+\P\D \37$\\{also\_code}=2$\C{command modifier for `\&{also}'}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{cur\_spec}: \37\\{pointer};\C{the principal output of \\{make\_spec}}\6
+\4\\{turning\_number}: \37\\{integer};\C{another output of \\{make\_spec}}\6
+\4\\{cur\_pen}: \37\\{pointer};\C{an implicit input of \\{make\_spec}, used in
+autorounding}\6
+\4\\{cur\_path\_type}: \37$\\{double\_path\_code}\to\\{contour\_code}$;%
+\C{likewise}\6
+\4\\{max\_allowed}: \37\\{scaled};\C{coordinates must be at most this big}\par
+\fi
+
+\M404. First we do a simple preprocessing step. The segment numbers inserted
+here will propagate to all descendants of cubics that are split into
+subintervals. These numbers must be nonzero, but otherwise they are
+present merely for diagnostic purposes. The cubic from \|p to~\|q
+that represents ``time interval'' $(\|t-1)\to\|t$ usually has $\\{right\_type}(%
+\|q)=\|t$,
+except when \|t is too large to be stored in a quarterword.
+
+\Y\P\D \37$\\{procrustes}(\#)\S$\ \&{if} $\\{abs}(\#)\G\\{dmax}$ \1\&{then}\6
+\&{if} $\\{abs}(\#)>\\{max\_allowed}$ \1\&{then}\6
+\&{begin} \37$\\{chopped}\K1$;\6
+\&{if} $\#>0$ \1\&{then}\5
+$\#\K\\{max\_allowed}$\ \&{else} $\#\K-\\{max\_allowed}$;\2\6
+\&{end}\6
+\4\&{else} \&{if} $\\{chopped}=0$ \1\&{then}\5
+$\\{chopped}\K-1$\2\2\2\par
+\Y\P$\4\X404:Truncate the values of all coordinates that exceed \\{max%
+\_allowed}, and stamp segment numbers in each \\{left\_type} field\X\S$\6
+$\|p\K\\{cur\_spec}$;\5
+$\|k\K1$;\5
+$\\{chopped}\K0$;\5
+$\\{dmax}\K\\{max\_allowed}/2$;\6
+\1\&{repeat} \37$\\{procrustes}(\\{left\_x}(\|p))$;\5
+$\\{procrustes}(\\{left\_y}(\|p))$;\5
+$\\{procrustes}(\\{x\_coord}(\|p))$;\5
+$\\{procrustes}(\\{y\_coord}(\|p))$;\5
+$\\{procrustes}(\\{right\_x}(\|p))$;\5
+$\\{procrustes}(\\{right\_y}(\|p))$;\6
+$\|p\K\\{link}(\|p)$;\5
+$\\{left\_type}(\|p)\K\|k$;\6
+\&{if} $\|k<\\{max\_quarterword}$ \1\&{then}\5
+$\\{incr}(\|k)$\ \&{else} $\|k\K1$;\2\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$;\2\6
+\&{if} $\\{chopped}>0$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Curve\ out\ of\ range"})$;\5
+$\\{help4}(\.{"At\ least\ one\ of\ the\ coordinates\ in\ the\ path\ I\'m\ about%
+\ to"})$\6
+$(\.{"digitize\ was\ really\ huge\ (potentially\ bigger\ than\ 4095)."})$\6
+$(\.{"So\ I\'ve\ cut\ it\ back\ to\ the\ maximum\ size."})$\6
+$(\.{"The\ results\ will\ probably\ be\ pretty\ wild."})$;\5
+\\{put\_get\_error};\6
+\&{end}\2\par
+\U402.\fi
+
+\M405. We may need to get rid of constant ``dead'' cubics that clutter up
+the data structure and interfere with autorounding.
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\S$\6
+\4\&{procedure}\1\ \37$\\{remove\_cubic}(\|p:\\{pointer})$;\C{removes the
+cubic following~\|p}\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the node that disappears}\2\6
+\&{begin} \37$\|q\K\\{link}(\|p)$;\5
+$\\{right\_type}(\|p)\K\\{right\_type}(\|q)$;\5
+$\\{link}(\|p)\K\\{link}(\|q)$;\6
+$\\{x\_coord}(\|p)\K\\{x\_coord}(\|q)$;\5
+$\\{y\_coord}(\|p)\K\\{y\_coord}(\|q)$;\6
+$\\{right\_x}(\|p)\K\\{right\_x}(\|q)$;\5
+$\\{right\_y}(\|p)\K\\{right\_y}(\|q)$;\6
+$\\{free\_node}(\|q,\39\\{knot\_node\_size})$;\6
+\&{end};\par
+\As406, 419, 426, 429, 431, 432, 433, 440\ETs451.
+\U402.\fi
+
+\M406. The subdivision process proceeds by first swapping $x\swap-x$, if
+necessary, to ensure that $x'\G0$; then swapping $y\swap-y$, if necessary,
+to ensure that $y'\G0$; and finally swapping $x\swap y$, if necessary,
+to ensure that $x'\G y'$.
+
+Recall that the octant codes have been defined in such a way that, for
+example, $\\{third\_octant}=\\{first\_octant}+\\{negate\_x}+\\{switch\_x\_and%
+\_y}$. The program
+uses the fact that $\\{negate\_x}<\\{negate\_y}<\\{switch\_x\_and\_y}$ to
+handle ``double
+negation'': If \|c is an octant code that possibly involves \\{negate\_x}
+and/or \\{negate\_y}, but not \\{switch\_x\_and\_y}, then negating~\|y changes~%
+\|c
+either to $\|c+\\{negate\_y}$ or $\|c-\\{negate\_y}$, depending on whether
+$\|c\L\\{negate\_y}$ or $\|c>\\{negate\_y}$. Octant codes are always greater
+than zero.
+
+The first step is to subdivide on \|x and \|y only, so that horizontal
+and vertical autorounding can be done before we compare $x'$ to $y'$.
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\hbox{\4}\X410:Declare the procedure called \\{split\_cubic}\X\6
+\4\&{procedure}\1\ \37\\{quadrant\_subdivide};\6
+\4\&{label} \37$\\{continue},\39\\{exit}$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s,\39\\{pp},\39\\{qq}$: \37\\{pointer};%
+\C{for traversing the lists}\6
+$\\{first\_x},\39\\{first\_y}$: \37\\{scaled};\C{unnegated coordinates of node %
+\\{cur\_spec}}\6
+$\\{del1},\39\\{del2},\39\\{del3},\39\\{del},\39\\{dmax}$: \37\\{scaled};%
+\C{proportional to the control points of a quadratic derived from a cubic}\6
+\|t: \37\\{fraction};\C{where a quadratic crosses zero}\6
+$\\{dest\_x},\39\\{dest\_y}$: \37\\{scaled};\C{final values of \|x and \|y in
+the current cubic}\6
+\\{constant\_x}: \37\\{boolean};\C{is \|x constant between \|p and \|q?}\2\6
+\&{begin} \37$\|p\K\\{cur\_spec}$;\5
+$\\{first\_x}\K\\{x\_coord}(\\{cur\_spec})$;\5
+$\\{first\_y}\K\\{y\_coord}(\\{cur\_spec})$;\6
+\1\&{repeat} \37\\{continue}: \37$\|q\K\\{link}(\|p)$;\5
+\X407:Subdivide the cubic between \|p and \|q so that the results travel toward
+the right halfplane\X;\6
+\X413:Subdivide all cubics between \|p and \|q so that the results travel
+toward the first quadrant; but \&{return} or \&{goto} \\{continue} if the cubic
+from \|p to \|q was dead\X;\6
+$\|p\K\|q$;\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$;\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M407. All three subdivision processes are similar, so it's possible to
+get the general idea by studying the first one (which is the simplest).
+The calculation makes use of the fact that the derivatives of
+Bernshte{\u\i}n polynomials satisfy
+$B'(z_0,z_1,\ldots,z_n;t)=nB(z_1-z_0,\ldots,z_n-z_{n-1};t)$.
+
+When this routine begins, $\\{right\_type}(\|p)$ is \\{explicit}; we should
+set $\\{right\_type}(\|p)\K\\{first\_octant}$. However, no assignment is made,
+because $\\{explicit}=\\{first\_octant}$. The author apologizes for using
+such trickery here; it is really hard to do redundant computations
+just for the sake of purity.
+
+\Y\P$\4\X407:Subdivide the cubic between \|p and \|q so that the results travel
+toward the right halfplane\X\S$\6
+\&{if} $\|q=\\{cur\_spec}$ \1\&{then}\6
+\&{begin} \37$\\{dest\_x}\K\\{first\_x}$;\5
+$\\{dest\_y}\K\\{first\_y}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{dest\_x}\K\\{x\_coord}(\|q)$;\5
+$\\{dest\_y}\K\\{y\_coord}(\|q)$;\6
+\&{end};\2\6
+$\\{del1}\K\\{right\_x}(\|p)-\\{x\_coord}(\|p)$;\5
+$\\{del2}\K\\{left\_x}(\|q)-\\{right\_x}(\|p)$;\5
+$\\{del3}\K\\{dest\_x}-\\{left\_x}(\|q)$;\5
+\X408:Scale up \\{del1}, \\{del2}, and \\{del3} for greater accuracy; also set %
+\\{del} to the first nonzero element of $(\\{del1},\\{del2},\\{del3})$\X;\6
+\&{if} $\\{del}=0$ \1\&{then}\5
+$\\{constant\_x}\K\\{true}$\6
+\4\&{else} \&{begin} \37$\\{constant\_x}\K\\{false}$;\6
+\&{if} $\\{del}<0$ \1\&{then}\5
+\X409:Complement the \|x coordinates of the cubic between \|p and~\|q\X;\2\6
+$\|t\K\\{crossing\_point}(\\{del1},\39\\{del2},\39\\{del3})$;\6
+\&{if} $\|t<\\{fraction\_one}$ \1\&{then}\5
+\X411:Subdivide the cubic with respect to $x'$, possibly twice\X;\2\6
+\&{end}\2\par
+\U406.\fi
+
+\M408. If $\\{del1}=\\{del2}=\\{del3}=0$, it's impossible to obey the title of
+this
+section. We just set $\\{del}=0$ in that case.
+
+\Y\P$\4\X408:Scale up \\{del1}, \\{del2}, and \\{del3} for greater accuracy;
+also set \\{del} to the first nonzero element of $(\\{del1},\\{del2},\\{del3})$%
+\X\S$\6
+\&{if} $\\{del1}\I0$ \1\&{then}\5
+$\\{del}\K\\{del1}$\6
+\4\&{else} \&{if} $\\{del2}\I0$ \1\&{then}\5
+$\\{del}\K\\{del2}$\6
+\4\&{else} $\\{del}\K\\{del3}$;\2\2\6
+\&{if} $\\{del}\I0$ \1\&{then}\6
+\&{begin} \37$\\{dmax}\K\\{abs}(\\{del1})$;\6
+\&{if} $\\{abs}(\\{del2})>\\{dmax}$ \1\&{then}\5
+$\\{dmax}\K\\{abs}(\\{del2})$;\2\6
+\&{if} $\\{abs}(\\{del3})>\\{dmax}$ \1\&{then}\5
+$\\{dmax}\K\\{abs}(\\{del3})$;\2\6
+\&{while} $\\{dmax}<\\{fraction\_half}$ \1\&{do}\6
+\&{begin} \37$\\{double}(\\{dmax})$;\5
+$\\{double}(\\{del1})$;\5
+$\\{double}(\\{del2})$;\5
+$\\{double}(\\{del3})$;\6
+\&{end};\2\6
+\&{end}\2\par
+\Us407, 413\ETs420.\fi
+
+\M409. During the subdivision phases of \\{make\_spec}, the \\{x\_coord} and %
+\\{y\_coord}
+fields of node~\|q are not transformed to agree with the octant
+stated in $\\{right\_type}(\|p)$; they remain consistent with $\\{right\_type}(%
+\|q)$.
+But $\\{left\_x}(\|q)$ and $\\{left\_y}(\|q)$ are governed by $\\{right\_type}(%
+\|p)$.
+
+\Y\P$\4\X409:Complement the \|x coordinates of the cubic between \|p and~\|q\X%
+\S$\6
+\&{begin} \37$\\{negate}(\\{x\_coord}(\|p))$;\5
+$\\{negate}(\\{right\_x}(\|p))$;\5
+$\\{negate}(\\{left\_x}(\|q))$;\6
+$\\{negate}(\\{del1})$;\5
+$\\{negate}(\\{del2})$;\5
+$\\{negate}(\\{del3})$;\6
+$\\{negate}(\\{dest\_x})$;\5
+$\\{right\_type}(\|p)\K\\{first\_octant}+\\{negate\_x}$;\6
+\&{end}\par
+\U407.\fi
+
+\M410. When a cubic is split at a \\{fraction} value \|t, we obtain two cubics
+whose B\'ezier control points are obtained by a generalization of the
+bisection process: The formula
+`$z_k^{(j+1)}={1\over2}(z_k^{(j)}+z\k^{(j)})$' becomes
+`$z_k^{(j+1)}=t[z_k^{(j)},z\k^{(j)}]$'.
+
+It is convenient to define a \.{WEB} macro \\{t\_of\_the\_way} such that
+$\\{t\_of\_the\_way}(\|a)(\|b)$ expands to $\|a-(\|a-\|b)\ast\|t$, i.e., to $%
+\|t[\|a,\|b]$.
+
+If $0\L\|t\L1$, the quantity $\|t[\|a,\|b]$ is always between \|a and~\|b, even
+in
+the presence of rounding errors. Our subroutines
+also obey the identity $\|t[\|a,\|b]+\|t[\|b,\|a]=\|a+\|b$.
+
+\Y\P\D \37$\\{t\_of\_the\_way\_end}(\#)\S\#,\39\|t\={)}$\par
+\P\D \37$\\{t\_of\_the\_way}(\#)\S\#-\\{take\_fraction}\={(}\#-\\{t\_of\_the%
+\_way\_end}$\par
+\Y\P$\4\X410:Declare the procedure called \\{split\_cubic}\X\S$\6
+\4\&{procedure}\1\ \37$\\{split\_cubic}(\|p:\\{pointer};\,\35\|t:\\{fraction};%
+\,\35\\{xq},\39\\{yq}:\\{scaled})$;\C{splits the cubic after \|p}\6
+\4\&{var} \37\|v: \37\\{scaled};\C{an intermediate value}\6
+$\|q,\39\|r$: \37\\{pointer};\C{for list manipulation}\2\6
+\&{begin} \37$\|q\K\\{link}(\|p)$;\5
+$\|r\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{link}(\|p)\K\|r$;\5
+$\\{link}(\|r)\K\|q$;\6
+$\\{left\_type}(\|r)\K\\{left\_type}(\|q)$;\5
+$\\{right\_type}(\|r)\K\\{right\_type}(\|p)$;\7
+$\|v\K\\{t\_of\_the\_way}(\\{right\_x}(\|p))(\\{left\_x}(\|q))$;\5
+$\\{right\_x}(\|p)\K\\{t\_of\_the\_way}(\\{x\_coord}(\|p))(\\{right\_x}(\|p))$;%
+\5
+$\\{left\_x}(\|q)\K\\{t\_of\_the\_way}(\\{left\_x}(\|q))(\\{xq})$;\5
+$\\{left\_x}(\|r)\K\\{t\_of\_the\_way}(\\{right\_x}(\|p))(\|v)$;\5
+$\\{right\_x}(\|r)\K\\{t\_of\_the\_way}(\|v)(\\{left\_x}(\|q))$;\5
+$\\{x\_coord}(\|r)\K\\{t\_of\_the\_way}(\\{left\_x}(\|r))(\\{right\_x}(\|r))$;\7
+$\|v\K\\{t\_of\_the\_way}(\\{right\_y}(\|p))(\\{left\_y}(\|q))$;\5
+$\\{right\_y}(\|p)\K\\{t\_of\_the\_way}(\\{y\_coord}(\|p))(\\{right\_y}(\|p))$;%
+\5
+$\\{left\_y}(\|q)\K\\{t\_of\_the\_way}(\\{left\_y}(\|q))(\\{yq})$;\5
+$\\{left\_y}(\|r)\K\\{t\_of\_the\_way}(\\{right\_y}(\|p))(\|v)$;\5
+$\\{right\_y}(\|r)\K\\{t\_of\_the\_way}(\|v)(\\{left\_y}(\|q))$;\5
+$\\{y\_coord}(\|r)\K\\{t\_of\_the\_way}(\\{left\_y}(\|r))(\\{right\_y}(\|r))$;\6
+\&{end};\par
+\U406.\fi
+
+\M411. Since $x'(t)$ is a quadratic equation, it can cross through zero
+at~most twice. When it does cross zero, we make doubly sure that the
+derivative is really zero at the splitting point, in case rounding errors
+have caused the split cubic to have an apparently nonzero derivative.
+We also make sure that the split cubic is monotonic.
+
+\Y\P$\4\X411:Subdivide the cubic with respect to $x'$, possibly twice\X\S$\6
+\&{begin} \37$\\{split\_cubic}(\|p,\39\|t,\39\\{dest\_x},\39\\{dest\_y})$;\5
+$\|r\K\\{link}(\|p)$;\6
+\&{if} $\\{right\_type}(\|r)>\\{negate\_x}$ \1\&{then}\5
+$\\{right\_type}(\|r)\K\\{first\_octant}$\6
+\4\&{else} $\\{right\_type}(\|r)\K\\{first\_octant}+\\{negate\_x}$;\2\6
+\&{if} $\\{x\_coord}(\|r)<\\{x\_coord}(\|p)$ \1\&{then}\5
+$\\{x\_coord}(\|r)\K\\{x\_coord}(\|p)$;\2\6
+$\\{left\_x}(\|r)\K\\{x\_coord}(\|r)$;\6
+\&{if} $\\{right\_x}(\|p)>\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{right\_x}(\|p)\K\\{x\_coord}(\|r)$;\C{we always have $\\{x\_coord}(\|p)\L%
+\\{right\_x}(\|p)$}\2\6
+$\\{negate}(\\{x\_coord}(\|r))$;\5
+$\\{right\_x}(\|r)\K\\{x\_coord}(\|r)$;\5
+$\\{negate}(\\{left\_x}(\|q))$;\5
+$\\{negate}(\\{dest\_x})$;\6
+$\\{del2}\K\\{t\_of\_the\_way}(\\{del2})(\\{del3})$;\C{now $0,\\{del2},%
+\\{del3}$ represent $x'$ on the remaining interval}\6
+\&{if} $\\{del2}>0$ \1\&{then}\5
+$\\{del2}\K0$;\2\6
+$\|t\K\\{crossing\_point}(0,\39-\\{del2},\39-\\{del3})$;\6
+\&{if} $\|t<\\{fraction\_one}$ \1\&{then}\5
+\X412:Subdivide the cubic a second time with respect to $x'$\X\6
+\4\&{else} \&{begin} \37\&{if} $\\{x\_coord}(\|r)>\\{dest\_x}$ \1\&{then}\6
+\&{begin} \37$\\{x\_coord}(\|r)\K\\{dest\_x}$;\5
+$\\{left\_x}(\|r)\K-\\{x\_coord}(\|r)$;\5
+$\\{right\_x}(\|r)\K\\{x\_coord}(\|r)$;\6
+\&{end};\2\6
+\&{if} $\\{left\_x}(\|q)>\\{dest\_x}$ \1\&{then}\5
+$\\{left\_x}(\|q)\K\\{dest\_x}$\6
+\4\&{else} \&{if} $\\{left\_x}(\|q)<\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{left\_x}(\|q)\K\\{x\_coord}(\|r)$;\2\2\6
+\&{end};\2\6
+\&{end}\par
+\U407.\fi
+
+\M412. \P$\X412:Subdivide the cubic a second time with respect to $x'$\X\S$\6
+\&{begin} \37$\\{split\_cubic}(\|r,\39\|t,\39\\{dest\_x},\39\\{dest\_y})$;\5
+$\|s\K\\{link}(\|r)$;\6
+\&{if} $\\{x\_coord}(\|s)<\\{dest\_x}$ \1\&{then}\5
+$\\{x\_coord}(\|s)\K\\{dest\_x}$;\2\6
+\&{if} $\\{x\_coord}(\|s)<\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{x\_coord}(\|s)\K\\{x\_coord}(\|r)$;\2\6
+$\\{right\_type}(\|s)\K\\{right\_type}(\|p)$;\5
+$\\{left\_x}(\|s)\K\\{x\_coord}(\|s)$;\C{now $\\{x\_coord}(\|r)=\\{right\_x}(%
+\|r)\L\\{left\_x}(\|s)$}\6
+\&{if} $\\{left\_x}(\|q)<\\{dest\_x}$ \1\&{then}\5
+$\\{left\_x}(\|q)\K-\\{dest\_x}$\6
+\4\&{else} \&{if} $\\{left\_x}(\|q)>\\{x\_coord}(\|s)$ \1\&{then}\5
+$\\{left\_x}(\|q)\K-\\{x\_coord}(\|s)$\6
+\4\&{else} $\\{negate}(\\{left\_x}(\|q))$;\2\2\6
+$\\{negate}(\\{x\_coord}(\|s))$;\5
+$\\{right\_x}(\|s)\K\\{x\_coord}(\|s)$;\6
+\&{end}\par
+\U411.\fi
+
+\M413. The process of subdivision with respect to $y'$ is like that with
+respect
+to~$x'$, with the slight additional complication that two or three cubics
+might now appear between \|p and~\|q.
+
+\Y\P$\4\X413:Subdivide all cubics between \|p and \|q so that the results
+travel toward the first quadrant; but \&{return} or \&{goto} \\{continue} if
+the cubic from \|p to \|q was dead\X\S$\6
+$\\{pp}\K\|p$;\6
+\1\&{repeat} \37$\\{qq}\K\\{link}(\\{pp})$;\5
+$\\{abnegate}(\\{x\_coord}(\\{qq}),\39\\{y\_coord}(\\{qq}),\39\\{right\_type}(%
+\\{qq}),\39\\{right\_type}(\\{pp}))$;\5
+$\\{dest\_x}\K\\{cur\_x}$;\5
+$\\{dest\_y}\K\\{cur\_y}$;\6
+$\\{del1}\K\\{right\_y}(\\{pp})-\\{y\_coord}(\\{pp})$;\5
+$\\{del2}\K\\{left\_y}(\\{qq})-\\{right\_y}(\\{pp})$;\5
+$\\{del3}\K\\{dest\_y}-\\{left\_y}(\\{qq})$;\5
+\X408:Scale up \\{del1}, \\{del2}, and \\{del3} for greater accuracy; also set %
+\\{del} to the first nonzero element of $(\\{del1},\\{del2},\\{del3})$\X;\6
+\&{if} $\\{del}\I0$ \1\&{then}\C{they weren't all zero}\6
+\&{begin} \37\&{if} $\\{del}<0$ \1\&{then}\5
+\X414:Complement the \|y coordinates of the cubic between \\{pp} and~\\{qq}\X;%
+\2\6
+$\|t\K\\{crossing\_point}(\\{del1},\39\\{del2},\39\\{del3})$;\6
+\&{if} $\|t<\\{fraction\_one}$ \1\&{then}\5
+\X415:Subdivide the cubic with respect to $y'$, possibly twice\X;\2\6
+\&{end}\6
+\4\&{else} \X417:Do any special actions needed when \|y is constant; \&{return}
+or \&{goto} \\{continue} if a dead cubic from \|p to \|q is removed\X;\2\6
+$\\{pp}\K\\{qq}$;\6
+\4\&{until}\5
+$\\{pp}=\|q$;\2\6
+\&{if} $\\{constant\_x}$ \1\&{then}\5
+\X418:Correct the octant code in segments with decreasing \|y\X\2\par
+\U406.\fi
+
+\M414. \P$\X414:Complement the \|y coordinates of the cubic between \\{pp} and~%
+\\{qq}\X\S$\6
+\&{begin} \37$\\{negate}(\\{y\_coord}(\\{pp}))$;\5
+$\\{negate}(\\{right\_y}(\\{pp}))$;\5
+$\\{negate}(\\{left\_y}(\\{qq}))$;\6
+$\\{negate}(\\{del1})$;\5
+$\\{negate}(\\{del2})$;\5
+$\\{negate}(\\{del3})$;\6
+$\\{negate}(\\{dest\_y})$;\5
+$\\{right\_type}(\\{pp})\K\\{right\_type}(\\{pp})+\\{negate\_y}$;\6
+\&{end}\par
+\Us413\ET417.\fi
+
+\M415. \P$\X415:Subdivide the cubic with respect to $y'$, possibly twice\X\S$\6
+\&{begin} \37$\\{split\_cubic}(\\{pp},\39\|t,\39\\{dest\_x},\39\\{dest\_y})$;\5
+$\|r\K\\{link}(\\{pp})$;\6
+\&{if} $\\{right\_type}(\|r)>\\{negate\_y}$ \1\&{then}\5
+$\\{right\_type}(\|r)\K\\{right\_type}(\|r)-\\{negate\_y}$\6
+\4\&{else} $\\{right\_type}(\|r)\K\\{right\_type}(\|r)+\\{negate\_y}$;\2\6
+\&{if} $\\{y\_coord}(\|r)<\\{y\_coord}(\\{pp})$ \1\&{then}\5
+$\\{y\_coord}(\|r)\K\\{y\_coord}(\\{pp})$;\2\6
+$\\{left\_y}(\|r)\K\\{y\_coord}(\|r)$;\6
+\&{if} $\\{right\_y}(\\{pp})>\\{y\_coord}(\|r)$ \1\&{then}\5
+$\\{right\_y}(\\{pp})\K\\{y\_coord}(\|r)$;\C{we always have $\\{y\_coord}(%
+\\{pp})\L\\{right\_y}(\\{pp})$}\2\6
+$\\{negate}(\\{y\_coord}(\|r))$;\5
+$\\{right\_y}(\|r)\K\\{y\_coord}(\|r)$;\5
+$\\{negate}(\\{left\_y}(\\{qq}))$;\5
+$\\{negate}(\\{dest\_y})$;\6
+\&{if} $\\{x\_coord}(\|r)<\\{x\_coord}(\\{pp})$ \1\&{then}\5
+$\\{x\_coord}(\|r)\K\\{x\_coord}(\\{pp})$\6
+\4\&{else} \&{if} $\\{x\_coord}(\|r)>\\{dest\_x}$ \1\&{then}\5
+$\\{x\_coord}(\|r)\K\\{dest\_x}$;\2\2\6
+\&{if} $\\{left\_x}(\|r)>\\{x\_coord}(\|r)$ \1\&{then}\6
+\&{begin} \37$\\{left\_x}(\|r)\K\\{x\_coord}(\|r)$;\6
+\&{if} $\\{right\_x}(\\{pp})>\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{right\_x}(\\{pp})\K\\{x\_coord}(\|r)$;\2\6
+\&{end};\2\6
+\&{if} $\\{right\_x}(\|r)<\\{x\_coord}(\|r)$ \1\&{then}\6
+\&{begin} \37$\\{right\_x}(\|r)\K\\{x\_coord}(\|r)$;\6
+\&{if} $\\{left\_x}(\\{qq})<\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{left\_x}(\\{qq})\K\\{x\_coord}(\|r)$;\2\6
+\&{end};\2\6
+$\\{del2}\K\\{t\_of\_the\_way}(\\{del2})(\\{del3})$;\C{now $0,\\{del2},%
+\\{del3}$ represent $y'$ on the remaining interval}\6
+\&{if} $\\{del2}>0$ \1\&{then}\5
+$\\{del2}\K0$;\2\6
+$\|t\K\\{crossing\_point}(0,\39-\\{del2},\39-\\{del3})$;\6
+\&{if} $\|t<\\{fraction\_one}$ \1\&{then}\5
+\X416:Subdivide the cubic a second time with respect to $y'$\X\6
+\4\&{else} \&{begin} \37\&{if} $\\{y\_coord}(\|r)>\\{dest\_y}$ \1\&{then}\6
+\&{begin} \37$\\{y\_coord}(\|r)\K\\{dest\_y}$;\5
+$\\{left\_y}(\|r)\K-\\{y\_coord}(\|r)$;\5
+$\\{right\_y}(\|r)\K\\{y\_coord}(\|r)$;\6
+\&{end};\2\6
+\&{if} $\\{left\_y}(\\{qq})>\\{dest\_y}$ \1\&{then}\5
+$\\{left\_y}(\\{qq})\K\\{dest\_y}$\6
+\4\&{else} \&{if} $\\{left\_y}(\\{qq})<\\{y\_coord}(\|r)$ \1\&{then}\5
+$\\{left\_y}(\\{qq})\K\\{y\_coord}(\|r)$;\2\2\6
+\&{end};\2\6
+\&{end}\par
+\U413.\fi
+
+\M416. \P$\X416:Subdivide the cubic a second time with respect to $y'$\X\S$\6
+\&{begin} \37$\\{split\_cubic}(\|r,\39\|t,\39\\{dest\_x},\39\\{dest\_y})$;\5
+$\|s\K\\{link}(\|r)$;\6
+\&{if} $\\{y\_coord}(\|s)<\\{dest\_y}$ \1\&{then}\5
+$\\{y\_coord}(\|s)\K\\{dest\_y}$;\2\6
+\&{if} $\\{y\_coord}(\|s)<\\{y\_coord}(\|r)$ \1\&{then}\5
+$\\{y\_coord}(\|s)\K\\{y\_coord}(\|r)$;\2\6
+$\\{right\_type}(\|s)\K\\{right\_type}(\\{pp})$;\5
+$\\{left\_y}(\|s)\K\\{y\_coord}(\|s)$;\C{now $\\{y\_coord}(\|r)=\\{right\_y}(%
+\|r)\L\\{left\_y}(\|s)$}\6
+\&{if} $\\{left\_y}(\\{qq})<\\{dest\_y}$ \1\&{then}\5
+$\\{left\_y}(\\{qq})\K-\\{dest\_y}$\6
+\4\&{else} \&{if} $\\{left\_y}(\\{qq})>\\{y\_coord}(\|s)$ \1\&{then}\5
+$\\{left\_y}(\\{qq})\K-\\{y\_coord}(\|s)$\6
+\4\&{else} $\\{negate}(\\{left\_y}(\\{qq}))$;\2\2\6
+$\\{negate}(\\{y\_coord}(\|s))$;\5
+$\\{right\_y}(\|s)\K\\{y\_coord}(\|s)$;\6
+\&{if} $\\{x\_coord}(\|s)<\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{x\_coord}(\|s)\K\\{x\_coord}(\|r)$\6
+\4\&{else} \&{if} $\\{x\_coord}(\|s)>\\{dest\_x}$ \1\&{then}\5
+$\\{x\_coord}(\|s)\K\\{dest\_x}$;\2\2\6
+\&{if} $\\{left\_x}(\|s)>\\{x\_coord}(\|s)$ \1\&{then}\6
+\&{begin} \37$\\{left\_x}(\|s)\K\\{x\_coord}(\|s)$;\6
+\&{if} $\\{right\_x}(\|r)>\\{x\_coord}(\|s)$ \1\&{then}\5
+$\\{right\_x}(\|r)\K\\{x\_coord}(\|s)$;\2\6
+\&{end};\2\6
+\&{if} $\\{right\_x}(\|s)<\\{x\_coord}(\|s)$ \1\&{then}\6
+\&{begin} \37$\\{right\_x}(\|s)\K\\{x\_coord}(\|s)$;\6
+\&{if} $\\{left\_x}(\\{qq})<\\{x\_coord}(\|s)$ \1\&{then}\5
+$\\{left\_x}(\\{qq})\K\\{x\_coord}(\|s)$;\2\6
+\&{end};\2\6
+\&{end}\par
+\U415.\fi
+
+\M417. If the cubic is constant in $y$ and increasing in $x$, we have
+classified
+it as traveling in the first octant. If the cubic is constant
+in~$y$ and decreasing in~$x$, it is desirable to classify it as traveling
+in the fifth octant (not the fourth), because autorounding will be consistent
+with respect to doublepaths only if the octant number changes by four when
+the path is reversed. Therefore we negate the $y$~coordinates
+when they are constant but the curve is decreasing in~$x$; this gives
+the desired result except in pathological paths.
+
+If the cubic is ``dead,'' i.e., constant in both \|x and \|y, we remove
+it unless it is the only cubic in the entire path. We \&{goto} \\{continue}
+if it wasn't the final cubic, so that the test $\|p=\\{cur\_spec}$ does not
+falsely imply that all cubics have been processed.
+
+\Y\P$\4\X417:Do any special actions needed when \|y is constant; \&{return} or %
+\&{goto} \\{continue} if a dead cubic from \|p to \|q is removed\X\S$\6
+\&{if} $\\{constant\_x}$ \1\&{then}\C{$\|p=\\{pp}$, $\|q=\\{qq}$, and the cubic
+is dead}\6
+\&{begin} \37\&{if} $\|q\I\|p$ \1\&{then}\6
+\&{begin} \37$\\{remove\_cubic}(\|p)$;\C{remove the dead cycle and recycle node
+\|q}\6
+\&{if} $\\{cur\_spec}\I\|q$ \1\&{then}\5
+\&{goto} \37\\{continue}\6
+\4\&{else} \&{begin} \37$\\{cur\_spec}\K\|p$;\5
+\&{return};\6
+\&{end};\C{the final cubic was dead and is gone}\2\6
+\&{end};\2\6
+\&{end}\6
+\4\&{else} \&{if} $\R\\{odd}(\\{right\_type}(\\{pp}))$ \1\&{then}\C{the $x$
+coordinates were negated}\6
+\X414:Complement the \|y coordinates of the cubic between \\{pp} and~\\{qq}\X\2%
+\2\par
+\U413.\fi
+
+\M418. A similar correction to octant codes deserves to be made when \|x is
+constant and \|y is decreasing.
+
+\Y\P$\4\X418:Correct the octant code in segments with decreasing \|y\X\S$\6
+\&{begin} \37$\\{pp}\K\|p$;\6
+\1\&{repeat} \37$\\{qq}\K\\{link}(\\{pp})$;\6
+\&{if} $\\{right\_type}(\\{pp})>\\{negate\_y}$ \1\&{then}\C{the $y$ coordinates
+were negated}\6
+\&{begin} \37$\\{right\_type}(\\{pp})\K\\{right\_type}(\\{pp})+\\{negate\_x}$;\5
+$\\{negate}(\\{x\_coord}(\\{pp}))$;\5
+$\\{negate}(\\{right\_x}(\\{pp}))$;\5
+$\\{negate}(\\{left\_x}(\\{qq}))$;\6
+\&{end};\2\6
+$\\{pp}\K\\{qq}$;\6
+\4\&{until}\5
+$\\{pp}=\|q$;\2\6
+\&{end}\par
+\U413.\fi
+
+\M419. Finally, the process of subdividing to make $x'\G y'$ is like the other
+two subdivisions, with a few new twists. We skew the coordinates at this time.
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{octant\_subdivide};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{for traversing the
+lists}\6
+$\\{del1},\39\\{del2},\39\\{del3},\39\\{del},\39\\{dmax}$: \37\\{scaled};%
+\C{proportional to the control points of a quadratic derived from a cubic}\6
+\|t: \37\\{fraction};\C{where a quadratic crosses zero}\6
+$\\{dest\_x},\39\\{dest\_y}$: \37\\{scaled};\C{final values of \|x and \|y in
+the current cubic}\2\6
+\&{begin} \37$\|p\K\\{cur\_spec}$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|p)$;\6
+$\\{x\_coord}(\|p)\K\\{x\_coord}(\|p)-\\{y\_coord}(\|p)$;\5
+$\\{right\_x}(\|p)\K\\{right\_x}(\|p)-\\{right\_y}(\|p)$;\5
+$\\{left\_x}(\|q)\K\\{left\_x}(\|q)-\\{left\_y}(\|q)$;\6
+\X420:Subdivide the cubic between \|p and \|q so that the results travel toward
+the first octant\X;\6
+$\|p\K\|q$;\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$;\2\6
+\&{end};\par
+\fi
+
+\M420. \P$\X420:Subdivide the cubic between \|p and \|q so that the results
+travel toward the first octant\X\S$\6
+\X421:Set up the variables $(\\{del1},\\{del2},\\{del3})$ to represent $x'-y'$%
+\X;\6
+\X408:Scale up \\{del1}, \\{del2}, and \\{del3} for greater accuracy; also set %
+\\{del} to the first nonzero element of $(\\{del1},\\{del2},\\{del3})$\X;\6
+\&{if} $\\{del}\I0$ \1\&{then}\C{they weren't all zero}\6
+\&{begin} \37\&{if} $\\{del}<0$ \1\&{then}\5
+\X423:Swap the \|x and \|y coordinates of the cubic between \|p and~\|q\X;\2\6
+$\|t\K\\{crossing\_point}(\\{del1},\39\\{del2},\39\\{del3})$;\6
+\&{if} $\|t<\\{fraction\_one}$ \1\&{then}\5
+\X424:Subdivide the cubic with respect to $x'-y'$, possibly twice\X;\2\6
+\&{end}\2\par
+\U419.\fi
+
+\M421. \P$\X421:Set up the variables $(\\{del1},\\{del2},\\{del3})$ to
+represent $x'-y'$\X\S$\6
+\&{if} $\|q=\\{cur\_spec}$ \1\&{then}\6
+\&{begin} \37$\\{unskew}(\\{x\_coord}(\|q),\39\\{y\_coord}(\|q),\39\\{right%
+\_type}(\|q))$;\5
+$\\{skew}(\\{cur\_x},\39\\{cur\_y},\39\\{right\_type}(\|p))$;\5
+$\\{dest\_x}\K\\{cur\_x}$;\5
+$\\{dest\_y}\K\\{cur\_y}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{abnegate}(\\{x\_coord}(\|q),\39\\{y\_coord}(\|q),%
+\39\\{right\_type}(\|q),\39\\{right\_type}(\|p))$;\5
+$\\{dest\_x}\K\\{cur\_x}-\\{cur\_y}$;\5
+$\\{dest\_y}\K\\{cur\_y}$;\6
+\&{end};\2\6
+$\\{del1}\K\\{right\_x}(\|p)-\\{x\_coord}(\|p)$;\5
+$\\{del2}\K\\{left\_x}(\|q)-\\{right\_x}(\|p)$;\5
+$\\{del3}\K\\{dest\_x}-\\{left\_x}(\|q)$\par
+\U420.\fi
+
+\M422. The swapping here doesn't simply interchange \|x and \|y values,
+because the coordinates are skewed. It turns out that this is easier
+than ordinary swapping, because it can be done in two assignment statements
+rather than three.
+
+\fi
+
+\M423. \P$\X423:Swap the \|x and \|y coordinates of the cubic between \|p and~%
+\|q\X\S$\6
+\&{begin} \37$\\{y\_coord}(\|p)\K\\{x\_coord}(\|p)+\\{y\_coord}(\|p)$;\5
+$\\{negate}(\\{x\_coord}(\|p))$;\6
+$\\{right\_y}(\|p)\K\\{right\_x}(\|p)+\\{right\_y}(\|p)$;\5
+$\\{negate}(\\{right\_x}(\|p))$;\6
+$\\{left\_y}(\|q)\K\\{left\_x}(\|q)+\\{left\_y}(\|q)$;\5
+$\\{negate}(\\{left\_x}(\|q))$;\6
+$\\{negate}(\\{del1})$;\5
+$\\{negate}(\\{del2})$;\5
+$\\{negate}(\\{del3})$;\6
+$\\{dest\_y}\K\\{dest\_x}+\\{dest\_y}$;\5
+$\\{negate}(\\{dest\_x})$;\6
+$\\{right\_type}(\|p)\K\\{right\_type}(\|p)+\\{switch\_x\_and\_y}$;\6
+\&{end}\par
+\U420.\fi
+
+\M424. A somewhat tedious case analysis is carried out here to make sure that
+nasty rounding errors don't destroy our assumptions of monotonicity.
+
+\Y\P$\4\X424:Subdivide the cubic with respect to $x'-y'$, possibly twice\X\S$\6
+\&{begin} \37$\\{split\_cubic}(\|p,\39\|t,\39\\{dest\_x},\39\\{dest\_y})$;\5
+$\|r\K\\{link}(\|p)$;\6
+\&{if} $\\{right\_type}(\|r)>\\{switch\_x\_and\_y}$ \1\&{then}\5
+$\\{right\_type}(\|r)\K\\{right\_type}(\|r)-\\{switch\_x\_and\_y}$\6
+\4\&{else} $\\{right\_type}(\|r)\K\\{right\_type}(\|r)+\\{switch\_x\_and\_y}$;%
+\2\6
+\&{if} $\\{y\_coord}(\|r)<\\{y\_coord}(\|p)$ \1\&{then}\5
+$\\{y\_coord}(\|r)\K\\{y\_coord}(\|p)$\6
+\4\&{else} \&{if} $\\{y\_coord}(\|r)>\\{dest\_y}$ \1\&{then}\5
+$\\{y\_coord}(\|r)\K\\{dest\_y}$;\2\2\6
+\&{if} $\\{x\_coord}(\|p)+\\{y\_coord}(\|r)>\\{dest\_x}+\\{dest\_y}$ \1\&{then}%
+\5
+$\\{y\_coord}(\|r)\K\\{dest\_x}+\\{dest\_y}-\\{x\_coord}(\|p)$;\2\6
+\&{if} $\\{left\_y}(\|r)>\\{y\_coord}(\|r)$ \1\&{then}\6
+\&{begin} \37$\\{left\_y}(\|r)\K\\{y\_coord}(\|r)$;\6
+\&{if} $\\{right\_y}(\|p)>\\{y\_coord}(\|r)$ \1\&{then}\5
+$\\{right\_y}(\|p)\K\\{y\_coord}(\|r)$;\2\6
+\&{end};\2\6
+\&{if} $\\{right\_y}(\|r)<\\{y\_coord}(\|r)$ \1\&{then}\6
+\&{begin} \37$\\{right\_y}(\|r)\K\\{y\_coord}(\|r)$;\6
+\&{if} $\\{left\_y}(\|q)<\\{y\_coord}(\|r)$ \1\&{then}\5
+$\\{left\_y}(\|q)\K\\{y\_coord}(\|r)$;\2\6
+\&{end};\2\6
+\&{if} $\\{x\_coord}(\|r)<\\{x\_coord}(\|p)$ \1\&{then}\5
+$\\{x\_coord}(\|r)\K\\{x\_coord}(\|p)$\6
+\4\&{else} \&{if} $\\{x\_coord}(\|r)+\\{y\_coord}(\|r)>\\{dest\_x}+\\{dest\_y}$
+\1\&{then}\5
+$\\{x\_coord}(\|r)\K\\{dest\_x}+\\{dest\_y}-\\{y\_coord}(\|r)$;\2\2\6
+$\\{left\_x}(\|r)\K\\{x\_coord}(\|r)$;\6
+\&{if} $\\{right\_x}(\|p)>\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{right\_x}(\|p)\K\\{x\_coord}(\|r)$;\C{we always have $\\{x\_coord}(\|p)\L%
+\\{right\_x}(\|p)$}\2\6
+$\\{y\_coord}(\|r)\K\\{y\_coord}(\|r)+\\{x\_coord}(\|r)$;\5
+$\\{right\_y}(\|r)\K\\{right\_y}(\|r)+\\{x\_coord}(\|r)$;\6
+$\\{negate}(\\{x\_coord}(\|r))$;\5
+$\\{right\_x}(\|r)\K\\{x\_coord}(\|r)$;\6
+$\\{left\_y}(\|q)\K\\{left\_y}(\|q)+\\{left\_x}(\|q)$;\5
+$\\{negate}(\\{left\_x}(\|q))$;\6
+$\\{dest\_y}\K\\{dest\_y}+\\{dest\_x}$;\5
+$\\{negate}(\\{dest\_x})$;\6
+\&{if} $\\{right\_y}(\|r)<\\{y\_coord}(\|r)$ \1\&{then}\6
+\&{begin} \37$\\{right\_y}(\|r)\K\\{y\_coord}(\|r)$;\6
+\&{if} $\\{left\_y}(\|q)<\\{y\_coord}(\|r)$ \1\&{then}\5
+$\\{left\_y}(\|q)\K\\{y\_coord}(\|r)$;\2\6
+\&{end};\2\6
+$\\{del2}\K\\{t\_of\_the\_way}(\\{del2})(\\{del3})$;\C{now $0,\\{del2},%
+\\{del3}$ represent $x'-y'$ on the remaining interval}\6
+\&{if} $\\{del2}>0$ \1\&{then}\5
+$\\{del2}\K0$;\2\6
+$\|t\K\\{crossing\_point}(0,\39-\\{del2},\39-\\{del3})$;\6
+\&{if} $\|t<\\{fraction\_one}$ \1\&{then}\5
+\X425:Subdivide the cubic a second time with respect to $x'-y'$\X\6
+\4\&{else} \&{begin} \37\&{if} $\\{x\_coord}(\|r)>\\{dest\_x}$ \1\&{then}\6
+\&{begin} \37$\\{x\_coord}(\|r)\K\\{dest\_x}$;\5
+$\\{left\_x}(\|r)\K-\\{x\_coord}(\|r)$;\5
+$\\{right\_x}(\|r)\K\\{x\_coord}(\|r)$;\6
+\&{end};\2\6
+\&{if} $\\{left\_x}(\|q)>\\{dest\_x}$ \1\&{then}\5
+$\\{left\_x}(\|q)\K\\{dest\_x}$\6
+\4\&{else} \&{if} $\\{left\_x}(\|q)<\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{left\_x}(\|q)\K\\{x\_coord}(\|r)$;\2\2\6
+\&{end};\2\6
+\&{end}\par
+\U420.\fi
+
+\M425. \P$\X425:Subdivide the cubic a second time with respect to $x'-y'$\X\S$\6
+\&{begin} \37$\\{split\_cubic}(\|r,\39\|t,\39\\{dest\_x},\39\\{dest\_y})$;\5
+$\|s\K\\{link}(\|r)$;\6
+\&{if} $\\{y\_coord}(\|s)<\\{y\_coord}(\|r)$ \1\&{then}\5
+$\\{y\_coord}(\|s)\K\\{y\_coord}(\|r)$\6
+\4\&{else} \&{if} $\\{y\_coord}(\|s)>\\{dest\_y}$ \1\&{then}\5
+$\\{y\_coord}(\|s)\K\\{dest\_y}$;\2\2\6
+\&{if} $\\{x\_coord}(\|r)+\\{y\_coord}(\|s)>\\{dest\_x}+\\{dest\_y}$ \1\&{then}%
+\5
+$\\{y\_coord}(\|s)\K\\{dest\_x}+\\{dest\_y}-\\{x\_coord}(\|r)$;\2\6
+\&{if} $\\{left\_y}(\|s)>\\{y\_coord}(\|s)$ \1\&{then}\6
+\&{begin} \37$\\{left\_y}(\|s)\K\\{y\_coord}(\|s)$;\6
+\&{if} $\\{right\_y}(\|r)>\\{y\_coord}(\|s)$ \1\&{then}\5
+$\\{right\_y}(\|r)\K\\{y\_coord}(\|s)$;\2\6
+\&{end};\2\6
+\&{if} $\\{right\_y}(\|s)<\\{y\_coord}(\|s)$ \1\&{then}\6
+\&{begin} \37$\\{right\_y}(\|s)\K\\{y\_coord}(\|s)$;\6
+\&{if} $\\{left\_y}(\|q)<\\{y\_coord}(\|s)$ \1\&{then}\5
+$\\{left\_y}(\|q)\K\\{y\_coord}(\|s)$;\2\6
+\&{end};\2\6
+\&{if} $\\{x\_coord}(\|s)+\\{y\_coord}(\|s)>\\{dest\_x}+\\{dest\_y}$ \1\&{then}%
+\5
+$\\{x\_coord}(\|s)\K\\{dest\_x}+\\{dest\_y}-\\{y\_coord}(\|s)$\6
+\4\&{else} \&{begin} \37\&{if} $\\{x\_coord}(\|s)<\\{dest\_x}$ \1\&{then}\5
+$\\{x\_coord}(\|s)\K\\{dest\_x}$;\2\6
+\&{if} $\\{x\_coord}(\|s)<\\{x\_coord}(\|r)$ \1\&{then}\5
+$\\{x\_coord}(\|s)\K\\{x\_coord}(\|r)$;\2\6
+\&{end};\2\6
+$\\{right\_type}(\|s)\K\\{right\_type}(\|p)$;\5
+$\\{left\_x}(\|s)\K\\{x\_coord}(\|s)$;\C{now $\\{x\_coord}(\|r)=\\{right\_x}(%
+\|r)\L\\{left\_x}(\|s)$}\6
+\&{if} $\\{left\_x}(\|q)<\\{dest\_x}$ \1\&{then}\6
+\&{begin} \37$\\{left\_y}(\|q)\K\\{left\_y}(\|q)+\\{dest\_x}$;\5
+$\\{left\_x}(\|q)\K-\\{dest\_x}$;\ \&{end}\6
+\4\&{else} \&{if} $\\{left\_x}(\|q)>\\{x\_coord}(\|s)$ \1\&{then}\6
+\&{begin} \37$\\{left\_y}(\|q)\K\\{left\_y}(\|q)+\\{x\_coord}(\|s)$;\5
+$\\{left\_x}(\|q)\K-\\{x\_coord}(\|s)$;\ \&{end}\6
+\4\&{else} \&{begin} \37$\\{left\_y}(\|q)\K\\{left\_y}(\|q)+\\{left\_x}(\|q)$;\5
+$\\{negate}(\\{left\_x}(\|q))$;\ \&{end};\2\2\6
+$\\{y\_coord}(\|s)\K\\{y\_coord}(\|s)+\\{x\_coord}(\|s)$;\5
+$\\{right\_y}(\|s)\K\\{right\_y}(\|s)+\\{x\_coord}(\|s)$;\6
+$\\{negate}(\\{x\_coord}(\|s))$;\5
+$\\{right\_x}(\|s)\K\\{x\_coord}(\|s)$;\6
+\&{if} $\\{right\_y}(\|s)<\\{y\_coord}(\|s)$ \1\&{then}\6
+\&{begin} \37$\\{right\_y}(\|s)\K\\{y\_coord}(\|s)$;\6
+\&{if} $\\{left\_y}(\|q)<\\{y\_coord}(\|s)$ \1\&{then}\5
+$\\{left\_y}(\|q)\K\\{y\_coord}(\|s)$;\2\6
+\&{end};\2\6
+\&{end}\par
+\U424.\fi
+
+\M426. It's time now to consider ``autorounding,'' which tries to make
+horizontal,
+vertical, and diagonal tangents occur at places that will produce appropriate
+images after the curve is digitized.
+
+The first job is to fix things so that $\|x(\|t)$ is an integer multiple of the
+current ``granularity'' when the derivative $x'(t)$ crosses through zero.
+The given cyclic path contains regions where $x'(t)\G0$ and regions
+where $x'(t)\L0$. The \\{quadrant\_subdivide} routine is called into action
+before any of the path coordinates have been skewed, but some of them
+may have been negated. In regions where $x'(t)\G0$ we have $\\{right\_type}=%
+\\{first\_octant}$ or $\\{right\_type}=\\{eighth\_octant}$; in regions where
+$x'(t)\L0$,
+we have $\\{right\_type}=\\{fifth\_octant}$ or $\\{right\_type}=\\{fourth%
+\_octant}$.
+
+Within any such region the transformed $x$ values increase monotonically
+from, say, $x_0$ to~$x_1$. We want to modify things by applying a linear
+transformation to all $x$ coordinates in the region, after which
+the $x$ values will increase monotonically from round$(x_0)$ to round$(x_1)$.
+
+This rounding scheme sounds quite simple, and it usually is. But several
+complications can arise that might make the task more difficult. In the
+first place, autorounding is inappropriate at cusps where $x'$ jumps
+discontinuously past zero without ever being zero. In the second place,
+the current pen might be unsymmetric in such a way that $x$ coordinates
+should round differently when $x'$ becomes positive than when it becomes
+negative. These considerations imply that round$(x_0)$ might be greater
+than round$(x_1)$, even though $x_0\L x_1$; in such cases we do not want
+to carry out the linear transformation. Furthermore, it's possible to have
+round$(x_1)-\hbox{round} (x_0)$ positive but much greater than $x_1-x_0$;
+then the transformation might distort the curve drastically, and again we
+want to avoid it. Finally, the rounded points must be consistent between
+adjacent regions, hence we can't transform one region without knowing
+about its neighbors.
+
+To handle all these complications, we must first look at the whole
+cycle and choose rounded $x$ values that are ``safe.'' The following
+procedure does this: Given $m$~values $(b_0,b_1,\ldots,b_{m-1})$ before
+rounding and $m$~corresponding values $(a_0,a_1,\ldots,a_{m-1})$ that would
+be desirable after rounding, the \\{make\_safe} routine sets $a$'s to $b$'s
+if necessary so that $0\L(a\k-a_k)/(b\k-b_k)\L2$ afterwards. It is
+symmetric under cyclic permutation, reversal, and/or negation of the inputs.
+(Instead of \|a, \|b, and~\|m, the program uses the names \\{after},
+\\{before}, and \\{cur\_rounding\_ptr}.)
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{make\_safe};\6
+\4\&{var} \37\|k: \37$0\to\\{max\_wiggle}$;\C{runs through the list of inputs}\6
+\\{all\_safe}: \37\\{boolean};\C{does everything look OK so far?}\6
+\\{next\_a}: \37\\{scaled};\C{$\\{after}[\|k]$ before it might have changed}\6
+$\\{delta\_a},\39\\{delta\_b}$: \37\\{scaled};\C{$\\{after}[\|k+1]-\\{after}[%
+\|k]$ and $\\{before}[\|k+1]-\\{before}[\|k]$}\2\6
+\&{begin} \37$\\{before}[\\{cur\_rounding\_ptr}]\K\\{before}[0]$;\C{wrap
+around}\6
+$\\{node\_to\_round}[\\{cur\_rounding\_ptr}]\K\\{node\_to\_round}[0]$;\6
+\1\&{repeat} \37$\\{after}[\\{cur\_rounding\_ptr}]\K\\{after}[0]$;\5
+$\\{all\_safe}\K\\{true}$;\5
+$\\{next\_a}\K\\{after}[0]$;\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{cur\_rounding\_ptr}-1$ \1\&{do}\6
+\&{begin} \37$\\{delta\_b}\K\\{before}[\|k+1]-\\{before}[\|k]$;\6
+\&{if} $\\{delta\_b}\G0$ \1\&{then}\5
+$\\{delta\_a}\K\\{after}[\|k+1]-\\{next\_a}$\6
+\4\&{else} $\\{delta\_a}\K\\{next\_a}-\\{after}[\|k+1]$;\2\6
+$\\{next\_a}\K\\{after}[\|k+1]$;\6
+\&{if} $(\\{delta\_a}<0)\V(\\{delta\_a}>\\{abs}(\\{delta\_b}+\\{delta\_b}))$ \1%
+\&{then}\6
+\&{begin} \37$\\{all\_safe}\K\\{false}$;\5
+$\\{after}[\|k]\K\\{before}[\|k]$;\6
+\&{if} $\|k=\\{cur\_rounding\_ptr}-1$ \1\&{then}\5
+$\\{after}[0]\K\\{before}[0]$\6
+\4\&{else} $\\{after}[\|k+1]\K\\{before}[\|k+1]$;\2\6
+\&{end};\2\6
+\&{end};\2\6
+\4\&{until}\5
+\\{all\_safe};\2\6
+\&{end};\par
+\fi
+
+\M427. The global arrays used by \\{make\_safe} are accompanied by an array of
+pointers into the current knot list.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{before},\39\\{after}$: \37\&{array} $[0\to\\{max\_wiggle}]$ \1\&{of}\5
+\\{scaled};\C{data for \\{make\_safe}}\2\6
+\4\\{node\_to\_round}: \37\&{array} $[0\to\\{max\_wiggle}]$ \1\&{of}\5
+\\{pointer};\C{reference back to the path}\2\6
+\4\\{cur\_rounding\_ptr}: \37$0\to\\{max\_wiggle}$;\C{how many are being used}\6
+\4\\{max\_rounding\_ptr}: \37$0\to\\{max\_wiggle}$;\C{how many have been used}%
+\par
+\fi
+
+\M428. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{max\_rounding\_ptr}\K0$;\par
+\fi
+
+\M429. New entries go into the tables via the \\{before\_and\_after} routine:
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{before\_and\_after}(\|b,\39\|a:\\{scaled};\,\35\|p:%
+\\{pointer})$;\2\6
+\&{begin} \37\&{if} $\\{cur\_rounding\_ptr}=\\{max\_rounding\_ptr}$ \1\&{then}\6
+\&{if} $\\{max\_rounding\_ptr}<\\{max\_wiggle}$ \1\&{then}\5
+$\\{incr}(\\{max\_rounding\_ptr})$\6
+\4\&{else} $\\{overflow}(\.{"rounding\ table\ size"},\39\\{max\_wiggle})$;\2\2\6
+$\\{after}[\\{cur\_rounding\_ptr}]\K\|a$;\5
+$\\{before}[\\{cur\_rounding\_ptr}]\K\|b$;\5
+$\\{node\_to\_round}[\\{cur\_rounding\_ptr}]\K\|p$;\5
+$\\{incr}(\\{cur\_rounding\_ptr})$;\6
+\&{end};\par
+\fi
+
+\M430. A global variable called \\{cur\_gran} is used instead of $\\{internal}[%
+\\{granularity}]$, because we want to work with a number that's guaranteed to
+be positive.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{cur\_gran}: \37\\{scaled};\C{the current granularity (which normally is %
+\\{unity})}\par
+\fi
+
+\M431. The \\{good\_val} function computes a number \|a that's as close as
+possible to~\|b, with the property that $\|a+\|o$ is a multiple of
+\\{cur\_gran}.
+
+If we assume that \\{cur\_gran} is even (since it will in fact be a multiple
+of \\{unity} in all reasonable applications), we have the identity
+$\\{good\_val}(-\|b-1,-\|o)=-\\{good\_val}(\|b,\|o)$.
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\4\&{function}\1\ \37$\\{good\_val}(\|b,\39\|o:\\{scaled})$: \37\\{scaled};\6
+\4\&{var} \37\|a: \37\\{scaled};\C{accumulator}\2\6
+\&{begin} \37$\|a\K\|b+\|o$;\6
+\&{if} $\|a\G0$ \1\&{then}\5
+$\|a\K\|a-(\|a\mathbin{\&{mod}}\\{cur\_gran})-\|o$\6
+\4\&{else} $\|a\K\|a+((-(\|a+1))\mathbin{\&{mod}}\\{cur\_gran})-\\{cur%
+\_gran}+1-\|o$;\2\6
+\&{if} $\|b-\|a<\|a+\\{cur\_gran}-\|b$ \1\&{then}\5
+$\\{good\_val}\K\|a$\6
+\4\&{else} $\\{good\_val}\K\|a+\\{cur\_gran}$;\2\6
+\&{end};\par
+\fi
+
+\M432. When we're rounding a doublepath, we might need to compromise between
+two opposing tendencies, if the pen thickness is not a multiple of the
+granularity. The following ``compromise'' adjustment, suggested by
+John Hobby, finds the best way out of the dilemma. (Only the value
+modulo \\{cur\_gran} is relevant in our applications, so the result turns
+out to be essentially symmetric in \|u and~\|v.)
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\4\&{function}\1\ \37$\\{compromise}(\|u,\39\|v:\\{scaled})$: \37\\{scaled};\2%
+\6
+\&{begin} \37$\\{compromise}\K\\{half}(\\{good\_val}(\|u+\|u,\39-\|u-\|v))$;\6
+\&{end};\par
+\fi
+
+\M433. Here, then, is the procedure that rounds $x$ coordinates as described;
+it does the same for $y$ coordinates too, independently.
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{xy\_round};\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{list manipulation registers}\6
+$\|b,\39\|a$: \37\\{scaled};\C{before and after values}\6
+\\{pen\_edge}: \37\\{scaled};\C{offset that governs rounding}\6
+\\{alpha}: \37\\{fraction};\C{coefficient of linear transformation}\2\6
+\&{begin} \37$\\{cur\_gran}\K\\{abs}(\\{internal}[\\{granularity}])$;\6
+\&{if} $\\{cur\_gran}=0$ \1\&{then}\5
+$\\{cur\_gran}\K\\{unity}$;\2\6
+$\|p\K\\{cur\_spec}$;\5
+$\\{cur\_rounding\_ptr}\K0$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|p)$;\5
+\X434:If node \|q is a transition point for \|x coordinates, compute and save
+its before-and-after coordinates\X;\6
+$\|p\K\|q$;\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$;\2\6
+\&{if} $\\{cur\_rounding\_ptr}>0$ \1\&{then}\5
+\X436:Transform the \|x coordinates\X;\2\6
+$\|p\K\\{cur\_spec}$;\5
+$\\{cur\_rounding\_ptr}\K0$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|p)$;\5
+\X437:If node \|q is a transition point for \|y coordinates, compute and save
+its before-and-after coordinates\X;\6
+$\|p\K\|q$;\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$;\2\6
+\&{if} $\\{cur\_rounding\_ptr}>0$ \1\&{then}\5
+\X439:Transform the \|y coordinates\X;\2\6
+\&{end};\par
+\fi
+
+\M434. When \|x has been negated, the \\{octant} codes are even. We allow
+for an error of up to .01 pixel (i.e., 655 \\{scaled} units) in the
+derivative calculations at transition nodes.
+
+\Y\P$\4\X434:If node \|q is a transition point for \|x coordinates, compute and
+save its before-and-after coordinates\X\S$\6
+\&{if} $\\{odd}(\\{right\_type}(\|p))\I\\{odd}(\\{right\_type}(\|q))$ \1%
+\&{then}\6
+\&{begin} \37\&{if} $\\{odd}(\\{right\_type}(\|q))$ \1\&{then}\5
+$\|b\K\\{x\_coord}(\|q)$\ \&{else} $\|b\K-\\{x\_coord}(\|q)$;\2\6
+\&{if} $(\\{abs}(\\{x\_coord}(\|q)-\\{right\_x}(\|q))<655)\V\30(\\{abs}(\\{x%
+\_coord}(\|q)+\\{left\_x}(\|q))<655)$ \1\&{then}\5
+\X435:Compute before-and-after \|x values based on the current pen\X\6
+\4\&{else} $\|a\K\|b$;\2\6
+\&{if} $\\{abs}(\|a)>\\{max\_allowed}$ \1\&{then}\6
+\&{if} $\|a>0$ \1\&{then}\5
+$\|a\K\\{max\_allowed}$\ \&{else} $\|a\K-\\{max\_allowed}$;\2\2\6
+$\\{before\_and\_after}(\|b,\39\|a,\39\|q)$;\6
+\&{end}\2\par
+\U433.\fi
+
+\M435. When we study the data representation for pens, we'll learn that the
+\|x~coordinate of the current pen's west edge is
+$$\hbox{$\\{y\_coord}(\\{link}(\\{cur\_pen}+\\{seventh\_octant}))$},$$
+and that there are similar ways to address other important offsets.
+An ``\\{east\_west\_edge}'' is computed as a compromise between east and
+west, for use in doublepaths, in case the two edges have conflicting
+tendencies.
+
+\Y\P\D \37$\\{north\_edge}(\#)\S\\{y\_coord}(\\{link}(\#+\\{fourth\_octant}))$%
+\par
+\P\D \37$\\{south\_edge}(\#)\S\\{y\_coord}(\\{link}(\#+\\{first\_octant}))$\par
+\P\D \37$\\{east\_edge}(\#)\S\\{y\_coord}(\\{link}(\#+\\{second\_octant}))$\par
+\P\D \37$\\{west\_edge}(\#)\S\\{y\_coord}(\\{link}(\#+\\{seventh\_octant}))$\par
+\P\D \37$\\{north\_south\_edge}(\#)\S\\{mem}[\#+10].\\{int}$\C{compromise
+between north and south}\par
+\P\D \37$\\{east\_west\_edge}(\#)\S\\{mem}[\#+11].\\{int}$\C{compromise between
+east and west}\par
+\P\D \37$\\{NE\_SW\_edge}(\#)\S\\{mem}[\#+12].\\{int}$\C{compromise between
+northeast and southwest}\par
+\P\D \37$\\{NW\_SE\_edge}(\#)\S\\{mem}[\#+13].\\{int}$\C{compromise between
+northwest and southeast}\par
+\Y\P$\4\X435:Compute before-and-after \|x values based on the current pen\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_pen}=\\{null\_pen}$ \1\&{then}\5
+$\\{pen\_edge}\K0$\6
+\4\&{else} \&{if} $\\{cur\_path\_type}=\\{double\_path\_code}$ \1\&{then}\5
+$\\{pen\_edge}\K\\{compromise}(\\{east\_edge}(\\{cur\_pen}),\39\\{west\_edge}(%
+\\{cur\_pen}))$\6
+\4\&{else} \&{if} $\\{odd}(\\{right\_type}(\|q))$ \1\&{then}\5
+$\\{pen\_edge}\K\\{west\_edge}(\\{cur\_pen})$\6
+\4\&{else} $\\{pen\_edge}\K\\{east\_edge}(\\{cur\_pen})$;\2\2\2\6
+$\|a\K\\{good\_val}(\|b,\39\\{pen\_edge})$;\6
+\&{end}\par
+\U434.\fi
+
+\M436. The monotone transformation computed here with fixed-point arithmetic
+is
+guaranteed to take consecutive \\{before} values $(b,b')$ into consecutive
+\\{after} values $(a,a')$, even in the presence of rounding errors,
+as long as $\vert b-b'\vert<2^{28}$.
+
+\Y\P$\4\X436:Transform the \|x coordinates\X\S$\6
+\&{begin} \37\\{make\_safe};\6
+\1\&{repeat} \37$\\{decr}(\\{cur\_rounding\_ptr})$;\6
+\&{if} $(\\{after}[\\{cur\_rounding\_ptr}]\I\\{before}[\\{cur\_rounding\_ptr}])%
+\V\30(\\{after}[\\{cur\_rounding\_ptr}+1]\I\\{before}[\\{cur\_rounding%
+\_ptr}+1])$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{node\_to\_round}[\\{cur\_rounding\_ptr}]$;\6
+\&{if} $\\{odd}(\\{right\_type}(\|p))$ \1\&{then}\6
+\&{begin} \37$\|b\K\\{before}[\\{cur\_rounding\_ptr}]$;\5
+$\|a\K\\{after}[\\{cur\_rounding\_ptr}]$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|b\K-\\{before}[\\{cur\_rounding\_ptr}]$;\5
+$\|a\K-\\{after}[\\{cur\_rounding\_ptr}]$;\6
+\&{end};\2\6
+\&{if} $\\{before}[\\{cur\_rounding\_ptr}]=\\{before}[\\{cur\_rounding%
+\_ptr}+1]$ \1\&{then}\5
+$\\{alpha}\K\\{fraction\_one}$\6
+\4\&{else} $\\{alpha}\K\\{make\_fraction}(\\{after}[\\{cur\_rounding\_ptr}+1]-%
+\\{after}[\\{cur\_rounding\_ptr}],\39\30\\{before}[\\{cur\_rounding\_ptr}+1]-%
+\\{before}[\\{cur\_rounding\_ptr}])$;\2\6
+\1\&{repeat} \37$\\{x\_coord}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{x%
+\_coord}(\|p)-\|b)+\|a$;\5
+$\\{right\_x}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{right\_x}(\|p)-\|b)+%
+\|a$;\5
+$\|p\K\\{link}(\|p)$;\5
+$\\{left\_x}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{left\_x}(\|p)-\|b)+\|a$;\6
+\4\&{until}\5
+$\|p=\\{node\_to\_round}[\\{cur\_rounding\_ptr}+1]$;\2\6
+\&{end};\2\6
+\4\&{until}\5
+$\\{cur\_rounding\_ptr}=0$;\2\6
+\&{end}\par
+\U433.\fi
+
+\M437. When \|y has been negated, the \\{octant} codes are $>\\{negate\_y}$.
+Otherwise
+these routines are essentially identical to the routines for \|x coordinates
+that we have just seen.
+
+\Y\P$\4\X437:If node \|q is a transition point for \|y coordinates, compute and
+save its before-and-after coordinates\X\S$\6
+\&{if} $(\\{right\_type}(\|p)>\\{negate\_y})\I(\\{right\_type}(\|q)>\\{negate%
+\_y})$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{right\_type}(\|q)\L\\{negate\_y}$ \1\&{then}\5
+$\|b\K\\{y\_coord}(\|q)$\ \&{else} $\|b\K-\\{y\_coord}(\|q)$;\2\6
+\&{if} $(\\{abs}(\\{y\_coord}(\|q)-\\{right\_y}(\|q))<655)\V\30(\\{abs}(\\{y%
+\_coord}(\|q)+\\{left\_y}(\|q))<655)$ \1\&{then}\5
+\X438:Compute before-and-after \|y values based on the current pen\X\6
+\4\&{else} $\|a\K\|b$;\2\6
+\&{if} $\\{abs}(\|a)>\\{max\_allowed}$ \1\&{then}\6
+\&{if} $\|a>0$ \1\&{then}\5
+$\|a\K\\{max\_allowed}$\ \&{else} $\|a\K-\\{max\_allowed}$;\2\2\6
+$\\{before\_and\_after}(\|b,\39\|a,\39\|q)$;\6
+\&{end}\2\par
+\U433.\fi
+
+\M438. \P$\X438:Compute before-and-after \|y values based on the current pen\X%
+\S$\6
+\&{begin} \37\&{if} $\\{cur\_pen}=\\{null\_pen}$ \1\&{then}\5
+$\\{pen\_edge}\K0$\6
+\4\&{else} \&{if} $\\{cur\_path\_type}=\\{double\_path\_code}$ \1\&{then}\5
+$\\{pen\_edge}\K\\{compromise}(\\{north\_edge}(\\{cur\_pen}),\39\\{south%
+\_edge}(\\{cur\_pen}))$\6
+\4\&{else} \&{if} $\\{right\_type}(\|q)\L\\{negate\_y}$ \1\&{then}\5
+$\\{pen\_edge}\K\\{south\_edge}(\\{cur\_pen})$\6
+\4\&{else} $\\{pen\_edge}\K\\{north\_edge}(\\{cur\_pen})$;\2\2\2\6
+$\|a\K\\{good\_val}(\|b,\39\\{pen\_edge})$;\6
+\&{end}\par
+\U437.\fi
+
+\M439. \P$\X439:Transform the \|y coordinates\X\S$\6
+\&{begin} \37\\{make\_safe};\6
+\1\&{repeat} \37$\\{decr}(\\{cur\_rounding\_ptr})$;\6
+\&{if} $(\\{after}[\\{cur\_rounding\_ptr}]\I\\{before}[\\{cur\_rounding\_ptr}])%
+\V\30(\\{after}[\\{cur\_rounding\_ptr}+1]\I\\{before}[\\{cur\_rounding%
+\_ptr}+1])$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{node\_to\_round}[\\{cur\_rounding\_ptr}]$;\6
+\&{if} $\\{right\_type}(\|p)\L\\{negate\_y}$ \1\&{then}\6
+\&{begin} \37$\|b\K\\{before}[\\{cur\_rounding\_ptr}]$;\5
+$\|a\K\\{after}[\\{cur\_rounding\_ptr}]$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|b\K-\\{before}[\\{cur\_rounding\_ptr}]$;\5
+$\|a\K-\\{after}[\\{cur\_rounding\_ptr}]$;\6
+\&{end};\2\6
+\&{if} $\\{before}[\\{cur\_rounding\_ptr}]=\\{before}[\\{cur\_rounding%
+\_ptr}+1]$ \1\&{then}\5
+$\\{alpha}\K\\{fraction\_one}$\6
+\4\&{else} $\\{alpha}\K\\{make\_fraction}(\\{after}[\\{cur\_rounding\_ptr}+1]-%
+\\{after}[\\{cur\_rounding\_ptr}],\39\30\\{before}[\\{cur\_rounding\_ptr}+1]-%
+\\{before}[\\{cur\_rounding\_ptr}])$;\2\6
+\1\&{repeat} \37$\\{y\_coord}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{y%
+\_coord}(\|p)-\|b)+\|a$;\5
+$\\{right\_y}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{right\_y}(\|p)-\|b)+%
+\|a$;\5
+$\|p\K\\{link}(\|p)$;\5
+$\\{left\_y}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{left\_y}(\|p)-\|b)+\|a$;\6
+\4\&{until}\5
+$\|p=\\{node\_to\_round}[\\{cur\_rounding\_ptr}+1]$;\2\6
+\&{end};\2\6
+\4\&{until}\5
+$\\{cur\_rounding\_ptr}=0$;\2\6
+\&{end}\par
+\U433.\fi
+
+\M440. Rounding at diagonal tangents takes place after the subdivision into
+octants is complete, hence after the coordinates have been skewed.
+The details are somewhat tricky, because we want to round to points
+whose skewed coordinates are halfway between integer multiples of
+the granularity. Furthermore, both coordinates change when they are
+rounded; this means we need a generalization of the \\{make\_safe} routine,
+ensuring safety in both \|x and \|y.
+
+In spite of these extra complications, we can take comfort in the fact
+that the basic structure of the routine is the same as before.
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{diag\_round};\6
+\4\&{var} \37$\|p,\39\|q,\39\\{pp}$: \37\\{pointer};\C{list manipulation
+registers}\6
+$\|b,\39\|a,\39\\{bb},\39\\{aa},\39\|d,\39\|c,\39\\{dd},\39\\{cc}$: \37%
+\\{scaled};\C{before and after values}\6
+\\{pen\_edge}: \37\\{scaled};\C{offset that governs rounding}\6
+$\\{alpha},\39\\{beta}$: \37\\{fraction};\C{coefficients of linear
+transformation}\6
+\\{next\_a}: \37\\{scaled};\C{$\\{after}[\|k]$ before it might have changed}\6
+\\{all\_safe}: \37\\{boolean};\C{does everything look OK so far?}\6
+\|k: \37$0\to\\{max\_wiggle}$;\C{runs through before-and-after values}\6
+$\\{first\_x},\39\\{first\_y}$: \37\\{scaled};\C{coordinates before rounding}\2%
+\6
+\&{begin} \37$\|p\K\\{cur\_spec}$;\5
+$\\{cur\_rounding\_ptr}\K0$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|p)$;\5
+\X441:If node \|q is a transition point between octants, compute and save its
+before-and-after coordinates\X;\6
+$\|p\K\|q$;\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$;\2\6
+\&{if} $\\{cur\_rounding\_ptr}>0$ \1\&{then}\5
+\X444:Transform the skewed coordinates\X;\2\6
+\&{end};\par
+\fi
+
+\M441. We negate the skewed \|x coordinates in the before-and-after table when
+the octant code is greater than \\{switch\_x\_and\_y}.
+
+\Y\P$\4\X441:If node \|q is a transition point between octants, compute and
+save its before-and-after coordinates\X\S$\6
+\&{if} $\\{right\_type}(\|p)\I\\{right\_type}(\|q)$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{right\_type}(\|q)>\\{switch\_x\_and\_y}$ \1\&{then}\5
+$\|b\K-\\{x\_coord}(\|q)$\6
+\4\&{else} $\|b\K\\{x\_coord}(\|q)$;\2\6
+\&{if} $\\{abs}(\\{right\_type}(\|q)-\\{right\_type}(\|p))=\\{switch\_x\_and%
+\_y}$ \1\&{then}\6
+\&{if} $(\\{abs}(\\{x\_coord}(\|q)-\\{right\_x}(\|q))<655)\V(\\{abs}(\\{x%
+\_coord}(\|q)+\\{left\_x}(\|q))<655)$ \1\&{then}\5
+\X442:Compute a good coordinate at a diagonal transition\X\6
+\4\&{else} $\|a\K\|b$\2\6
+\4\&{else} $\|a\K\|b$;\2\6
+$\\{before\_and\_after}(\|b,\39\|a,\39\|q)$;\6
+\&{end}\2\par
+\U440.\fi
+
+\M442. In octants whose code number is even, $x$~has been
+negated; we want to round ambiguous cases downward instead of upward,
+so that the rounding will be consistent with octants whose code
+number is odd. This downward bias can be achieved by
+subtracting~1 from the first argument of \\{good\_val}.
+
+\Y\P\D \37$\\{diag\_offset}(\#)\S\\{x\_coord}(\\{knil}(\\{link}(\\{cur\_pen}+%
+\#)))$\par
+\Y\P$\4\X442:Compute a good coordinate at a diagonal transition\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_pen}=\\{null\_pen}$ \1\&{then}\5
+$\\{pen\_edge}\K0$\6
+\4\&{else} \&{if} $\\{cur\_path\_type}=\\{double\_path\_code}$ \1\&{then}\5
+\X443:Compute a compromise \\{pen\_edge}\X\6
+\4\&{else} \&{if} $\\{right\_type}(\|q)\L\\{switch\_x\_and\_y}$ \1\&{then}\5
+$\\{pen\_edge}\K\\{diag\_offset}(\\{right\_type}(\|q))$\6
+\4\&{else} $\\{pen\_edge}\K-\\{diag\_offset}(\\{right\_type}(\|q))$;\2\2\2\6
+\&{if} $\\{odd}(\\{right\_type}(\|q))$ \1\&{then}\5
+$\|a\K\\{good\_val}(\|b,\39\\{pen\_edge}+\\{half}(\\{cur\_gran}))$\6
+\4\&{else} $\|a\K\\{good\_val}(\|b-1,\39\\{pen\_edge}+\\{half}(\\{cur%
+\_gran}))$;\2\6
+\&{end}\par
+\U441.\fi
+
+\M443. (It seems a shame to compute these compromise offsets repeatedly. The
+author would have stored them directly in the pen data structure, if the
+granularity had been constant.)
+
+\Y\P$\4\X443:Compute a compromise \\{pen\_edge}\X\S$\6
+\&{case} $\\{right\_type}(\|q)$ \1\&{of}\6
+\4$\\{first\_octant},\39\\{second\_octant}$: \37$\\{pen\_edge}\K\\{compromise}(%
+\\{diag\_offset}(\\{first\_octant}),\39\30-\\{diag\_offset}(\\{fifth%
+\_octant}))$;\6
+\4$\\{fifth\_octant},\39\\{sixth\_octant}$: \37$\\{pen\_edge}\K-\\{compromise}(%
+\\{diag\_offset}(\\{first\_octant}),\39\30-\\{diag\_offset}(\\{fifth%
+\_octant}))$;\6
+\4$\\{third\_octant},\39\\{fourth\_octant}$: \37$\\{pen\_edge}\K\\{compromise}(%
+\\{diag\_offset}(\\{fourth\_octant}),\39\30-\\{diag\_offset}(\\{eighth%
+\_octant}))$;\6
+\4$\\{seventh\_octant},\39\\{eighth\_octant}$: \37$\\{pen\_edge}\K-%
+\\{compromise}(\\{diag\_offset}(\\{fourth\_octant}),\39\30-\\{diag\_offset}(%
+\\{eighth\_octant}))$;\2\6
+\&{end}\C{there are no other cases}\par
+\U442.\fi
+
+\M444. \P$\X444:Transform the skewed coordinates\X\S$\6
+\&{begin} \37$\|p\K\\{node\_to\_round}[0]$;\5
+$\\{first\_x}\K\\{x\_coord}(\|p)$;\5
+$\\{first\_y}\K\\{y\_coord}(\|p)$;\5
+\X446:Make sure that all the diagonal roundings are safe\X;\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{cur\_rounding\_ptr}-1$ \1\&{do}\6
+\&{begin} \37$\|a\K\\{after}[\|k]$;\5
+$\|b\K\\{before}[\|k]$;\5
+$\\{aa}\K\\{after}[\|k+1]$;\5
+$\\{bb}\K\\{before}[\|k+1]$;\6
+\&{if} $(\|a\I\|b)\V(\\{aa}\I\\{bb})$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{node\_to\_round}[\|k]$;\5
+$\\{pp}\K\\{node\_to\_round}[\|k+1]$;\5
+\X445:Determine the before-and-after values of both coordinates\X;\6
+\&{if} $\|b=\\{bb}$ \1\&{then}\5
+$\\{alpha}\K\\{fraction\_one}$\6
+\4\&{else} $\\{alpha}\K\\{make\_fraction}(\\{aa}-\|a,\39\\{bb}-\|b)$;\2\6
+\&{if} $\|d=\\{dd}$ \1\&{then}\5
+$\\{beta}\K\\{fraction\_one}$\6
+\4\&{else} $\\{beta}\K\\{make\_fraction}(\\{cc}-\|c,\39\\{dd}-\|d)$;\2\6
+\1\&{repeat} \37$\\{x\_coord}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{x%
+\_coord}(\|p)-\|b)+\|a$;\5
+$\\{y\_coord}(\|p)\K\\{take\_fraction}(\\{beta},\39\\{y\_coord}(\|p)-\|d)+\|c$;%
+\5
+$\\{right\_x}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{right\_x}(\|p)-\|b)+%
+\|a$;\5
+$\\{right\_y}(\|p)\K\\{take\_fraction}(\\{beta},\39\\{right\_y}(\|p)-\|d)+\|c$;%
+\5
+$\|p\K\\{link}(\|p)$;\5
+$\\{left\_x}(\|p)\K\\{take\_fraction}(\\{alpha},\39\\{left\_x}(\|p)-\|b)+\|a$;\5
+$\\{left\_y}(\|p)\K\\{take\_fraction}(\\{beta},\39\\{left\_y}(\|p)-\|d)+\|c$;\6
+\4\&{until}\5
+$\|p=\\{pp}$;\2\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end}\par
+\U440.\fi
+
+\M445. In node \|p, the coordinates $(\|b,\|d)$ will be rounded to $(\|a,\|c)$;
+in node \\{pp}, the coordinates $(\\{bb},\\{dd})$ will be rounded to $(\\{aa},%
+\\{cc})$.
+(We transform the values from node \\{pp} so that they agree with the
+conventions of node \|p.)
+
+If $\\{aa}\I\\{bb}$, we know that $\\{abs}(\\{right\_type}(\|p)-\\{right%
+\_type}(\\{pp}))=\\{switch\_x\_and\_y}$.
+
+\Y\P$\4\X445:Determine the before-and-after values of both coordinates\X\S$\6
+\&{if} $\\{aa}=\\{bb}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{pp}=\\{node\_to\_round}[0]$ \1\&{then}\5
+$\\{unskew}(\\{first\_x},\39\\{first\_y},\39\\{right\_type}(\\{pp}))$\6
+\4\&{else} $\\{unskew}(\\{x\_coord}(\\{pp}),\39\\{y\_coord}(\\{pp}),\39\\{right%
+\_type}(\\{pp}))$;\2\6
+$\\{skew}(\\{cur\_x},\39\\{cur\_y},\39\\{right\_type}(\|p))$;\5
+$\\{bb}\K\\{cur\_x}$;\5
+$\\{aa}\K\\{bb}$;\5
+$\\{dd}\K\\{cur\_y}$;\5
+$\\{cc}\K\\{dd}$;\6
+\&{if} $\\{right\_type}(\|p)>\\{switch\_x\_and\_y}$ \1\&{then}\6
+\&{begin} \37$\|b\K-\|b$;\5
+$\|a\K-\|a$;\6
+\&{end};\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{right\_type}(\|p)>\\{switch\_x\_and\_y}$ \1%
+\&{then}\6
+\&{begin} \37$\\{bb}\K-\\{bb}$;\5
+$\\{aa}\K-\\{aa}$;\5
+$\|b\K-\|b$;\5
+$\|a\K-\|a$;\6
+\&{end};\2\6
+\&{if} $\\{pp}=\\{node\_to\_round}[0]$ \1\&{then}\5
+$\\{dd}\K\\{first\_y}-\\{bb}$\ \&{else} $\\{dd}\K\\{y\_coord}(\\{pp})-\\{bb}$;%
+\2\6
+\&{if} $\\{odd}(\\{aa}-\\{bb})$ \1\&{then}\6
+\&{if} $\\{right\_type}(\|p)>\\{switch\_x\_and\_y}$ \1\&{then}\5
+$\\{cc}\K\\{dd}-\\{half}(\\{aa}-\\{bb}+1)$\6
+\4\&{else} $\\{cc}\K\\{dd}-\\{half}(\\{aa}-\\{bb}-1)$\2\6
+\4\&{else} $\\{cc}\K\\{dd}-\\{half}(\\{aa}-\\{bb})$;\2\6
+\&{end};\2\6
+$\|d\K\\{y\_coord}(\|p)$;\6
+\&{if} $\\{odd}(\|a-\|b)$ \1\&{then}\6
+\&{if} $\\{right\_type}(\|p)>\\{switch\_x\_and\_y}$ \1\&{then}\5
+$\|c\K\|d-\\{half}(\|a-\|b-1)$\6
+\4\&{else} $\|c\K\|d-\\{half}(\|a-\|b+1)$\2\6
+\4\&{else} $\|c\K\|d-\\{half}(\|a-\|b)$\2\par
+\Us444\ET446.\fi
+
+\M446. \P$\X446:Make sure that all the diagonal roundings are safe\X\S$\6
+$\\{before}[\\{cur\_rounding\_ptr}]\K\\{before}[0]$;\C{cf.~\\{make\_safe}}\6
+$\\{node\_to\_round}[\\{cur\_rounding\_ptr}]\K\\{node\_to\_round}[0]$;\6
+\1\&{repeat} \37$\\{after}[\\{cur\_rounding\_ptr}]\K\\{after}[0]$;\5
+$\\{all\_safe}\K\\{true}$;\5
+$\\{next\_a}\K\\{after}[0]$;\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{cur\_rounding\_ptr}-1$ \1\&{do}\6
+\&{begin} \37$\|a\K\\{next\_a}$;\5
+$\|b\K\\{before}[\|k]$;\5
+$\\{next\_a}\K\\{after}[\|k+1]$;\5
+$\\{aa}\K\\{next\_a}$;\5
+$\\{bb}\K\\{before}[\|k+1]$;\6
+\&{if} $(\|a\I\|b)\V(\\{aa}\I\\{bb})$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{node\_to\_round}[\|k]$;\5
+$\\{pp}\K\\{node\_to\_round}[\|k+1]$;\5
+\X445:Determine the before-and-after values of both coordinates\X;\6
+\&{if} $(\\{aa}<\|a)\V(\\{cc}<\|c)\V(\\{aa}-\|a>2\ast(\\{bb}-\|b))\V(\\{cc}-%
+\|c>2\ast(\\{dd}-\|d))$ \1\&{then}\6
+\&{begin} \37$\\{all\_safe}\K\\{false}$;\5
+$\\{after}[\|k]\K\\{before}[\|k]$;\6
+\&{if} $\|k=\\{cur\_rounding\_ptr}-1$ \1\&{then}\5
+$\\{after}[0]\K\\{before}[0]$\6
+\4\&{else} $\\{after}[\|k+1]\K\\{before}[\|k+1]$;\2\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\2\6
+\4\&{until}\5
+\\{all\_safe}\2\par
+\U444.\fi
+
+\M447. Here we get rid of ``dead'' cubics, i.e., polynomials that don't move at
+all when \|t~changes, since the subdivision process might have introduced
+such things. If the cycle reduces to a single point, however, we are left
+with a single dead cubic that will not be removed until later.
+
+\Y\P$\4\X447:Remove dead cubics\X\S$\6
+$\|p\K\\{cur\_spec}$;\6
+\1\&{repeat} \37\\{continue}: \37$\|q\K\\{link}(\|p)$;\6
+\&{if} $\|p\I\|q$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{x\_coord}(\|p)=\\{right\_x}(\|p)$ \1\&{then}\6
+\&{if} $\\{y\_coord}(\|p)=\\{right\_y}(\|p)$ \1\&{then}\6
+\&{if} $\\{x\_coord}(\|p)=\\{left\_x}(\|q)$ \1\&{then}\6
+\&{if} $\\{y\_coord}(\|p)=\\{left\_y}(\|q)$ \1\&{then}\6
+\&{begin} \37$\\{unskew}(\\{x\_coord}(\|q),\39\\{y\_coord}(\|q),\39\\{right%
+\_type}(\|q))$;\5
+$\\{skew}(\\{cur\_x},\39\\{cur\_y},\39\\{right\_type}(\|p))$;\6
+\&{if} $\\{x\_coord}(\|p)=\\{cur\_x}$ \1\&{then}\6
+\&{if} $\\{y\_coord}(\|p)=\\{cur\_y}$ \1\&{then}\6
+\&{begin} \37$\\{remove\_cubic}(\|p)$;\C{remove the cubic following \|p}\6
+\&{if} $\|q\I\\{cur\_spec}$ \1\&{then}\5
+\&{goto} \37\\{continue};\2\6
+$\\{cur\_spec}\K\|p$;\5
+$\|q\K\|p$;\6
+\&{end};\2\2\6
+\&{end};\2\2\2\2\6
+\&{end};\2\6
+$\|p\K\|q$;\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$;\2\par
+\U402.\fi
+
+\M448. Finally we come to the last steps of \\{make\_spec}, when boundary nodes
+are inserted between cubics that move in different octants. The main
+complication remaining arises from consecutive cubics whose octants
+are not adjacent; we should insert more than one octant boundary
+at such sharp turns, so that the envelope-forming routine will work.
+
+For this purpose, conversion tables between numeric and Gray codes for
+octants are desirable.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{octant\_number}: \37\&{array} $[\\{first\_octant}\to\\{sixth\_octant}]$ \1%
+\&{of}\5
+$1\to8$;\2\6
+\4\\{octant\_code}: \37\&{array} $[1\to8]$ \1\&{of}\5
+$\\{first\_octant}\to\\{sixth\_octant}$;\2\par
+\fi
+
+\M449. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{octant\_code}[1]\K\\{first\_octant}$;\5
+$\\{octant\_code}[2]\K\\{second\_octant}$;\5
+$\\{octant\_code}[3]\K\\{third\_octant}$;\5
+$\\{octant\_code}[4]\K\\{fourth\_octant}$;\5
+$\\{octant\_code}[5]\K\\{fifth\_octant}$;\5
+$\\{octant\_code}[6]\K\\{sixth\_octant}$;\5
+$\\{octant\_code}[7]\K\\{seventh\_octant}$;\5
+$\\{octant\_code}[8]\K\\{eighth\_octant}$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}8$ \1\&{do}\5
+$\\{octant\_number}[\\{octant\_code}[\|k]]\K\|k$;\2\par
+\fi
+
+\M450. The main loop for boundary insertion deals with three consecutive
+nodes $\|p,\|q,\|r$.
+
+\Y\P$\4\X450:Insert octant boundaries and compute the turning number\X\S$\6
+$\\{turning\_number}\K0$;\5
+$\|p\K\\{cur\_spec}$;\5
+$\|q\K\\{link}(\|p)$;\6
+\1\&{repeat} \37$\|r\K\\{link}(\|q)$;\6
+\&{if} $(\\{right\_type}(\|p)\I\\{right\_type}(\|q))\V(\|q=\|r)$ \1\&{then}\5
+\X452:Insert one or more octant boundary nodes just before~\|q\X;\2\6
+$\|p\K\|q$;\5
+$\|q\K\|r$;\6
+\4\&{until}\5
+$\|p=\\{cur\_spec}$;\2\par
+\U402.\fi
+
+\M451. The \\{new\_boundary} subroutine comes in handy at this point. It
+inserts
+a new boundary node just after a given node \|p, using a given octant code
+to transform the new node's coordinates. The ``transition'' fields are
+not computed here.
+
+\Y\P$\4\X405:Declare subroutines needed by \\{make\_spec}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{new\_boundary}(\|p:\\{pointer};\,\35\\{octant}:%
+\\{small\_number})$;\6
+\4\&{var} \37$\|q,\39\|r$: \37\\{pointer};\C{for list manipulation}\2\6
+\&{begin} \37$\|q\K\\{link}(\|p)$;\C{we assume that $\\{right\_type}(\|q)\I%
+\\{endpoint}$}\6
+$\|r\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{link}(\|r)\K\|q$;\5
+$\\{link}(\|p)\K\|r$;\5
+$\\{left\_type}(\|r)\K\\{left\_type}(\|q)$;\C{but possibly $\\{left\_type}(%
+\|q)=\\{endpoint}$}\6
+$\\{left\_x}(\|r)\K\\{left\_x}(\|q)$;\5
+$\\{left\_y}(\|r)\K\\{left\_y}(\|q)$;\5
+$\\{right\_type}(\|r)\K\\{endpoint}$;\5
+$\\{left\_type}(\|q)\K\\{endpoint}$;\5
+$\\{right\_octant}(\|r)\K\\{octant}$;\5
+$\\{left\_octant}(\|q)\K\\{right\_type}(\|q)$;\5
+$\\{unskew}(\\{x\_coord}(\|q),\39\\{y\_coord}(\|q),\39\\{right\_type}(\|q))$;\5
+$\\{skew}(\\{cur\_x},\39\\{cur\_y},\39\\{octant})$;\5
+$\\{x\_coord}(\|r)\K\\{cur\_x}$;\5
+$\\{y\_coord}(\|r)\K\\{cur\_y}$;\6
+\&{end};\par
+\fi
+
+\M452. The case $\|q=\|r$ occurs if and only if $\|p=\|q=\|r=\\{cur\_spec}$,
+when we want to turn
+$360^\circ$ in eight steps and then remove a solitary dead cubic.
+The program below happens to work in that case, but the reader isn't
+expected to understand why.
+
+\Y\P$\4\X452:Insert one or more octant boundary nodes just before~\|q\X\S$\6
+\&{begin} \37$\\{new\_boundary}(\|p,\39\\{right\_type}(\|p))$;\5
+$\|s\K\\{link}(\|p)$;\5
+$\\{o1}\K\\{octant\_number}[\\{right\_type}(\|p)]$;\5
+$\\{o2}\K\\{octant\_number}[\\{right\_type}(\|q)]$;\6
+\&{case} $\\{o2}-\\{o1}$ \1\&{of}\6
+\4$1,\39-7,\397,\39-1$: \37\&{goto} \37\\{done};\6
+\4$2,\39-6$: \37$\\{clockwise}\K\\{false}$;\6
+\4$3,\39-5,\394,\39-4,\395,\39-3$: \37\X454:Decide whether or not to go
+clockwise\X;\6
+\4$6,\39-2$: \37$\\{clockwise}\K\\{true}$;\6
+\40: \37$\\{clockwise}\K\\{rev\_turns}$;\2\6
+\&{end};\C{there are no other cases}\6
+\X458:Insert additional boundary nodes, then \&{goto} \\{done}\X;\6
+\4\\{done}: \37\&{if} $\|q=\|r$ \1\&{then}\6
+\&{begin} \37$\|q\K\\{link}(\|q)$;\5
+$\|r\K\|q$;\5
+$\|p\K\|s$;\5
+$\\{link}(\|s)\K\|q$;\5
+$\\{left\_octant}(\|q)\K\\{right\_octant}(\|q)$;\5
+$\\{left\_type}(\|q)\K\\{endpoint}$;\5
+$\\{free\_node}(\\{cur\_spec},\39\\{knot\_node\_size})$;\5
+$\\{cur\_spec}\K\|q$;\6
+\&{end};\2\6
+\X459:Fix up the transition fields and adjust the turning number\X;\6
+\&{end}\par
+\U450.\fi
+
+\M453. \P$\X453:Other local variables for \\{make\_spec}\X\S$\6
+\4$\\{o1},\39\\{o2}$: \37\\{small\_number};\C{octant numbers}\6
+\4\\{clockwise}: \37\\{boolean};\C{should we turn clockwise?}\6
+\4$\\{dx1},\39\\{dy1},\39\\{dx2},\39\\{dy2}$: \37\\{integer};\C{directions of
+travel at a cusp}\6
+\4$\\{dmax},\39\\{del}$: \37\\{integer};\C{temporary registers}\par
+\U402.\fi
+
+\M454. A tricky question arises when a path jumps four octants. We want the
+direction of turning to be counterclockwise if the curve has changed
+direction by $180^\circ$, or by something so close to $180^\circ$ that
+the difference is probably due to rounding errors; otherwise we want to
+turn through an angle of less than $180^\circ$. This decision needs to
+be made even when a curve seems to have jumped only three octants, since
+a curve may approach direction $(-1,0)$ from the fourth octant, then
+it might leave from direction $(+1,0)$ into the first.
+
+The following code solves the problem by analyzing the incoming
+direction $(\\{dx1},\\{dy1})$ and the outgoing direction $(\\{dx2},\\{dy2})$.
+
+\Y\P$\4\X454:Decide whether or not to go clockwise\X\S$\6
+\&{begin} \37\X457:Compute the incoming and outgoing directions\X;\6
+$\\{unskew}(\\{dx1},\39\\{dy1},\39\\{right\_type}(\|p))$;\5
+$\\{del}\K\\{pyth\_add}(\\{cur\_x},\39\\{cur\_y})$;\6
+$\\{dx1}\K\\{make\_fraction}(\\{cur\_x},\39\\{del})$;\5
+$\\{dy1}\K\\{make\_fraction}(\\{cur\_y},\39\\{del})$;\C{$\cos\theta_1$ and $%
+\sin\theta_1$}\6
+$\\{unskew}(\\{dx2},\39\\{dy2},\39\\{right\_type}(\|q))$;\5
+$\\{del}\K\\{pyth\_add}(\\{cur\_x},\39\\{cur\_y})$;\6
+$\\{dx2}\K\\{make\_fraction}(\\{cur\_x},\39\\{del})$;\5
+$\\{dy2}\K\\{make\_fraction}(\\{cur\_y},\39\\{del})$;\C{$\cos\theta_2$ and $%
+\sin\theta_2$}\6
+$\\{del}\K\\{take\_fraction}(\\{dx1},\39\\{dy2})-\\{take\_fraction}(\\{dx2},\39%
+\\{dy1})$;\C{$\sin(\theta_2-\theta_1)$}\6
+\&{if} $\\{del}>4684844$ \1\&{then}\5
+$\\{clockwise}\K\\{false}$\6
+\4\&{else} \&{if} $\\{del}<-4684844$ \1\&{then}\5
+$\\{clockwise}\K\\{true}$\C{$2^{28}\cdot\sin 1^\circ\approx4684844.68$}\6
+\4\&{else} $\\{clockwise}\K\\{rev\_turns}$;\2\2\6
+\&{end}\par
+\U452.\fi
+
+\M455. Actually the turnarounds just computed will be clockwise,
+not counterclockwise, if
+the global variable \\{rev\_turns} is \\{true}; it is usually \\{false}.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{rev\_turns}: \37\\{boolean};\C{should we make U-turns in the English
+manner?}\par
+\fi
+
+\M456. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{rev\_turns}\K\\{false}$;\par
+\fi
+
+\M457. \P$\X457:Compute the incoming and outgoing directions\X\S$\6
+$\\{dx1}\K\\{x\_coord}(\|s)-\\{left\_x}(\|s)$;\5
+$\\{dy1}\K\\{y\_coord}(\|s)-\\{left\_y}(\|s)$;\6
+\&{if} $\\{dx1}=0$ \1\&{then}\6
+\&{if} $\\{dy1}=0$ \1\&{then}\6
+\&{begin} \37$\\{dx1}\K\\{x\_coord}(\|s)-\\{right\_x}(\|p)$;\5
+$\\{dy1}\K\\{y\_coord}(\|s)-\\{right\_y}(\|p)$;\6
+\&{if} $\\{dx1}=0$ \1\&{then}\6
+\&{if} $\\{dy1}=0$ \1\&{then}\6
+\&{begin} \37$\\{dx1}\K\\{x\_coord}(\|s)-\\{x\_coord}(\|p)$;\5
+$\\{dy1}\K\\{y\_coord}(\|s)-\\{y\_coord}(\|p)$;\6
+\&{end};\C{and they {\sl can't} both be zero}\2\2\6
+\&{end};\2\2\6
+$\\{dmax}\K\\{abs}(\\{dx1})$;\ \&{if} $\\{abs}(\\{dy1})>\\{dmax}$ \1\&{then}\5
+$\\{dmax}\K\\{abs}(\\{dy1})$;\2\6
+\&{while} $\\{dmax}<\\{fraction\_one}$ \1\&{do}\6
+\&{begin} \37$\\{double}(\\{dmax})$;\5
+$\\{double}(\\{dx1})$;\5
+$\\{double}(\\{dy1})$;\6
+\&{end};\2\6
+$\\{dx2}\K\\{right\_x}(\|q)-\\{x\_coord}(\|q)$;\5
+$\\{dy2}\K\\{right\_y}(\|q)-\\{y\_coord}(\|q)$;\6
+\&{if} $\\{dx2}=0$ \1\&{then}\6
+\&{if} $\\{dy2}=0$ \1\&{then}\6
+\&{begin} \37$\\{dx2}\K\\{left\_x}(\|r)-\\{x\_coord}(\|q)$;\5
+$\\{dy2}\K\\{left\_y}(\|r)-\\{y\_coord}(\|q)$;\6
+\&{if} $\\{dx2}=0$ \1\&{then}\6
+\&{if} $\\{dy2}=0$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{right\_type}(\|r)=\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_x}\K\\{x\_coord}(\|r)$;\5
+$\\{cur\_y}\K\\{y\_coord}(\|r)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{unskew}(\\{x\_coord}(\|r),\39\\{y\_coord}(\|r),\39%
+\\{right\_type}(\|r))$;\5
+$\\{skew}(\\{cur\_x},\39\\{cur\_y},\39\\{right\_type}(\|q))$;\6
+\&{end};\2\6
+$\\{dx2}\K\\{cur\_x}-\\{x\_coord}(\|q)$;\5
+$\\{dy2}\K\\{cur\_y}-\\{y\_coord}(\|q)$;\6
+\&{end};\C{and they {\sl can't} both be zero}\2\2\6
+\&{end};\2\2\6
+$\\{dmax}\K\\{abs}(\\{dx2})$;\ \&{if} $\\{abs}(\\{dy2})>\\{dmax}$ \1\&{then}\5
+$\\{dmax}\K\\{abs}(\\{dy2})$;\2\6
+\&{while} $\\{dmax}<\\{fraction\_one}$ \1\&{do}\6
+\&{begin} \37$\\{double}(\\{dmax})$;\5
+$\\{double}(\\{dx2})$;\5
+$\\{double}(\\{dy2})$;\6
+\&{end}\2\par
+\U454.\fi
+
+\M458. \P$\X458:Insert additional boundary nodes, then \&{goto} \\{done}\X\S$\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\\{clockwise}$ \1\&{then}\6
+\&{if} $\\{o1}=1$ \1\&{then}\5
+$\\{o1}\K8$\ \&{else} $\\{decr}(\\{o1})$\2\6
+\4\&{else} \&{if} $\\{o1}=8$ \1\&{then}\5
+$\\{o1}\K1$\ \&{else} $\\{incr}(\\{o1})$;\2\2\6
+\&{if} $\\{o1}=\\{o2}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{new\_boundary}(\|s,\39\\{octant\_code}[\\{o1}])$;\5
+$\|s\K\\{link}(\|s)$;\5
+$\\{left\_octant}(\|s)\K\\{right\_octant}(\|s)$;\6
+\&{end}\2\par
+\U452.\fi
+
+\M459. Now it remains to insert the redundant
+transition information into the \\{left\_transition}
+and \\{right\_transition} fields between adjacent octants, in the octant
+boundary nodes that have just been inserted between $\\{link}(\|p)$ and~\|q.
+The turning number is easily computed from these transitions.
+
+\Y\P$\4\X459:Fix up the transition fields and adjust the turning number\X\S$\6
+$\|p\K\\{link}(\|p)$;\6
+\1\&{repeat} \37$\|s\K\\{link}(\|p)$;\5
+$\\{o1}\K\\{octant\_number}[\\{right\_octant}(\|p)]$;\5
+$\\{o2}\K\\{octant\_number}[\\{left\_octant}(\|s)]$;\6
+\&{if} $\\{abs}(\\{o1}-\\{o2})=1$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{o2}<\\{o1}$ \1\&{then}\5
+$\\{o2}\K\\{o1}$;\2\6
+\&{if} $\\{odd}(\\{o2})$ \1\&{then}\5
+$\\{right\_transition}(\|p)\K\\{axis}$\6
+\4\&{else} $\\{right\_transition}(\|p)\K\\{diagonal}$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{o1}=8$ \1\&{then}\5
+$\\{incr}(\\{turning\_number})$\ \&{else} $\\{decr}(\\{turning\_number})$;\2\6
+$\\{right\_transition}(\|p)\K\\{axis}$;\6
+\&{end};\2\6
+$\\{left\_transition}(\|s)\K\\{right\_transition}(\|p)$;\5
+$\|p\K\|s$;\6
+\4\&{until}\5
+$\|p=\|q$\2\par
+\U452.\fi
+
+\N460. \[22] Filling a contour.
+Given the low-level machinery for making moves and for transforming a
+cyclic path into a cycle spec, we're almost able to fill a digitized path.
+All we need is a high-level routine that walks through the cycle spec and
+controls the overall process.
+
+Our overall goal is to plot the integer points $\bigl(\round(x(t)),
+\round(y(t))\bigr)$ and to connect them by rook moves, assuming that
+$\round(x(t))$ and $\round(y(t))$ don't both jump simultaneously from
+one integer to another as $t$~varies; these rook moves will be the edge
+of the contour that will be filled. We have reduced this problem to the
+case of curves that travel in first octant directions, i.e., curves
+such that $0\L y'(t)\L x'(t)$, by transforming the original coordinates.
+
+\def\xtilde{{\tilde x}} \def\ytilde{{\tilde y}}
+Another transformation makes the problem still simpler. We shall say that
+we are working with {\sl biased coordinates\/} when $(x,y)$ has been
+replaced by $(\xtilde,\ytilde)=(x-y,y+{1\over2})$. When a curve travels
+in first octant directions, the corresponding curve with biased
+coordinates travels in first {\sl quadrant\/} directions; the latter
+condition is symmetric in $x$ and~$y$, so it has advantages for the
+design of algorithms. The \\{make\_spec} routine gives us skewed coordinates
+$(x-y,y)$, hence we obtain biased coordinates by simply adding $1\over2$
+to the second component.
+
+The most important fact about biased coordinates is that we can determine the
+rounded unbiased path $\bigl(\round(x(t)),\round(y(t))\bigr)$ from the
+truncated biased path $\bigl(\lfloor\xtilde(t)\rfloor,\lfloor\ytilde(t)\rfloor
+\bigr)$ and information about the initial and final endpoints. If the
+unrounded and unbiased
+path begins at $(x_0,y_0)$ and ends at $(x_1,y_1)$, it's possible to
+prove (by induction on the length of truncated biased path) that the
+rounded unbiased path is obtained by the following construction:
+
+\yskip\textindent{1)} Start at $\bigl(\round(x_0),\round(y_0)\bigr)$.
+
+\yskip\textindent{2)} If $(x_0+{1\over2})\bmod1\G(y_0+{1\over2})\bmod1$,
+move one step right.
+
+\yskip\textindent{3)} Whenever the path
+$\bigl(\lfloor\xtilde(t)\rfloor,\lfloor\ytilde(t)\rfloor\bigr)$
+takes an upward step (i.e., when
+$\lfloor\xtilde(t+\epsilon)\rfloor=\lfloor\xtilde(t)\rfloor$ and
+$\lfloor\ytilde(t+\epsilon)\rfloor=\lfloor\ytilde(t)\rfloor+1$),
+move one step up and then one step right.
+
+\yskip\textindent{4)} Whenever the path
+$\bigl(\lfloor\xtilde(t)\rfloor,\lfloor\ytilde(t)\rfloor\bigr)$
+takes a rightward step (i.e., when
+$\lfloor\xtilde(t+\epsilon)\rfloor=\lfloor\xtilde(t)\rfloor+1$ and
+$\lfloor\ytilde(t+\epsilon)\rfloor=\lfloor\ytilde(t)\rfloor$),
+move one step right.
+
+\yskip\textindent{5)} Finally, if
+$(x_1+{1\over2})\bmod1\G(y_1+{1\over2})\bmod1$, move one step left (thereby
+cancelling the previous move, which was one step right). You will now be
+at the point $\bigl(\round(x_1),\round(y_1)\bigr)$.
+
+\fi
+
+\M461. In order to validate the assumption that $\round(x(t))$ and $%
+\round(y(t))$
+don't both jump simultaneously, we shall consider that a coordinate pair
+$(x,y)$ actually represents $(x+\epsilon,y+\epsilon\delta)$, where
+$\epsilon$ and $\delta$ are extremely small positive numbers---so small
+that their precise values never matter. This convention makes rounding
+unambiguous, since there is always a unique integer point nearest to any
+given scaled numbers~$(x,y)$.
+
+When coordinates are transformed so that \MF\ needs to work only in ``first
+octant'' directions, the transformations involve negating~$x$, negating~$y$,
+and/or interchanging $x$ with~$y$. Corresponding adjustments to the
+rounding conventions must be made so that consistent values will be
+obtained. For example, suppose that we're working with coordinates that
+have been transformed so that a third-octant curve travels in first-octant
+directions. The skewed coordinates $(x,y)$ in our data structure represent
+unskewed coordinates $(-y,x+y)$, which are actually $(-y+\epsilon,
+x+y+\epsilon\delta)$. We should therefore round as if our skewed coordinates
+were $(x+\epsilon+\epsilon\delta,y-\epsilon)$ instead of $(x,y)$. The following
+table shows how the skewed coordinates should be perturbed when rounding
+decisions are made:
+$$\vcenter{\halign{#\hfil&&\quad$#$\hfil&\hskip4em#\hfil\cr
+\\{first\_octant}&(x+\epsilon-\epsilon\delta,y+\epsilon\delta)&
+\\{fifth\_octant}&(x-\epsilon+\epsilon\delta,y-\epsilon\delta)\cr
+\\{second\_octant}&(x-\epsilon+\epsilon\delta,y+\epsilon)&
+\\{sixth\_octant}&(x+\epsilon-\epsilon\delta,y-\epsilon)\cr
+\\{third\_octant}&(x+\epsilon+\epsilon\delta,y-\epsilon)&
+\\{seventh\_octant}&(x-\epsilon-\epsilon\delta,y+\epsilon)\cr
+\\{fourth\_octant}&(x-\epsilon-\epsilon\delta,y+\epsilon\delta)&
+\\{eighth\_octant}&(x+\epsilon+\epsilon\delta,y-\epsilon\delta)\cr}}$$
+
+Four small arrays are set up so that the rounding operations will be
+fairly easy in any given octant.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{y\_corr},\39\\{xy\_corr},\39\\{z\_corr}$: \37\&{array} $[\\{first%
+\_octant}\to\\{sixth\_octant}]$ \1\&{of}\5
+$0\to1$;\2\6
+\4\\{x\_corr}: \37\&{array} $[\\{first\_octant}\to\\{sixth\_octant}]$ \1\&{of}\5
+$-1\to1$;\2\par
+\fi
+
+\M462. Here \\{xy\_corr} is 1 if and only if the $x$ component of a skewed
+coordinate
+is to be decreased by an infinitesimal amount; \\{y\_corr} is similar, but for
+the $y$ components. The other tables are set up so that the condition
+$$(x+y+\\{half\_unit})\bmod\\{unity}\G(y+\\{half\_unit})\bmod\\{unity}$$
+is properly perturbed to the condition
+$$(x+y+\\{half\_unit}-\\{x\_corr}-\\{y\_corr})\bmod\\{unity}\G
+(y+\\{half\_unit}-\\{y\_corr})\bmod\\{unity}+\\{z\_corr}.$$
+
+\Y\P$\4\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{x\_corr}[\\{first\_octant}]\K0$;\5
+$\\{y\_corr}[\\{first\_octant}]\K0$;\5
+$\\{xy\_corr}[\\{first\_octant}]\K0$;\6
+$\\{x\_corr}[\\{second\_octant}]\K0$;\5
+$\\{y\_corr}[\\{second\_octant}]\K0$;\5
+$\\{xy\_corr}[\\{second\_octant}]\K1$;\6
+$\\{x\_corr}[\\{third\_octant}]\K-1$;\5
+$\\{y\_corr}[\\{third\_octant}]\K1$;\5
+$\\{xy\_corr}[\\{third\_octant}]\K0$;\6
+$\\{x\_corr}[\\{fourth\_octant}]\K1$;\5
+$\\{y\_corr}[\\{fourth\_octant}]\K0$;\5
+$\\{xy\_corr}[\\{fourth\_octant}]\K1$;\6
+$\\{x\_corr}[\\{fifth\_octant}]\K0$;\5
+$\\{y\_corr}[\\{fifth\_octant}]\K1$;\5
+$\\{xy\_corr}[\\{fifth\_octant}]\K1$;\6
+$\\{x\_corr}[\\{sixth\_octant}]\K0$;\5
+$\\{y\_corr}[\\{sixth\_octant}]\K1$;\5
+$\\{xy\_corr}[\\{sixth\_octant}]\K0$;\6
+$\\{x\_corr}[\\{seventh\_octant}]\K1$;\5
+$\\{y\_corr}[\\{seventh\_octant}]\K0$;\5
+$\\{xy\_corr}[\\{seventh\_octant}]\K1$;\6
+$\\{x\_corr}[\\{eighth\_octant}]\K-1$;\5
+$\\{y\_corr}[\\{eighth\_octant}]\K1$;\5
+$\\{xy\_corr}[\\{eighth\_octant}]\K0$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}8$ \1\&{do}\5
+$\\{z\_corr}[\|k]\K\\{xy\_corr}[\|k]-\\{x\_corr}[\|k]$;\2\par
+\fi
+
+\M463. Here's a procedure that handles the details of rounding at the
+endpoints: Given skewed coordinates $(\|x,\|y)$, it sets $(\\{m1},\\{n1})$
+to the corresponding rounded lattice points, taking the current
+\\{octant} into account. Global variable \\{d1} is also set to 1 if
+$(x+y+{1\over2})\bmod1\G(y+{1\over2})\bmod1$.
+
+\Y\P\4\&{procedure}\1\ \37$\\{end\_round}(\|x,\39\|y:\\{scaled})$;\2\6
+\&{begin} \37$\|y\K\|y+\\{half\_unit}-\\{y\_corr}[\\{octant}]$;\5
+$\|x\K\|x+\|y-\\{x\_corr}[\\{octant}]$;\5
+$\\{m1}\K\\{floor\_unscaled}(\|x)$;\5
+$\\{n1}\K\\{floor\_unscaled}(\|y)$;\6
+\&{if} $\|x-\\{unity}\ast\\{m1}\G\|y-\\{unity}\ast\\{n1}+\\{z\_corr}[%
+\\{octant}]$ \1\&{then}\5
+$\\{d1}\K1$\ \&{else} $\\{d1}\K0$;\2\6
+\&{end};\par
+\fi
+
+\M464. The outputs $(\\{m1},\\{n1},\\{d1})$ of \\{end\_round} will sometimes be
+moved
+to $(\\{m0},\\{n0},\\{d0})$.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{m0},\39\\{n0},\39\\{m1},\39\\{n1}$: \37\\{integer};\C{lattice point
+coordinates}\6
+\4$\\{d0},\39\\{d1}$: \37$0\to1$;\C{displacement corrections}\par
+\fi
+
+\M465. We're ready now to fill the pixels enclosed by a given cycle spec~\|h;
+the knot list that represents the cycle is destroyed in the process.
+The edge structure that gets all the resulting data is \\{cur\_edges},
+and the edges are weighted by \\{cur\_wt}.
+
+\Y\P\4\&{procedure}\1\ \37$\\{fill\_spec}(\|h:\\{pointer})$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{for list traversal}%
+\2\6
+\&{begin} \37\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+\\{begin\_edge\_tracing};\2\6
+$\|p\K\|h$;\C{we assume that $\\{left\_type}(\|h)=\\{endpoint}$}\6
+\1\&{repeat} \37$\\{octant}\K\\{left\_octant}(\|p)$;\5
+\X466:Set variable \|q to the node at the end of the current octant\X;\6
+\&{if} $\|q\I\|p$ \1\&{then}\6
+\&{begin} \37\X467:Determine the starting and ending lattice points $(\\{m0},%
+\\{n0})$ and $(\\{m1},\\{n1})$\X;\6
+\X468:Make the moves for the current octant\X;\6
+$\\{move\_to\_edges}(\\{m0},\39\\{n0},\39\\{m1},\39\\{n1})$;\6
+\&{end};\2\6
+$\|p\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\|p=\|h$;\2\6
+$\\{toss\_knot\_list}(\|h)$;\6
+\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+\\{end\_edge\_tracing};\2\6
+\&{end};\par
+\fi
+
+\M466. \P$\X466:Set variable \|q to the node at the end of the current octant\X%
+\S$\6
+$\|q\K\|p$;\6
+\&{while} $\\{right\_type}(\|q)\I\\{endpoint}$ \1\&{do}\5
+$\|q\K\\{link}(\|q)$\2\par
+\Us465, 506\ETs506.\fi
+
+\M467. \P$\X467:Determine the starting and ending lattice points $(\\{m0},%
+\\{n0})$ and $(\\{m1},\\{n1})$\X\S$\6
+$\\{end\_round}(\\{x\_coord}(\|p),\39\\{y\_coord}(\|p))$;\5
+$\\{m0}\K\\{m1}$;\5
+$\\{n0}\K\\{n1}$;\5
+$\\{d0}\K\\{d1}$;\6
+$\\{end\_round}(\\{x\_coord}(\|q),\39\\{y\_coord}(\|q))$\par
+\U465.\fi
+
+\M468. Finally we perform the five-step process that was explained at
+the very beginning of this part of the program.
+
+\Y\P$\4\X468:Make the moves for the current octant\X\S$\6
+\&{if} $\\{n1}-\\{n0}\G\\{move\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"move\ table\ size"},\39\\{move\_size})$;\2\6
+$\\{move}[0]\K\\{d0}$;\5
+$\\{move\_ptr}\K0$;\5
+$\|r\K\|p$;\6
+\1\&{repeat} \37$\|s\K\\{link}(\|r)$;\6
+$\\{make\_moves}(\\{x\_coord}(\|r),\39\\{right\_x}(\|r),\39\\{left\_x}(\|s),\39%
+\\{x\_coord}(\|s),\39\30\\{y\_coord}(\|r)+\\{half\_unit},\39\\{right\_y}(\|r)+%
+\\{half\_unit},\39\\{left\_y}(\|s)+\\{half\_unit},\39\\{y\_coord}(\|s)+\\{half%
+\_unit},\39\30\\{xy\_corr}[\\{octant}],\39\\{y\_corr}[\\{octant}])$;\5
+$\|r\K\|s$;\6
+\4\&{until}\5
+$\|r=\|q$;\2\6
+$\\{move}[\\{move\_ptr}]\K\\{move}[\\{move\_ptr}]-\\{d1}$;\6
+\&{if} $\\{internal}[\\{smoothing}]>0$ \1\&{then}\5
+$\\{smooth\_moves}(0,\39\\{move\_ptr})$\2\par
+\U465.\fi
+
+\N469. \[23] Polygonal pens.
+The next few parts of the program deal with the additional complications
+associated with ``envelopes,'' leading up to an algorithm that fills a
+contour with respect to a pen whose boundary is a convex polygon. The
+mathematics underlying this algorithm is based on simple aspects of the
+theory of tracings developed by Leo Guibas, Lyle Ramshaw, and Jorge
+Stolfi [``A kinetic framework for computational geometry,''
+{\sl Proc.\ IEEE Symp.\ Foundations of Computer Science\/ \bf24} (1983),
+100--111].
+
+If the vertices of the polygon are $w_0$, $w_1$, \dots, $w_{n-1}$, $w_n=w_0$,
+in counterclockwise order, the convexity condition requires that ``left
+turns'' are made at each vertex when a person proceeds from $w_0$ to
+$w_1$ to $\cdots$ to~$w_n$. The envelope is obtained if we offset a given
+curve $z(t)$ by $w_k$ when that curve is traveling in a direction
+$z'(t)$ lying between the directions $w_k-w_{k-1}$ and $w\k-w_k$.
+At times~$t$ when the curve direction $z'(t)$ increases past
+$w\k-w_k$, we temporarily stop plotting the offset curve and we insert
+a straight line from $z(t)+w_k$ to $z(t)+w\k$; notice that this straight
+line is tangent to the offset curve. Similarly, when the curve direction
+decreases past $w_k-w_{k-1}$, we stop plotting and insert a straight
+line from $z(t)+w_k$ to $z(t)+w_{k-1}$; the latter line is actually a
+``retrograde'' step, which won't be part of the final envelope under
+\MF's assumptions. The result of this construction is a continuous path
+that consists of alternating curves and straight line segments. The
+segments are usually so short, in practice, that they blend with the
+curves; after all, it's possible to represent any digitized path as
+a sequence of digitized straight lines.
+
+The nicest feature of this approach to envelopes is that it blends
+perfectly with the octant subdivision process we have already developed.
+The envelope travels in the same direction as the curve itself, as we
+plot it, and we need merely be careful what offset is being added.
+Retrograde motion presents a problem, but we will see that there is
+a decent way to handle it.
+
+\fi
+
+\M470. We shall represent pens by maintaining eight lists of offsets,
+one for each octant direction. The offsets at the boundary points
+where a curve turns into a new octant will appear in the lists for
+both octants. This means that we can restrict consideration to
+segments of the original polygon whose directions aim in the first
+octant, as we have done in the simpler case when envelopes were not
+required.
+
+An example should help to clarify this situation: Consider the
+quadrilateral whose vertices are $w_0=(0,-1)$, $w_1=(3,-1)$,
+$w_2=(6,1)$, and $w_3=(1,2)$. A curve that travels in the first octant
+will be offset by $w_1$ or $w_2$, unless its slope drops to zero
+en route to the eighth octant; in the latter case we should switch to $w_0$ as
+we cross the octant boundary. Our list for the first octant will
+contain the three offsets $w_0$, $w_1$,~$w_2$. By convention we will
+duplicate a boundary offset if the angle between octants doesn't
+explicitly appear; in this case there is no explicit line of slope~1
+at the end of the list, so the full list is
+$$w_0\;w_1\;w_2\;w_2\;=\;(0,-1)\;(3,-1)\;(6,1)\;(6,1).$$
+With skewed coordinates $(u-v,v)$ instead of $(u,v)$ we obtain the list
+$$w_0\;w_1\;w_2\;w_2\;\mapsto\;(1,-1)\;(4,-1)\;(5,1)\;(5,1),$$
+which is what actually appears in the data structure. In the second
+octant there's only one offset; we list it three times (with coordinates
+interchanged, so as to make the second octant look like the first),
+and skew those coordinates, obtaining
+$$\tabskip\centering
+\halign to\hsize{$\hfil#\;\mapsto\;{}$\tabskip=0pt&
+$#\hfil$&\quad in the #\hfil\tabskip\centering\cr
+w_2\;w_2\;w_2&(-5,6)\;(-5,6)\;(-5,6)\cr
+\noalign{\vskip\belowdisplayskip
+\vbox{\noindent\strut as the list of transformed and skewed offsets to use
+when curves that travel in the second octant. Similarly, we will have\strut}
+\vskip\abovedisplayskip}
+w_2\;w_2\;w_2&(7,-6)\;(7,-6)\;(7,-6)&third;\cr
+w_2\;w_2\;w_3\;w_3&(-7,1)\;(-7,1)\;(-3,2)\;(-3,2)&fourth;\cr
+w_3\;w_3\;w_3&(3,-2)\;(3,-2)\;(3,-2)&fifth;\cr
+w_3\;w_3\;w_0\;w_0&(-3,1)\;(-3,1)\;(1,0)\;(1,0)&sixth;\cr
+w_0\;w_0\;w_0&(1,0)\;(1,0)\;(1,0)&seventh;\cr
+w_0\;w_0\;w_0&(-1,1)\;(-1,1)\;(-1,1)&eighth.\cr}$$
+Notice that $w_1$ is considered here to be internal to the first octant;
+it's not part of the eighth. We could equally well have taken $w_0$ out
+of the first octant list and put it into the eighth; then the first octant
+list would have been
+$$w_1\;w_1\;w_2\;w_2\;\mapsto\;(4,-1)\;(4,-1)\;(5,1)\;(5,1)$$
+and the eighth octant list would have been
+$$w_0\;w_0\;w_1\;\mapsto\;(-1,1)\;(-1,1)\;(2,1).$$
+
+Actually, there's one more complication: The order of offsets is reversed
+in even-numbered octants, because the transformation of coordinates has
+reversed counterclockwise and clockwise orientations in those octants.
+The offsets in the fourth octant, for example, are really $w_3$, $w_3$,
+$w_2$,~$w_2$, not $w_2$, $w_2$, $w_3$,~$w_3$.
+
+\fi
+
+\M471. In general, the list of offsets for an octant will have the form
+$$w_0\;\;w_1\;\;\ldots\;\;w_n\;\;w_{n+1}$$
+(if we renumber the subscripts in each list), where $w_0$ and $w_{n+1}$
+are offsets common to the neighboring lists. We'll often have $w_0=w_1$
+and/or $w_n=w_{n+1}$, but the other $w$'s will be distinct. Curves
+that travel between slope~0 and direction $w_2-w_1$ will use offset~$w_1$;
+curves that travel between directions $w_k-w_{k-1}$ and $w\k-w_k$ will
+use offset~$w_k$, for $1<k<n$; curves between direction $w_n-w_{n-1}$
+and slope~1 (actually slope~$\infty$ after skewing) will use offset~$w_n$.
+In even-numbered octants, the directions are actually $w_k-w\k$ instead
+of $w\k-w_k$, because the offsets have been listed in reverse order.
+
+Each offset $w_k$ is represented by skewed coordinates $(u_k-v_k,v_k)$,
+where $(u_k,v_k)$ is the representation of $w_k$ after it has been rotated
+into a first-octant disguise.
+
+\fi
+
+\M472. The top-level data structure of a pen polygon is a 10-word node
+containing
+a reference count followed by pointers to the eight pen lists, followed
+by an indication of the pen's range of values.
+
+If \|p~points to such a node, and if the
+offset list for, say, the fourth octant has entries $w_0$, $w_1$, \dots,
+$w_n$,~$w_{n+1}$, then $\\{info}(\|p+\\{fourth\_octant})$ will equal~$n$, and
+$\\{link}(\|p+\\{fourth\_octant})$ will point to the offset node
+containing~$w_0$.
+Memory location $\|p+\\{fourth\_octant}$ is said to be the {\sl header\/} of
+the pen-offset list for the fourth octant. Since this is an even-numbered
+octant, $w_0$ is the offset that goes with the fifth octant, and
+$w_{n+1}$ goes with the third.
+
+The elements of the offset list themselves are doubly linked 3-word nodes,
+containing coordinates in their \\{x\_coord} and \\{y\_coord} fields.
+The two link fields are called \\{link} and \\{knil}; if \|w~points to
+the node for~$w_k$, then $\\{link}(\|w)$ and $\\{knil}(\|w)$ point respectively
+to the nodes for $w\k$ and~$w_{k-1}$. If \|h is the list header,
+$\\{link}(\|h)$ points to the node for~$w_0$ and $\\{knil}(\\{link}(\|h))$ to
+the
+node for~$w_{n+1}$.
+
+The tenth word of a pen header node contains the maximum absolute value of
+an $x$ or $y$ coordinate among all of the unskewed pen offsets.
+
+The \\{link} field of a pen header node should be \\{null} if and only if
+the pen has no offsets.
+
+\Y\P\D \37$\\{pen\_node\_size}=10$\par
+\P\D \37$\\{coord\_node\_size}=3$\par
+\P\D \37$\\{max\_offset}(\#)\S\\{mem}[\#+9].\\{sc}$\par
+\fi
+
+\M473. The \\{print\_pen} subroutine illustrates these conventions by
+reconstructing the vertices of a polygon from \MF's complicated
+internal offset representation.
+
+\Y\P$\4\X257:Declare subroutines for printing expressions\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_pen}(\|p:\\{pointer};\,\35\|s:\\{str%
+\_number};\,\35\\{nuline}:\\{boolean})$;\6
+\4\&{var} \37\\{nothing\_printed}: \37\\{boolean};\C{has there been any action
+yet?}\6
+\|k: \37$1\to8$;\C{octant number}\6
+\|h: \37\\{pointer};\C{offset list head}\6
+$\|m,\39\|n$: \37\\{integer};\C{offset indices}\6
+$\|w,\39\\{ww}$: \37\\{pointer};\C{pointers that traverse the offset list}\2\6
+\&{begin} \37$\\{print\_diagnostic}(\.{"Pen\ polygon"},\39\|s,\39\\{nuline})$;\5
+$\\{nothing\_printed}\K\\{true}$;\5
+\\{print\_ln};\6
+\&{for} $\|k\K1\mathrel{\&{to}}8$ \1\&{do}\6
+\&{begin} \37$\\{octant}\K\\{octant\_code}[\|k]$;\5
+$\|h\K\|p+\\{octant}$;\5
+$\|n\K\\{info}(\|h)$;\5
+$\|w\K\\{link}(\|h)$;\6
+\&{if} $\R\\{odd}(\|k)$ \1\&{then}\5
+$\|w\K\\{knil}(\|w)$;\C{in even octants, start at $w_{n+1}$}\2\6
+\&{for} $\|m\K1\mathrel{\&{to}}\|n+1$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{odd}(\|k)$ \1\&{then}\5
+$\\{ww}\K\\{link}(\|w)$\ \&{else} $\\{ww}\K\\{knil}(\|w)$;\2\6
+\&{if} $(\\{x\_coord}(\\{ww})\I\\{x\_coord}(\|w))\V(\\{y\_coord}(\\{ww})\I\\{y%
+\_coord}(\|w))$ \1\&{then}\5
+\X474:Print the unskewed and unrotated coordinates of node \\{ww}\X;\2\6
+$\|w\K\\{ww}$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{if} $\\{nothing\_printed}$ \1\&{then}\6
+\&{begin} \37$\|w\K\\{link}(\|p+\\{first\_octant})$;\5
+$\\{print\_two}(\\{x\_coord}(\|w)+\\{y\_coord}(\|w),\39\\{y\_coord}(\|w))$;\6
+\&{end};\2\6
+$\\{print\_nl}(\.{"\ ..\ cycle"})$;\5
+$\\{end\_diagnostic}(\\{true})$;\6
+\&{end};\par
+\fi
+
+\M474. \P$\X474:Print the unskewed and unrotated coordinates of node \\{ww}\X%
+\S$\6
+\&{begin} \37\&{if} $\\{nothing\_printed}$ \1\&{then}\5
+$\\{nothing\_printed}\K\\{false}$\6
+\4\&{else} $\\{print\_nl}(\.{"\ ..\ "})$;\2\6
+$\\{print\_two\_true}(\\{x\_coord}(\\{ww}),\39\\{y\_coord}(\\{ww}))$;\6
+\&{end}\par
+\U473.\fi
+
+\M475. A null pen polygon, which has just one vertex $(0,0)$, is
+predeclared for error recovery. It doesn't need a proper
+reference count, because the \\{toss\_pen} procedure below
+will never delete it from memory.
+
+\Y\P$\4\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}\S$\6
+$\\{ref\_count}(\\{null\_pen})\K\\{null}$;\5
+$\\{link}(\\{null\_pen})\K\\{null}$;\6
+$\\{info}(\\{null\_pen}+1)\K1$;\5
+$\\{link}(\\{null\_pen}+1)\K\\{null\_coords}$;\6
+\&{for} $\|k\K\\{null\_pen}+2\mathrel{\&{to}}\\{null\_pen}+8$ \1\&{do}\5
+$\\{mem}[\|k]\K\\{mem}[\\{null\_pen}+1]$;\2\6
+$\\{max\_offset}(\\{null\_pen})\K0$;\6
+$\\{link}(\\{null\_coords})\K\\{null\_coords}$;\5
+$\\{knil}(\\{null\_coords})\K\\{null\_coords}$;\6
+$\\{x\_coord}(\\{null\_coords})\K0$;\5
+$\\{y\_coord}(\\{null\_coords})\K0$;\par
+\fi
+
+\M476. Here's a trivial subroutine that inserts a copy of an offset
+on the \\{link} side of its clone in the doubly linked list.
+
+\Y\P\4\&{procedure}\1\ \37$\\{dup\_offset}(\|w:\\{pointer})$;\6
+\4\&{var} \37\|r: \37\\{pointer};\C{the new node}\2\6
+\&{begin} \37$\|r\K\\{get\_node}(\\{coord\_node\_size})$;\5
+$\\{x\_coord}(\|r)\K\\{x\_coord}(\|w)$;\5
+$\\{y\_coord}(\|r)\K\\{y\_coord}(\|w)$;\5
+$\\{link}(\|r)\K\\{link}(\|w)$;\5
+$\\{knil}(\\{link}(\|w))\K\|r$;\5
+$\\{knil}(\|r)\K\|w$;\5
+$\\{link}(\|w)\K\|r$;\6
+\&{end};\par
+\fi
+
+\M477. The following algorithm is somewhat more interesting: It converts a
+knot list for a cyclic path into a pen polygon, ignoring everything
+but the \\{x\_coord}, \\{y\_coord}, and \\{link} fields. If the given path
+vertices do not define a convex polygon, an error message is issued
+and the null pen is returned.
+
+\Y\P\4\&{function}\1\ \37$\\{make\_pen}(\|h:\\{pointer})$: \37\\{pointer};\6
+\4\&{label} \37$\\{done},\39\\{done1},\39\\{not\_found},\39\\{found}$;\6
+\4\&{var} \37$\|o,\39\\{oo},\39\|k$: \37\\{small\_number};\C{octant
+numbers---old, new, and current}\6
+\|p: \37\\{pointer};\C{top-level node for the new pen}\6
+$\|q,\39\|r,\39\|s,\39\|w,\39\\{hh}$: \37\\{pointer};\C{for list manipulation}\6
+\|n: \37\\{integer};\C{offset counter}\6
+$\\{dx},\39\\{dy}$: \37\\{scaled};\C{polygon direction}\6
+\\{mc}: \37\\{scaled};\C{the largest coordinate}\2\6
+\&{begin} \37\X479:Stamp all nodes with an octant code, compute the maximum
+offset, and set \\{hh} to the node that begins the first octant; \&{goto} %
+\\{not\_found} if there's a problem\X;\6
+\&{if} $\\{mc}\G\\{fraction\_one}-\\{half\_unit}$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\|p\K\\{get\_node}(\\{pen\_node\_size})$;\5
+$\|q\K\\{hh}$;\5
+$\\{max\_offset}(\|p)\K\\{mc}$;\5
+$\\{ref\_count}(\|p)\K\\{null}$;\6
+\&{if} $\\{link}(\|q)\I\|q$ \1\&{then}\5
+$\\{link}(\|p)\K\\{null}+1$;\2\6
+\&{for} $\|k\K1\mathrel{\&{to}}8$ \1\&{do}\5
+\X481:Construct the offset list for the \|kth octant\X;\2\6
+\&{goto} \37\\{found};\6
+\4\\{not\_found}: \37$\|p\K\\{null\_pen}$;\5
+\X478:Complain about a bad pen path\X;\6
+\4\\{found}: \37\&{if} $\\{internal}[\\{tracing\_pens}]>0$ \1\&{then}\5
+$\\{print\_pen}(\|p,\39\.{"\ (newly\ created)"},\39\\{true})$;\2\6
+$\\{make\_pen}\K\|p$;\6
+\&{end};\par
+\fi
+
+\M478. \P$\X478:Complain about a bad pen path\X\S$\6
+\&{if} $\\{mc}\G\\{fraction\_one}-\\{half\_unit}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Pen\ too\ large"})$;\5
+$\\{help2}(\.{"The\ cycle\ you\ specified\ has\ a\ coordinate\ of\ 4095.5\ or\
+more."})$\6
+$(\.{"So\ I\'ve\ replaced\ it\ by\ the\ trivial\ path\ \`(0,0)..cycle\'."})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Pen\ cycle\ must\ be\ convex"})$;\5
+$\\{help3}(\.{"The\ cycle\ you\ specified\ either\ has\ consecutive\ equal\
+points"})$\6
+$(\.{"or\ turns\ right\ or\ turns\ through\ more\ than\ 360\ degrees."})$\6
+$(\.{"So\ I\'ve\ replaced\ it\ by\ the\ trivial\ path\ \`(0,0)..cycle\'."})$;\6
+\&{end};\2\6
+\\{put\_get\_error}\par
+\U477.\fi
+
+\M479. There should be exactly one node whose octant number is less than its
+predecessor in the cycle; that is node~\\{hh}.
+
+The loop here will terminate in all cases, but the proof is somewhat tricky:
+If there are at least two distinct $y$~coordinates in the cycle, we will have
+$\|o>4$ and $\|o\L4$ at different points of the cycle. Otherwise there are
+at least two distinct $x$~coordinates, and we will have $\|o>2$ somewhere,
+$\|o\L2$ somewhere.
+
+\Y\P$\4\X479:Stamp all nodes with an octant code, compute the maximum offset,
+and set \\{hh} to the node that begins the first octant; \&{goto} \\{not%
+\_found} if there's a problem\X\S$\6
+$\|q\K\|h$;\5
+$\|r\K\\{link}(\|q)$;\5
+$\\{mc}\K\\{abs}(\\{x\_coord}(\|h))$;\6
+\&{if} $\|q=\|r$ \1\&{then}\6
+\&{begin} \37$\\{hh}\K\|h$;\5
+$\\{right\_type}(\|h)\K0$;\C{this trick is explained below}\6
+\&{if} $\\{mc}<\\{abs}(\\{y\_coord}(\|h))$ \1\&{then}\5
+$\\{mc}\K\\{abs}(\\{y\_coord}(\|h))$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|o\K0$;\5
+$\\{hh}\K\\{null}$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|s\K\\{link}(\|r)$;\6
+\&{if} $\\{mc}<\\{abs}(\\{x\_coord}(\|r))$ \1\&{then}\5
+$\\{mc}\K\\{abs}(\\{x\_coord}(\|r))$;\2\6
+\&{if} $\\{mc}<\\{abs}(\\{y\_coord}(\|r))$ \1\&{then}\5
+$\\{mc}\K\\{abs}(\\{y\_coord}(\|r))$;\2\6
+$\\{dx}\K\\{x\_coord}(\|r)-\\{x\_coord}(\|q)$;\5
+$\\{dy}\K\\{y\_coord}(\|r)-\\{y\_coord}(\|q)$;\6
+\&{if} $\\{dx}=0$ \1\&{then}\6
+\&{if} $\\{dy}=0$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\C{double point}\2\2\6
+\&{if} $\\{ab\_vs\_cd}(\\{dx},\39\\{y\_coord}(\|s)-\\{y\_coord}(\|r),\39\\{dy},%
+\39\\{x\_coord}(\|s)-\\{x\_coord}(\|r))<0$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\C{right turn}\2\6
+\X480:Determine the octant code for direction $(\\{dx},\\{dy})$\X;\6
+$\\{right\_type}(\|q)\K\\{octant}$;\5
+$\\{oo}\K\\{octant\_number}[\\{octant}]$;\6
+\&{if} $\|o>\\{oo}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{hh}\I\\{null}$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\C{$>360^\circ$}\2\6
+$\\{hh}\K\|q$;\6
+\&{end};\2\6
+$\|o\K\\{oo}$;\6
+\&{if} $(\|q=\|h)\W(\\{hh}\I\\{null})$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|q\K\|r$;\5
+$\|r\K\|s$;\6
+\&{end};\2\6
+\4\\{done}: \37\&{end}\2\par
+\U477.\fi
+
+\M480. We want the octant for $(-\\{dx},-\\{dy})$ to be
+exactly opposite the octant for $(\\{dx},\\{dy})$.
+
+\Y\P$\4\X480:Determine the octant code for direction $(\\{dx},\\{dy})$\X\S$\6
+\&{if} $\\{dx}>0$ \1\&{then}\5
+$\\{octant}\K\\{first\_octant}$\6
+\4\&{else} \&{if} $\\{dx}=0$ \1\&{then}\6
+\&{if} $\\{dy}>0$ \1\&{then}\5
+$\\{octant}\K\\{first\_octant}$\ \&{else} $\\{octant}\K\\{first\_octant}+%
+\\{negate\_x}$\2\6
+\4\&{else} \&{begin} \37$\\{negate}(\\{dx})$;\5
+$\\{octant}\K\\{first\_octant}+\\{negate\_x}$;\6
+\&{end};\2\2\6
+\&{if} $\\{dy}<0$ \1\&{then}\6
+\&{begin} \37$\\{negate}(\\{dy})$;\5
+$\\{octant}\K\\{octant}+\\{negate\_y}$;\6
+\&{end}\6
+\4\&{else} \&{if} $\\{dy}=0$ \1\&{then}\6
+\&{if} $\\{octant}>\\{first\_octant}$ \1\&{then}\5
+$\\{octant}\K\\{first\_octant}+\\{negate\_x}+\\{negate\_y}$;\2\2\2\6
+\&{if} $\\{dx}<\\{dy}$ \1\&{then}\5
+$\\{octant}\K\\{octant}+\\{switch\_x\_and\_y}$\2\par
+\U479.\fi
+
+\M481. Now \|q points to the node that the present octant shares with the
+previous
+octant, and $\\{right\_type}(\|q)$ is the octant code during which \|q~should
+advance.
+We have set $\\{right\_type}(\|q)=0$ in the special case that \|q should never
+advance
+(because the pen is degenerate).
+
+The number of offsets \|n must be smaller than \\{max\_quarterword}, because
+the \\{fill\_envelope} routine stores $\|n+1$ in the \\{right\_type} field
+of a knot node.
+
+\Y\P$\4\X481:Construct the offset list for the \|kth octant\X\S$\6
+\&{begin} \37$\\{octant}\K\\{octant\_code}[\|k]$;\5
+$\|n\K0$;\5
+$\|h\K\|p+\\{octant}$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|r\K\\{get\_node}(\\{coord\_node\_size})$;\5
+$\\{skew}(\\{x\_coord}(\|q),\39\\{y\_coord}(\|q),\39\\{octant})$;\5
+$\\{x\_coord}(\|r)\K\\{cur\_x}$;\5
+$\\{y\_coord}(\|r)\K\\{cur\_y}$;\6
+\&{if} $\|n=0$ \1\&{then}\5
+$\\{link}(\|h)\K\|r$\6
+\4\&{else} \X482:Link node \|r to the previous node\X;\2\6
+$\|w\K\|r$;\6
+\&{if} $\\{right\_type}(\|q)\I\\{octant}$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+$\|q\K\\{link}(\|q)$;\5
+$\\{incr}(\|n)$;\6
+\&{end};\2\6
+\4\\{done1}: \37\X483:Finish linking the offset nodes, and duplicate the
+borderline offset nodes if necessary\X;\6
+\&{if} $\|n\G\\{max\_quarterword}$ \1\&{then}\5
+$\\{overflow}(\.{"pen\ polygon\ size"},\39\\{max\_quarterword})$;\2\6
+$\\{info}(\|h)\K\|n$;\6
+\&{end}\par
+\U477.\fi
+
+\M482. Now \|w points to the node that was inserted most recently, and
+\|k is the current octant number.
+
+\Y\P$\4\X482:Link node \|r to the previous node\X\S$\6
+\&{if} $\\{odd}(\|k)$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|w)\K\|r$;\5
+$\\{knil}(\|r)\K\|w$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{knil}(\|w)\K\|r$;\5
+$\\{link}(\|r)\K\|w$;\6
+\&{end}\2\par
+\U481.\fi
+
+\M483. We have inserted $\|n+1$ nodes; it remains to duplicate the nodes at the
+ends, if slopes 0 and~$\infty$ aren't already represented. At the end of
+this section the total number of offset nodes should be $\|n+2$
+(since we call them $w_0$, $w_1$, \dots,~$w_{n+1}$).
+
+\Y\P$\4\X483:Finish linking the offset nodes, and duplicate the borderline
+offset nodes if necessary\X\S$\6
+$\|r\K\\{link}(\|h)$;\6
+\&{if} $\\{odd}(\|k)$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|w)\K\|r$;\5
+$\\{knil}(\|r)\K\|w$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{knil}(\|w)\K\|r$;\5
+$\\{link}(\|r)\K\|w$;\5
+$\\{link}(\|h)\K\|w$;\5
+$\|r\K\|w$;\6
+\&{end};\2\6
+\&{if} $(\\{y\_coord}(\|r)\I\\{y\_coord}(\\{link}(\|r)))\V(\|n=0)$ \1\&{then}\6
+\&{begin} \37$\\{dup\_offset}(\|r)$;\5
+$\\{incr}(\|n)$;\6
+\&{end};\2\6
+$\|r\K\\{knil}(\|r)$;\6
+\&{if} $\\{x\_coord}(\|r)\I\\{x\_coord}(\\{knil}(\|r))$ \1\&{then}\5
+$\\{dup\_offset}(\|r)$\6
+\4\&{else} $\\{decr}(\|n)$\2\par
+\U481.\fi
+
+\M484. Conversely, \\{make\_path} goes back from a pen to a cyclic path that
+might have generated it. The structure of this subroutine is essentially
+the same as \\{print\_pen}.
+
+\Y\P\hbox{\4}\X486:Declare the function called \\{trivial\_knot}\X\6
+\4\&{function}\1\ \37$\\{make\_path}(\\{pen\_head}:\\{pointer})$: \37%
+\\{pointer};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the most recently copied knot}\6
+\|k: \37$1\to8$;\C{octant number}\6
+\|h: \37\\{pointer};\C{offset list head}\6
+$\|m,\39\|n$: \37\\{integer};\C{offset indices}\6
+$\|w,\39\\{ww}$: \37\\{pointer};\C{pointers that traverse the offset list}\2\6
+\&{begin} \37$\|p\K\\{temp\_head}$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}8$ \1\&{do}\6
+\&{begin} \37$\\{octant}\K\\{octant\_code}[\|k]$;\5
+$\|h\K\\{pen\_head}+\\{octant}$;\5
+$\|n\K\\{info}(\|h)$;\5
+$\|w\K\\{link}(\|h)$;\6
+\&{if} $\R\\{odd}(\|k)$ \1\&{then}\5
+$\|w\K\\{knil}(\|w)$;\C{in even octants, start at $w_{n+1}$}\2\6
+\&{for} $\|m\K1\mathrel{\&{to}}\|n+1$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{odd}(\|k)$ \1\&{then}\5
+$\\{ww}\K\\{link}(\|w)$\ \&{else} $\\{ww}\K\\{knil}(\|w)$;\2\6
+\&{if} $(\\{x\_coord}(\\{ww})\I\\{x\_coord}(\|w))\V(\\{y\_coord}(\\{ww})\I\\{y%
+\_coord}(\|w))$ \1\&{then}\5
+\X485:Copy the unskewed and unrotated coordinates of node \\{ww}\X;\2\6
+$\|w\K\\{ww}$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{if} $\|p=\\{temp\_head}$ \1\&{then}\6
+\&{begin} \37$\|w\K\\{link}(\\{pen\_head}+\\{first\_octant})$;\5
+$\|p\K\\{trivial\_knot}(\\{x\_coord}(\|w)+\\{y\_coord}(\|w),\39\\{y\_coord}(%
+\|w))$;\5
+$\\{link}(\\{temp\_head})\K\|p$;\6
+\&{end};\2\6
+$\\{link}(\|p)\K\\{link}(\\{temp\_head})$;\5
+$\\{make\_path}\K\\{link}(\\{temp\_head})$;\6
+\&{end};\par
+\fi
+
+\M485. \P$\X485:Copy the unskewed and unrotated coordinates of node \\{ww}\X\S$%
+\6
+\&{begin} \37$\\{unskew}(\\{x\_coord}(\\{ww}),\39\\{y\_coord}(\\{ww}),\39%
+\\{octant})$;\5
+$\\{link}(\|p)\K\\{trivial\_knot}(\\{cur\_x},\39\\{cur\_y})$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end}\par
+\U484.\fi
+
+\M486. \P$\X486:Declare the function called \\{trivial\_knot}\X\S$\6
+\4\&{function}\1\ \37$\\{trivial\_knot}(\|x,\39\|y:\\{scaled})$: \37%
+\\{pointer};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{a new knot for explicit coordinates \|x and
+\|y}\2\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{left\_type}(\|p)\K\\{explicit}$;\5
+$\\{right\_type}(\|p)\K\\{explicit}$;\6
+$\\{x\_coord}(\|p)\K\|x$;\5
+$\\{left\_x}(\|p)\K\|x$;\5
+$\\{right\_x}(\|p)\K\|x$;\6
+$\\{y\_coord}(\|p)\K\|y$;\5
+$\\{left\_y}(\|p)\K\|y$;\5
+$\\{right\_y}(\|p)\K\|y$;\6
+$\\{trivial\_knot}\K\|p$;\6
+\&{end};\par
+\U484.\fi
+
+\M487. That which can be created can be destroyed.
+
+\Y\P\D \37$\\{add\_pen\_ref}(\#)\S\\{incr}(\\{ref\_count}(\#))$\par
+\P\D \37$\\{delete\_pen\_ref}(\#)\S$\1\6
+\&{if} $\\{ref\_count}(\#)=\\{null}$ \1\&{then}\5
+$\\{toss\_pen}(\#)$\6
+\4\&{else} $\\{decr}(\\{ref\_count}(\#))$\2\2\par
+\Y\P$\4\X268:Declare the recycling subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{toss\_pen}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|k: \37$1\to8$;\C{relative header locations}\6
+$\|w,\39\\{ww}$: \37\\{pointer};\C{pointers to offset nodes}\2\6
+\&{begin} \37\&{if} $\|p\I\\{null\_pen}$ \1\&{then}\6
+\&{begin} \37\&{for} $\|k\K1\mathrel{\&{to}}8$ \1\&{do}\6
+\&{begin} \37$\|w\K\\{link}(\|p+\|k)$;\6
+\1\&{repeat} \37$\\{ww}\K\\{link}(\|w)$;\5
+$\\{free\_node}(\|w,\39\\{coord\_node\_size})$;\5
+$\|w\K\\{ww}$;\6
+\4\&{until}\5
+$\|w=\\{link}(\|p+\|k)$;\2\6
+\&{end};\2\6
+$\\{free\_node}(\|p,\39\\{pen\_node\_size})$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M488. The \\{find\_offset} procedure sets $(\\{cur\_x},\\{cur\_y})$ to the
+offset associated
+with a given direction~$(\|x,\|y)$ and a given pen~\|p. If $\|x=\|y=0$, the
+result is $(0,0)$. If two different offsets apply, one of them is
+chosen arbitrarily.
+
+\Y\P\4\&{procedure}\1\ \37$\\{find\_offset}(\|x,\39\|y:\\{scaled};\,\35\|p:%
+\\{pointer})$;\6
+\4\&{label} \37$\\{done},\39\\{exit}$;\6
+\4\&{var} \37\\{octant}: \37$\\{first\_octant}\to\\{sixth\_octant}$;\C{octant
+code for $(\|x,\|y)$}\6
+\|s: \37$-1\to+1$;\C{sign of the octant}\6
+\|n: \37\\{integer};\C{number of offsets remaining}\6
+$\|h,\39\|w,\39\\{ww}$: \37\\{pointer};\C{list traversal registers}\2\6
+\&{begin} \37\X489:Compute the octant code; skew and rotate the coordinates $(%
+\|x,\|y)$\X;\6
+\&{if} $\\{odd}(\\{octant\_number}[\\{octant}])$ \1\&{then}\5
+$\|s\K-1$\ \&{else} $\|s\K+1$;\2\6
+$\|h\K\|p+\\{octant}$;\5
+$\|w\K\\{link}(\\{link}(\|h))$;\5
+$\\{ww}\K\\{link}(\|w)$;\5
+$\|n\K\\{info}(\|h)$;\6
+\&{while} $\|n>1$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{ab\_vs\_cd}(\|x,\39\\{y\_coord}(\\{ww})-\\{y\_coord}(%
+\|w),\39\30\|y,\39\\{x\_coord}(\\{ww})-\\{x\_coord}(\|w))\I\|s$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|w\K\\{ww}$;\5
+$\\{ww}\K\\{link}(\|w)$;\5
+$\\{decr}(\|n)$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{unskew}(\\{x\_coord}(\|w),\39\\{y\_coord}(\|w),\39%
+\\{octant})$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M489. \P$\X489:Compute the octant code; skew and rotate the coordinates $(\|x,%
+\|y)$\X\S$\6
+\&{if} $\|x>0$ \1\&{then}\5
+$\\{octant}\K\\{first\_octant}$\6
+\4\&{else} \&{if} $\|x=0$ \1\&{then}\6
+\&{if} $\|y\L0$ \1\&{then}\6
+\&{if} $\|y=0$ \1\&{then}\6
+\&{begin} \37$\\{cur\_x}\K0$;\5
+$\\{cur\_y}\K0$;\5
+\&{return};\6
+\&{end}\6
+\4\&{else} $\\{octant}\K\\{first\_octant}+\\{negate\_x}$\2\6
+\4\&{else} $\\{octant}\K\\{first\_octant}$\2\6
+\4\&{else} \&{begin} \37$\|x\K-\|x$;\6
+\&{if} $\|y=0$ \1\&{then}\5
+$\\{octant}\K\\{first\_octant}+\\{negate\_x}+\\{negate\_y}$\6
+\4\&{else} $\\{octant}\K\\{first\_octant}+\\{negate\_x}$;\2\6
+\&{end};\2\2\6
+\&{if} $\|y<0$ \1\&{then}\6
+\&{begin} \37$\\{octant}\K\\{octant}+\\{negate\_y}$;\5
+$\|y\K-\|y$;\6
+\&{end};\2\6
+\&{if} $\|x\G\|y$ \1\&{then}\5
+$\|x\K\|x-\|y$\6
+\4\&{else} \&{begin} \37$\\{octant}\K\\{octant}+\\{switch\_x\_and\_y}$;\5
+$\|x\K\|y-\|x$;\5
+$\|y\K\|y-\|x$;\6
+\&{end}\2\par
+\U488.\fi
+
+\N490. \[24] Filling an envelope.
+We are about to reach the culmination of \MF's digital plotting routines:
+Almost all of the previous algorithms will be brought to bear on \MF's
+most difficult task, which is to fill the envelope of a given cyclic path
+with respect to a given pen polygon.
+
+But we still must complete some of the preparatory work before taking such
+a big plunge.
+
+\fi
+
+\M491. Given a pointer \|c to a nonempty list of cubics,
+and a pointer~\|h to the header information of a pen polygon segment,
+the \\{offset\_prep} routine changes the list into cubics that are
+associated with particular pen offsets. Namely, the cubic between \|p
+and~\|q should be associated with the \|kth offset when $\\{right\_type}(\|p)=%
+\|k$.
+
+List \|c is actually part of a cycle spec, so it terminates at the
+first node whose \\{right\_type} is \\{endpoint}. The cubics all have
+monotone-nondecreasing $x'(t)$ and $y'(t)$.
+
+\Y\P\hbox{\4}\X493:Declare subroutines needed by \\{offset\_prep}\X\6
+\4\&{procedure}\1\ \37$\\{offset\_prep}(\|c,\39\|h:\\{pointer})$;\6
+\4\&{label} \37$\\{done},\39\\{not\_found}$;\6
+\4\&{var} \37\|n: \37\\{halfword};\C{the number of pen offsets}\6
+$\|p,\39\|q,\39\|r,\39\\{lh},\39\\{ww}$: \37\\{pointer};\C{for list
+manipulation}\6
+\|k: \37\\{halfword};\C{the current offset index}\6
+\|w: \37\\{pointer};\C{a pointer to offset $w_k$}\6
+\X495:Other local variables for \\{offset\_prep}\X\2\6
+\&{begin} \37$\|p\K\|c$;\5
+$\|n\K\\{info}(\|h)$;\5
+$\\{lh}\K\\{link}(\|h)$;\C{now \\{lh} points to $w_0$}\6
+\&{while} $\\{right\_type}(\|p)\I\\{endpoint}$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{link}(\|p)$;\5
+\X494:Split the cubic between \|p and \|q, if necessary, into cubics associated
+with single offsets, after which \|q should point to the end of the final such
+cubic\X;\6
+\X492:Advance \|p to node \|q, removing any ``dead'' cubics that might have
+been introduced by the splitting process\X;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M492. \P$\X492:Advance \|p to node \|q, removing any ``dead'' cubics that
+might have been introduced by the splitting process\X\S$\6
+\1\&{repeat} \37$\|r\K\\{link}(\|p)$;\6
+\&{if} $\\{x\_coord}(\|p)=\\{right\_x}(\|p)$ \1\&{then}\6
+\&{if} $\\{y\_coord}(\|p)=\\{right\_y}(\|p)$ \1\&{then}\6
+\&{if} $\\{x\_coord}(\|p)=\\{left\_x}(\|r)$ \1\&{then}\6
+\&{if} $\\{y\_coord}(\|p)=\\{left\_y}(\|r)$ \1\&{then}\6
+\&{if} $\\{x\_coord}(\|p)=\\{x\_coord}(\|r)$ \1\&{then}\6
+\&{if} $\\{y\_coord}(\|p)=\\{y\_coord}(\|r)$ \1\&{then}\6
+\&{begin} \37$\\{remove\_cubic}(\|p)$;\6
+\&{if} $\|r=\|q$ \1\&{then}\5
+$\|q\K\|p$;\2\6
+$\|r\K\|p$;\6
+\&{end};\2\2\2\2\2\2\6
+$\|p\K\|r$;\6
+\4\&{until}\5
+$\|p=\|q$\2\par
+\U491.\fi
+
+\M493. The splitting process uses a subroutine like \\{split\_cubic}, but
+(for ``bulletproof'' operation) we check to make sure that the
+resulting (skewed) coordinates satisfy $\Delta x\G0$ and $\Delta y\G0$
+after splitting; \\{make\_spec} has made sure that these relations hold
+before splitting. (This precaution is surely unnecessary, now that
+\\{make\_spec} is so much more careful than it used to be. But who
+wants to take a chance? Maybe the hardware will fail or something.)
+
+\Y\P$\4\X493:Declare subroutines needed by \\{offset\_prep}\X\S$\6
+\4\&{procedure}\1\ \37$\\{split\_for\_offset}(\|p:\\{pointer};\,\35\|t:%
+\\{fraction})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the successor of \|p}\6
+\|r: \37\\{pointer};\C{the new node}\2\6
+\&{begin} \37$\|q\K\\{link}(\|p)$;\5
+$\\{split\_cubic}(\|p,\39\|t,\39\\{x\_coord}(\|q),\39\\{y\_coord}(\|q))$;\5
+$\|r\K\\{link}(\|p)$;\6
+\&{if} $\\{y\_coord}(\|r)<\\{y\_coord}(\|p)$ \1\&{then}\5
+$\\{y\_coord}(\|r)\K\\{y\_coord}(\|p)$\6
+\4\&{else} \&{if} $\\{y\_coord}(\|r)>\\{y\_coord}(\|q)$ \1\&{then}\5
+$\\{y\_coord}(\|r)\K\\{y\_coord}(\|q)$;\2\2\6
+\&{if} $\\{x\_coord}(\|r)<\\{x\_coord}(\|p)$ \1\&{then}\5
+$\\{x\_coord}(\|r)\K\\{x\_coord}(\|p)$\6
+\4\&{else} \&{if} $\\{x\_coord}(\|r)>\\{x\_coord}(\|q)$ \1\&{then}\5
+$\\{x\_coord}(\|r)\K\\{x\_coord}(\|q)$;\2\2\6
+\&{end};\par
+\A497.
+\U491.\fi
+
+\M494. If the pen polygon has \|n offsets, and if $w_k=(u_k,v_k)$ is the $k$th
+of these, the $k$th pen slope is defined by the formula
+$$s_k={v\k-v_k\over u\k-u_k},\qquad\hbox{for $0<k<n$}.$$
+In odd-numbered octants, the numerator and denominator of this fraction
+will be positive; in even-numbered octants they will both be negative.
+Furthermore we always have $0=s_0<s_1<\cdots<s_n=\infty$. The goal of
+\\{offset\_prep} is to find an offset index~\|k to associate with
+each cubic, such that the slope $s(t)$ of the cubic satisfies
+$$s_{k-1}\le s(t)\le s_k\qquad\hbox{for $0\le t\le 1$.}\eqno(*)$$
+We may have to split a cubic into as many as $2n-1$ pieces before each
+piece corresponds to a unique offset.
+
+\Y\P$\4\X494:Split the cubic between \|p and \|q, if necessary, into cubics
+associated with single offsets, after which \|q should point to the end of the
+final such cubic\X\S$\6
+\&{if} $\|n\L1$ \1\&{then}\5
+$\\{right\_type}(\|p)\K1$\C{this case is easy}\6
+\4\&{else} \&{begin} \37\X496:Prepare for derivative computations; \&{goto} %
+\\{not\_found} if the current cubic is dead\X;\6
+\X501:Find the initial slope, $\\{dy}/\\{dx}$\X;\6
+\&{if} $\\{dx}=0$ \1\&{then}\5
+\X505:Handle the special case of infinite slope\X\6
+\4\&{else} \&{begin} \37\X502:Find the index \|k such that $s_{k-1}\L\\{dy}/%
+\\{dx}<s_k$\X;\6
+\X503:Complete the offset splitting process\X;\6
+\&{end};\2\6
+\4\\{not\_found}: \37\&{end}\2\par
+\U491.\fi
+
+\M495. The slope of a cubic $B(z_0,z_1,z_2,z_3;t)=\bigl(x(t),y(t)\bigr)$ can be
+calculated from the quadratic polynomials
+${1\over3}x'(t)=B(x_1-x_0,x_2-x_1,x_3-x_2;t)$ and
+${1\over3}y'(t)=B(y_1-y_0,y_2-y_1,y_3-y_2;t)$.
+Since we may be calculating slopes from several cubics
+split from the current one, it is desirable to do these calculations
+without losing too much precision. ``Scaled up'' values of the
+derivatives, which will be less tainted by accumulated errors than
+derivatives found from the cubics themselves, are maintained in
+local variables \\{x0}, \\{x1}, and \\{x2}, representing $X_0=2^l(x_1-x_0)$,
+$X_1=2^l(x_2-x_1)$, and $X_2=2^l(x_3-x_2)$; similarly \\{y0}, \\{y1}, and~%
+\\{y2}
+represent $Y_0=2^l(y_1-y_0)$, $Y_1=2^l(y_2-y_1)$, and $Y_2=2^l(y_3-y_2)$.
+To test whether the slope of the cubic is $\ge s$ or $\le s$, we will test
+the sign of the quadratic ${1\over3}2^l\bigl(y'(t)-sx'(t)\bigr)$ if $s\le1$,
+or ${1\over3}2^l\bigl(y'(t)/s-x'(t)\bigr)$ if $s>1$.
+
+\Y\P$\4\X495:Other local variables for \\{offset\_prep}\X\S$\6
+\4$\\{x0},\39\\{x1},\39\\{x2},\39\\{y0},\39\\{y1},\39\\{y2}$: \37\\{integer};%
+\C{representatives of derivatives}\6
+\4$\\{t0},\39\\{t1},\39\\{t2}$: \37\\{integer};\C{coefficients of polynomial
+for slope testing}\6
+\4$\\{du},\39\\{dv},\39\\{dx},\39\\{dy}$: \37\\{integer};\C{for slopes of the
+pen and the curve}\6
+\4\\{max\_coef}: \37\\{integer};\C{used while scaling}\6
+\4$\\{x0a},\39\\{x1a},\39\\{x2a},\39\\{y0a},\39\\{y1a},\39\\{y2a}$: \37%
+\\{integer};\C{intermediate values}\6
+\4\|t: \37\\{fraction};\C{where the derivative passes through zero}\6
+\4\|s: \37\\{fraction};\C{slope or reciprocal slope}\par
+\U491.\fi
+
+\M496. \P$\X496:Prepare for derivative computations; \&{goto} \\{not\_found} if
+the current cubic is dead\X\S$\6
+$\\{x0}\K\\{right\_x}(\|p)-\\{x\_coord}(\|p)$;\C{should be $\G0$}\6
+$\\{x2}\K\\{x\_coord}(\|q)-\\{left\_x}(\|q)$;\C{likewise}\6
+$\\{x1}\K\\{left\_x}(\|q)-\\{right\_x}(\|p)$;\C{but this might be negative}\6
+$\\{y0}\K\\{right\_y}(\|p)-\\{y\_coord}(\|p)$;\5
+$\\{y2}\K\\{y\_coord}(\|q)-\\{left\_y}(\|q)$;\5
+$\\{y1}\K\\{left\_y}(\|q)-\\{right\_y}(\|p)$;\5
+$\\{max\_coef}\K\\{abs}(\\{x0})$;\C{we take \\{abs} just to make sure}\6
+\&{if} $\\{abs}(\\{x1})>\\{max\_coef}$ \1\&{then}\5
+$\\{max\_coef}\K\\{abs}(\\{x1})$;\2\6
+\&{if} $\\{abs}(\\{x2})>\\{max\_coef}$ \1\&{then}\5
+$\\{max\_coef}\K\\{abs}(\\{x2})$;\2\6
+\&{if} $\\{abs}(\\{y0})>\\{max\_coef}$ \1\&{then}\5
+$\\{max\_coef}\K\\{abs}(\\{y0})$;\2\6
+\&{if} $\\{abs}(\\{y1})>\\{max\_coef}$ \1\&{then}\5
+$\\{max\_coef}\K\\{abs}(\\{y1})$;\2\6
+\&{if} $\\{abs}(\\{y2})>\\{max\_coef}$ \1\&{then}\5
+$\\{max\_coef}\K\\{abs}(\\{y2})$;\2\6
+\&{if} $\\{max\_coef}=0$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{while} $\\{max\_coef}<\\{fraction\_half}$ \1\&{do}\6
+\&{begin} \37$\\{double}(\\{max\_coef})$;\5
+$\\{double}(\\{x0})$;\5
+$\\{double}(\\{x1})$;\5
+$\\{double}(\\{x2})$;\5
+$\\{double}(\\{y0})$;\5
+$\\{double}(\\{y1})$;\5
+$\\{double}(\\{y2})$;\6
+\&{end}\2\par
+\U494.\fi
+
+\M497. Let us first solve a special case of the problem: Suppose we
+know an index~$k$ such that either (i)~$s(t)\G s_{k-1}$ for all~$t$
+and $s(0)<s_k$, or (ii)~$s(t)\L s_k$ for all~$t$ and $s(0)>s_{k-1}$.
+Then, in a sense, we're halfway done, since one of the two inequalities
+in $(*)$ is satisfied, and the other couldn't be satisfied for
+any other value of~\|k.
+
+The \\{fin\_offset\_prep} subroutine solves the stated subproblem.
+It has a boolean parameter called \\{rising} that is \\{true} in
+case~(i), \\{false} in case~(ii). When $\\{rising}=\\{false}$, parameters
+\\{x0} through \\{y2} represent the negative of the derivative of
+the cubic following \|p; otherwise they represent the actual derivative.
+The \|w parameter should point to offset~$w_k$.
+
+\Y\P$\4\X493:Declare subroutines needed by \\{offset\_prep}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{fin\_offset\_prep}(\|p:\\{pointer};\,\35\|k:%
+\\{halfword};\,\35\|w:\\{pointer};\,\35\\{x0},\39\\{x1},\39\\{x2},\39\\{y0},\39%
+\\{y1},\39\\{y2}:\\{integer};\,\35\\{rising}:\\{boolean};\,\35\|n:%
+\\{integer})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\\{ww}: \37\\{pointer};\C{for list manipulation}\6
+$\\{du},\39\\{dv}$: \37\\{scaled};\C{for slope calculation}\6
+$\\{t0},\39\\{t1},\39\\{t2}$: \37\\{integer};\C{test coefficients}\6
+\|t: \37\\{fraction};\C{place where the derivative passes a critical slope}\6
+\|s: \37\\{fraction};\C{slope or reciprocal slope}\6
+\|v: \37\\{integer};\C{intermediate value for updating $\\{x0}\to\\{y2}$}\2\6
+\&{begin} \37\~ \1\&{loop}\6
+\&{begin} \37$\\{right\_type}(\|p)\K\|k$;\6
+\&{if} $\\{rising}$ \1\&{then}\6
+\&{if} $\|k=\|n$ \1\&{then}\5
+\&{return}\6
+\4\&{else} $\\{ww}\K\\{link}(\|w)$\C{a pointer to $w\k$}\2\6
+\4\&{else} \&{if} $\|k=1$ \1\&{then}\5
+\&{return}\6
+\4\&{else} $\\{ww}\K\\{knil}(\|w)$;\C{a pointer to $w_{k-1}$}\2\2\6
+\X498:Compute test coefficients $(\\{t0},\\{t1},\\{t2})$ for $s(t)$ versus
+$s_k$ or $s_{k-1}$\X;\6
+$\|t\K\\{crossing\_point}(\\{t0},\39\\{t1},\39\\{t2})$;\6
+\&{if} $\|t\G\\{fraction\_one}$ \1\&{then}\5
+\&{return};\2\6
+\X499:Split the cubic at $t$, and split off another cubic if the derivative
+crosses back\X;\6
+\&{if} $\\{rising}$ \1\&{then}\5
+$\\{incr}(\|k)$\ \&{else} $\\{decr}(\|k)$;\2\6
+$\|w\K\\{ww}$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M498. \P$\X498:Compute test coefficients $(\\{t0},\\{t1},\\{t2})$ for $s(t)$
+versus $s_k$ or $s_{k-1}$\X\S$\6
+$\\{du}\K\\{x\_coord}(\\{ww})-\\{x\_coord}(\|w)$;\5
+$\\{dv}\K\\{y\_coord}(\\{ww})-\\{y\_coord}(\|w)$;\6
+\&{if} $\\{abs}(\\{du})\G\\{abs}(\\{dv})$ \1\&{then}\C{$s_{k\pm1}\le1$}\6
+\&{begin} \37$\|s\K\\{make\_fraction}(\\{dv},\39\\{du})$;\5
+$\\{t0}\K\\{take\_fraction}(\\{x0},\39\|s)-\\{y0}$;\5
+$\\{t1}\K\\{take\_fraction}(\\{x1},\39\|s)-\\{y1}$;\5
+$\\{t2}\K\\{take\_fraction}(\\{x2},\39\|s)-\\{y2}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|s\K\\{make\_fraction}(\\{du},\39\\{dv})$;\5
+$\\{t0}\K\\{x0}-\\{take\_fraction}(\\{y0},\39\|s)$;\5
+$\\{t1}\K\\{x1}-\\{take\_fraction}(\\{y1},\39\|s)$;\5
+$\\{t2}\K\\{x2}-\\{take\_fraction}(\\{y2},\39\|s)$;\6
+\&{end}\2\par
+\Us497\ET503.\fi
+
+\M499. The curve has crossed $s_k$ or $s_{k-1}$; its initial segment satisfies
+$(*)$, and it might cross again and return towards $s_k$, yielding another
+solution of $(*)$.
+
+\Y\P$\4\X499:Split the cubic at $t$, and split off another cubic if the
+derivative crosses back\X\S$\6
+\&{begin} \37$\\{split\_for\_offset}(\|p,\39\|t)$;\5
+$\\{right\_type}(\|p)\K\|k$;\5
+$\|p\K\\{link}(\|p)$;\6
+$\|v\K\\{t\_of\_the\_way}(\\{x0})(\\{x1})$;\5
+$\\{x1}\K\\{t\_of\_the\_way}(\\{x1})(\\{x2})$;\5
+$\\{x0}\K\\{t\_of\_the\_way}(\|v)(\\{x1})$;\6
+$\|v\K\\{t\_of\_the\_way}(\\{y0})(\\{y1})$;\5
+$\\{y1}\K\\{t\_of\_the\_way}(\\{y1})(\\{y2})$;\5
+$\\{y0}\K\\{t\_of\_the\_way}(\|v)(\\{y1})$;\6
+$\\{t1}\K\\{t\_of\_the\_way}(\\{t1})(\\{t2})$;\6
+\&{if} $\\{t1}>0$ \1\&{then}\5
+$\\{t1}\K0$;\C{without rounding error, \\{t1} would be $\L0$}\2\6
+$\|t\K\\{crossing\_point}(0,\39-\\{t1},\39-\\{t2})$;\6
+\&{if} $\|t<\\{fraction\_one}$ \1\&{then}\6
+\&{begin} \37$\\{split\_for\_offset}(\|p,\39\|t)$;\5
+$\\{right\_type}(\\{link}(\|p))\K\|k$;\6
+$\|v\K\\{t\_of\_the\_way}(\\{x1})(\\{x2})$;\5
+$\\{x1}\K\\{t\_of\_the\_way}(\\{x0})(\\{x1})$;\5
+$\\{x2}\K\\{t\_of\_the\_way}(\\{x1})(\|v)$;\6
+$\|v\K\\{t\_of\_the\_way}(\\{y1})(\\{y2})$;\5
+$\\{y1}\K\\{t\_of\_the\_way}(\\{y0})(\\{y1})$;\5
+$\\{y2}\K\\{t\_of\_the\_way}(\\{y1})(\|v)$;\6
+\&{end};\2\6
+\&{end}\par
+\U497.\fi
+
+\M500. Now we must consider the general problem of \\{offset\_prep}, when
+nothing is known about a given cubic. We start by finding its
+slope $s(0)$ in the vicinity of $\|t=0$.
+
+If $z'(t)=0$, the given cubic is numerically unstable, since the
+slope direction is probably being influenced primarily by rounding
+errors. A user who specifies such cuspy curves should expect to generate
+rather wild results. The present code tries its best to believe the
+existing data, as if no rounding errors were present.
+
+\fi
+
+\M501. \P$\X501:Find the initial slope, $\\{dy}/\\{dx}$\X\S$\6
+$\\{dx}\K\\{x0}$;\5
+$\\{dy}\K\\{y0}$;\6
+\&{if} $\\{dx}=0$ \1\&{then}\6
+\&{if} $\\{dy}=0$ \1\&{then}\6
+\&{begin} \37$\\{dx}\K\\{x1}$;\5
+$\\{dy}\K\\{y1}$;\6
+\&{if} $\\{dx}=0$ \1\&{then}\6
+\&{if} $\\{dy}=0$ \1\&{then}\6
+\&{begin} \37$\\{dx}\K\\{x2}$;\5
+$\\{dy}\K\\{y2}$;\6
+\&{end};\2\2\6
+\&{end}\2\2\par
+\U494.\fi
+
+\M502. The next step is to bracket the initial slope between consecutive
+slopes of the pen polygon. The most important invariant relation in the
+following loop is that $\\{dy}/\\{dx}\G\hbox{$s_{k-1}$}$.
+
+\Y\P$\4\X502:Find the index \|k such that $s_{k-1}\L\\{dy}/\\{dx}<s_k$\X\S$\6
+$\|k\K1$;\5
+$\|w\K\\{link}(\\{lh})$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\|k=\|n$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{ww}\K\\{link}(\|w)$;\6
+\&{if} $\\{ab\_vs\_cd}(\\{dy},\39\\{abs}(\\{x\_coord}(\\{ww})-\\{x\_coord}(%
+\|w)),\39\30\\{dx},\39\\{abs}(\\{y\_coord}(\\{ww})-\\{y\_coord}(\|w)))\G0$ \1%
+\&{then}\6
+\&{begin} \37$\\{incr}(\|k)$;\5
+$\|w\K\\{ww}$;\6
+\&{end}\6
+\4\&{else} \&{goto} \37\\{done};\2\6
+\&{end};\2\6
+\4\\{done}: \37\par
+\U494.\fi
+
+\M503. Finally we want to reduce the general problem to situations that
+\\{fin\_offset\_prep} can handle. If $\|k=1$, we already are in the desired
+situation. Otherwise we can split the cubic into at most three parts
+with respect to $s_{k-1}$, and apply \\{fin\_offset\_prep} to each part.
+
+\Y\P$\4\X503:Complete the offset splitting process\X\S$\6
+\&{if} $\|k=1$ \1\&{then}\5
+$\|t\K\\{fraction\_one}+1$\6
+\4\&{else} \&{begin} \37$\\{ww}\K\\{knil}(\|w)$;\5
+\X498:Compute test coefficients $(\\{t0},\\{t1},\\{t2})$ for $s(t)$ versus
+$s_k$ or $s_{k-1}$\X;\6
+$\|t\K\\{crossing\_point}(-\\{t0},\39-\\{t1},\39-\\{t2})$;\6
+\&{end};\2\6
+\&{if} $\|t\G\\{fraction\_one}$ \1\&{then}\5
+$\\{fin\_offset\_prep}(\|p,\39\|k,\39\|w,\39\\{x0},\39\\{x1},\39\\{x2},\39%
+\\{y0},\39\\{y1},\39\\{y2},\39\\{true},\39\|n)$\6
+\4\&{else} \&{begin} \37$\\{split\_for\_offset}(\|p,\39\|t)$;\5
+$\|r\K\\{link}(\|p)$;\6
+$\\{x1a}\K\\{t\_of\_the\_way}(\\{x0})(\\{x1})$;\5
+$\\{x1}\K\\{t\_of\_the\_way}(\\{x1})(\\{x2})$;\5
+$\\{x2a}\K\\{t\_of\_the\_way}(\\{x1a})(\\{x1})$;\6
+$\\{y1a}\K\\{t\_of\_the\_way}(\\{y0})(\\{y1})$;\5
+$\\{y1}\K\\{t\_of\_the\_way}(\\{y1})(\\{y2})$;\5
+$\\{y2a}\K\\{t\_of\_the\_way}(\\{y1a})(\\{y1})$;\6
+$\\{fin\_offset\_prep}(\|p,\39\|k,\39\|w,\39\\{x0},\39\\{x1a},\39\\{x2a},\39%
+\\{y0},\39\\{y1a},\39\\{y2a},\39\\{true},\39\|n)$;\5
+$\\{x0}\K\\{x2a}$;\5
+$\\{y0}\K\\{y2a}$;\5
+$\\{t1}\K\\{t\_of\_the\_way}(\\{t1})(\\{t2})$;\6
+\&{if} $\\{t1}<0$ \1\&{then}\5
+$\\{t1}\K0$;\2\6
+$\|t\K\\{crossing\_point}(0,\39\\{t1},\39\\{t2})$;\6
+\&{if} $\|t<\\{fraction\_one}$ \1\&{then}\5
+\X504:Split off another \\{rising} cubic for \\{fin\_offset\_prep}\X;\2\6
+$\\{fin\_offset\_prep}(\|r,\39\|k-1,\39\\{ww},\39-\\{x0},\39-\\{x1},\39-\\{x2},%
+\39-\\{y0},\39-\\{y1},\39-\\{y2},\39\\{false},\39\|n)$;\6
+\&{end}\2\par
+\U494.\fi
+
+\M504. \P$\X504:Split off another \\{rising} cubic for \\{fin\_offset\_prep}\X%
+\S$\6
+\&{begin} \37$\\{split\_for\_offset}(\|r,\39\|t)$;\6
+$\\{x1a}\K\\{t\_of\_the\_way}(\\{x1})(\\{x2})$;\5
+$\\{x1}\K\\{t\_of\_the\_way}(\\{x0})(\\{x1})$;\5
+$\\{x0a}\K\\{t\_of\_the\_way}(\\{x1})(\\{x1a})$;\6
+$\\{y1a}\K\\{t\_of\_the\_way}(\\{y1})(\\{y2})$;\5
+$\\{y1}\K\\{t\_of\_the\_way}(\\{y0})(\\{y1})$;\5
+$\\{y0a}\K\\{t\_of\_the\_way}(\\{y1})(\\{y1a})$;\6
+$\\{fin\_offset\_prep}(\\{link}(\|r),\39\|k,\39\|w,\39\\{x0a},\39\\{x1a},\39%
+\\{x2},\39\\{y0a},\39\\{y1a},\39\\{y2},\39\\{true},\39\|n)$;\5
+$\\{x2}\K\\{x0a}$;\5
+$\\{y2}\K\\{y0a}$;\6
+\&{end}\par
+\U503.\fi
+
+\M505. \P$\X505:Handle the special case of infinite slope\X\S$\6
+$\\{fin\_offset\_prep}(\|p,\39\|n,\39\\{knil}(\\{knil}(\\{lh})),\39-\\{x0},\39-%
+\\{x1},\39-\\{x2},\39-\\{y0},\39-\\{y1},\39-\\{y2},\39\\{false},\39\|n)$\par
+\U494.\fi
+
+\M506. OK, it's time now for the biggie. The \\{fill\_envelope} routine
+generalizes
+\\{fill\_spec} to polygonal envelopes. Its outer structure is essentially the
+same as before, except that octants with no cubics do contribute to
+the envelope.
+
+\Y\P\hbox{\4}\X510:Declare the procedure called \\{skew\_line\_edges}\X\6
+\hbox{\4}\X518:Declare the procedure called \\{dual\_moves}\X\6
+\4\&{procedure}\1\ \37$\\{fill\_envelope}(\\{spec\_head}:\\{pointer})$;\6
+\4\&{label} \37$\\{done},\39\\{done1}$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{for list traversal}\6
+\|h: \37\\{pointer};\C{head of pen offset list for current octant}\6
+\\{www}: \37\\{pointer};\C{a pen offset of temporary interest}\6
+\X511:Other local variables for \\{fill\_envelope}\X\2\6
+\&{begin} \37\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+\\{begin\_edge\_tracing};\2\6
+$\|p\K\\{spec\_head}$;\C{we assume that $\\{left\_type}(\\{spec\_head})=%
+\\{endpoint}$}\6
+\1\&{repeat} \37$\\{octant}\K\\{left\_octant}(\|p)$;\5
+$\|h\K\\{cur\_pen}+\\{octant}$;\5
+\X466:Set variable \|q to the node at the end of the current octant\X;\6
+\X508:Determine the envelope's starting and ending lattice points $(\\{m0},%
+\\{n0})$ and $(\\{m1},\\{n1})$\X;\6
+$\\{offset\_prep}(\|p,\39\|h)$;\C{this may clobber node~\|q, if it becomes
+``dead''}\6
+\X466:Set variable \|q to the node at the end of the current octant\X;\6
+\X512:Make the envelope moves for the current octant and insert them in the
+pixel data\X;\6
+$\|p\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\|p=\\{spec\_head}$;\2\6
+\&{if} $\\{internal}[\\{tracing\_edges}]>0$ \1\&{then}\5
+\\{end\_edge\_tracing};\2\6
+$\\{toss\_knot\_list}(\\{spec\_head})$;\6
+\&{end};\par
+\fi
+
+\M507. In even-numbered octants we have reflected the coordinates an odd number
+of times, hence clockwise and counterclockwise are reversed; this means that
+the envelope is being formed in a ``dual'' manner. For the time being, let's
+concentrate on odd-numbered octants, since they're easier to understand.
+After we have coded the program for odd-numbered octants, the changes needed
+to dualize it will not be so mysterious.
+
+It is convenient to assume that we enter an odd-numbered octant with
+an \\{axis} transition (where the skewed slope is zero) and leave at a
+\\{diagonal} one (where the skewed slope is infinite). Then all of the
+offset points $z(t)+w(t)$ will lie in a rectangle whose lower left and
+upper right corners are the initial and final offset points. If this
+assumption doesn't hold we can implicitly change the curve so that it does.
+For example, if the entering transition is diagonal, we can draw a
+straight line from $z_0+w_{n+1}$ to $z_0+w_0$ and continue as if the
+curve were moving rightward. The effect of this on the envelope is simply
+to ``doubly color'' the region enveloped by a section of the pen that
+goes from $w_0$ to $w_1$ to $\cdots$ to $w_{n+1}$ to~$w_0$. The additional
+straight line at the beginning (and a similar one at the end, where it
+may be necessary to go from $z_1+w_{n+1}$ to $z_1+w_0$) can be drawn by
+the \\{line\_edges} routine; we are thereby saved from the embarrassment that
+these lines travel backwards from the current octant direction.
+
+Once we have established the assumption that the curve goes from
+$z_0+w_0$ to $z_1+w_{n+1}$, any further retrograde moves that might
+occur within the octant can be essentially ignored; we merely need to
+keep track of the rightmost edge in each row, in order to compute
+the envelope.
+
+Envelope moves consist of offset cubics intermixed with straight line
+segments. We record them in a separate \\{env\_move} array, which is
+something like \\{move} but it keeps track of the rightmost position of the
+envelope in each row.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{env\_move}: \37\&{array} $[0\to\\{move\_size}]$ \1\&{of}\5
+\\{integer};\2\par
+\fi
+
+\M508. \P$\X508:Determine the envelope's starting and ending lattice points $(%
+\\{m0},\\{n0})$ and $(\\{m1},\\{n1})$\X\S$\6
+$\|w\K\\{link}(\|h)$;\ \&{if} $\\{left\_transition}(\|p)=\\{diagonal}$ \1%
+\&{then}\5
+$\|w\K\\{knil}(\|w)$;\2\6
+\&{stat} \37\&{if} $\\{internal}[\\{tracing\_edges}]>\\{unity}$ \1\&{then}\5
+\X509:Print a line of diagnostic info to introduce this octant\X;\2\6
+\&{tats}\6
+$\\{ww}\K\\{link}(\|h)$;\5
+$\\{www}\K\\{ww}$;\C{starting and ending offsets}\6
+\&{if} $\\{odd}(\\{octant\_number}[\\{octant}])$ \1\&{then}\5
+$\\{www}\K\\{knil}(\\{www})$\ \&{else} $\\{ww}\K\\{knil}(\\{ww})$;\2\6
+\&{if} $\|w\I\\{ww}$ \1\&{then}\5
+$\\{skew\_line\_edges}(\|p,\39\|w,\39\\{ww})$;\2\6
+$\\{end\_round}(\\{x\_coord}(\|p)+\\{x\_coord}(\\{ww}),\39\\{y\_coord}(\|p)+%
+\\{y\_coord}(\\{ww}))$;\5
+$\\{m0}\K\\{m1}$;\5
+$\\{n0}\K\\{n1}$;\5
+$\\{d0}\K\\{d1}$;\6
+$\\{end\_round}(\\{x\_coord}(\|q)+\\{x\_coord}(\\{www}),\39\\{y\_coord}(\|q)+%
+\\{y\_coord}(\\{www}))$;\6
+\&{if} $\\{n1}-\\{n0}\G\\{move\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"move\ table\ size"},\39\\{move\_size})$\2\par
+\U506.\fi
+
+\M509. \P$\X509:Print a line of diagnostic info to introduce this octant\X\S$\6
+\&{begin} \37$\\{print\_nl}(\.{"@\ Octant\ "})$;\5
+$\\{print}(\\{octant\_dir}[\\{octant}])$;\5
+$\\{print}(\.{"\ ("})$;\5
+$\\{print\_int}(\\{info}(\|h))$;\5
+$\\{print}(\.{"\ offset"})$;\6
+\&{if} $\\{info}(\|h)\I1$ \1\&{then}\5
+$\\{print\_char}(\.{"s"})$;\2\6
+$\\{print}(\.{"),\ from\ "})$;\5
+$\\{print\_two\_true}(\\{x\_coord}(\|p)+\\{x\_coord}(\|w),\39\\{y\_coord}(\|p)+%
+\\{y\_coord}(\|w))$;\5
+$\\{ww}\K\\{link}(\|h)$;\ \&{if} $\\{right\_transition}(\|q)=\\{diagonal}$ \1%
+\&{then}\5
+$\\{ww}\K\\{knil}(\\{ww})$;\2\6
+$\\{print}(\.{"\ to\ "})$;\5
+$\\{print\_two\_true}(\\{x\_coord}(\|q)+\\{x\_coord}(\\{ww}),\39\\{y\_coord}(%
+\|q)+\\{y\_coord}(\\{ww}))$;\6
+\&{end}\par
+\U508.\fi
+
+\M510. A slight variation of the \\{line\_edges} procedure comes in handy
+when we must draw the retrograde lines for nonstandard entry and exit
+conditions.
+
+\Y\P$\4\X510:Declare the procedure called \\{skew\_line\_edges}\X\S$\6
+\4\&{procedure}\1\ \37$\\{skew\_line\_edges}(\|p,\39\|w,\39\\{ww}:%
+\\{pointer})$;\6
+\4\&{var} \37$\\{x0},\39\\{y0},\39\\{x1},\39\\{y1}$: \37\\{scaled};\C{from and
+to}\2\6
+\&{begin} \37\&{if} $(\\{x\_coord}(\|w)\I\\{x\_coord}(\\{ww}))\V(\\{y\_coord}(%
+\|w)\I\\{y\_coord}(\\{ww}))$ \1\&{then}\6
+\&{begin} \37$\\{x0}\K\\{x\_coord}(\|p)+\\{x\_coord}(\|w)$;\5
+$\\{y0}\K\\{y\_coord}(\|p)+\\{y\_coord}(\|w)$;\6
+$\\{x1}\K\\{x\_coord}(\|p)+\\{x\_coord}(\\{ww})$;\5
+$\\{y1}\K\\{y\_coord}(\|p)+\\{y\_coord}(\\{ww})$;\6
+$\\{unskew}(\\{x0},\39\\{y0},\39\\{octant})$;\C{unskew and unrotate the
+coordinates}\6
+$\\{x0}\K\\{cur\_x}$;\5
+$\\{y0}\K\\{cur\_y}$;\6
+$\\{unskew}(\\{x1},\39\\{y1},\39\\{octant})$;\6
+\&{stat} \37\&{if} $\\{internal}[\\{tracing\_edges}]>\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"@\ retrograde\ line\ from\ "})$;\5
+$\\{print\_two}(\\{x0},\39\\{y0})$;\5
+$\\{print}(\.{"\ to\ "})$;\5
+$\\{print\_two}(\\{cur\_x},\39\\{cur\_y})$;\5
+$\\{print\_nl}(\.{""})$;\6
+\&{end};\ \2\6
+\&{tats}\6
+$\\{line\_edges}(\\{x0},\39\\{y0},\39\\{cur\_x},\39\\{cur\_y})$;\C{then draw a
+straight line}\6
+\&{end};\2\6
+\&{end};\par
+\U506.\fi
+
+\M511. The envelope calculations require more local variables than we needed
+in the simpler case of \\{fill\_spec}. At critical points in the computation,
+\|w will point to offset $w_k$; \|m and \|n will record the current
+lattice positions. The values of \\{move\_ptr} after the initial and before
+the final offset adjustments are stored in \\{smooth\_bot} and \\{smooth\_top},
+respectively.
+
+\Y\P$\4\X511:Other local variables for \\{fill\_envelope}\X\S$\6
+\4$\|m,\39\|n$: \37\\{integer};\C{current lattice position}\6
+\4$\\{mm0},\39\\{mm1}$: \37\\{integer};\C{skewed equivalents of \\{m0} and %
+\\{m1}}\6
+\4\|k: \37\\{integer};\C{current offset number}\6
+\4$\|w,\39\\{ww}$: \37\\{pointer};\C{pointers to the current offset and its
+neighbor}\6
+\4$\\{smooth\_bot},\39\\{smooth\_top}$: \37$0\to\\{move\_size}$;\C{boundaries
+of smoothing}\6
+\4$\\{xx},\39\\{yy},\39\\{xp},\39\\{yp},\39\\{delx},\39\\{dely},\39\\{tx},\39%
+\\{ty}$: \37\\{scaled};\C{registers for coordinate calculations}\par
+\Us506\ET518.\fi
+
+\M512. \P$\X512:Make the envelope moves for the current octant and insert them
+in the pixel data\X\S$\6
+\&{if} $\\{odd}(\\{octant\_number}[\\{octant}])$ \1\&{then}\6
+\&{begin} \37\X513:Initialize for ordinary envelope moves\X;\6
+$\|r\K\|p$;\5
+$\\{right\_type}(\|q)\K\\{info}(\|h)+1$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\|r=\|q$ \1\&{then}\5
+$\\{smooth\_top}\K\\{move\_ptr}$;\2\6
+\&{while} $\\{right\_type}(\|r)\I\|k$ \1\&{do}\5
+\X515:Insert a line segment to approach the correct offset\X;\2\6
+\&{if} $\|r=\|p$ \1\&{then}\5
+$\\{smooth\_bot}\K\\{move\_ptr}$;\2\6
+\&{if} $\|r=\|q$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{move}[\\{move\_ptr}]\K1$;\5
+$\|n\K\\{move\_ptr}$;\5
+$\|s\K\\{link}(\|r)$;\6
+$\\{make\_moves}(\\{x\_coord}(\|r)+\\{x\_coord}(\|w),\39\\{right\_x}(\|r)+\\{x%
+\_coord}(\|w),\39\\{left\_x}(\|s)+\\{x\_coord}(\|w),\39\\{x\_coord}(\|s)+\\{x%
+\_coord}(\|w),\39\30\\{y\_coord}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit},\39%
+\\{right\_y}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit},\39\\{left\_y}(\|s)+\\{y%
+\_coord}(\|w)+\\{half\_unit},\39\\{y\_coord}(\|s)+\\{y\_coord}(\|w)+\\{half%
+\_unit},\39\30\\{xy\_corr}[\\{octant}],\39\\{y\_corr}[\\{octant}])$;\6
+\X514:Transfer moves from the \\{move} array to \\{env\_move}\X;\6
+$\|r\K\|s$;\6
+\&{end};\2\6
+\4\\{done}: \37\X517:Insert the new envelope moves in the pixel data\X;\6
+\&{end}\6
+\4\&{else} $\\{dual\_moves}(\|h,\39\|p,\39\|q)$;\2\6
+$\\{right\_type}(\|q)\K\\{endpoint}$\par
+\U506.\fi
+
+\M513. \P$\X513:Initialize for ordinary envelope moves\X\S$\6
+$\|k\K0$;\5
+$\|w\K\\{link}(\|h)$;\5
+$\\{ww}\K\\{knil}(\|w)$;\5
+$\\{mm0}\K\\{floor\_unscaled}(\\{x\_coord}(\|p)+\\{x\_coord}(\|w)-\\{xy\_corr}[%
+\\{octant}])$;\5
+$\\{mm1}\K\\{floor\_unscaled}(\\{x\_coord}(\|q)+\\{x\_coord}(\\{ww})-\\{xy%
+\_corr}[\\{octant}])$;\6
+\&{for} $\|n\K0\mathrel{\&{to}}\\{n1}-\\{n0}$ \1\&{do}\5
+$\\{env\_move}[\|n]\K\\{mm0}$;\2\6
+$\\{env\_move}[\\{n1}-\\{n0}]\K\\{mm1}$;\5
+$\\{move\_ptr}\K0$;\5
+$\|m\K\\{mm0}$\par
+\U512.\fi
+
+\M514. At this point \|n holds the value of \\{move\_ptr} that was current
+when \\{make\_moves} began to record its moves.
+
+\Y\P$\4\X514:Transfer moves from the \\{move} array to \\{env\_move}\X\S$\6
+\1\&{repeat} \37$\|m\K\|m+\\{move}[\|n]-1$;\6
+\&{if} $\|m>\\{env\_move}[\|n]$ \1\&{then}\5
+$\\{env\_move}[\|n]\K\|m$;\2\6
+$\\{incr}(\|n)$;\6
+\4\&{until}\5
+$\|n>\\{move\_ptr}$\2\par
+\U512.\fi
+
+\M515. Retrograde lines (when \|k decreases) do not need to be recorded in
+\\{env\_move} because their edges are not the furthest right in any row.
+
+\Y\P$\4\X515:Insert a line segment to approach the correct offset\X\S$\6
+\&{begin} \37$\\{xx}\K\\{x\_coord}(\|r)+\\{x\_coord}(\|w)$;\5
+$\\{yy}\K\\{y\_coord}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit}$;\6
+\&{stat} \37\&{if} $\\{internal}[\\{tracing\_edges}]>\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"@\ transition\ line\ "})$;\5
+$\\{print\_int}(\|k)$;\5
+$\\{print}(\.{",\ from\ "})$;\5
+$\\{print\_two\_true}(\\{xx},\39\\{yy}-\\{half\_unit})$;\6
+\&{end};\ \2\6
+\&{tats}\6
+\&{if} $\\{right\_type}(\|r)>\|k$ \1\&{then}\6
+\&{begin} \37$\\{incr}(\|k)$;\5
+$\|w\K\\{link}(\|w)$;\5
+$\\{xp}\K\\{x\_coord}(\|r)+\\{x\_coord}(\|w)$;\5
+$\\{yp}\K\\{y\_coord}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit}$;\6
+\&{if} $\\{yp}\I\\{yy}$ \1\&{then}\5
+\X516:Record a line segment from $(\\{xx},\\{yy})$ to $(\\{xp},\\{yp})$ in %
+\\{env\_move}\X;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{decr}(\|k)$;\5
+$\|w\K\\{knil}(\|w)$;\5
+$\\{xp}\K\\{x\_coord}(\|r)+\\{x\_coord}(\|w)$;\5
+$\\{yp}\K\\{y\_coord}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit}$;\6
+\&{end};\2\6
+\&{stat} \37\&{if} $\\{internal}[\\{tracing\_edges}]>\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"\ to\ "})$;\5
+$\\{print\_two\_true}(\\{xp},\39\\{yp}-\\{half\_unit})$;\5
+$\\{print\_nl}(\.{""})$;\6
+\&{end};\ \2\6
+\&{tats}\6
+$\|m\K\\{floor\_unscaled}(\\{xp}-\\{xy\_corr}[\\{octant}])$;\5
+$\\{move\_ptr}\K\\{floor\_unscaled}(\\{yp}-\\{y\_corr}[\\{octant}])-\\{n0}$;\6
+\&{if} $\|m>\\{env\_move}[\\{move\_ptr}]$ \1\&{then}\5
+$\\{env\_move}[\\{move\_ptr}]\K\|m$;\2\6
+\&{end}\par
+\U512.\fi
+
+\M516. In this step we have $\\{xp}\G\\{xx}$ and $\\{yp}\G\\{yy}$.
+
+\Y\P$\4\X516:Record a line segment from $(\\{xx},\\{yy})$ to $(\\{xp},\\{yp})$
+in \\{env\_move}\X\S$\6
+\&{begin} \37$\\{ty}\K\\{floor\_scaled}(\\{yy}-\\{y\_corr}[\\{octant}])$;\5
+$\\{dely}\K\\{yp}-\\{yy}$;\5
+$\\{yy}\K\\{yy}-\\{ty}$;\5
+$\\{ty}\K\\{yp}-\\{y\_corr}[\\{octant}]-\\{ty}$;\6
+\&{if} $\\{ty}\G\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{delx}\K\\{xp}-\\{xx}$;\5
+$\\{yy}\K\\{unity}-\\{yy}$;\6
+\~ \1\&{loop}\ \&{begin} \37$\\{tx}\K\\{take\_fraction}(\\{delx},\39\\{make%
+\_fraction}(\\{yy},\39\\{dely}))$;\6
+\&{if} $\\{ab\_vs\_cd}(\\{tx},\39\\{dely},\39\\{delx},\39\\{yy})+\\{xy\_corr}[%
+\\{octant}]>0$ \1\&{then}\5
+$\\{decr}(\\{tx})$;\2\6
+$\|m\K\\{floor\_unscaled}(\\{xx}+\\{tx})$;\6
+\&{if} $\|m>\\{env\_move}[\\{move\_ptr}]$ \1\&{then}\5
+$\\{env\_move}[\\{move\_ptr}]\K\|m$;\2\6
+$\\{ty}\K\\{ty}-\\{unity}$;\6
+\&{if} $\\{ty}<\\{unity}$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+$\\{yy}\K\\{yy}+\\{unity}$;\5
+$\\{incr}(\\{move\_ptr})$;\6
+\&{end};\2\6
+\4\\{done1}: \37\&{end};\2\6
+\&{end}\par
+\U515.\fi
+
+\M517. \P$\X517:Insert the new envelope moves in the pixel data\X\S$\6
+\&{debug} \37\&{if} $(\|m\I\\{mm1})\V(\\{move\_ptr}\I\\{n1}-\\{n0})$ \1\&{then}%
+\5
+$\\{confusion}(\.{"1"})$;\ \2\6
+\&{gubed}\6
+$\\{move}[0]\K\\{d0}+\\{env\_move}[0]-\\{mm0}$;\6
+\&{for} $\|n\K1\mathrel{\&{to}}\\{move\_ptr}$ \1\&{do}\5
+$\\{move}[\|n]\K\\{env\_move}[\|n]-\\{env\_move}[\|n-1]+1$;\2\6
+$\\{move}[\\{move\_ptr}]\K\\{move}[\\{move\_ptr}]-\\{d1}$;\6
+\&{if} $\\{internal}[\\{smoothing}]>0$ \1\&{then}\5
+$\\{smooth\_moves}(\\{smooth\_bot},\39\\{smooth\_top})$;\2\6
+$\\{move\_to\_edges}(\\{m0},\39\\{n0},\39\\{m1},\39\\{n1})$;\6
+\&{if} $\\{right\_transition}(\|q)=\\{axis}$ \1\&{then}\6
+\&{begin} \37$\|w\K\\{link}(\|h)$;\5
+$\\{skew\_line\_edges}(\|q,\39\\{knil}(\|w),\39\|w)$;\6
+\&{end}\2\par
+\U512.\fi
+
+\M518. We've done it all in the odd-octant case; the only thing remaining
+is to repeat the same ideas, upside down and/or backwards.
+
+The following code has been split off as a subprocedure of \\{fill\_envelope},
+because some \PASCAL\ compilers cannot handle procedures as large as
+\\{fill\_envelope} would otherwise be.
+
+\Y\P$\4\X518:Declare the procedure called \\{dual\_moves}\X\S$\6
+\4\&{procedure}\1\ \37$\\{dual\_moves}(\|h,\39\|p,\39\|q:\\{pointer})$;\6
+\4\&{label} \37$\\{done},\39\\{done1}$;\6
+\4\&{var} \37$\|r,\39\|s$: \37\\{pointer};\C{for list traversal}\6
+\X511:Other local variables for \\{fill\_envelope}\X\2\6
+\&{begin} \37\X519:Initialize for dual envelope moves\X;\6
+$\|r\K\|p$;\C{recall that $\\{right\_type}(\|q)=\\{endpoint}=0$ now}\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\|r=\|q$ \1\&{then}\5
+$\\{smooth\_top}\K\\{move\_ptr}$;\2\6
+\&{while} $\\{right\_type}(\|r)\I\|k$ \1\&{do}\5
+\X521:Insert a line segment dually to approach the correct offset\X;\2\6
+\&{if} $\|r=\|p$ \1\&{then}\5
+$\\{smooth\_bot}\K\\{move\_ptr}$;\2\6
+\&{if} $\|r=\|q$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{move}[\\{move\_ptr}]\K1$;\5
+$\|n\K\\{move\_ptr}$;\5
+$\|s\K\\{link}(\|r)$;\6
+$\\{make\_moves}(\\{x\_coord}(\|r)+\\{x\_coord}(\|w),\39\\{right\_x}(\|r)+\\{x%
+\_coord}(\|w),\39\\{left\_x}(\|s)+\\{x\_coord}(\|w),\39\\{x\_coord}(\|s)+\\{x%
+\_coord}(\|w),\39\30\\{y\_coord}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit},\39%
+\\{right\_y}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit},\39\\{left\_y}(\|s)+\\{y%
+\_coord}(\|w)+\\{half\_unit},\39\\{y\_coord}(\|s)+\\{y\_coord}(\|w)+\\{half%
+\_unit},\39\30\\{xy\_corr}[\\{octant}],\39\\{y\_corr}[\\{octant}])$;\5
+\X520:Transfer moves dually from the \\{move} array to \\{env\_move}\X;\6
+$\|r\K\|s$;\6
+\&{end};\2\6
+\4\\{done}: \37\X523:Insert the new envelope moves dually in the pixel data\X;\6
+\&{end};\par
+\U506.\fi
+
+\M519. In the dual case the normal situation is to arrive with a \\{diagonal}
+transition and to leave at the \\{axis}. The leftmost edge in each row
+is relevant instead of the rightmost one.
+
+\Y\P$\4\X519:Initialize for dual envelope moves\X\S$\6
+$\|k\K\\{info}(\|h)+1$;\5
+$\\{ww}\K\\{link}(\|h)$;\5
+$\|w\K\\{knil}(\\{ww})$;\6
+$\\{mm0}\K\\{floor\_unscaled}(\\{x\_coord}(\|p)+\\{x\_coord}(\|w)-\\{xy\_corr}[%
+\\{octant}])$;\5
+$\\{mm1}\K\\{floor\_unscaled}(\\{x\_coord}(\|q)+\\{x\_coord}(\\{ww})-\\{xy%
+\_corr}[\\{octant}])$;\6
+\&{for} $\|n\K1\mathrel{\&{to}}\\{n1}-\\{n0}+1$ \1\&{do}\5
+$\\{env\_move}[\|n]\K\\{mm1}$;\2\6
+$\\{env\_move}[0]\K\\{mm0}$;\5
+$\\{move\_ptr}\K0$;\5
+$\|m\K\\{mm0}$\par
+\U518.\fi
+
+\M520. \P$\X520:Transfer moves dually from the \\{move} array to \\{env\_move}%
+\X\S$\6
+\1\&{repeat} \37\&{if} $\|m<\\{env\_move}[\|n]$ \1\&{then}\5
+$\\{env\_move}[\|n]\K\|m$;\2\6
+$\|m\K\|m+\\{move}[\|n]-1$;\5
+$\\{incr}(\|n)$;\6
+\4\&{until}\5
+$\|n>\\{move\_ptr}$\2\par
+\U518.\fi
+
+\M521. Dual retrograde lines occur when \|k increases; the edges of such lines
+are not the furthest left in any row.
+
+\Y\P$\4\X521:Insert a line segment dually to approach the correct offset\X\S$\6
+\&{begin} \37$\\{xx}\K\\{x\_coord}(\|r)+\\{x\_coord}(\|w)$;\5
+$\\{yy}\K\\{y\_coord}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit}$;\6
+\&{stat} \37\&{if} $\\{internal}[\\{tracing\_edges}]>\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"@\ transition\ line\ "})$;\5
+$\\{print\_int}(\|k)$;\5
+$\\{print}(\.{",\ from\ "})$;\5
+$\\{print\_two\_true}(\\{xx},\39\\{yy}-\\{half\_unit})$;\6
+\&{end};\ \2\6
+\&{tats}\6
+\&{if} $\\{right\_type}(\|r)<\|k$ \1\&{then}\6
+\&{begin} \37$\\{decr}(\|k)$;\5
+$\|w\K\\{knil}(\|w)$;\5
+$\\{xp}\K\\{x\_coord}(\|r)+\\{x\_coord}(\|w)$;\5
+$\\{yp}\K\\{y\_coord}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit}$;\6
+\&{if} $\\{yp}\I\\{yy}$ \1\&{then}\5
+\X522:Record a line segment from $(\\{xx},\\{yy})$ to $(\\{xp},\\{yp})$ dually
+in \\{env\_move}\X;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{incr}(\|k)$;\5
+$\|w\K\\{link}(\|w)$;\5
+$\\{xp}\K\\{x\_coord}(\|r)+\\{x\_coord}(\|w)$;\5
+$\\{yp}\K\\{y\_coord}(\|r)+\\{y\_coord}(\|w)+\\{half\_unit}$;\6
+\&{end};\2\6
+\&{stat} \37\&{if} $\\{internal}[\\{tracing\_edges}]>\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"\ to\ "})$;\5
+$\\{print\_two\_true}(\\{xp},\39\\{yp}-\\{half\_unit})$;\5
+$\\{print\_nl}(\.{""})$;\6
+\&{end};\ \2\6
+\&{tats}\6
+$\|m\K\\{floor\_unscaled}(\\{xp}-\\{xy\_corr}[\\{octant}])$;\5
+$\\{move\_ptr}\K\\{floor\_unscaled}(\\{yp}-\\{y\_corr}[\\{octant}])-\\{n0}$;\6
+\&{if} $\|m<\\{env\_move}[\\{move\_ptr}]$ \1\&{then}\5
+$\\{env\_move}[\\{move\_ptr}]\K\|m$;\2\6
+\&{end}\par
+\U518.\fi
+
+\M522. Again, $\\{xp}\G\\{xx}$ and $\\{yp}\G\\{yy}$; but this time we are
+interested in the {\sl
+smallest\/} \|m that belongs to a given \\{move\_ptr} position, instead of
+the largest~\|m.
+
+\Y\P$\4\X522:Record a line segment from $(\\{xx},\\{yy})$ to $(\\{xp},\\{yp})$
+dually in \\{env\_move}\X\S$\6
+\&{begin} \37$\\{ty}\K\\{floor\_scaled}(\\{yy}-\\{y\_corr}[\\{octant}])$;\5
+$\\{dely}\K\\{yp}-\\{yy}$;\5
+$\\{yy}\K\\{yy}-\\{ty}$;\5
+$\\{ty}\K\\{yp}-\\{y\_corr}[\\{octant}]-\\{ty}$;\6
+\&{if} $\\{ty}\G\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{delx}\K\\{xp}-\\{xx}$;\5
+$\\{yy}\K\\{unity}-\\{yy}$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\|m<\\{env\_move}[\\{move\_ptr}]$ \1%
+\&{then}\5
+$\\{env\_move}[\\{move\_ptr}]\K\|m$;\2\6
+$\\{tx}\K\\{take\_fraction}(\\{delx},\39\\{make\_fraction}(\\{yy},\39%
+\\{dely}))$;\6
+\&{if} $\\{ab\_vs\_cd}(\\{tx},\39\\{dely},\39\\{delx},\39\\{yy})+\\{xy\_corr}[%
+\\{octant}]>0$ \1\&{then}\5
+$\\{decr}(\\{tx})$;\2\6
+$\|m\K\\{floor\_unscaled}(\\{xx}+\\{tx})$;\5
+$\\{ty}\K\\{ty}-\\{unity}$;\5
+$\\{incr}(\\{move\_ptr})$;\6
+\&{if} $\\{ty}<\\{unity}$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+$\\{yy}\K\\{yy}+\\{unity}$;\6
+\&{end};\2\6
+\4\\{done1}: \37\&{if} $\|m<\\{env\_move}[\\{move\_ptr}]$ \1\&{then}\5
+$\\{env\_move}[\\{move\_ptr}]\K\|m$;\2\6
+\&{end};\2\6
+\&{end}\par
+\U521.\fi
+
+\M523. Since \\{env\_move} contains minimum values instead of maximum values,
+the
+finishing-up process is slightly different in the dual case.
+
+\Y\P$\4\X523:Insert the new envelope moves dually in the pixel data\X\S$\6
+\&{debug} \37\&{if} $(\|m\I\\{mm1})\V(\\{move\_ptr}\I\\{n1}-\\{n0})$ \1\&{then}%
+\5
+$\\{confusion}(\.{"2"})$;\ \2\6
+\&{gubed}\6
+$\\{move}[0]\K\\{d0}+\\{env\_move}[1]-\\{mm0}$;\6
+\&{for} $\|n\K1\mathrel{\&{to}}\\{move\_ptr}$ \1\&{do}\5
+$\\{move}[\|n]\K\\{env\_move}[\|n+1]-\\{env\_move}[\|n]+1$;\2\6
+$\\{move}[\\{move\_ptr}]\K\\{move}[\\{move\_ptr}]-\\{d1}$;\6
+\&{if} $\\{internal}[\\{smoothing}]>0$ \1\&{then}\5
+$\\{smooth\_moves}(\\{smooth\_bot},\39\\{smooth\_top})$;\2\6
+$\\{move\_to\_edges}(\\{m0},\39\\{n0},\39\\{m1},\39\\{n1})$;\6
+\&{if} $\\{right\_transition}(\|q)=\\{diagonal}$ \1\&{then}\6
+\&{begin} \37$\|w\K\\{link}(\|h)$;\5
+$\\{skew\_line\_edges}(\|q,\39\|w,\39\\{knil}(\|w))$;\6
+\&{end}\2\par
+\U518.\fi
+
+\N524. \[25] Elliptical pens.
+To get the envelope of a cyclic path with respect to an ellipse, \MF\
+calculates the envelope with respect to a polygonal approximation to
+the ellipse, using an approach due to John Hobby (Ph.D. thesis,
+Stanford University, 1985).
+This has two important advantages over trying to obtain the ``exact''
+envelope:
+
+\yskip\textindent{1)}It gives better results, because the polygon has been
+designed to counteract problems that arise from digitization; the
+polygon includes sub-pixel corrections to an exact ellipse that make
+the results essentially independent of where the path falls on the raster.
+For example, the exact envelope with respect to a pen of diameter~1
+blackens a pixel if and only if the path intersects a circle of diameter~1
+inscribed in that pixel; the resulting pattern has ``blots'' when the path
+is travelling diagonally in unfortunate raster positions. A much better
+result is obtained when pixels are blackened only when the path intersects
+an inscribed {\sl diamond\/} of diameter~1. Such a diamond is precisely
+the polygon that \MF\ uses in the special case of a circle whose diameter is~1.
+
+\yskip\textindent{2)}Polygonal envelopes of cubic splines are cubic
+splines, hence it isn't necessary to introduce completely different
+routines. By contrast, exact envelopes of cubic splines with respect
+to circles are complicated curves, more difficult to plot than cubics.
+
+\fi
+
+\M525. Hobby's construction involves some interesting number theory.
+If $u$ and~$v$ are relatively prime integers, we divide the
+set of integer points $(m,n)$ into equivalence classes by saying
+that $(m,n)$ belongs to class $um+vn$. Then any two integer points
+that lie on a line of slope $-u/v$ belong to the same class, because
+such points have the form $(m+tv,n-tu)$. Neighboring lines of slope $-u/v$
+that go through integer points are separated by distance $1/\psqrt{u^2+v^2}$
+from each other, and these lines are perpendicular to lines of slope~$v/u$.
+If we start at the origin and travel a distance $k/\psqrt{u^2+v^2}$ in
+direction $(u,v)$, we reach the line of slope~$-u/v$ whose points
+belong to class~$k$.
+
+For example, let $u=2$ and $v=3$. Then the points $(0,0)$, $(3,-2)$,
+$\ldots$ belong to class~0; the points $(-1,1)$, $(2,-1)$, $\ldots$ belong
+to class~1; and the distance between these two lines is $1/\sqrt{13}$.
+The point $(2,3)$ itself belongs to class~13, hence its distance from
+the origin is $13/\sqrt{13}=\sqrt{13}$ (which we already knew).
+
+Suppose we wish to plot envelopes with respect to polygons with
+integer vertices. Then the best polygon for curves that travel in
+direction $(v,-u)$ will contain the points of class~$k$ such that
+$k/\psqrt{u^2+v^2}$ is as close as possible to~$d$, where $d$ is the
+maximum distance of the given ellipse from the line $ux+vy=0$.
+
+The \\{fillin} correction assumes that a diagonal line has an
+apparent thickness $$2f\cdot\min(\vert u\vert,\vert v\vert)/\psqrt{u^2+v^2}$$
+greater than would be obtained with truly square pixels. (If a
+white pixel at an exterior corner is assumed to have apparent
+darkness $f_1$ and a black pixel at an interior corner is assumed
+to have apparent darkness $1-f_2$, then $f=f_1-f_2$ is the \\{fillin}
+parameter.) Under this assumption we want to choose $k$ so that
+$\bigl(k+2f\cdot\min(\vert u\vert,\vert v\vert)\bigr)\big/\psqrt{u^2+v^2}$
+is as close as possible to $d$.
+
+Integer coordinates for the vertices work nicely because the thickness of
+the envelope at any given slope is independent of the position of the
+path with respect to the raster. It turns out, in fact, that the same
+property holds for polygons whose vertices have coordinates that are
+integer multiples of~$1\over2$, because ellipses are symmetric about
+the origin. It's convenient to double all dimensions and require the
+resulting polygon to have vertices with integer coordinates. For example,
+to get a circle of {\sl diameter}~$r$, we shall compute integer
+coordinates for a circle of {\sl radius}~$r$. The circle of radius~$r$
+will want to be represented by a polygon that contains the boundary
+points $(0,\pm r)$ and~$(\pm r,0)$; later we will divide everything
+by~2 and get a polygon with $(0,\pm{1\over2}r)$ and $(\pm{1\over2}r,0)$
+on its boundary.
+
+\fi
+
+\M526. In practice the important slopes are those having small values of
+$u$ and~$v$; these make regular patterns in which our eyes quickly
+spot irregularities. For example, horizontal and vertical lines
+(when $u=0$ and $\vert v\vert=1$, or $\vert u\vert=1$ and $v=0$)
+are the most important; diagonal lines (when $\vert u\vert=\vert v\vert=1$)
+are next; and then come lines with slope $\pm2$ or $\pm1/2$.
+
+The nicest way to generate all rational directions having small
+numerators and denominators is to generalize the Stern-Brocot tree
+[cf.~{\sl Concrete Mathematics}, section 4.5]
+to a ``Stern-Brocot wreath'' as follows: Begin with four nodes
+arranged in a circle, containing the respective directions
+$(u,v)=(1,0)$, $(0,1)$, $(-1,0)$, and~$(0,-1)$. Then between pairs of
+consecutive terms $(u,v)$ and $(u',v')$ of the wreath, insert the
+direction $(u+u',v+v')$; continue doing this until some stopping
+criterion is fulfilled.
+
+It is not difficult to verify that, regardless of the stopping
+criterion, consecutive directions $(u,v)$ and $(u',v')$ of this
+wreath will always satisfy the relation $uv'-u'v=1$. Such pairs
+of directions have a nice property with respect to the equivalence
+classes described above. Let $l$ be a line of equivalent integer points
+$(m+tv,n-tu)$ with respect to~$(u,v)$, and let $l'$ be a line of
+equivalent integer points $(m'+tv',n'-tu')$ with respect to~$(u',v')$.
+Then $l$ and~$l'$ intersect in an integer point $(m'',n'')$, because
+the determinant of the linear equations for intersection is $uv'-u'v=1$.
+Notice that the class number of $(m'',n'')$ with respect to $(u+u',v+v')$
+is the sum of its class numbers with respect to $(u,v)$ and~$(u',v')$.
+Moreover, consecutive points on~$l$ and~$l'$ belong to classes that
+differ by exactly~1 with respect to $(u+u',v+v')$.
+
+This leads to a nice algorithm in which we construct a polygon having
+``correct'' class numbers for as many small-integer directions $(u,v)$
+as possible: Assuming that lines $l$ and~$l'$ contain points of the
+correct class for $(u,v)$ and~$(u',v')$, respectively, we determine
+the intersection $(m'',n'')$ and compute its class with respect to
+$(u+u',v+v')$. If the class is too large to be the best approximation,
+we move back the proper number of steps from $(m'',n'')$ toward smaller
+class numbers on both $l$ and~$l'$, unless this requires moving to points
+that are no longer in the polygon; in this we arrive at two points that
+determine a line~$l''$ having the appropriate class. The process continues
+recursively, until it cannot proceed without removing the last remaining
+point from the class for $(u,v)$ or the class for $(u',v')$.
+
+\fi
+
+\M527. The \\{make\_ellipse} subroutine produces a pointer to a cyclic path
+whose vertices define a polygon suitable for envelopes. The control
+points on this path will be ignored; in fact, the fields in knot nodes
+that are usually reserved for control points are occupied by other
+data that helps \\{make\_ellipse} compute the desired polygon.
+
+Parameters \\{major\_axis} and \\{minor\_axis} define the axes of the ellipse;
+and parameter \\{theta} is an angle by which the ellipse is rotated
+counterclockwise. If $\\{theta}=0$, the ellipse has the equation
+$(x/a)^2+(y/b)^2=1$, where $\|a=\\{major\_axis}/2$ and $\|b=\\{minor\_axis}/2$.
+In general, the points of the ellipse are generated in the complex plane
+by the formula $e^{i\theta}(a\cos t+ib\sin t)$, as $t$~ranges over all
+angles. Notice that if $\\{major\_axis}=\\{minor\_axis}=\|d$, we obtain a
+circle
+of diameter~\|d, regardless of the value of \\{theta}.
+
+The method sketched above is used to produce the elliptical polygon,
+except that the main work is done only in the halfplane obtained from
+the three starting directions $(0,-1)$, $(1,0)$,~$(0,1)$. Since the ellipse
+has circular symmetry, we use the fact that the last half of the polygon
+is simply the negative of the first half. Furthermore, we need to compute only
+one quarter of the polygon if the ellipse has axis symmetry.
+
+\Y\P\4\&{function}\1\ \37$\\{make\_ellipse}(\\{major\_axis},\39\\{minor%
+\_axis}:\\{scaled};\,\35\\{theta}:\\{angle})$: \37\\{pointer};\6
+\4\&{label} \37$\\{done},\39\\{done1},\39\\{found}$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s$: \37\\{pointer};\C{for list
+manipulation}\6
+\|h: \37\\{pointer};\C{head of the constructed knot list}\6
+$\\{alpha},\39\\{beta},\39\\{gamma},\39\\{delta}$: \37\\{integer};\C{special
+points}\6
+$\|c,\39\|d$: \37\\{integer};\C{class numbers}\6
+$\|u,\39\|v$: \37\\{integer};\C{directions}\6
+\\{symmetric}: \37\\{boolean};\C{should the result be symmetric about the
+axes?}\2\6
+\&{begin} \37\X528:Initialize the ellipse data structure by beginning with
+directions $(0,-1)$, $(1,0)$, $(0,1)$\X;\6
+\X531:Interpolate new vertices in the ellipse data structure until improvement
+is impossible\X;\6
+\&{if} $\\{symmetric}$ \1\&{then}\5
+\X536:Complete the half ellipse by reflecting the quarter already computed\X;\2%
+\6
+\X537:Complete the ellipse by copying the negative of the half already computed%
+\X;\6
+$\\{make\_ellipse}\K\|h$;\6
+\&{end};\par
+\fi
+
+\M528. A special data structure is used only with \\{make\_ellipse}: The
+\\{right\_x}, \\{left\_x}, \\{right\_y}, and \\{left\_y} fields of knot nodes
+are renamed \\{right\_u}, \\{left\_v}, \\{right\_class}, and \\{left\_length},
+in order to store information that simplifies the necessary computations.
+
+If \|p and \|q are consecutive knots in this data structure, the
+\\{x\_coord} and \\{y\_coord} fields of \|p and~\|q contain current vertices
+of the polygon; their values are integer multiples
+of \\{half\_unit}. Both of these vertices belong to equivalence class
+$\\{right\_class}(\|p)$ with respect to the direction
+$\bigl($$\\{right\_u}(\|p),\\{left\_v}(\|q)$$\bigr)$. The number of points of
+this class
+on the line from vertex~\|p to vertex~\|q is $1+\\{left\_length}(\|q)$.
+In particular, $\\{left\_length}(\|q)=0$ means that $\\{x\_coord}(\|p)=\\{x%
+\_coord}(\|q)$
+and $\\{y\_coord}(\|p)=\\{y\_coord}(\|q)$; such duplicate vertices will be
+discarded during the course of the algorithm.
+
+The contents of $\\{right\_u}(\|p)$ and $\\{left\_v}(\|q)$ are integer
+multiples
+of \\{half\_unit}, just like the coordinate fields. Hence, for example,
+the point $\bigl($$\\{x\_coord}(\|p)-\\{left\_v}(\|q),\\{y\_coord}(\|p)+%
+\\{right\_u}(\|q)$$\bigr)$
+also belongs to class number $\\{right\_class}(\|p)$. This point is one
+step closer to the vertex in node~\|q; it equals that vertex
+if and only if $\\{left\_length}(\|q)=1$.
+
+The \\{left\_type} and \\{right\_type} fields are not used, but \\{link}
+has its normal meaning.
+
+To start the process, we create four nodes for the three directions
+$(0,-1)$, $(1,0)$, and $(0,1)$. The corresponding vertices are
+$(-\alpha,-\beta)$, $(\gamma,-\beta)$, $(\gamma,\beta)$, and
+$(\alpha,\beta)$, where $(\alpha,\beta)$ is a half-integer approximation
+to where the ellipse rises highest above the $x$-axis, and where
+$\gamma$ is a half-integer approximation to the maximum $x$~coordinate
+of the ellipse. The fourth of these nodes is not actually calculated
+if the ellipse has axis symmetry.
+
+\Y\P\D \37$\\{right\_u}\S\\{right\_x}$\C{\|u value for a pen edge}\par
+\P\D \37$\\{left\_v}\S\\{left\_x}$\C{\|v value for a pen edge}\par
+\P\D \37$\\{right\_class}\S\\{right\_y}$\C{equivalence class number of a pen
+edge}\par
+\P\D \37$\\{left\_length}\S\\{left\_y}$\C{length of a pen edge}\par
+\Y\P$\4\X528:Initialize the ellipse data structure by beginning with directions
+$(0,-1)$, $(1,0)$, $(0,1)$\X\S$\6
+\X530:Calculate integers $\alpha$, $\beta$, $\gamma$ for the vertex coordinates%
+\X;\6
+$\|p\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\|q\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\|r\K\\{get\_node}(\\{knot\_node\_size})$;\6
+\&{if} $\\{symmetric}$ \1\&{then}\5
+$\|s\K\\{null}$\ \&{else} $\|s\K\\{get\_node}(\\{knot\_node\_size})$;\2\6
+$\|h\K\|p$;\5
+$\\{link}(\|p)\K\|q$;\5
+$\\{link}(\|q)\K\|r$;\5
+$\\{link}(\|r)\K\|s$;\C{$\|s=\\{null}$ or $\\{link}(\|s)=\\{null}$}\6
+\X529:Revise the values of $\alpha$, $\beta$, $\gamma$, if necessary, so that
+degenerate lines of length zero will not be obtained\X;\6
+$\\{x\_coord}(\|p)\K-\\{alpha}\ast\\{half\_unit}$;\5
+$\\{y\_coord}(\|p)\K-\\{beta}\ast\\{half\_unit}$;\5
+$\\{x\_coord}(\|q)\K\\{gamma}\ast\\{half\_unit}$;\6
+$\\{y\_coord}(\|q)\K\\{y\_coord}(\|p)$;\5
+$\\{x\_coord}(\|r)\K\\{x\_coord}(\|q)$;\6
+$\\{right\_u}(\|p)\K0$;\5
+$\\{left\_v}(\|q)\K-\\{half\_unit}$;\6
+$\\{right\_u}(\|q)\K\\{half\_unit}$;\5
+$\\{left\_v}(\|r)\K0$;\6
+$\\{right\_u}(\|r)\K0$;\5
+$\\{right\_class}(\|p)\K\\{beta}$;\5
+$\\{right\_class}(\|q)\K\\{gamma}$;\5
+$\\{right\_class}(\|r)\K\\{beta}$;\6
+$\\{left\_length}(\|q)\K\\{gamma}+\\{alpha}$;\6
+\&{if} $\\{symmetric}$ \1\&{then}\6
+\&{begin} \37$\\{y\_coord}(\|r)\K0$;\5
+$\\{left\_length}(\|r)\K\\{beta}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{y\_coord}(\|r)\K-\\{y\_coord}(\|p)$;\5
+$\\{left\_length}(\|r)\K\\{beta}+\\{beta}$;\6
+$\\{x\_coord}(\|s)\K-\\{x\_coord}(\|p)$;\5
+$\\{y\_coord}(\|s)\K\\{y\_coord}(\|r)$;\6
+$\\{left\_v}(\|s)\K\\{half\_unit}$;\5
+$\\{left\_length}(\|s)\K\\{gamma}-\\{alpha}$;\6
+\&{end}\2\par
+\U527.\fi
+
+\M529. One of the important invariants of the pen data structure is that
+the points are distinct. We may need to correct the pen specification
+in order to avoid this. (The result of \&{pencircle} will always be at
+least one pixel wide and one pixel tall, although \&{makepen} is
+capable of producing smaller pens.)
+
+\Y\P$\4\X529:Revise the values of $\alpha$, $\beta$, $\gamma$, if necessary, so
+that degenerate lines of length zero will not be obtained\X\S$\6
+\&{if} $\\{beta}=0$ \1\&{then}\5
+$\\{beta}\K1$;\2\6
+\&{if} $\\{gamma}=0$ \1\&{then}\5
+$\\{gamma}\K1$;\2\6
+\&{if} $\\{gamma}\L\\{abs}(\\{alpha})$ \1\&{then}\6
+\&{if} $\\{alpha}>0$ \1\&{then}\5
+$\\{alpha}\K\\{gamma}-1$\6
+\4\&{else} $\\{alpha}\K1-\\{gamma}$\2\2\par
+\U528.\fi
+
+\M530. If $a$ and $b$ are the semi-major and semi-minor axes,
+the given ellipse rises highest above the $y$-axis at the point
+$\bigl((a^2-b^2)\sin\theta\cos\theta/\rho\bigr)+i\rho$, where
+$\rho=\sqrt{(a\sin\theta)^2+(b\cos\theta)^2}$. It reaches
+furthest to the right of~the $x$-axis at the point
+$\sigma+i(a^2-b^2)\sin\theta\cos\theta/\sigma$, where
+$\sigma=\sqrt{(a\cos\theta)^2+(b\sin\theta)^2}$.
+
+\Y\P$\4\X530:Calculate integers $\alpha$, $\beta$, $\gamma$ for the vertex
+coordinates\X\S$\6
+\&{if} $(\\{major\_axis}=\\{minor\_axis})\V(\\{theta}\mathbin{\&{mod}}\\{ninety%
+\_deg}=0)$ \1\&{then}\6
+\&{begin} \37$\\{symmetric}\K\\{true}$;\5
+$\\{alpha}\K0$;\6
+\&{if} $\\{odd}(\\{theta}\mathbin{\&{div}}\\{ninety\_deg})$ \1\&{then}\6
+\&{begin} \37$\\{beta}\K\\{major\_axis}$;\5
+$\\{gamma}\K\\{minor\_axis}$;\5
+$\\{n\_sin}\K\\{fraction\_one}$;\5
+$\\{n\_cos}\K0$;\C{\\{n\_sin} and \\{n\_cos} are used later}\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{beta}\K\\{minor\_axis}$;\5
+$\\{gamma}\K\\{major\_axis}$;\6
+\&{end};\C{\\{n\_sin} and \\{n\_cos} aren't needed in this case}\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{symmetric}\K\\{false}$;\5
+$\\{n\_sin\_cos}(\\{theta})$;\C{set up $\\{n\_sin}=\sin\theta$ and $\\{n\_cos}=%
+\cos\theta$}\6
+$\\{gamma}\K\\{take\_fraction}(\\{major\_axis},\39\\{n\_sin})$;\5
+$\\{delta}\K\\{take\_fraction}(\\{minor\_axis},\39\\{n\_cos})$;\5
+$\\{beta}\K\\{pyth\_add}(\\{gamma},\39\\{delta})$;\5
+$\\{alpha}\K\\{take\_fraction}(\\{take\_fraction}(\\{major\_axis},\39\\{make%
+\_fraction}(\\{gamma},\39\\{beta})),\39\\{n\_cos})\30-\\{take\_fraction}(%
+\\{take\_fraction}(\\{minor\_axis},\39\\{make\_fraction}(\\{delta},\39%
+\\{beta})),\39\\{n\_sin})$;\5
+$\\{alpha}\K(\\{alpha}+\\{half\_unit})\mathbin{\&{div}}\\{unity}$;\5
+$\\{gamma}\K\\{pyth\_add}(\\{take\_fraction}(\\{major\_axis},\39\\{n\_cos}),\39%
+\\{take\_fraction}(\\{minor\_axis},\39\\{n\_sin}))$;\6
+\&{end};\2\6
+$\\{beta}\K(\\{beta}+\\{half\_unit})\mathbin{\&{div}}\\{unity}$;\5
+$\\{gamma}\K(\\{gamma}+\\{half\_unit})\mathbin{\&{div}}\\{unity}$\par
+\U528.\fi
+
+\M531. Now \|p, \|q, and \|r march through the list, always representing
+three consecutive vertices and two consecutive slope directions.
+When a new slope is interpolated, we back up slightly, until
+further refinement is impossible; then we march forward again.
+The somewhat magical operations performed in this part of the
+algorithm are justified by the theory sketched earlier.
+Complications arise only from the need to keep zero-length lines
+out of the final data structure.
+
+\Y\P$\4\X531:Interpolate new vertices in the ellipse data structure until
+improvement is impossible\X\S$\6
+\~ \1\&{loop}\ \&{begin} \37$\|u\K\\{right\_u}(\|p)+\\{right\_u}(\|q)$;\5
+$\|v\K\\{left\_v}(\|q)+\\{left\_v}(\|r)$;\5
+$\|c\K\\{right\_class}(\|p)+\\{right\_class}(\|q)$;\6
+\X533:Compute the distance \|d from class~0 to the edge of the ellipse in
+direction $(\|u,\|v)$, times $\psqrt{u^2+v^2}$, rounded to the nearest integer%
+\X;\6
+$\\{delta}\K\|c-\|d$;\C{we want to move \\{delta} steps back from the
+intersection vertex~\|q}\6
+\&{if} $\\{delta}>0$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{delta}>\\{left\_length}(\|r)$ \1\&{then}\5
+$\\{delta}\K\\{left\_length}(\|r)$;\2\6
+\&{if} $\\{delta}\G\\{left\_length}(\|q)$ \1\&{then}\5
+\X534:Remove the line from \|p to \|q, and adjust vertex~\|q to introduce a new
+line\X\6
+\4\&{else} \X535:Insert a new line for direction $(\|u,\|v)$ between \|p and~%
+\|q\X;\2\6
+\&{end}\6
+\4\&{else} $\|p\K\|q$;\2\6
+\X532:Move to the next remaining triple $(\|p,\|q,\|r)$, removing and skipping
+past zero-length lines that might be present; \&{goto} \\{done} if all triples
+have been processed\X;\6
+\&{end};\2\6
+\4\\{done}: \37\par
+\U527.\fi
+
+\M532. The appearance of a zero-length line means that we should advance \|p
+past it. We must not try to straddle a missing direction, because the
+algorithm works only on consecutive pairs of directions.
+
+\Y\P$\4\X532:Move to the next remaining triple $(\|p,\|q,\|r)$, removing and
+skipping past zero-length lines that might be present; \&{goto} \\{done} if all
+triples have been processed\X\S$\6
+\~ \1\&{loop}\ \&{begin} \37$\|q\K\\{link}(\|p)$;\6
+\&{if} $\|q=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\\{left\_length}(\|q)=0$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|p)\K\\{link}(\|q)$;\5
+$\\{right\_class}(\|p)\K\\{right\_class}(\|q)$;\5
+$\\{right\_u}(\|p)\K\\{right\_u}(\|q)$;\5
+$\\{free\_node}(\|q,\39\\{knot\_node\_size})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|r\K\\{link}(\|q)$;\6
+\&{if} $\|r=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\\{left\_length}(\|r)=0$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|p)\K\|r$;\5
+$\\{free\_node}(\|q,\39\\{knot\_node\_size})$;\5
+$\|p\K\|r$;\6
+\&{end}\6
+\4\&{else} \&{goto} \37\\{found};\2\6
+\&{end};\2\6
+\&{end};\2\6
+\4\\{found}: \37\par
+\U531.\fi
+
+\M533. The `\&{div} 8' near the end of this step comes from
+the fact that \\{delta} is scaled by~$2^{15}$ and $d$~by~$2^{16}$,
+while \\{take\_fraction} removes a scale factor of~$2^{28}$.
+We also make sure that $d\G\max(\vert u\vert,\vert v\vert)$, so that
+the pen will always include a circular pen of diameter~1 as a subset;
+then it won't be possible to get disconnected path envelopes.
+
+\Y\P$\4\X533:Compute the distance \|d from class~0 to the edge of the ellipse
+in direction $(\|u,\|v)$, times $\psqrt{u^2+v^2}$, rounded to the nearest
+integer\X\S$\6
+$\\{delta}\K\\{pyth\_add}(\|u,\39\|v)$;\6
+\&{if} $\\{major\_axis}=\\{minor\_axis}$ \1\&{then}\5
+$\|d\K\\{major\_axis}$\C{circles are easy}\6
+\4\&{else} \&{begin} \37\&{if} $\\{theta}=0$ \1\&{then}\6
+\&{begin} \37$\\{alpha}\K\|u$;\5
+$\\{beta}\K\|v$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{alpha}\K\\{take\_fraction}(\|u,\39\\{n\_cos})+%
+\\{take\_fraction}(\|v,\39\\{n\_sin})$;\5
+$\\{beta}\K\\{take\_fraction}(\|v,\39\\{n\_cos})-\\{take\_fraction}(\|u,\39\\{n%
+\_sin})$;\6
+\&{end};\2\6
+$\\{alpha}\K\\{make\_fraction}(\\{alpha},\39\\{delta})$;\5
+$\\{beta}\K\\{make\_fraction}(\\{beta},\39\\{delta})$;\5
+$\|d\K\\{pyth\_add}(\\{take\_fraction}(\\{major\_axis},\39\\{alpha}),\39\\{take%
+\_fraction}(\\{minor\_axis},\39\\{beta}))$;\6
+\&{end};\2\6
+$\\{alpha}\K\\{abs}(\|u)$;\5
+$\\{beta}\K\\{abs}(\|v)$;\6
+\&{if} $\\{alpha}<\\{beta}$ \1\&{then}\6
+\&{begin} \37$\\{alpha}\K\\{abs}(\|v)$;\5
+$\\{beta}\K\\{abs}(\|u)$;\6
+\&{end};\C{now $\alpha=\max(\vert u\vert,\vert v\vert)$, $\beta=\min(%
+\vert u\vert,\vert v\vert)$}\2\6
+\&{if} $\\{internal}[\\{fillin}]\I0$ \1\&{then}\5
+$\|d\K\|d-\\{take\_fraction}(\\{internal}[\\{fillin}],\39\\{make\_fraction}(%
+\\{beta}+\\{beta},\39\\{delta}))$;\2\6
+$\|d\K\\{take\_fraction}((\|d+4)\mathbin{\&{div}}8,\39\\{delta})$;\5
+$\\{alpha}\K\\{alpha}\mathbin{\&{div}}\\{half\_unit}$;\6
+\&{if} $\|d<\\{alpha}$ \1\&{then}\5
+$\|d\K\\{alpha}$\2\par
+\U531.\fi
+
+\M534. At this point there's a line of length $\L\\{delta}$ from vertex~\|p
+to vertex~\|q, orthogonal to direction $\bigl($$\\{right\_u}(\|p),\\{left\_v}(%
+\|q)$$\bigr)$;
+and there's a line of length $\G\\{delta}$ from vertex~\|q to
+to vertex~\|r, orthogonal to direction $\bigl($$\\{right\_u}(\|q),\\{left\_v}(%
+\|r)$$\bigr)$.
+The best line to direction $(u,v)$ should replace the line from
+\|p to~\|q; this new line will have the same length as the old.
+
+\Y\P$\4\X534:Remove the line from \|p to \|q, and adjust vertex~\|q to
+introduce a new line\X\S$\6
+\&{begin} \37$\\{delta}\K\\{left\_length}(\|q)$;\6
+$\\{right\_class}(\|p)\K\|c-\\{delta}$;\5
+$\\{right\_u}(\|p)\K\|u$;\5
+$\\{left\_v}(\|q)\K\|v$;\6
+$\\{x\_coord}(\|q)\K\\{x\_coord}(\|q)-\\{delta}\ast\\{left\_v}(\|r)$;\5
+$\\{y\_coord}(\|q)\K\\{y\_coord}(\|q)+\\{delta}\ast\\{right\_u}(\|q)$;\6
+$\\{left\_length}(\|r)\K\\{left\_length}(\|r)-\\{delta}$;\6
+\&{end}\par
+\U531.\fi
+
+\M535. Here is the main case, now that we have dealt with the exception:
+We insert a new line of length \\{delta} for direction $(\|u,\|v)$, decreasing
+each of the adjacent lines by \\{delta} steps.
+
+\Y\P$\4\X535:Insert a new line for direction $(\|u,\|v)$ between \|p and~\|q\X%
+\S$\6
+\&{begin} \37$\|s\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{link}(\|p)\K\|s$;\5
+$\\{link}(\|s)\K\|q$;\6
+$\\{x\_coord}(\|s)\K\\{x\_coord}(\|q)+\\{delta}\ast\\{left\_v}(\|q)$;\5
+$\\{y\_coord}(\|s)\K\\{y\_coord}(\|q)-\\{delta}\ast\\{right\_u}(\|p)$;\6
+$\\{x\_coord}(\|q)\K\\{x\_coord}(\|q)-\\{delta}\ast\\{left\_v}(\|r)$;\5
+$\\{y\_coord}(\|q)\K\\{y\_coord}(\|q)+\\{delta}\ast\\{right\_u}(\|q)$;\6
+$\\{left\_v}(\|s)\K\\{left\_v}(\|q)$;\5
+$\\{right\_u}(\|s)\K\|u$;\5
+$\\{left\_v}(\|q)\K\|v$;\6
+$\\{right\_class}(\|s)\K\|c-\\{delta}$;\6
+$\\{left\_length}(\|s)\K\\{left\_length}(\|q)-\\{delta}$;\5
+$\\{left\_length}(\|q)\K\\{delta}$;\5
+$\\{left\_length}(\|r)\K\\{left\_length}(\|r)-\\{delta}$;\6
+\&{end}\par
+\U531.\fi
+
+\M536. Only the coordinates need to be copied, not the class numbers and other
+stuff.
+
+\Y\P$\4\X536:Complete the half ellipse by reflecting the quarter already
+computed\X\S$\6
+\&{begin} \37$\|s\K\\{null}$;\5
+$\|q\K\|h$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|r\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{link}(\|r)\K\|s$;\5
+$\|s\K\|r$;\6
+$\\{x\_coord}(\|s)\K\\{x\_coord}(\|q)$;\5
+$\\{y\_coord}(\|s)\K-\\{y\_coord}(\|q)$;\6
+\&{if} $\|q=\|p$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+$\|q\K\\{link}(\|q)$;\6
+\&{if} $\\{y\_coord}(\|q)=0$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+\&{end};\2\6
+\4\\{done1}: \37$\\{link}(\|p)\K\|s$;\5
+$\\{beta}\K-\\{y\_coord}(\|h)$;\6
+\&{while} $\\{y\_coord}(\|p)\I\\{beta}$ \1\&{do}\5
+$\|p\K\\{link}(\|p)$;\2\6
+$\|q\K\\{link}(\|p)$;\6
+\&{end}\par
+\U527.\fi
+
+\M537. Now we use a somewhat tricky fact: The pointer \|q will be null if and
+only if the line for the final direction $(0,1)$ has been removed. If
+that line still survives, it should be combined with a possibly
+surviving line in the initial direction $(0,-1)$.
+
+\Y\P$\4\X537:Complete the ellipse by copying the negative of the half already
+computed\X\S$\6
+\&{if} $\|q\I\\{null}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{right\_u}(\|h)=0$ \1\&{then}\6
+\&{begin} \37$\|p\K\|h$;\5
+$\|h\K\\{link}(\|h)$;\5
+$\\{free\_node}(\|p,\39\\{knot\_node\_size})$;\6
+$\\{x\_coord}(\|q)\K-\\{x\_coord}(\|h)$;\6
+\&{end};\2\6
+$\|p\K\|q$;\6
+\&{end}\6
+\4\&{else} $\|q\K\|p$;\2\6
+$\|r\K\\{link}(\|h)$;\C{now $\|p=\|q$, $\\{x\_coord}(\|p)=-\\{x\_coord}(\|h)$,
+$\\{y\_coord}(\|p)=-\\{y\_coord}(\|h)$}\6
+\1\&{repeat} \37$\|s\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{link}(\|p)\K\|s$;\5
+$\|p\K\|s$;\6
+$\\{x\_coord}(\|p)\K-\\{x\_coord}(\|r)$;\5
+$\\{y\_coord}(\|p)\K-\\{y\_coord}(\|r)$;\5
+$\|r\K\\{link}(\|r)$;\6
+\4\&{until}\5
+$\|r=\|q$;\2\6
+$\\{link}(\|p)\K\|h$\par
+\U527.\fi
+
+\N538. \[26] Direction and intersection times.
+A path of length $n$ is defined parametrically by functions $x(t)$ and
+$y(t)$, for $0\L\|t\L\|n$; we can regard $t$ as the ``time'' at which the path
+reaches the point $\bigl(x(t),y(t)\bigr)$. In this section of the program
+we shall consider operations that determine special times associated with
+given paths: the first time that a path travels in a given direction, and
+a pair of times at which two paths cross each other.
+
+\fi
+
+\M539. Let's start with the easier task. The function \\{find\_direction\_time}
+is
+given a direction $(\|x,\|y)$ and a path starting at~\|h. If the path never
+travels in direction $(\|x,\|y)$, the direction time will be~$-1$; otherwise
+it will be nonnegative.
+
+Certain anomalous cases can arise: If $(\|x,\|y)=(0,0)$, so that the given
+direction is undefined, the direction time will be~0. If $\bigl(x'(t),
+y'(t)\bigr)=(0,0)$, so that the path direction is undefined, it will be
+assumed to match any given direction at time~\|t.
+
+The routine solves this problem in nondegenerate cases by rotating the path
+and the given direction so that $(\|x,\|y)=(1,0)$; i.e., the main task will be
+to find when a given path first travels ``due east.''
+
+\Y\P\4\&{function}\1\ \37$\\{find\_direction\_time}(\|x,\39\|y:\\{scaled};\,%
+\35\|h:\\{pointer})$: \37\\{scaled};\6
+\4\&{label} \37$\\{exit},\39\\{found},\39\\{not\_found},\39\\{done}$;\6
+\4\&{var} \37\\{max}: \37\\{scaled};\C{$\max\bigl(\vert x\vert,\vert y\vert%
+\bigr)$}\6
+$\|p,\39\|q$: \37\\{pointer};\C{for list traversal}\6
+\|n: \37\\{scaled};\C{the direction time at knot \|p}\6
+\\{tt}: \37\\{scaled};\C{the direction time within a cubic}\6
+\X542:Other local variables for \\{find\_direction\_time}\X\2\6
+\&{begin} \37\X540:Normalize the given direction for better accuracy; but %
+\&{return} with zero result if it's zero\X;\6
+$\|n\K0$;\5
+$\|p\K\|h$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\\{right\_type}(\|p)=\\{endpoint}$ \1%
+\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\|q\K\\{link}(\|p)$;\5
+\X541:Rotate the cubic between \|p and \|q; then \&{goto} \\{found} if the
+rotated cubic travels due east at some time \\{tt}; but \&{goto} \\{not\_found}
+if an entire cyclic path has been traversed\X;\6
+$\|p\K\|q$;\5
+$\|n\K\|n+\\{unity}$;\6
+\&{end};\2\6
+\4\\{not\_found}: \37$\\{find\_direction\_time}\K-\\{unity}$;\5
+\&{return};\6
+\4\\{found}: \37$\\{find\_direction\_time}\K\|n+\\{tt}$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M540. \P$\X540:Normalize the given direction for better accuracy; but %
+\&{return} with zero result if it's zero\X\S$\6
+\&{if} $\\{abs}(\|x)<\\{abs}(\|y)$ \1\&{then}\6
+\&{begin} \37$\|x\K\\{make\_fraction}(\|x,\39\\{abs}(\|y))$;\6
+\&{if} $\|y>0$ \1\&{then}\5
+$\|y\K\\{fraction\_one}$\ \&{else} $\|y\K-\\{fraction\_one}$;\2\6
+\&{end}\6
+\4\&{else} \&{if} $\|x=0$ \1\&{then}\6
+\&{begin} \37$\\{find\_direction\_time}\K0$;\5
+\&{return};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|y\K\\{make\_fraction}(\|y,\39\\{abs}(\|x))$;\6
+\&{if} $\|x>0$ \1\&{then}\5
+$\|x\K\\{fraction\_one}$\ \&{else} $\|x\K-\\{fraction\_one}$;\2\6
+\&{end}\2\2\par
+\U539.\fi
+
+\M541. Since we're interested in the tangent directions, we work with the
+derivative $${\textstyle1\over3}B'(x_0,x_1,x_2,x_3;t)=
+B(x_1-x_0,x_2-x_1,x_3-x_2;t)$$ instead of
+$B(x_0,x_1,x_2,x_3;t)$ itself. The derived coefficients are also scaled up
+in order to achieve better accuracy.
+
+The given path may turn abruptly at a knot, and it might pass the critical
+tangent direction at such a time. Therefore we remember the direction \\{phi}
+in which the previous rotated cubic was traveling. (The value of \\{phi} will
+be
+undefined on the first cubic, i.e., when $\|n=0$.)
+
+\Y\P$\4\X541:Rotate the cubic between \|p and \|q; then \&{goto} \\{found} if
+the rotated cubic travels due east at some time \\{tt}; but \&{goto} \\{not%
+\_found} if an entire cyclic path has been traversed\X\S$\6
+$\\{tt}\K0$;\5
+\X543:Set local variables $\\{x1},\\{x2},\\{x3}$ and $\\{y1},\\{y2},\\{y3}$ to
+multiples of the control points of the rotated derivatives\X;\6
+\&{if} $\\{y1}=0$ \1\&{then}\6
+\&{if} $\\{x1}\G0$ \1\&{then}\5
+\&{goto} \37\\{found};\2\2\6
+\&{if} $\|n>0$ \1\&{then}\6
+\&{begin} \37\X544:Exit to \\{found} if an eastward direction occurs at knot %
+\|p\X;\6
+\&{if} $\|p=\|h$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{end};\2\6
+\&{if} $(\\{x3}\I0)\V(\\{y3}\I0)$ \1\&{then}\5
+$\\{phi}\K\\{n\_arg}(\\{x3},\39\\{y3})$;\2\6
+\X546:Exit to \\{found} if the curve whose derivatives are specified by $%
+\\{x1},\\{x2},\\{x3},\\{y1},\\{y2},\\{y3}$ travels eastward at some time~\\{tt}%
+\X\par
+\U539.\fi
+
+\M542. \P$\X542:Other local variables for \\{find\_direction\_time}\X\S$\6
+\4$\\{x1},\39\\{x2},\39\\{x3},\39\\{y1},\39\\{y2},\39\\{y3}$: \37\\{scaled};%
+\C{multiples of rotated derivatives}\6
+\4$\\{theta},\39\\{phi}$: \37\\{angle};\C{angles of exit and entry at a knot}\6
+\4\|t: \37\\{fraction};\C{temp storage}\par
+\U539.\fi
+
+\M543. \P$\X543:Set local variables $\\{x1},\\{x2},\\{x3}$ and $\\{y1},\\{y2},%
+\\{y3}$ to multiples of the control points of the rotated derivatives\X\S$\6
+$\\{x1}\K\\{right\_x}(\|p)-\\{x\_coord}(\|p)$;\5
+$\\{x2}\K\\{left\_x}(\|q)-\\{right\_x}(\|p)$;\5
+$\\{x3}\K\\{x\_coord}(\|q)-\\{left\_x}(\|q)$;\6
+$\\{y1}\K\\{right\_y}(\|p)-\\{y\_coord}(\|p)$;\5
+$\\{y2}\K\\{left\_y}(\|q)-\\{right\_y}(\|p)$;\5
+$\\{y3}\K\\{y\_coord}(\|q)-\\{left\_y}(\|q)$;\6
+$\\{max}\K\\{abs}(\\{x1})$;\6
+\&{if} $\\{abs}(\\{x2})>\\{max}$ \1\&{then}\5
+$\\{max}\K\\{abs}(\\{x2})$;\2\6
+\&{if} $\\{abs}(\\{x3})>\\{max}$ \1\&{then}\5
+$\\{max}\K\\{abs}(\\{x3})$;\2\6
+\&{if} $\\{abs}(\\{y1})>\\{max}$ \1\&{then}\5
+$\\{max}\K\\{abs}(\\{y1})$;\2\6
+\&{if} $\\{abs}(\\{y2})>\\{max}$ \1\&{then}\5
+$\\{max}\K\\{abs}(\\{y2})$;\2\6
+\&{if} $\\{abs}(\\{y3})>\\{max}$ \1\&{then}\5
+$\\{max}\K\\{abs}(\\{y3})$;\2\6
+\&{if} $\\{max}=0$ \1\&{then}\5
+\&{goto} \37\\{found};\2\6
+\&{while} $\\{max}<\\{fraction\_half}$ \1\&{do}\6
+\&{begin} \37$\\{double}(\\{max})$;\5
+$\\{double}(\\{x1})$;\5
+$\\{double}(\\{x2})$;\5
+$\\{double}(\\{x3})$;\5
+$\\{double}(\\{y1})$;\5
+$\\{double}(\\{y2})$;\5
+$\\{double}(\\{y3})$;\6
+\&{end};\2\6
+$\|t\K\\{x1}$;\5
+$\\{x1}\K\\{take\_fraction}(\\{x1},\39\|x)+\\{take\_fraction}(\\{y1},\39\|y)$;\5
+$\\{y1}\K\\{take\_fraction}(\\{y1},\39\|x)-\\{take\_fraction}(\|t,\39\|y)$;\6
+$\|t\K\\{x2}$;\5
+$\\{x2}\K\\{take\_fraction}(\\{x2},\39\|x)+\\{take\_fraction}(\\{y2},\39\|y)$;\5
+$\\{y2}\K\\{take\_fraction}(\\{y2},\39\|x)-\\{take\_fraction}(\|t,\39\|y)$;\6
+$\|t\K\\{x3}$;\5
+$\\{x3}\K\\{take\_fraction}(\\{x3},\39\|x)+\\{take\_fraction}(\\{y3},\39\|y)$;\5
+$\\{y3}\K\\{take\_fraction}(\\{y3},\39\|x)-\\{take\_fraction}(\|t,\39\|y)$\par
+\U541.\fi
+
+\M544. \P$\X544:Exit to \\{found} if an eastward direction occurs at knot \|p\X%
+\S$\6
+$\\{theta}\K\\{n\_arg}(\\{x1},\39\\{y1})$;\6
+\&{if} $\\{theta}\G0$ \1\&{then}\6
+\&{if} $\\{phi}\L0$ \1\&{then}\6
+\&{if} $\\{phi}\G\\{theta}-\\{one\_eighty\_deg}$ \1\&{then}\5
+\&{goto} \37\\{found};\2\2\2\6
+\&{if} $\\{theta}\L0$ \1\&{then}\6
+\&{if} $\\{phi}\G0$ \1\&{then}\6
+\&{if} $\\{phi}\L\\{theta}+\\{one\_eighty\_deg}$ \1\&{then}\5
+\&{goto} \37\\{found}\2\2\2\par
+\U541.\fi
+
+\M545. In this step we want to use the \\{crossing\_point} routine to find the
+roots of the quadratic equation $B(y_1,y_2,y_3;t)=0$.
+Several complications arise: If the quadratic equation has a double root,
+the curve never crosses zero, and \\{crossing\_point} will find nothing;
+this case occurs iff $y_1y_3=y_2^2$ and $y_1y_2<0$. If the quadratic
+equation has simple roots, or only one root, we may have to negate it
+so that $B(y_1,y_2,y_3;t)$ crosses from positive to negative at its first root.
+And finally, we need to do special things if $B(y_1,y_2,y_3;t)$ is
+identically zero.
+
+\fi
+
+\M546. \P$\X546:Exit to \\{found} if the curve whose derivatives are specified
+by $\\{x1},\\{x2},\\{x3},\\{y1},\\{y2},\\{y3}$ travels eastward at some time~%
+\\{tt}\X\S$\6
+\&{if} $\\{x1}<0$ \1\&{then}\6
+\&{if} $\\{x2}<0$ \1\&{then}\6
+\&{if} $\\{x3}<0$ \1\&{then}\5
+\&{goto} \37\\{done};\2\2\2\6
+\&{if} $\\{ab\_vs\_cd}(\\{y1},\39\\{y3},\39\\{y2},\39\\{y2})=0$ \1\&{then}\5
+\X548:Handle the test for eastward directions when $y_1y_3=y_2^2$; either %
+\&{goto} \\{found} or \&{goto} \\{done}\X;\2\6
+\&{if} $\\{y1}\L0$ \1\&{then}\6
+\&{if} $\\{y1}<0$ \1\&{then}\6
+\&{begin} \37$\\{y1}\K-\\{y1}$;\5
+$\\{y2}\K-\\{y2}$;\5
+$\\{y3}\K-\\{y3}$;\6
+\&{end}\6
+\4\&{else} \&{if} $\\{y2}>0$ \1\&{then}\6
+\&{begin} \37$\\{y2}\K-\\{y2}$;\5
+$\\{y3}\K-\\{y3}$;\6
+\&{end};\2\2\2\6
+\X547:Check the places where $B(y_1,y_2,y_3;t)=0$ to see if $B(x_1,x_2,x_3;t)%
+\ge0$\X;\6
+\4\\{done}: \37\par
+\U541.\fi
+
+\M547. The quadratic polynomial $B(y_1,y_2,y_3;t)$ begins $\G0$ and has at most
+two roots, because we know that it isn't identically zero.
+
+It must be admitted that the \\{crossing\_point} routine is not perfectly
+accurate;
+rounding errors might cause it to find a root when $y_1y_3>y_2^2$, or to
+miss the roots when $y_1y_3<y_2^2$. The rotation process is itself
+subject to rounding errors. Yet this code optimistically tries to
+do the right thing.
+
+\Y\P\D \37$\\{we\_found\_it}\S$\1\6
+\&{begin} \37$\\{tt}\K(\|t+\O{4000})\mathbin{\&{div}}\O{10000}$;\5
+\&{goto} \37\\{found};\6
+\&{end}\2\par
+\Y\P$\4\X547:Check the places where $B(y_1,y_2,y_3;t)=0$ to see if
+$B(x_1,x_2,x_3;t)\ge0$\X\S$\6
+$\|t\K\\{crossing\_point}(\\{y1},\39\\{y2},\39\\{y3})$;\6
+\&{if} $\|t>\\{fraction\_one}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{y2}\K\\{t\_of\_the\_way}(\\{y2})(\\{y3})$;\5
+$\\{x1}\K\\{t\_of\_the\_way}(\\{x1})(\\{x2})$;\5
+$\\{x2}\K\\{t\_of\_the\_way}(\\{x2})(\\{x3})$;\5
+$\\{x1}\K\\{t\_of\_the\_way}(\\{x1})(\\{x2})$;\6
+\&{if} $\\{x1}\G0$ \1\&{then}\5
+\\{we\_found\_it};\2\6
+\&{if} $\\{y2}>0$ \1\&{then}\5
+$\\{y2}\K0$;\2\6
+$\\{tt}\K\|t$;\5
+$\|t\K\\{crossing\_point}(0,\39-\\{y2},\39-\\{y3})$;\6
+\&{if} $\|t>\\{fraction\_one}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{x1}\K\\{t\_of\_the\_way}(\\{x1})(\\{x2})$;\5
+$\\{x2}\K\\{t\_of\_the\_way}(\\{x2})(\\{x3})$;\6
+\&{if} $\\{t\_of\_the\_way}(\\{x1})(\\{x2})\G0$ \1\&{then}\6
+\&{begin} \37$\|t\K\\{t\_of\_the\_way}(\\{tt})(\\{fraction\_one})$;\5
+\\{we\_found\_it};\6
+\&{end}\2\par
+\U546.\fi
+
+\M548. \P$\X548:Handle the test for eastward directions when $y_1y_3=y_2^2$;
+either \&{goto} \\{found} or \&{goto} \\{done}\X\S$\6
+\&{begin} \37\&{if} $\\{ab\_vs\_cd}(\\{y1},\39\\{y2},\390,\390)<0$ \1\&{then}\6
+\&{begin} \37$\|t\K\\{make\_fraction}(\\{y1},\39\\{y1}-\\{y2})$;\5
+$\\{x1}\K\\{t\_of\_the\_way}(\\{x1})(\\{x2})$;\5
+$\\{x2}\K\\{t\_of\_the\_way}(\\{x2})(\\{x3})$;\6
+\&{if} $\\{t\_of\_the\_way}(\\{x1})(\\{x2})\G0$ \1\&{then}\5
+\\{we\_found\_it};\2\6
+\&{end}\6
+\4\&{else} \&{if} $\\{y3}=0$ \1\&{then}\6
+\&{if} $\\{y1}=0$ \1\&{then}\5
+\X549:Exit to \\{found} if the derivative $B(x_1,x_2,x_3;t)$ becomes $\G0$\X\6
+\4\&{else} \&{if} $\\{x3}\G0$ \1\&{then}\6
+\&{begin} \37$\\{tt}\K\\{unity}$;\5
+\&{goto} \37\\{found};\6
+\&{end};\2\2\2\2\6
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U546.\fi
+
+\M549. At this point we know that the derivative of $\|y(\|t)$ is identically
+zero,
+and that $\\{x1}<0$; but either $\\{x2}\G0$ or $\\{x3}\G0$, so there's some
+hope of
+traveling east.
+
+\Y\P$\4\X549:Exit to \\{found} if the derivative $B(x_1,x_2,x_3;t)$ becomes $%
+\G0$\X\S$\6
+\&{begin} \37$\|t\K\\{crossing\_point}(-\\{x1},\39-\\{x2},\39-\\{x3})$;\6
+\&{if} $\|t\L\\{fraction\_one}$ \1\&{then}\5
+\\{we\_found\_it};\2\6
+\&{if} $\\{ab\_vs\_cd}(\\{x1},\39\\{x3},\39\\{x2},\39\\{x2})\L0$ \1\&{then}\6
+\&{begin} \37$\|t\K\\{make\_fraction}(\\{x1},\39\\{x1}-\\{x2})$;\5
+\\{we\_found\_it};\6
+\&{end};\2\6
+\&{end}\par
+\U548.\fi
+
+\M550. The intersection of two cubics can be found by an interesting variant
+of the general bisection scheme described in the introduction to \\{make%
+\_moves}.\
+Given $w(t)=B(w_0,w_1,w_2,w_3;t)$ and $z(t)=B(z_0,z_1,z_2,z_3;t)$,
+we wish to find a pair of times $(t_1,t_2)$ such that $w(t_1)=z(t_2)$,
+if an intersection exists. First we find the smallest rectangle that
+encloses the points $\{w_0,w_1,w_2,w_3\}$ and check that it overlaps
+the smallest rectangle that encloses
+$\{z_0,z_1,z_2,z_3\}$; if not, the cubics certainly don't intersect.
+But if the rectangles do overlap, we bisect the intervals, getting
+new cubics $w'$ and~$w''$, $z'$~and~$z''$; the intersection routine first
+tries for an intersection between $w'$ and~$z'$, then (if unsuccessful)
+between $w'$ and~$z''$, then (if still unsuccessful) between $w''$ and~$z'$,
+finally (if thrice unsuccessful) between $w''$ and~$z''$. After $l$~successful
+levels of bisection we will have determined the intersection times $t_1$
+and~$t_2$ to $l$~bits of accuracy.
+
+\def\submin{_{\rm min}} \def\submax{_{\rm max}}
+As before, it is better to work with the numbers $W_k=2^l(w_k-w_{k-1})$
+and $Z_k=2^l(z_k-z_{k-1})$ rather than the coefficients $w_k$ and $z_k$
+themselves. We also need one other quantity, $\Delta=2^l(w_0-z_0)$,
+to determine when the enclosing rectangles overlap. Here's why:
+The $x$~coordinates of~$w(t)$ are between $u\submin$ and $u\submax$,
+and the $x$~coordinates of~$z(t)$ are between $x\submin$ and $x\submax$,
+if we write $w_k=(u_k,v_k)$ and $z_k=(x_k,y_k)$ and $u\submin=
+\min(u_0,u_1,u_2,u_3)$, etc. These intervals of $x$~coordinates
+overlap if and only if $u\submin\L x\submax$ and
+$x\submin\L u\submax$. Letting
+$$U\submin=\min(0,U_1,U_1+U_2,U_1+U_2+U_3),\;
+U\submax=\max(0,U_1,U_1+U_2,U_1+U_2+U_3),$$
+we have $u\submin=2^lu_0+U\submin$, etc.; the condition for overlap
+reduces to
+$$X\submin-U\submax\L 2^l(u_0-x_0)\L X\submax-U\submin.$$
+Thus we want to maintain the quantity $2^l(u_0-x_0)$; similarly,
+the quantity $2^l(v_0-y_0)$ accounts for the $y$~coordinates. The
+coordinates of $\Delta=2^l(w_0-z_0)$ must stay bounded as $l$ increases,
+because of the overlap condition; i.e., we know that $X\submin$,
+$X\submax$, and their relatives are bounded, hence $X\submax-
+U\submin$ and $X\submin-U\submax$ are bounded.
+
+\fi
+
+\M551. Incidentally, if the given cubics intersect more than once, the process
+just sketched will not necessarily find the lexicographically smallest pair
+$(t_1,t_2)$. The solution actually obtained will be smallest in ``shuffled
+order''; i.e., if $t_1=(.a_1a_2\ldots a_{16})_2$ and
+$t_2=(.b_1b_2\ldots b_{16})_2$, then we will minimize
+$a_1b_1a_2b_2\ldots a_{16}b_{16}$, not
+$a_1a_2\ldots a_{16}b_1b_2\ldots b_{16}$.
+Shuffled order agrees with lexicographic order if all pairs of solutions
+$(t_1,t_2)$ and $(t_1',t_2')$ have the property that $t_1<t_1'$ iff
+$t_2<t_2'$; but in general, lexicographic order can be quite different,
+and the bisection algorithm would be substantially less efficient if it were
+constrained by lexicographic order.
+
+For example, suppose that an overlap has been found for $l=3$ and
+$(t_1,t_2)= (.101,.011)$ in binary, but that no overlap is produced by
+either of the alternatives $(.1010,.0110)$, $(.1010,.0111)$ at level~4.
+Then there is probably an intersection in one of the subintervals
+$(.1011,.011x)$; but lexicographic order would require us to explore
+$(.1010,.1xxx)$ and $(.1011,.00xx)$ and $(.1011,.010x)$ first. We wouldn't
+want to store all of the subdivision data for the second path, so the
+subdivisions would have to be regenerated many times. Such inefficiencies
+would be associated with every `1' in the binary representation of~$t_1$.
+
+\fi
+
+\M552. The subdivision process introduces rounding errors, hence we need to
+make a more liberal test for overlap. It is not hard to show that the
+computed values of $U_i$ differ from the truth by at most~$l$, on
+level~$l$, hence $U\submin$ and $U\submax$ will be at most $3l$ in error.
+If $\beta$ is an upper bound on the absolute error in the computed
+components of $\Delta=(\\{delx},\\{dely})$ on level~$l$, we will replace
+the test `$X\submin-U\submax\L\\{delx}$' by the more liberal test
+`$X\submin-U\submax\L\\{delx}+\\{tol}$', where $\\{tol}=6l+\beta$.
+
+More accuracy is obtained if we try the algorithm first with $\\{tol}=0$;
+the more liberal tolerance is used only if an exact approach fails.
+It is convenient to do this double-take by letting `3' in the preceding
+paragraph be a parameter, which is first 0, then 3.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{tol\_step}: \37$0\to6$;\C{either 0 or 3, usually}\par
+\fi
+
+\M553. We shall use an explicit stack to implement the recursive bisection
+method described above. In fact, the \\{bisect\_stack} array is available for
+this purpose. It will contain numerous 5-word packets like
+$(U_1,U_2,U_3,U\submin,U\submax)$, as well as 20-word packets comprising
+the 5-word packets for $U$, $V$, $X$, and~$Y$.
+
+The following macros define the allocation of stack positions to
+the quantities needed for bisection-intersection.
+
+\Y\P\D \37$\\{stack\_1}(\#)\S\\{bisect\_stack}[\#]$\C{$U_1$, $V_1$, $X_1$, or
+$Y_1$}\par
+\P\D \37$\\{stack\_2}(\#)\S\\{bisect\_stack}[\#+1]$\C{$U_2$, $V_2$, $X_2$, or
+$Y_2$}\par
+\P\D \37$\\{stack\_3}(\#)\S\\{bisect\_stack}[\#+2]$\C{$U_3$, $V_3$, $X_3$, or
+$Y_3$}\par
+\P\D \37$\\{stack\_min}(\#)\S\\{bisect\_stack}[\#+3]$\C{$U\submin$, $V\submin$,
+$X\submin$, or $Y\submin$}\par
+\P\D \37$\\{stack\_max}(\#)\S\\{bisect\_stack}[\#+4]$\C{$U\submax$, $V\submax$,
+$X\submax$, or $Y\submax$}\par
+\P\D \37$\\{int\_packets}=20$\C{number of words to represent $U_k$, $V_k$,
+$X_k$, and $Y_k$}\Y\par
+\P\D \37$\\{u\_packet}(\#)\S\#-5$\par
+\P\D \37$\\{v\_packet}(\#)\S\#-10$\par
+\P\D \37$\\{x\_packet}(\#)\S\#-15$\par
+\P\D \37$\\{y\_packet}(\#)\S\#-20$\par
+\P\D \37$\\{l\_packets}\S\\{bisect\_ptr}-\\{int\_packets}$\par
+\P\D \37$\\{r\_packets}\S\\{bisect\_ptr}$\par
+\P\D \37$\\{ul\_packet}\S\\{u\_packet}(\\{l\_packets})$\C{base of $U'_k$
+variables}\par
+\P\D \37$\\{vl\_packet}\S\\{v\_packet}(\\{l\_packets})$\C{base of $V'_k$
+variables}\par
+\P\D \37$\\{xl\_packet}\S\\{x\_packet}(\\{l\_packets})$\C{base of $X'_k$
+variables}\par
+\P\D \37$\\{yl\_packet}\S\\{y\_packet}(\\{l\_packets})$\C{base of $Y'_k$
+variables}\par
+\P\D \37$\\{ur\_packet}\S\\{u\_packet}(\\{r\_packets})$\C{base of $U''_k$
+variables}\par
+\P\D \37$\\{vr\_packet}\S\\{v\_packet}(\\{r\_packets})$\C{base of $V''_k$
+variables}\par
+\P\D \37$\\{xr\_packet}\S\\{x\_packet}(\\{r\_packets})$\C{base of $X''_k$
+variables}\par
+\P\D \37$\\{yr\_packet}\S\\{y\_packet}(\\{r\_packets})$\C{base of $Y''_k$
+variables}\Y\par
+\P\D \37$\\{u1l}\S\\{stack\_1}(\\{ul\_packet})$\C{$U'_1$}\par
+\P\D \37$\\{u2l}\S\\{stack\_2}(\\{ul\_packet})$\C{$U'_2$}\par
+\P\D \37$\\{u3l}\S\\{stack\_3}(\\{ul\_packet})$\C{$U'_3$}\par
+\P\D \37$\\{v1l}\S\\{stack\_1}(\\{vl\_packet})$\C{$V'_1$}\par
+\P\D \37$\\{v2l}\S\\{stack\_2}(\\{vl\_packet})$\C{$V'_2$}\par
+\P\D \37$\\{v3l}\S\\{stack\_3}(\\{vl\_packet})$\C{$V'_3$}\par
+\P\D \37$\\{x1l}\S\\{stack\_1}(\\{xl\_packet})$\C{$X'_1$}\par
+\P\D \37$\\{x2l}\S\\{stack\_2}(\\{xl\_packet})$\C{$X'_2$}\par
+\P\D \37$\\{x3l}\S\\{stack\_3}(\\{xl\_packet})$\C{$X'_3$}\par
+\P\D \37$\\{y1l}\S\\{stack\_1}(\\{yl\_packet})$\C{$Y'_1$}\par
+\P\D \37$\\{y2l}\S\\{stack\_2}(\\{yl\_packet})$\C{$Y'_2$}\par
+\P\D \37$\\{y3l}\S\\{stack\_3}(\\{yl\_packet})$\C{$Y'_3$}\par
+\P\D \37$\\{u1r}\S\\{stack\_1}(\\{ur\_packet})$\C{$U''_1$}\par
+\P\D \37$\\{u2r}\S\\{stack\_2}(\\{ur\_packet})$\C{$U''_2$}\par
+\P\D \37$\\{u3r}\S\\{stack\_3}(\\{ur\_packet})$\C{$U''_3$}\par
+\P\D \37$\\{v1r}\S\\{stack\_1}(\\{vr\_packet})$\C{$V''_1$}\par
+\P\D \37$\\{v2r}\S\\{stack\_2}(\\{vr\_packet})$\C{$V''_2$}\par
+\P\D \37$\\{v3r}\S\\{stack\_3}(\\{vr\_packet})$\C{$V''_3$}\par
+\P\D \37$\\{x1r}\S\\{stack\_1}(\\{xr\_packet})$\C{$X''_1$}\par
+\P\D \37$\\{x2r}\S\\{stack\_2}(\\{xr\_packet})$\C{$X''_2$}\par
+\P\D \37$\\{x3r}\S\\{stack\_3}(\\{xr\_packet})$\C{$X''_3$}\par
+\P\D \37$\\{y1r}\S\\{stack\_1}(\\{yr\_packet})$\C{$Y''_1$}\par
+\P\D \37$\\{y2r}\S\\{stack\_2}(\\{yr\_packet})$\C{$Y''_2$}\par
+\P\D \37$\\{y3r}\S\\{stack\_3}(\\{yr\_packet})$\C{$Y''_3$}\Y\par
+\P\D \37$\\{stack\_dx}\S\\{bisect\_stack}[\\{bisect\_ptr}]$\C{stacked value of %
+\\{delx}}\par
+\P\D \37$\\{stack\_dy}\S\\{bisect\_stack}[\\{bisect\_ptr}+1]$\C{stacked value
+of \\{dely}}\par
+\P\D \37$\\{stack\_tol}\S\\{bisect\_stack}[\\{bisect\_ptr}+2]$\C{stacked value
+of \\{tol}}\par
+\P\D \37$\\{stack\_uv}\S\\{bisect\_stack}[\\{bisect\_ptr}+3]$\C{stacked value
+of \\{uv}}\par
+\P\D \37$\\{stack\_xy}\S\\{bisect\_stack}[\\{bisect\_ptr}+4]$\C{stacked value
+of \\{xy}}\par
+\P\D \37$\\{int\_increment}=\\{int\_packets}+\\{int\_packets}+5$\C{number of
+stack words per level}\par
+\Y\P$\4\X14:Check the ``constant'' values for consistency\X\mathrel{+}\S$\6
+\&{if} $\\{int\_packets}+17\ast\\{int\_increment}>\\{bistack\_size}$ \1\&{then}%
+\5
+$\\{bad}\K32$;\2\par
+\fi
+
+\M554. Computation of the min and max is a tedious but fairly fast sequence of
+instructions; exactly four comparisons are made in each branch.
+
+\Y\P\D \37$\\{set\_min\_max}(\#)\S$\1\6
+\&{if} $\\{stack\_1}(\#)<0$ \1\&{then}\6
+\&{if} $\\{stack\_3}(\#)\G0$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{stack\_2}(\#)<0$ \1\&{then}\5
+$\\{stack\_min}(\#)\K\\{stack\_1}(\#)+\\{stack\_2}(\#)$\6
+\4\&{else} $\\{stack\_min}(\#)\K\\{stack\_1}(\#)$;\2\6
+$\\{stack\_max}(\#)\K\\{stack\_1}(\#)+\\{stack\_2}(\#)+\\{stack\_3}(\#)$;\6
+\&{if} $\\{stack\_max}(\#)<0$ \1\&{then}\5
+$\\{stack\_max}(\#)\K0$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{stack\_min}(\#)\K\\{stack\_1}(\#)+\\{stack\_2}(\#)+%
+\\{stack\_3}(\#)$;\6
+\&{if} $\\{stack\_min}(\#)>\\{stack\_1}(\#)$ \1\&{then}\5
+$\\{stack\_min}(\#)\K\\{stack\_1}(\#)$;\2\6
+$\\{stack\_max}(\#)\K\\{stack\_1}(\#)+\\{stack\_2}(\#)$;\6
+\&{if} $\\{stack\_max}(\#)<0$ \1\&{then}\5
+$\\{stack\_max}(\#)\K0$;\2\6
+\&{end}\2\6
+\4\&{else} \&{if} $\\{stack\_3}(\#)\L0$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{stack\_2}(\#)>0$ \1\&{then}\5
+$\\{stack\_max}(\#)\K\\{stack\_1}(\#)+\\{stack\_2}(\#)$\6
+\4\&{else} $\\{stack\_max}(\#)\K\\{stack\_1}(\#)$;\2\6
+$\\{stack\_min}(\#)\K\\{stack\_1}(\#)+\\{stack\_2}(\#)+\\{stack\_3}(\#)$;\6
+\&{if} $\\{stack\_min}(\#)>0$ \1\&{then}\5
+$\\{stack\_min}(\#)\K0$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{stack\_max}(\#)\K\\{stack\_1}(\#)+\\{stack\_2}(\#)+%
+\\{stack\_3}(\#)$;\6
+\&{if} $\\{stack\_max}(\#)<\\{stack\_1}(\#)$ \1\&{then}\5
+$\\{stack\_max}(\#)\K\\{stack\_1}(\#)$;\2\6
+$\\{stack\_min}(\#)\K\\{stack\_1}(\#)+\\{stack\_2}(\#)$;\6
+\&{if} $\\{stack\_min}(\#)>0$ \1\&{then}\5
+$\\{stack\_min}(\#)\K0$;\2\6
+\&{end}\2\2\2\par
+\fi
+
+\M555. It's convenient to keep the current values of $l$, $t_1$, and $t_2$ in
+the integer form $2^l+2^lt_1$ and $2^l+2^lt_2$. The \\{cubic\_intersection}
+routine uses global variables \\{cur\_t} and \\{cur\_tt} for this purpose;
+after successful completion, \\{cur\_t} and \\{cur\_tt} will contain \\{unity}
+plus the \\{scaled} values of $t_1$ and~$t_2$.
+
+The values of \\{cur\_t} and \\{cur\_tt} will be set to zero if \\{cubic%
+\_intersection}
+finds no intersection. The routine gives up and gives an approximate answer
+if it has backtracked
+more than 5000 times (otherwise there are cases where several minutes
+of fruitless computation would be possible).
+
+\Y\P\D \37$\\{max\_patience}=5000$\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{cur\_t},\39\\{cur\_tt}$: \37\\{integer};\C{controls and results of %
+\\{cubic\_intersection}}\6
+\4\\{time\_to\_go}: \37\\{integer};\C{this many backtracks before giving up}\6
+\4\\{max\_t}: \37\\{integer};\C{maximum of $2^{l+1}$ so far achieved}\par
+\fi
+
+\M556. The given cubics $B(w_0,w_1,w_2,w_3;t)$ and
+$B(z_0,z_1,z_2,z_3;t)$ are specified in adjacent knot nodes $(\|p,\\{link}(%
+\|p))$
+and $(\\{pp},\\{link}(\\{pp}))$, respectively.
+
+\Y\P\4\&{procedure}\1\ \37$\\{cubic\_intersection}(\|p,\39\\{pp}:%
+\\{pointer})$;\6
+\4\&{label} \37$\\{continue},\39\\{not\_found},\39\\{exit}$;\6
+\4\&{var} \37$\|q,\39\\{qq}$: \37\\{pointer};\C{$\\{link}(\|p)$, $\\{link}(%
+\\{pp})$}\2\6
+\&{begin} \37$\\{time\_to\_go}\K\\{max\_patience}$;\5
+$\\{max\_t}\K2$;\5
+\X558:Initialize for intersections at level zero\X;\6
+\~ \1\&{loop}\ \&{begin} \37\\{continue}: \37\&{if} $\\{delx}-\\{tol}\L\\{stack%
+\_max}(\\{x\_packet}(\\{xy}))-\\{stack\_min}(\\{u\_packet}(\\{uv}))$ \1\&{then}%
+\6
+\&{if} $\\{delx}+\\{tol}\G\\{stack\_min}(\\{x\_packet}(\\{xy}))-\\{stack\_max}(%
+\\{u\_packet}(\\{uv}))$ \1\&{then}\6
+\&{if} $\\{dely}-\\{tol}\L\\{stack\_max}(\\{y\_packet}(\\{xy}))-\\{stack\_min}(%
+\\{v\_packet}(\\{uv}))$ \1\&{then}\6
+\&{if} $\\{dely}+\\{tol}\G\\{stack\_min}(\\{y\_packet}(\\{xy}))-\\{stack\_max}(%
+\\{v\_packet}(\\{uv}))$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{cur\_t}\G\\{max\_t}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{max\_t}=\\{two}$ \1\&{then}\C{we've done 17 bisections}%
+\6
+\&{begin} \37$\\{cur\_t}\K\\{half}(\\{cur\_t}+1)$;\5
+$\\{cur\_tt}\K\\{half}(\\{cur\_tt}+1)$;\5
+\&{return};\6
+\&{end};\2\6
+$\\{double}(\\{max\_t})$;\5
+$\\{appr\_t}\K\\{cur\_t}$;\5
+$\\{appr\_tt}\K\\{cur\_tt}$;\6
+\&{end};\2\6
+\X559:Subdivide for a new level of intersection\X;\6
+\&{goto} \37\\{continue};\6
+\&{end};\2\2\2\2\6
+\&{if} $\\{time\_to\_go}>0$ \1\&{then}\5
+$\\{decr}(\\{time\_to\_go})$\6
+\4\&{else} \&{begin} \37\&{while} $\\{appr\_t}<\\{unity}$ \1\&{do}\6
+\&{begin} \37$\\{double}(\\{appr\_t})$;\5
+$\\{double}(\\{appr\_tt})$;\6
+\&{end};\2\6
+$\\{cur\_t}\K\\{appr\_t}$;\5
+$\\{cur\_tt}\K\\{appr\_tt}$;\5
+\&{return};\6
+\&{end};\2\6
+\X560:Advance to the next pair $(\\{cur\_t},\\{cur\_tt})$\X;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M557. The following variables are global, although they are used only by
+\\{cubic\_intersection}, because it is necessary on some machines to
+split \\{cubic\_intersection} up into two procedures.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{delx},\39\\{dely}$: \37\\{integer};\C{the components of $%
+\Delta=2^l(w_0-z_0)$}\6
+\4\\{tol}: \37\\{integer};\C{bound on the uncertainly in the overlap test}\6
+\4$\\{uv},\39\\{xy}$: \37$0\to\\{bistack\_size}$;\C{pointers to the current
+packets of interest}\6
+\4\\{three\_l}: \37\\{integer};\C{\\{tol\_step} times the bisection level}\6
+\4$\\{appr\_t},\39\\{appr\_tt}$: \37\\{integer};\C{best approximations known to
+the answers}\par
+\fi
+
+\M558. We shall assume that the coordinates are sufficiently non-extreme that
+integer overflow will not occur.
+
+\Y\P$\4\X558:Initialize for intersections at level zero\X\S$\6
+$\|q\K\\{link}(\|p)$;\5
+$\\{qq}\K\\{link}(\\{pp})$;\5
+$\\{bisect\_ptr}\K\\{int\_packets}$;\6
+$\\{u1r}\K\\{right\_x}(\|p)-\\{x\_coord}(\|p)$;\5
+$\\{u2r}\K\\{left\_x}(\|q)-\\{right\_x}(\|p)$;\5
+$\\{u3r}\K\\{x\_coord}(\|q)-\\{left\_x}(\|q)$;\5
+$\\{set\_min\_max}(\\{ur\_packet})$;\6
+$\\{v1r}\K\\{right\_y}(\|p)-\\{y\_coord}(\|p)$;\5
+$\\{v2r}\K\\{left\_y}(\|q)-\\{right\_y}(\|p)$;\5
+$\\{v3r}\K\\{y\_coord}(\|q)-\\{left\_y}(\|q)$;\5
+$\\{set\_min\_max}(\\{vr\_packet})$;\6
+$\\{x1r}\K\\{right\_x}(\\{pp})-\\{x\_coord}(\\{pp})$;\5
+$\\{x2r}\K\\{left\_x}(\\{qq})-\\{right\_x}(\\{pp})$;\5
+$\\{x3r}\K\\{x\_coord}(\\{qq})-\\{left\_x}(\\{qq})$;\5
+$\\{set\_min\_max}(\\{xr\_packet})$;\6
+$\\{y1r}\K\\{right\_y}(\\{pp})-\\{y\_coord}(\\{pp})$;\5
+$\\{y2r}\K\\{left\_y}(\\{qq})-\\{right\_y}(\\{pp})$;\5
+$\\{y3r}\K\\{y\_coord}(\\{qq})-\\{left\_y}(\\{qq})$;\5
+$\\{set\_min\_max}(\\{yr\_packet})$;\6
+$\\{delx}\K\\{x\_coord}(\|p)-\\{x\_coord}(\\{pp})$;\5
+$\\{dely}\K\\{y\_coord}(\|p)-\\{y\_coord}(\\{pp})$;\6
+$\\{tol}\K0$;\5
+$\\{uv}\K\\{r\_packets}$;\5
+$\\{xy}\K\\{r\_packets}$;\5
+$\\{three\_l}\K0$;\5
+$\\{cur\_t}\K1$;\5
+$\\{cur\_tt}\K1$\par
+\U556.\fi
+
+\M559. \P$\X559:Subdivide for a new level of intersection\X\S$\6
+$\\{stack\_dx}\K\\{delx}$;\5
+$\\{stack\_dy}\K\\{dely}$;\5
+$\\{stack\_tol}\K\\{tol}$;\5
+$\\{stack\_uv}\K\\{uv}$;\5
+$\\{stack\_xy}\K\\{xy}$;\5
+$\\{bisect\_ptr}\K\\{bisect\_ptr}+\\{int\_increment}$;\6
+$\\{double}(\\{cur\_t})$;\5
+$\\{double}(\\{cur\_tt})$;\6
+$\\{u1l}\K\\{stack\_1}(\\{u\_packet}(\\{uv}))$;\5
+$\\{u3r}\K\\{stack\_3}(\\{u\_packet}(\\{uv}))$;\5
+$\\{u2l}\K\\{half}(\\{u1l}+\\{stack\_2}(\\{u\_packet}(\\{uv})))$;\5
+$\\{u2r}\K\\{half}(\\{u3r}+\\{stack\_2}(\\{u\_packet}(\\{uv})))$;\5
+$\\{u3l}\K\\{half}(\\{u2l}+\\{u2r})$;\5
+$\\{u1r}\K\\{u3l}$;\5
+$\\{set\_min\_max}(\\{ul\_packet})$;\5
+$\\{set\_min\_max}(\\{ur\_packet})$;\6
+$\\{v1l}\K\\{stack\_1}(\\{v\_packet}(\\{uv}))$;\5
+$\\{v3r}\K\\{stack\_3}(\\{v\_packet}(\\{uv}))$;\5
+$\\{v2l}\K\\{half}(\\{v1l}+\\{stack\_2}(\\{v\_packet}(\\{uv})))$;\5
+$\\{v2r}\K\\{half}(\\{v3r}+\\{stack\_2}(\\{v\_packet}(\\{uv})))$;\5
+$\\{v3l}\K\\{half}(\\{v2l}+\\{v2r})$;\5
+$\\{v1r}\K\\{v3l}$;\5
+$\\{set\_min\_max}(\\{vl\_packet})$;\5
+$\\{set\_min\_max}(\\{vr\_packet})$;\6
+$\\{x1l}\K\\{stack\_1}(\\{x\_packet}(\\{xy}))$;\5
+$\\{x3r}\K\\{stack\_3}(\\{x\_packet}(\\{xy}))$;\5
+$\\{x2l}\K\\{half}(\\{x1l}+\\{stack\_2}(\\{x\_packet}(\\{xy})))$;\5
+$\\{x2r}\K\\{half}(\\{x3r}+\\{stack\_2}(\\{x\_packet}(\\{xy})))$;\5
+$\\{x3l}\K\\{half}(\\{x2l}+\\{x2r})$;\5
+$\\{x1r}\K\\{x3l}$;\5
+$\\{set\_min\_max}(\\{xl\_packet})$;\5
+$\\{set\_min\_max}(\\{xr\_packet})$;\6
+$\\{y1l}\K\\{stack\_1}(\\{y\_packet}(\\{xy}))$;\5
+$\\{y3r}\K\\{stack\_3}(\\{y\_packet}(\\{xy}))$;\5
+$\\{y2l}\K\\{half}(\\{y1l}+\\{stack\_2}(\\{y\_packet}(\\{xy})))$;\5
+$\\{y2r}\K\\{half}(\\{y3r}+\\{stack\_2}(\\{y\_packet}(\\{xy})))$;\5
+$\\{y3l}\K\\{half}(\\{y2l}+\\{y2r})$;\5
+$\\{y1r}\K\\{y3l}$;\5
+$\\{set\_min\_max}(\\{yl\_packet})$;\5
+$\\{set\_min\_max}(\\{yr\_packet})$;\6
+$\\{uv}\K\\{l\_packets}$;\5
+$\\{xy}\K\\{l\_packets}$;\5
+$\\{double}(\\{delx})$;\5
+$\\{double}(\\{dely})$;\6
+$\\{tol}\K\\{tol}-\\{three\_l}+\\{tol\_step}$;\5
+$\\{double}(\\{tol})$;\5
+$\\{three\_l}\K\\{three\_l}+\\{tol\_step}$\par
+\U556.\fi
+
+\M560. \P$\X560:Advance to the next pair $(\\{cur\_t},\\{cur\_tt})$\X\S$\6
+\4\\{not\_found}: \37\&{if} $\\{odd}(\\{cur\_tt})$ \1\&{then}\6
+\&{if} $\\{odd}(\\{cur\_t})$ \1\&{then}\5
+\X561:Descend to the previous level and \&{goto} \\{not\_found}\X\6
+\4\&{else} \&{begin} \37$\\{incr}(\\{cur\_t})$;\5
+$\\{delx}\K\\{delx}+\\{stack\_1}(\\{u\_packet}(\\{uv}))+\\{stack\_2}(\\{u%
+\_packet}(\\{uv}))+\\{stack\_3}(\\{u\_packet}(\\{uv}))$;\5
+$\\{dely}\K\\{dely}+\\{stack\_1}(\\{v\_packet}(\\{uv}))+\\{stack\_2}(\\{v%
+\_packet}(\\{uv}))+\\{stack\_3}(\\{v\_packet}(\\{uv}))$;\5
+$\\{uv}\K\\{uv}+\\{int\_packets}$;\C{switch from \\{l\_packet} to \\{r%
+\_packet}}\6
+$\\{decr}(\\{cur\_tt})$;\5
+$\\{xy}\K\\{xy}-\\{int\_packets}$;\C{switch from \\{r\_packet} to \\{l%
+\_packet}}\6
+$\\{delx}\K\\{delx}+\\{stack\_1}(\\{x\_packet}(\\{xy}))+\\{stack\_2}(\\{x%
+\_packet}(\\{xy}))+\\{stack\_3}(\\{x\_packet}(\\{xy}))$;\5
+$\\{dely}\K\\{dely}+\\{stack\_1}(\\{y\_packet}(\\{xy}))+\\{stack\_2}(\\{y%
+\_packet}(\\{xy}))+\\{stack\_3}(\\{y\_packet}(\\{xy}))$;\6
+\&{end}\2\6
+\4\&{else} \&{begin} \37$\\{incr}(\\{cur\_tt})$;\5
+$\\{tol}\K\\{tol}+\\{three\_l}$;\5
+$\\{delx}\K\\{delx}-\\{stack\_1}(\\{x\_packet}(\\{xy}))-\\{stack\_2}(\\{x%
+\_packet}(\\{xy}))-\\{stack\_3}(\\{x\_packet}(\\{xy}))$;\5
+$\\{dely}\K\\{dely}-\\{stack\_1}(\\{y\_packet}(\\{xy}))-\\{stack\_2}(\\{y%
+\_packet}(\\{xy}))-\\{stack\_3}(\\{y\_packet}(\\{xy}))$;\5
+$\\{xy}\K\\{xy}+\\{int\_packets}$;\C{switch from \\{l\_packet} to \\{r%
+\_packet}}\6
+\&{end}\2\par
+\U556.\fi
+
+\M561. \P$\X561:Descend to the previous level and \&{goto} \\{not\_found}\X\S$\6
+\&{begin} \37$\\{cur\_t}\K\\{half}(\\{cur\_t})$;\5
+$\\{cur\_tt}\K\\{half}(\\{cur\_tt})$;\6
+\&{if} $\\{cur\_t}=0$ \1\&{then}\5
+\&{return};\2\6
+$\\{bisect\_ptr}\K\\{bisect\_ptr}-\\{int\_increment}$;\5
+$\\{three\_l}\K\\{three\_l}-\\{tol\_step}$;\5
+$\\{delx}\K\\{stack\_dx}$;\5
+$\\{dely}\K\\{stack\_dy}$;\5
+$\\{tol}\K\\{stack\_tol}$;\5
+$\\{uv}\K\\{stack\_uv}$;\5
+$\\{xy}\K\\{stack\_xy}$;\6
+\&{goto} \37\\{not\_found};\6
+\&{end}\par
+\U560.\fi
+
+\M562. The \\{path\_intersection} procedure is much simpler.
+It invokes \\{cubic\_intersection} in lexicographic order until finding a
+pair of cubics that intersect. The final intersection times are placed in
+\\{cur\_t} and~\\{cur\_tt}.
+
+\Y\P\4\&{procedure}\1\ \37$\\{path\_intersection}(\|h,\39\\{hh}:\\{pointer})$;%
+\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\|p,\39\\{pp}$: \37\\{pointer};\C{link registers that traverse
+the given paths}\6
+$\|n,\39\\{nn}$: \37\\{integer};\C{integer parts of intersection times, minus %
+\\{unity}}\2\6
+\&{begin} \37\X563:Change one-point paths into dead cycles\X;\6
+$\\{tol\_step}\K0$;\6
+\1\&{repeat} \37$\|n\K-\\{unity}$;\5
+$\|p\K\|h$;\6
+\1\&{repeat} \37\&{if} $\\{right\_type}(\|p)\I\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\\{nn}\K-\\{unity}$;\5
+$\\{pp}\K\\{hh}$;\6
+\1\&{repeat} \37\&{if} $\\{right\_type}(\\{pp})\I\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\\{cubic\_intersection}(\|p,\39\\{pp})$;\6
+\&{if} $\\{cur\_t}>0$ \1\&{then}\6
+\&{begin} \37$\\{cur\_t}\K\\{cur\_t}+\|n$;\5
+$\\{cur\_tt}\K\\{cur\_tt}+\\{nn}$;\5
+\&{return};\6
+\&{end};\2\6
+\&{end};\2\6
+$\\{nn}\K\\{nn}+\\{unity}$;\5
+$\\{pp}\K\\{link}(\\{pp})$;\6
+\4\&{until}\5
+$\\{pp}=\\{hh}$;\2\6
+\&{end};\2\6
+$\|n\K\|n+\\{unity}$;\5
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\|p=\|h$;\2\6
+$\\{tol\_step}\K\\{tol\_step}+3$;\6
+\4\&{until}\5
+$\\{tol\_step}>3$;\2\6
+$\\{cur\_t}\K-\\{unity}$;\5
+$\\{cur\_tt}\K-\\{unity}$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M563. \P$\X563:Change one-point paths into dead cycles\X\S$\6
+\&{if} $\\{right\_type}(\|h)=\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\\{right\_x}(\|h)\K\\{x\_coord}(\|h)$;\5
+$\\{left\_x}(\|h)\K\\{x\_coord}(\|h)$;\5
+$\\{right\_y}(\|h)\K\\{y\_coord}(\|h)$;\5
+$\\{left\_y}(\|h)\K\\{y\_coord}(\|h)$;\5
+$\\{right\_type}(\|h)\K\\{explicit}$;\6
+\&{end};\2\6
+\&{if} $\\{right\_type}(\\{hh})=\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\\{right\_x}(\\{hh})\K\\{x\_coord}(\\{hh})$;\5
+$\\{left\_x}(\\{hh})\K\\{x\_coord}(\\{hh})$;\5
+$\\{right\_y}(\\{hh})\K\\{y\_coord}(\\{hh})$;\5
+$\\{left\_y}(\\{hh})\K\\{y\_coord}(\\{hh})$;\5
+$\\{right\_type}(\\{hh})\K\\{explicit}$;\6
+\&{end};\2\par
+\U562.\fi
+
+\N564. \[27] Online graphic output.
+\MF\ displays images on the user's screen by means of a few primitive
+operations that are defined below. These operations have deliberately been
+kept simple so that they can be implemented without great difficulty on a
+wide variety of machines. Since \PASCAL\ has no traditional standards for
+graphic output, some system-dependent code needs to be written in order to
+support this aspect of \MF; but the necessary routines are usually quite
+easy to write.
+
+In fact, there are exactly four such routines:
+
+\yskip\hang
+\\{init\_screen} does whatever initialization is necessary to
+support the other operations; it is a boolean function that returns
+\\{false} if graphic output cannot be supported (e.g., if the other three
+routines have not been written, or if the user doesn't have the
+right kind of terminal).
+
+\yskip\hang
+\\{blank\_rectangle} updates a buffer area in memory so that
+all pixels in a specified rectangle will be set to the background color.
+
+\yskip\hang
+\\{paint\_row} assigns values to specified pixels in a row of
+the buffer just mentioned, based on ``transition'' indices explained below.
+
+\yskip\hang
+\\{update\_screen} displays the current screen buffer; the
+effects of \\{blank\_rectangle} and \\{paint\_row} commands may or may not
+become visible until the next \\{update\_screen} operation is performed.
+(Thus, \\{update\_screen} is analogous to \\{update\_terminal}.)
+
+\yskip\noindent
+The \PASCAL\ code here is a minimum version of \\{init\_screen} and
+\\{update\_screen}, usable on \MF\ installations that don't
+support screen output. If \\{init\_screen} is changed to return \\{true}
+instead of \\{false}, the other routines will simply log the fact
+that they have been called; they won't really display anything.
+The standard test routines for \MF\ use this log information to check
+that \MF\ is working properly, but the \\{wlog} instructions should be
+removed from production versions of \MF.
+
+\Y\P\4\&{function}\1\ \37\\{init\_screen}: \37\\{boolean};\2\6
+\&{begin} \37$\\{init\_screen}\K\\{false}$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37\\{update\_screen};\C{will be called only if \\{init%
+\_screen} returns \\{true}}\2\6
+\&{begin} \37\&{init} \37$\\{wlog\_ln}(\.{\'Calling\ UPDATESCREEN\'})$;\ %
+\&{tini}\C{for testing only}\6
+\&{end};\par
+\fi
+
+\M565. The user's screen is assumed to be a rectangular area, \\{screen\_width}
+pixels wide and \\{screen\_depth} pixels deep. The pixel in the upper left
+corner is said to be in column~0 of row~0; the pixel in the lower right
+corner is said to be in column $\\{screen\_width}-1$ of row $\\{screen%
+\_depth}-1$.
+Notice that row numbers increase from top to bottom, contrary to \MF's
+other coordinates.
+
+Each pixel is assumed to have two states, referred to in this documentation
+as \\{black} and \\{white}. The background color is called \\{white} and the
+other color is called \\{black}; but any two distinct pixel values
+can actually be used. For example, the author developed \MF\ on a
+system for which \\{white} was black and \\{black} was bright green.
+
+\Y\P\D \37$\\{white}=0$\C{background pixels}\par
+\P\D \37$\\{black}=1$\C{visible pixels}\par
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{screen\_row}=0\to\\{screen\_depth}$;\C{a row number on the screen}\6
+$\\{screen\_col}=0\to\\{screen\_width}$;\C{a column number on the screen}\6
+$\\{trans\_spec}=$\1\5
+\&{array} $[\\{screen\_col}]$ \1\&{of}\5
+\\{screen\_col};\C{a transition spec, see below}\2\2\6
+$\\{pixel\_color}=\\{white}\to\\{black}$;\C{specifies one of the two pixel
+values}\par
+\fi
+
+\M566. We'll illustrate the \\{blank\_rectangle} and \\{paint\_row} operations
+by
+pretending to declare a screen buffer called \\{screen\_pixel}. This code
+is actually commented out, but it does specify the intended effects.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\B\\{screen\_pixel}$: \37\&{array} $[\\{screen\_row},\39\\{screen\_col}]$ \1%
+\&{of}\5
+\\{pixel\_color};\ \2\6
+$\T$\par
+\fi
+
+\M567. The \\{blank\_rectangle} routine simply whitens all pixels that lie in
+columns \\{left\_col} through $\\{right\_col}-1$, inclusive, of rows
+\\{top\_row} through $\\{bot\_row}-1$, inclusive, given four parameters that
+satisfy
+the relations
+$$\hbox{$0\L\\{left\_col}\L\\{right\_col}\L\\{screen\_width}$,\quad
+$0\L\\{top\_row}\L\\{bot\_row}\L\\{screen\_depth}$.}$$
+If $\\{left\_col}=\\{right\_col}$ or $\\{top\_row}=\\{bot\_row}$, nothing
+happens.
+
+The commented-out code in the following procedure is for illustrative
+purposes only.
+
+\Y\P\4\&{procedure}\1\ \37$\\{blank\_rectangle}(\\{left\_col},\39\\{right%
+\_col}:\\{screen\_col};\,\35\\{top\_row},\39\\{bot\_row}:\\{screen\_row})$;\6
+\4\&{var} \37\|r: \37\\{screen\_row};\5
+\|c: \37\\{screen\_col};\2\6
+\&{begin} \37$\B$\ \&{for} $\|r\K\\{top\_row}\mathrel{\&{to}}\\{bot\_row}-1$ \1%
+\&{do}\6
+\&{for} $\|c\K\\{left\_col}\mathrel{\&{to}}\\{right\_col}-1$ \1\&{do}\5
+$\\{screen\_pixel}[\|r,\39\|c]\K\\{white}$;\ \2\2\6
+$\T$\6
+\&{init} \37\\{wlog\_cr};\C{this will be done only after $\\{init\_screen}=%
+\\{true}$}\6
+$\\{wlog\_ln}(\.{\'Calling\ BLANKRECTANGLE(\'},\39\\{left\_col}:1,\39\.{\',\'},%
+\39\\{right\_col}:1,\39\.{\',\'},\39\\{top\_row}:1,\39\.{\',\'},\39\\{bot%
+\_row}:1,\39\.{\')\'})$;\ \&{tini}\6
+\&{end};\par
+\fi
+
+\M568. The real work of screen display is done by \\{paint\_row}. But it's not
+hard work, because the operation affects only
+one of the screen rows, and it affects only a contiguous set of columns
+in that row. There are four parameters: \|r~(the row),
+\|b~(the initial color),
+\|a~(the array of transition specifications),
+and \|n~(the number of transitions). The elements of~\|a will satisfy
+$$0\L a[0]<a[1]<\cdots<a[n]\L \\{screen\_width};$$
+the value of \|r will satisfy $0\L\|r<\\{screen\_depth}$; and \|n will be
+positive.
+
+The general idea is to paint blocks of pixels in alternate colors;
+the precise details are best conveyed by means of a \PASCAL\
+program (see the commented-out code below).
+
+\Y\P\4\&{procedure}\1\ \37$\\{paint\_row}(\|r:\\{screen\_row};\,\35\|b:%
+\\{pixel\_color};\,\35\mathop{\&{var}}\|a:\\{trans\_spec};\,\35\|n:\\{screen%
+\_col})$;\6
+\4\&{var} \37\|k: \37\\{screen\_col};\C{an index into \|a}\6
+\|c: \37\\{screen\_col};\C{an index into \\{screen\_pixel}}\2\6
+\&{begin} \37$\B\|k\K0$;\5
+$\|c\K\|a[0]$;\6
+\1\&{repeat} \37$\\{incr}(\|k)$;\6
+\1\&{repeat} \37$\\{screen\_pixel}[\|r,\39\|c]\K\|b$;\5
+$\\{incr}(\|c)$;\6
+\4\&{until}\5
+$\|c=\|a[\|k]$;\2\6
+$\|b\K\\{black}-\|b$;\C{$\\{black}\swap\\{white}$}\6
+\4\&{until}\5
+$\|k=\|n$;\ \2\6
+$\T$\6
+\&{init} \37$\\{wlog}(\.{\'Calling\ PAINTROW(\'},\39\|r:1,\39\.{\',\'},\39%
+\|b:1,\39\.{\';\'})$;\C{this is done only after $\\{init\_screen}=\\{true}$}\6
+\&{for} $\|k\K0\mathrel{\&{to}}\|n$ \1\&{do}\6
+\&{begin} \37$\\{wlog}(\|a[\|k]:1)$;\6
+\&{if} $\|k\I\|n$ \1\&{then}\5
+$\\{wlog}(\.{\',\'})$;\2\6
+\&{end};\2\6
+$\\{wlog\_ln}(\.{\')\'})$;\ \&{tini}\6
+\&{end};\par
+\fi
+
+\M569. The remainder of \MF's screen routines are system-independent calls
+on the four primitives just defined.
+
+First we have a global boolean variable that tells if \\{init\_screen}
+has been called, and another one that tells if \\{init\_screen} has
+given a \\{true} response.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{screen\_started}: \37\\{boolean};\C{have the screen primitives been
+initialized?}\6
+\4\\{screen\_OK}: \37\\{boolean};\C{is it legitimate to call \\{blank%
+\_rectangle}, \\{paint\_row}, and \\{update\_screen}?}\par
+\fi
+
+\M570. \P\D \37$\\{start\_screen}\S$\1\6
+\&{begin} \37\&{if} $\R\\{screen\_started}$ \1\&{then}\6
+\&{begin} \37$\\{screen\_OK}\K\\{init\_screen}$;\5
+$\\{screen\_started}\K\\{true}$;\6
+\&{end};\2\6
+\&{end}\2\par
+\Y\P$\4\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{screen\_started}\K\\{false}$;\5
+$\\{screen\_OK}\K\\{false}$;\par
+\fi
+
+\M571. \MF\ provides the user with 16 ``window'' areas on the screen, in each
+of which it is possible to produce independent displays.
+
+It should be noted that \MF's windows aren't really independent
+``clickable'' entities in the sense of multi-window graphic workstations;
+\MF\ simply maps them into subsets of a single screen image that is
+controlled by \\{init\_screen}, \\{blank\_rectangle}, \\{paint\_row}, and
+\\{update\_screen} as described above. Implementations of \MF\ on a
+multi-window workstation probably therefore make use of only two
+windows in the other sense: one for the terminal output and another
+for the screen with \MF's 16 areas. Henceforth we shall
+use the term window only in \MF's sense.
+
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{window\_number}=0\to15$;\par
+\fi
+
+\M572. A user doesn't have to use any of the 16 windows. But when a window is
+``opened,'' it is allocated to a specific rectangular portion of the screen
+and to a specific rectangle with respect to \MF's coordinates. The relevant
+data is stored in global arrays \\{window\_open}, \\{left\_col}, \\{right%
+\_col},
+\\{top\_row}, \\{bot\_row}, \\{m\_window}, and \\{n\_window}.
+
+The \\{window\_open} array is boolean, and its significance is obvious. The
+\\{left\_col}, \dots, \\{bot\_row} arrays contain screen coordinates that
+can be used to blank the entire window with \\{blank\_rectangle}. And the
+other two arrays just mentioned handle the conversion between
+actual coordinates and screen coordinates: \MF's pixel in column~$m$
+of row~$n$ will appear in screen column $\\{m\_window}+\|m$ and in screen row
+$\\{n\_window}-\|n$, provided that these lie inside the boundaries of the
+window.
+
+Another array \\{window\_time} holds the number of times this window has
+been updated.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{window\_open}: \37\&{array} $[\\{window\_number}]$ \1\&{of}\5
+\\{boolean};\C{has this window been opened?}\2\6
+\4\\{left\_col}: \37\&{array} $[\\{window\_number}]$ \1\&{of}\5
+\\{screen\_col};\C{leftmost column position on screen}\2\6
+\4\\{right\_col}: \37\&{array} $[\\{window\_number}]$ \1\&{of}\5
+\\{screen\_col};\C{rightmost column position, plus~1}\2\6
+\4\\{top\_row}: \37\&{array} $[\\{window\_number}]$ \1\&{of}\5
+\\{screen\_row};\C{topmost row position on screen}\2\6
+\4\\{bot\_row}: \37\&{array} $[\\{window\_number}]$ \1\&{of}\5
+\\{screen\_row};\C{bottommost row position, plus~1}\2\6
+\4\\{m\_window}: \37\&{array} $[\\{window\_number}]$ \1\&{of}\5
+\\{integer};\C{offset between user and screen columns}\2\6
+\4\\{n\_window}: \37\&{array} $[\\{window\_number}]$ \1\&{of}\5
+\\{integer};\C{offset between user and screen rows}\2\6
+\4\\{window\_time}: \37\&{array} $[\\{window\_number}]$ \1\&{of}\5
+\\{integer};\C{it has been updated this often}\2\par
+\fi
+
+\M573. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+\&{for} $\|k\K0\mathrel{\&{to}}15$ \1\&{do}\6
+\&{begin} \37$\\{window\_open}[\|k]\K\\{false}$;\5
+$\\{window\_time}[\|k]\K0$;\6
+\&{end};\2\par
+\fi
+
+\M574. Opening a window isn't like opening a file, because you can open it
+as often as you like, and you never have to close it again. The idea is
+simply to define special points on the current screen display.
+
+Overlapping window specifications may cause complex effects that can
+be understood only by scrutinizing \MF's display algorithms; thus it
+has been left undefined in the \MF\ user manual, although the behavior
+is in fact predictable.
+
+Here is a subroutine that implements the command `\&{openwindow}~\|k
+\&{from}~$(\\{r0},\\{c0})$ \&{to}~$(\\{r1},\\{c1})$ \&{at}~$(x,y)$'.
+
+\Y\P\4\&{procedure}\1\ \37$\\{open\_a\_window}(\|k:\\{window\_number};\,\35%
+\\{r0},\39\\{c0},\39\\{r1},\39\\{c1}:\\{scaled};\,\35\|x,\39\|y:\\{scaled})$;\6
+\4\&{var} \37$\|m,\39\|n$: \37\\{integer};\C{pixel coordinates}\2\6
+\&{begin} \37\X575:Adjust the coordinates $(\\{r0},\\{c0})$ and $(\\{r1},%
+\\{c1})$ so that they lie in the proper range\X;\6
+$\\{window\_open}[\|k]\K\\{true}$;\5
+$\\{incr}(\\{window\_time}[\|k])$;\6
+$\\{left\_col}[\|k]\K\\{c0}$;\5
+$\\{right\_col}[\|k]\K\\{c1}$;\5
+$\\{top\_row}[\|k]\K\\{r0}$;\5
+$\\{bot\_row}[\|k]\K\\{r1}$;\6
+\X576:Compute the offsets between screen coordinates and actual coordinates\X;\6
+\\{start\_screen};\6
+\&{if} $\\{screen\_OK}$ \1\&{then}\6
+\&{begin} \37$\\{blank\_rectangle}(\\{c0},\39\\{c1},\39\\{r0},\39\\{r1})$;\5
+\\{update\_screen};\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M575. A window whose coordinates don't fit the existing screen size will be
+truncated until they do.
+
+\Y\P$\4\X575:Adjust the coordinates $(\\{r0},\\{c0})$ and $(\\{r1},\\{c1})$ so
+that they lie in the proper range\X\S$\6
+\&{if} $\\{r0}<0$ \1\&{then}\5
+$\\{r0}\K0$\ \&{else} $\\{r0}\K\\{round\_unscaled}(\\{r0})$;\2\6
+$\\{r1}\K\\{round\_unscaled}(\\{r1})$;\6
+\&{if} $\\{r1}>\\{screen\_depth}$ \1\&{then}\5
+$\\{r1}\K\\{screen\_depth}$;\2\6
+\&{if} $\\{r1}<\\{r0}$ \1\&{then}\6
+\&{if} $\\{r0}>\\{screen\_depth}$ \1\&{then}\5
+$\\{r0}\K\\{r1}$\ \&{else} $\\{r1}\K\\{r0}$;\2\2\6
+\&{if} $\\{c0}<0$ \1\&{then}\5
+$\\{c0}\K0$\ \&{else} $\\{c0}\K\\{round\_unscaled}(\\{c0})$;\2\6
+$\\{c1}\K\\{round\_unscaled}(\\{c1})$;\6
+\&{if} $\\{c1}>\\{screen\_width}$ \1\&{then}\5
+$\\{c1}\K\\{screen\_width}$;\2\6
+\&{if} $\\{c1}<\\{c0}$ \1\&{then}\6
+\&{if} $\\{c0}>\\{screen\_width}$ \1\&{then}\5
+$\\{c0}\K\\{c1}$\ \&{else} $\\{c1}\K\\{c0}$\2\2\par
+\U574.\fi
+
+\M576. Three sets of coordinates are rampant, and they must be kept straight!
+(i)~\MF's main coordinates refer to the edges between pixels. (ii)~\MF's
+pixel coordinates (within edge structures) say that the pixel bounded by
+$(m,n)$, $(m,n+1)$, $(m+1,n)$, and~$(m+1,n+1)$ is in pixel row number~$n$
+and pixel column number~$m$. (iii)~Screen coordinates, on the other hand,
+have rows numbered in increasing order from top to bottom, as mentioned
+above.
+
+The program here first computes integers $m$ and $n$ such that
+pixel column~$m$ of pixel row~$n$ will be at the upper left corner
+of the window. Hence pixel column $\|m-\\{c0}$ of pixel row $\|n+\\{r0}$
+will be at the upper left corner of the screen.
+
+\Y\P$\4\X576:Compute the offsets between screen coordinates and actual
+coordinates\X\S$\6
+$\|m\K\\{round\_unscaled}(\|x)$;\5
+$\|n\K\\{round\_unscaled}(\|y)-1$;\6
+$\\{m\_window}[\|k]\K\\{c0}-\|m$;\5
+$\\{n\_window}[\|k]\K\\{r0}+\|n$\par
+\U574.\fi
+
+\M577. Now here comes \MF's most complicated operation related to window
+display: Given the number~\|k of an open window, the pixels of positive
+weight in \\{cur\_edges} will be shown as \\{black} in the window; all other
+pixels will be shown as \\{white}.
+
+\Y\P\4\&{procedure}\1\ \37$\\{disp\_edges}(\|k:\\{window\_number})$;\6
+\4\&{label} \37$\\{done},\39\\{found}$;\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{for list manipulation}\6
+\\{already\_there}: \37\\{boolean};\C{is a previous incarnation in the window?}%
+\6
+\|r: \37\\{integer};\C{row number}\6
+\X580:Other local variables for \\{disp\_edges}\X\2\6
+\&{begin} \37\&{if} $\\{screen\_OK}$ \1\&{then}\6
+\&{if} $\\{left\_col}[\|k]<\\{right\_col}[\|k]$ \1\&{then}\6
+\&{if} $\\{top\_row}[\|k]<\\{bot\_row}[\|k]$ \1\&{then}\6
+\&{begin} \37$\\{already\_there}\K\\{false}$;\6
+\&{if} $\\{last\_window}(\\{cur\_edges})=\|k$ \1\&{then}\6
+\&{if} $\\{last\_window\_time}(\\{cur\_edges})=\\{window\_time}[\|k]$ \1%
+\&{then}\5
+$\\{already\_there}\K\\{true}$;\2\2\6
+\&{if} $\R\\{already\_there}$ \1\&{then}\5
+$\\{blank\_rectangle}(\\{left\_col}[\|k],\39\\{right\_col}[\|k],\39\\{top%
+\_row}[\|k],\39\\{bot\_row}[\|k])$;\2\6
+\X581:Initialize for the display computations\X;\6
+$\|p\K\\{link}(\\{cur\_edges})$;\5
+$\|r\K\\{n\_window}[\|k]-(\\{n\_min}(\\{cur\_edges})-\\{zero\_field})$;\6
+\&{while} $(\|p\I\\{cur\_edges})\W(\|r\G\\{top\_row}[\|k])$ \1\&{do}\6
+\&{begin} \37\&{if} $\|r<\\{bot\_row}[\|k]$ \1\&{then}\5
+\X578:Display the pixels of edge row \|p in screen row \|r\X;\2\6
+$\|p\K\\{link}(\|p)$;\5
+$\\{decr}(\|r)$;\6
+\&{end};\2\6
+\\{update\_screen};\5
+$\\{incr}(\\{window\_time}[\|k])$;\5
+$\\{last\_window}(\\{cur\_edges})\K\|k$;\5
+$\\{last\_window\_time}(\\{cur\_edges})\K\\{window\_time}[\|k]$;\6
+\&{end};\2\2\2\6
+\&{end};\par
+\fi
+
+\M578. Since it takes some work to display a row, we try to avoid recomputation
+whenever we can.
+
+\Y\P$\4\X578:Display the pixels of edge row \|p in screen row \|r\X\S$\6
+\&{begin} \37\&{if} $\\{unsorted}(\|p)>\\{void}$ \1\&{then}\5
+$\\{sort\_edges}(\|p)$\6
+\4\&{else} \&{if} $\\{unsorted}(\|p)=\\{void}$ \1\&{then}\6
+\&{if} $\\{already\_there}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\2\2\6
+$\\{unsorted}(\|p)\K\\{void}$;\C{this time we'll paint, but maybe not next
+time}\6
+\X582:Set up the parameters needed for \\{paint\_row}; but \&{goto} \\{done} if
+no painting is needed after all\X;\6
+$\\{paint\_row}(\|r,\39\|b,\39\\{row\_transition},\39\|n)$;\6
+\4\\{done}: \37\&{end}\par
+\U577.\fi
+
+\M579. The transition-specification parameter to \\{paint\_row} is always the
+same
+array.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{row\_transition}: \37\\{trans\_spec};\C{an array of \\{black}/\\{white}
+transitions}\par
+\fi
+
+\M580. The job remaining is to go through the list $\\{sorted}(\|p)$, unpacking
+the
+\\{info} fields into \|m and weight, then making \\{black} the pixels whose
+accumulated weight~\|w is positive.
+
+\Y\P$\4\X580:Other local variables for \\{disp\_edges}\X\S$\6
+\4\|n: \37\\{screen\_col};\C{the highest active index in \\{row\_transition}}\6
+\4$\|w,\39\\{ww}$: \37\\{integer};\C{old and new accumulated weights}\6
+\4\|b: \37\\{pixel\_color};\C{status of first pixel in the row transitions}\6
+\4$\|m,\39\\{mm}$: \37\\{integer};\C{old and new screen column positions}\6
+\4\|d: \37\\{integer};\C{edge-and-weight without \\{min\_halfword}
+compensation}\6
+\4\\{m\_adjustment}: \37\\{integer};\C{conversion between edge and screen
+coordinates}\6
+\4\\{right\_edge}: \37\\{integer};\C{largest edge-and-weight that could affect
+the window}\6
+\4\\{min\_col}: \37\\{screen\_col};\C{the smallest screen column number in the
+window}\par
+\U577.\fi
+
+\M581. Some precomputed constants make the display calculations faster.
+
+\Y\P$\4\X581:Initialize for the display computations\X\S$\6
+$\\{m\_adjustment}\K\\{m\_window}[\|k]-\\{m\_offset}(\\{cur\_edges})$;\6
+$\\{right\_edge}\K8\ast(\\{right\_col}[\|k]-\\{m\_adjustment})$;\6
+$\\{min\_col}\K\\{left\_col}[\|k]$\par
+\U577.\fi
+
+\M582. \P$\X582:Set up the parameters needed for \\{paint\_row}; but \&{goto} %
+\\{done} if no painting is needed after all\X\S$\6
+$\|n\K0$;\5
+$\\{ww}\K0$;\5
+$\|m\K-1$;\5
+$\|w\K0$;\5
+$\|q\K\\{sorted}(\|p)$;\5
+$\\{row\_transition}[0]\K\\{min\_col}$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\|q=\\{sentinel}$ \1\&{then}\5
+$\|d\K\\{right\_edge}$\6
+\4\&{else} $\|d\K\\{ho}(\\{info}(\|q))$;\2\6
+$\\{mm}\K(\|d\mathbin{\&{div}}8)+\\{m\_adjustment}$;\6
+\&{if} $\\{mm}\I\|m$ \1\&{then}\6
+\&{begin} \37\X583:Record a possible transition in column \|m\X;\6
+$\|m\K\\{mm}$;\5
+$\|w\K\\{ww}$;\6
+\&{end};\2\6
+\&{if} $\|d\G\\{right\_edge}$ \1\&{then}\5
+\&{goto} \37\\{found};\2\6
+$\\{ww}\K\\{ww}+(\|d\mathbin{\&{mod}}8)-\\{zero\_w}$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+\4\\{found}: \37\X584:Wind up the \\{paint\_row} parameter calculation by
+inserting the final transition; \&{goto} \\{done} if no painting is needed\X;%
+\par
+\U578.\fi
+
+\M583. Now \|m is a screen column $<\\{right\_col}[\|k]$.
+
+\Y\P$\4\X583:Record a possible transition in column \|m\X\S$\6
+\&{if} $\|w\L0$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{ww}>0$ \1\&{then}\6
+\&{if} $\|m>\\{min\_col}$ \1\&{then}\6
+\&{begin} \37\&{if} $\|n=0$ \1\&{then}\6
+\&{if} $\\{already\_there}$ \1\&{then}\6
+\&{begin} \37$\|b\K\\{white}$;\5
+$\\{incr}(\|n)$;\6
+\&{end}\6
+\4\&{else} $\|b\K\\{black}$\2\6
+\4\&{else} $\\{incr}(\|n)$;\2\6
+$\\{row\_transition}[\|n]\K\|m$;\6
+\&{end};\2\2\6
+\&{end}\6
+\4\&{else} \&{if} $\\{ww}\L0$ \1\&{then}\6
+\&{if} $\|m>\\{min\_col}$ \1\&{then}\6
+\&{begin} \37\&{if} $\|n=0$ \1\&{then}\5
+$\|b\K\\{black}$;\2\6
+$\\{incr}(\|n)$;\5
+$\\{row\_transition}[\|n]\K\|m$;\6
+\&{end}\2\2\2\par
+\U582.\fi
+
+\M584. If the entire row is \\{white} in the window area, we can omit painting
+it
+when \\{already\_there} is false, since it has already been blanked out in
+that case.
+
+When the following code is invoked, $\\{row\_transition}[\|n]$ will be
+strictly less than $\\{right\_col}[\|k]$.
+
+\Y\P$\4\X584:Wind up the \\{paint\_row} parameter calculation by inserting the
+final transition; \&{goto} \\{done} if no painting is needed\X\S$\6
+\&{if} $\\{already\_there}\V(\\{ww}>0)$ \1\&{then}\6
+\&{begin} \37\&{if} $\|n=0$ \1\&{then}\6
+\&{if} $\\{ww}>0$ \1\&{then}\5
+$\|b\K\\{black}$\6
+\4\&{else} $\|b\K\\{white}$;\2\2\6
+$\\{incr}(\|n)$;\5
+$\\{row\_transition}[\|n]\K\\{right\_col}[\|k]$;\6
+\&{end}\6
+\4\&{else} \&{if} $\|n=0$ \1\&{then}\5
+\&{goto} \37\\{done}\2\2\par
+\U582.\fi
+
+\N585. \[28] Dynamic linear equations.
+\MF\ users define variables implicitly by stating equations that should be
+satisfied; the computer is supposed to be smart enough to solve those
+equations.
+And indeed, the computer tries valiantly to do so, by distinguishing five
+different types of numeric values:
+
+\smallskip\hang
+$\\{type}(\|p)=\\{known}$ is the nice case, when $\\{value}(\|p)$ is the %
+\\{scaled} value
+of the variable whose address is~\|p.
+
+\smallskip\hang
+$\\{type}(\|p)=\\{dependent}$ means that $\\{value}(\|p)$ is not present, but $%
+\\{dep\_list}(\|p)$
+points to a {\sl dependency list\/} that expresses the value of variable~\|p
+as a \\{scaled} number plus a sum of independent variables with \\{fraction}
+coefficients.
+
+\smallskip\hang
+$\\{type}(\|p)=\\{independent}$ means that $\\{value}(\|p)=64\|s+\|m$, where $%
+\|s>0$ is a ``serial
+number'' reflecting the time this variable was first used in an equation;
+also $0\L\|m<64$, and each dependent variable
+that refers to this one is actually referring to the future value of
+this variable times~$2^m$. (Usually $\|m=0$, but higher degrees of
+scaling are sometimes needed to keep the coefficients in dependency lists
+from getting too large. The value of~\|m will always be even.)
+
+\smallskip\hang
+$\\{type}(\|p)=\\{numeric\_type}$ means that variable \|p hasn't appeared in an
+equation before, but it has been explicitly declared to be numeric.
+
+\smallskip\hang
+$\\{type}(\|p)=\\{undefined}$ means that variable \|p hasn't appeared before.
+
+\smallskip\noindent
+We have actually discussed these five types in the reverse order of their
+history during a computation: Once \\{known}, a variable never again
+becomes \\{dependent}; once \\{dependent}, it almost never again becomes
+\\{independent}; once \\{independent}, it never again becomes \\{numeric%
+\_type};
+and once \\{numeric\_type}, it never again becomes \\{undefined} (except
+of course when the user specifically decides to scrap the old value
+and start again). A backward step may, however, take place: Sometimes
+a \\{dependent} variable becomes \\{independent} again, when one of the
+independent variables it depends on is reverting to \\{undefined}.
+
+\Y\P\D \37$\\{s\_scale}=64$\C{the serial numbers are multiplied by this factor}%
+\par
+\P\D \37$\\{new\_indep}(\#)\S$\C{create a new independent variable}\6
+\&{begin} \37$\\{type}(\#)\K\\{independent}$;\5
+$\\{serial\_no}\K\\{serial\_no}+\\{s\_scale}$;\5
+$\\{value}(\#)\K\\{serial\_no}$;\6
+\&{end}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{serial\_no}: \37\\{integer};\C{the most recent serial number, times \\{s%
+\_scale}}\par
+\fi
+
+\M586. \P$\X586:Make variable $\|q+\|s$ newly independent\X\S$\6
+$\\{new\_indep}(\|q+\|s)$\par
+\U232.\fi
+
+\M587. But how are dependency lists represented? It's simple: The linear
+combination
+$\alpha_1v_1+\cdots+\alpha_kv_k+\beta$ appears in $\|k+1$ value nodes. If
+$\|q=\\{dep\_list}(\|p)$ points to this list, and if $\|k>0$, then $\\{value}(%
+\|q)=\hbox{$\alpha_1$}$ (which is a \\{fraction}); $\\{info}(\|q)$ points to
+the location
+of $v_1$; and $\\{link}(\|p)$ points to the dependency list
+$\alpha_2v_2+\cdots+\alpha_kv_k+\beta$. On the other hand if $\|k=0$,
+then $\\{value}(\|q)=\hbox{$\beta$}$ (which is \\{scaled}) and $\\{info}(\|q)=%
+\\{null}$.
+The independent variables $v_1$, \dots,~$v_k$ have been sorted so that
+they appear in decreasing order of their \\{value} fields (i.e., of
+their serial numbers). \ (It is convenient to use decreasing order,
+since $\\{value}(\\{null})=0$. If the independent variables were not sorted by
+serial number but by some other criterion, such as their location in \\{mem},
+the equation-solving mechanism would be too system-dependent, because
+the ordering can affect the computed results.)
+
+The \\{link} field in the node that contains the constant term $\beta$ is
+called the {\sl final link\/} of the dependency list. \MF\ maintains
+a doubly-linked master list of all dependency lists, in terms of a permanently
+allocated node
+in \\{mem} called \\{dep\_head}. If there are no dependencies, we have
+$\\{link}(\\{dep\_head})=\\{dep\_head}$ and $\\{prev\_dep}(\\{dep\_head})=%
+\\{dep\_head}$;
+otherwise $\\{link}(\\{dep\_head})$ points to the first dependent variable,
+say~\|p,
+and $\\{prev\_dep}(\|p)=\\{dep\_head}$. We have $\\{type}(\|p)=\\{dependent}$,
+and $\\{dep\_list}(\|p)$
+points to its dependency list. If the final link of that dependency list
+occurs in location~\|q, then $\\{link}(\|q)$ points to the next dependent
+variable (say~\|r); and we have $\\{prev\_dep}(\|r)=\|q$, etc.
+
+\Y\P\D \37$\\{dep\_list}(\#)\S\\{link}(\\{value\_loc}(\#))$\C{half of the %
+\\{value} field in a \\{dependent} variable}\par
+\P\D \37$\\{prev\_dep}(\#)\S\\{info}(\\{value\_loc}(\#))$\C{the other half;
+makes a doubly linked list}\par
+\P\D \37$\\{dep\_node\_size}=2$\C{the number of words per dependency node}\par
+\Y\P$\4\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}\S$\6
+$\\{serial\_no}\K0$;\5
+$\\{link}(\\{dep\_head})\K\\{dep\_head}$;\5
+$\\{prev\_dep}(\\{dep\_head})\K\\{dep\_head}$;\5
+$\\{info}(\\{dep\_head})\K\\{null}$;\5
+$\\{dep\_list}(\\{dep\_head})\K\\{null}$;\par
+\fi
+
+\M588. Actually the description above contains a little white lie. There's
+another kind of variable called \\{proto\_dependent}, which is
+just like a \\{dependent} one except that the $\alpha$ coefficients
+in its dependency list are \\{scaled} instead of being fractions.
+Proto-dependency lists are mixed with dependency lists in the
+nodes reachable from \\{dep\_head}.
+
+\fi
+
+\M589. Here is a procedure that prints a dependency list in symbolic form.
+The second parameter should be either \\{dependent} or \\{proto\_dependent},
+to indicate the scaling of the coefficients.
+
+\Y\P$\4\X257:Declare subroutines for printing expressions\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_dependency}(\|p:\\{pointer};\,\35\|t:\\{small%
+\_number})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|v: \37\\{integer};\C{a coefficient}\6
+$\\{pp},\39\|q$: \37\\{pointer};\C{for list manipulation}\2\6
+\&{begin} \37$\\{pp}\K\|p$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|v\K\\{abs}(\\{value}(\|p))$;\5
+$\|q\K\\{info}(\|p)$;\6
+\&{if} $\|q=\\{null}$ \1\&{then}\C{the constant term}\6
+\&{begin} \37\&{if} $(\|v\I0)\V(\|p=\\{pp})$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{value}(\|p)>0$ \1\&{then}\6
+\&{if} $\|p\I\\{pp}$ \1\&{then}\5
+$\\{print\_char}(\.{"+"})$;\2\2\6
+$\\{print\_scaled}(\\{value}(\|p))$;\6
+\&{end};\2\6
+\&{return};\6
+\&{end};\2\6
+\X590:Print the coefficient, unless it's $\pm1.0$\X;\6
+\&{if} $\\{type}(\|q)\I\\{independent}$ \1\&{then}\5
+$\\{confusion}(\.{"dep"})$;\2\6
+$\\{print\_variable\_name}(\|q)$;\5
+$\|v\K\\{value}(\|q)\mathbin{\&{mod}}\\{s\_scale}$;\6
+\&{while} $\|v>0$ \1\&{do}\6
+\&{begin} \37$\\{print}(\.{"*4"})$;\5
+$\|v\K\|v-2$;\6
+\&{end};\2\6
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M590. \P$\X590:Print the coefficient, unless it's $\pm1.0$\X\S$\6
+\&{if} $\\{value}(\|p)<0$ \1\&{then}\5
+$\\{print\_char}(\.{"-"})$\6
+\4\&{else} \&{if} $\|p\I\\{pp}$ \1\&{then}\5
+$\\{print\_char}(\.{"+"})$;\2\2\6
+\&{if} $\|t=\\{dependent}$ \1\&{then}\5
+$\|v\K\\{round\_fraction}(\|v)$;\2\6
+\&{if} $\|v\I\\{unity}$ \1\&{then}\5
+$\\{print\_scaled}(\|v)$\2\par
+\U589.\fi
+
+\M591. The maximum absolute value of a coefficient in a given dependency list
+is returned by the following simple function.
+
+\Y\P\4\&{function}\1\ \37$\\{max\_coef}(\|p:\\{pointer})$: \37\\{fraction};\6
+\4\&{var} \37\|x: \37\\{fraction};\C{the maximum so far}\2\6
+\&{begin} \37$\|x\K0$;\6
+\&{while} $\\{info}(\|p)\I\\{null}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{abs}(\\{value}(\|p))>\|x$ \1\&{then}\5
+$\|x\K\\{abs}(\\{value}(\|p))$;\2\6
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\\{max\_coef}\K\|x$;\6
+\&{end};\par
+\fi
+
+\M592. One of the main operations needed on dependency lists is to add a
+multiple
+of one list to the other; we call this \\{p\_plus\_fq}, where \|p and~\|q point
+to dependency lists and \|f is a fraction.
+
+If the coefficient of any independent variable becomes \\{coef\_bound} or
+more, in absolute value, this procedure changes the type of that variable
+to `\\{independent\_needing\_fix}', and sets the global variable \\{fix%
+\_needed}
+to~\\{true}. The value of $\\{coef\_bound}=\mu$ is chosen so that
+$\mu^2+\mu<8$; this means that the numbers we deal with won't
+get too large. (Instead of the ``optimum'' $\mu=(\sqrt{33}-1)/2\approx
+2.3723$, the safer value 7/3 is taken as the threshold.)
+
+The changes mentioned in the preceding paragraph are actually done only if
+the global variable \\{watch\_coefs} is \\{true}. But it usually is; in fact,
+it is \\{false} only when \MF\ is making a dependency list that will soon
+be equated to zero.
+
+Several procedures that act on dependency lists, including \\{p\_plus\_fq},
+set the global variable \\{dep\_final} to the final (constant term) node of
+the dependency list that they produce.
+
+\Y\P\D \37$\\{coef\_bound}\S\O{4525252525}$\C{\\{fraction} approximation to
+7/3}\par
+\P\D \37$\\{independent\_needing\_fix}=0$\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{fix\_needed}: \37\\{boolean};\C{does at least one \\{independent} variable
+need scaling?}\6
+\4\\{watch\_coefs}: \37\\{boolean};\C{should we scale coefficients that exceed %
+\\{coef\_bound}?}\6
+\4\\{dep\_final}: \37\\{pointer};\C{location of the constant term and final
+link}\par
+\fi
+
+\M593. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{fix\_needed}\K\\{false}$;\5
+$\\{watch\_coefs}\K\\{true}$;\par
+\fi
+
+\M594. The \\{p\_plus\_fq} procedure has a fourth parameter, \|t, that should
+be
+set to \\{proto\_dependent} if \|p is a proto-dependency list. In this
+case \|f will be \\{scaled}, not a \\{fraction}. Similarly, the fifth
+parameter~\\{tt}
+should be \\{proto\_dependent} if \|q is a proto-dependency list.
+
+List \|q is unchanged by the operation; but list \|p is totally destroyed.
+
+The final link of the dependency list or proto-dependency list returned
+by \\{p\_plus\_fq} is the same as the original final link of~\|p. Indeed, the
+constant term of the result will be located in the same \\{mem} location
+as the original constant term of~\|p.
+
+Coefficients of the result are assumed to be zero if they are less than
+a certain threshold. This compensates for inevitable rounding errors,
+and tends to make more variables `\\{known}'. The threshold is approximately
+$10^{-5}$ in the case of normal dependency lists, $10^{-4}$ for
+proto-dependencies.
+
+\Y\P\D \37$\\{fraction\_threshold}=2685$\C{a \\{fraction} coefficient less than
+this is zeroed}\par
+\P\D \37$\\{half\_fraction\_threshold}=1342$\C{half of \\{fraction\_threshold}}%
+\par
+\P\D \37$\\{scaled\_threshold}=8$\C{a \\{scaled} coefficient less than this is
+zeroed}\par
+\P\D \37$\\{half\_scaled\_threshold}=4$\C{half of \\{scaled\_threshold}}\par
+\Y\P$\4\X594:Declare basic dependency-list subroutines\X\S$\6
+\4\&{function}\1\ \37$\\{p\_plus\_fq}(\|p:\\{pointer};\,\35\|f:\\{integer};\,%
+\35\|q:\\{pointer};\,\35\|t,\39\\{tt}:\\{small\_number})$: \37\\{pointer};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\\{pp},\39\\{qq}$: \37\\{pointer};\C{$\\{info}(\|p)$ and $%
+\\{info}(\|q)$, respectively}\6
+$\|r,\39\|s$: \37\\{pointer};\C{for list manipulation}\6
+\\{threshold}: \37\\{integer};\C{defines a neighborhood of zero}\6
+\|v: \37\\{integer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\|t=\\{dependent}$ \1\&{then}\5
+$\\{threshold}\K\\{fraction\_threshold}$\6
+\4\&{else} $\\{threshold}\K\\{scaled\_threshold}$;\2\6
+$\|r\K\\{temp\_head}$;\5
+$\\{pp}\K\\{info}(\|p)$;\5
+$\\{qq}\K\\{info}(\|q)$;\6
+\~ \1\&{loop}\ \&{if} $\\{pp}=\\{qq}$ \1\&{then}\6
+\&{if} $\\{pp}=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done}\6
+\4\&{else} \X595:Contribute a term from \|p, plus \|f times the corresponding
+term from \|q\X\2\6
+\4\&{else} \&{if} $\\{value}(\\{pp})<\\{value}(\\{qq})$ \1\&{then}\5
+\X596:Contribute a term from \|q, multiplied by~\|f\X\6
+\4\&{else} \&{begin} \37$\\{link}(\|r)\K\|p$;\5
+$\|r\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\5
+$\\{pp}\K\\{info}(\|p)$;\6
+\&{end};\2\2\2\6
+\4\\{done}: \37\&{if} $\|t=\\{dependent}$ \1\&{then}\5
+$\\{value}(\|p)\K\\{slow\_add}(\\{value}(\|p),\39\\{take\_fraction}(\\{value}(%
+\|q),\39\|f))$\6
+\4\&{else} $\\{value}(\|p)\K\\{slow\_add}(\\{value}(\|p),\39\\{take\_scaled}(%
+\\{value}(\|q),\39\|f))$;\2\6
+$\\{link}(\|r)\K\|p$;\5
+$\\{dep\_final}\K\|p$;\5
+$\\{p\_plus\_fq}\K\\{link}(\\{temp\_head})$;\6
+\&{end};\par
+\As600, 602, 603\ETs604.
+\U246.\fi
+
+\M595. \P$\X595:Contribute a term from \|p, plus \|f times the corresponding
+term from \|q\X\S$\6
+\&{begin} \37\&{if} $\\{tt}=\\{dependent}$ \1\&{then}\5
+$\|v\K\\{value}(\|p)+\\{take\_fraction}(\|f,\39\\{value}(\|q))$\6
+\4\&{else} $\|v\K\\{value}(\|p)+\\{take\_scaled}(\|f,\39\\{value}(\|q))$;\2\6
+$\\{value}(\|p)\K\|v$;\5
+$\|s\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{if} $\\{abs}(\|v)<\\{threshold}$ \1\&{then}\5
+$\\{free\_node}(\|s,\39\\{dep\_node\_size})$\6
+\4\&{else} \&{begin} \37\&{if} $\\{abs}(\|v)\G\\{coef\_bound}$ \1\&{then}\6
+\&{if} $\\{watch\_coefs}$ \1\&{then}\6
+\&{begin} \37$\\{type}(\\{qq})\K\\{independent\_needing\_fix}$;\5
+$\\{fix\_needed}\K\\{true}$;\6
+\&{end};\2\2\6
+$\\{link}(\|r)\K\|s$;\5
+$\|r\K\|s$;\6
+\&{end};\2\6
+$\\{pp}\K\\{info}(\|p)$;\5
+$\|q\K\\{link}(\|q)$;\5
+$\\{qq}\K\\{info}(\|q)$;\6
+\&{end}\par
+\U594.\fi
+
+\M596. \P$\X596:Contribute a term from \|q, multiplied by~\|f\X\S$\6
+\&{begin} \37\&{if} $\\{tt}=\\{dependent}$ \1\&{then}\5
+$\|v\K\\{take\_fraction}(\|f,\39\\{value}(\|q))$\6
+\4\&{else} $\|v\K\\{take\_scaled}(\|f,\39\\{value}(\|q))$;\2\6
+\&{if} $\\{abs}(\|v)>\\{half}(\\{threshold})$ \1\&{then}\6
+\&{begin} \37$\|s\K\\{get\_node}(\\{dep\_node\_size})$;\5
+$\\{info}(\|s)\K\\{qq}$;\5
+$\\{value}(\|s)\K\|v$;\6
+\&{if} $\\{abs}(\|v)\G\\{coef\_bound}$ \1\&{then}\6
+\&{if} $\\{watch\_coefs}$ \1\&{then}\6
+\&{begin} \37$\\{type}(\\{qq})\K\\{independent\_needing\_fix}$;\5
+$\\{fix\_needed}\K\\{true}$;\6
+\&{end};\2\2\6
+$\\{link}(\|r)\K\|s$;\5
+$\|r\K\|s$;\6
+\&{end};\2\6
+$\|q\K\\{link}(\|q)$;\5
+$\\{qq}\K\\{info}(\|q)$;\6
+\&{end}\par
+\U594.\fi
+
+\M597. It is convenient to have another subroutine for the special case
+of \\{p\_plus\_fq} when $\|f=1.0$. In this routine lists \|p and \|q are
+both of the same type~\|t (either \\{dependent} or \\{proto\_dependent}).
+
+\Y\P\4\&{function}\1\ \37$\\{p\_plus\_q}(\|p:\\{pointer};\,\35\|q:\\{pointer};%
+\,\35\|t:\\{small\_number})$: \37\\{pointer};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\\{pp},\39\\{qq}$: \37\\{pointer};\C{$\\{info}(\|p)$ and $%
+\\{info}(\|q)$, respectively}\6
+$\|r,\39\|s$: \37\\{pointer};\C{for list manipulation}\6
+\\{threshold}: \37\\{integer};\C{defines a neighborhood of zero}\6
+\|v: \37\\{integer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\|t=\\{dependent}$ \1\&{then}\5
+$\\{threshold}\K\\{fraction\_threshold}$\6
+\4\&{else} $\\{threshold}\K\\{scaled\_threshold}$;\2\6
+$\|r\K\\{temp\_head}$;\5
+$\\{pp}\K\\{info}(\|p)$;\5
+$\\{qq}\K\\{info}(\|q)$;\6
+\~ \1\&{loop}\ \&{if} $\\{pp}=\\{qq}$ \1\&{then}\6
+\&{if} $\\{pp}=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done}\6
+\4\&{else} \X598:Contribute a term from \|p, plus the corresponding term from %
+\|q\X\2\6
+\4\&{else} \&{if} $\\{value}(\\{pp})<\\{value}(\\{qq})$ \1\&{then}\6
+\&{begin} \37$\|s\K\\{get\_node}(\\{dep\_node\_size})$;\5
+$\\{info}(\|s)\K\\{qq}$;\5
+$\\{value}(\|s)\K\\{value}(\|q)$;\5
+$\|q\K\\{link}(\|q)$;\5
+$\\{qq}\K\\{info}(\|q)$;\5
+$\\{link}(\|r)\K\|s$;\5
+$\|r\K\|s$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{link}(\|r)\K\|p$;\5
+$\|r\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\5
+$\\{pp}\K\\{info}(\|p)$;\6
+\&{end};\2\2\2\6
+\4\\{done}: \37$\\{value}(\|p)\K\\{slow\_add}(\\{value}(\|p),\39\\{value}(%
+\|q))$;\5
+$\\{link}(\|r)\K\|p$;\5
+$\\{dep\_final}\K\|p$;\5
+$\\{p\_plus\_q}\K\\{link}(\\{temp\_head})$;\6
+\&{end};\par
+\fi
+
+\M598. \P$\X598:Contribute a term from \|p, plus the corresponding term from %
+\|q\X\S$\6
+\&{begin} \37$\|v\K\\{value}(\|p)+\\{value}(\|q)$;\5
+$\\{value}(\|p)\K\|v$;\5
+$\|s\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\5
+$\\{pp}\K\\{info}(\|p)$;\6
+\&{if} $\\{abs}(\|v)<\\{threshold}$ \1\&{then}\5
+$\\{free\_node}(\|s,\39\\{dep\_node\_size})$\6
+\4\&{else} \&{begin} \37\&{if} $\\{abs}(\|v)\G\\{coef\_bound}$ \1\&{then}\6
+\&{if} $\\{watch\_coefs}$ \1\&{then}\6
+\&{begin} \37$\\{type}(\\{qq})\K\\{independent\_needing\_fix}$;\5
+$\\{fix\_needed}\K\\{true}$;\6
+\&{end};\2\2\6
+$\\{link}(\|r)\K\|s$;\5
+$\|r\K\|s$;\6
+\&{end};\2\6
+$\|q\K\\{link}(\|q)$;\5
+$\\{qq}\K\\{info}(\|q)$;\6
+\&{end}\par
+\U597.\fi
+
+\M599. A somewhat simpler routine will multiply a dependency list
+by a given constant~\|v. The constant is either a \\{fraction} less than
+\\{fraction\_one}, or it is \\{scaled}. In the latter case we might be forced
+to
+convert a dependency list to a proto-dependency list.
+Parameters \\{t0} and \\{t1} are the list types before and after;
+they should agree unless $\\{t0}=\\{dependent}$ and $\\{t1}=\\{proto%
+\_dependent}$
+and $\\{v\_is\_scaled}=\\{true}$.
+
+\Y\P\4\&{function}\1\ \37$\\{p\_times\_v}(\|p:\\{pointer};\,\35\|v:%
+\\{integer};\,\35\\{t0},\39\\{t1}:\\{small\_number};\,\35\\{v\_is\_scaled}:%
+\\{boolean})$: \37\\{pointer};\6
+\4\&{var} \37$\|r,\39\|s$: \37\\{pointer};\C{for list manipulation}\6
+\|w: \37\\{integer};\C{tentative coefficient}\6
+\\{threshold}: \37\\{integer};\5
+\\{scaling\_down}: \37\\{boolean};\2\6
+\&{begin} \37\&{if} $\\{t0}\I\\{t1}$ \1\&{then}\5
+$\\{scaling\_down}\K\\{true}$\ \&{else} $\\{scaling\_down}\K\R\\{v\_is%
+\_scaled}$;\2\6
+\&{if} $\\{t1}=\\{dependent}$ \1\&{then}\5
+$\\{threshold}\K\\{half\_fraction\_threshold}$\6
+\4\&{else} $\\{threshold}\K\\{half\_scaled\_threshold}$;\2\6
+$\|r\K\\{temp\_head}$;\6
+\&{while} $\\{info}(\|p)\I\\{null}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{scaling\_down}$ \1\&{then}\5
+$\|w\K\\{take\_fraction}(\|v,\39\\{value}(\|p))$\6
+\4\&{else} $\|w\K\\{take\_scaled}(\|v,\39\\{value}(\|p))$;\2\6
+\&{if} $\\{abs}(\|w)\L\\{threshold}$ \1\&{then}\6
+\&{begin} \37$\|s\K\\{link}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{dep\_node\_size})$;\5
+$\|p\K\|s$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{abs}(\|w)\G\\{coef\_bound}$ \1\&{then}\6
+\&{begin} \37$\\{fix\_needed}\K\\{true}$;\5
+$\\{type}(\\{info}(\|p))\K\\{independent\_needing\_fix}$;\6
+\&{end};\2\6
+$\\{link}(\|r)\K\|p$;\5
+$\|r\K\|p$;\5
+$\\{value}(\|p)\K\|w$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\\{link}(\|r)\K\|p$;\6
+\&{if} $\\{v\_is\_scaled}$ \1\&{then}\5
+$\\{value}(\|p)\K\\{take\_scaled}(\\{value}(\|p),\39\|v)$\6
+\4\&{else} $\\{value}(\|p)\K\\{take\_fraction}(\\{value}(\|p),\39\|v)$;\2\6
+$\\{p\_times\_v}\K\\{link}(\\{temp\_head})$;\6
+\&{end};\par
+\fi
+
+\M600. Similarly, we sometimes need to divide a dependency list
+by a given \\{scaled} constant.
+
+\Y\P$\4\X594:Declare basic dependency-list subroutines\X\mathrel{+}\S$\6
+\4\&{function}\1\ \37$\\{p\_over\_v}(\|p:\\{pointer};\,\35\|v:\\{scaled};\,\35%
+\\{t0},\39\\{t1}:\\{small\_number})$: \37\\{pointer};\6
+\4\&{var} \37$\|r,\39\|s$: \37\\{pointer};\C{for list manipulation}\6
+\|w: \37\\{integer};\C{tentative coefficient}\6
+\\{threshold}: \37\\{integer};\5
+\\{scaling\_down}: \37\\{boolean};\2\6
+\&{begin} \37\&{if} $\\{t0}\I\\{t1}$ \1\&{then}\5
+$\\{scaling\_down}\K\\{true}$\ \&{else} $\\{scaling\_down}\K\\{false}$;\2\6
+\&{if} $\\{t1}=\\{dependent}$ \1\&{then}\5
+$\\{threshold}\K\\{half\_fraction\_threshold}$\6
+\4\&{else} $\\{threshold}\K\\{half\_scaled\_threshold}$;\2\6
+$\|r\K\\{temp\_head}$;\6
+\&{while} $\\{info}(\|p)\I\\{null}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{scaling\_down}$ \1\&{then}\6
+\&{if} $\\{abs}(\|v)<\O{2000000}$ \1\&{then}\5
+$\|w\K\\{make\_scaled}(\\{value}(\|p),\39\|v\ast\O{10000})$\6
+\4\&{else} $\|w\K\\{make\_scaled}(\\{round\_fraction}(\\{value}(\|p)),\39\|v)$%
+\2\6
+\4\&{else} $\|w\K\\{make\_scaled}(\\{value}(\|p),\39\|v)$;\2\6
+\&{if} $\\{abs}(\|w)\L\\{threshold}$ \1\&{then}\6
+\&{begin} \37$\|s\K\\{link}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{dep\_node\_size})$;\5
+$\|p\K\|s$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{abs}(\|w)\G\\{coef\_bound}$ \1\&{then}\6
+\&{begin} \37$\\{fix\_needed}\K\\{true}$;\5
+$\\{type}(\\{info}(\|p))\K\\{independent\_needing\_fix}$;\6
+\&{end};\2\6
+$\\{link}(\|r)\K\|p$;\5
+$\|r\K\|p$;\5
+$\\{value}(\|p)\K\|w$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\\{link}(\|r)\K\|p$;\5
+$\\{value}(\|p)\K\\{make\_scaled}(\\{value}(\|p),\39\|v)$;\5
+$\\{p\_over\_v}\K\\{link}(\\{temp\_head})$;\6
+\&{end};\par
+\fi
+
+\M601. Here's another utility routine for dependency lists. When an independent
+variable becomes dependent, we want to remove it from all existing
+dependencies. The \\{p\_with\_x\_becoming\_q} function computes the
+dependency list of~\|p after variable~\|x has been replaced by~\|q.
+
+This procedure has basically the same calling conventions as \\{p\_plus\_fq}:
+List~\|q is unchanged; list~\|p is destroyed; the constant node and the
+final link are inherited from~\|p; and the fourth parameter tells whether
+or not \|p is \\{proto\_dependent}. However, the global variable \\{dep\_final}
+is not altered if \|x does not occur in list~\|p.
+
+\Y\P\4\&{function}\1\ \37$\\{p\_with\_x\_becoming\_q}(\|p,\39\|x,\39\|q:%
+\\{pointer};\,\35\|t:\\{small\_number})$: \37\\{pointer};\6
+\4\&{var} \37$\|r,\39\|s$: \37\\{pointer};\C{for list manipulation}\6
+\|v: \37\\{integer};\C{coefficient of \|x}\6
+\\{sx}: \37\\{integer};\C{serial number of \|x}\2\6
+\&{begin} \37$\|s\K\|p$;\5
+$\|r\K\\{temp\_head}$;\5
+$\\{sx}\K\\{value}(\|x)$;\6
+\&{while} $\\{value}(\\{info}(\|s))>\\{sx}$ \1\&{do}\6
+\&{begin} \37$\|r\K\|s$;\5
+$\|s\K\\{link}(\|s)$;\6
+\&{end};\2\6
+\&{if} $\\{info}(\|s)\I\|x$ \1\&{then}\5
+$\\{p\_with\_x\_becoming\_q}\K\|p$\6
+\4\&{else} \&{begin} \37$\\{link}(\\{temp\_head})\K\|p$;\5
+$\\{link}(\|r)\K\\{link}(\|s)$;\5
+$\|v\K\\{value}(\|s)$;\5
+$\\{free\_node}(\|s,\39\\{dep\_node\_size})$;\5
+$\\{p\_with\_x\_becoming\_q}\K\\{p\_plus\_fq}(\\{link}(\\{temp\_head}),\39\|v,%
+\39\|q,\39\|t,\39\\{dependent})$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M602. Here's a simple procedure that reports an error when a variable
+has just received a known value that's out of the required range.
+
+\Y\P$\4\X594:Declare basic dependency-list subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{val\_too\_big}(\|x:\\{scaled})$;\2\6
+\&{begin} \37\&{if} $\\{internal}[\\{warning\_check}]>0$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Value\ is\ too\ large\ ("})$;\5
+$\\{print\_scaled}(\|x)$;\5
+$\\{print\_char}(\.{")"})$;\5
+$\\{help4}(\.{"The\ equation\ I\ just\ processed\ has\ given\ some\
+variable"})$\6
+$(\.{"a\ value\ of\ 4096\ or\ more.\ Continue\ and\ I\'ll\ try\ to\ cope"})$\6
+$(\.{"with\ that\ big\ value;\ but\ it\ might\ be\ dangerous."})$\6
+$(\.{"(Set\ warningcheck:=0\ to\ suppress\ this\ message.)"})$;\5
+\\{error};\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M603. When a dependent variable becomes known, the following routine
+removes its dependency list. Here \|p points to the variable, and
+\|q points to the dependency list (which is one node long).
+
+\Y\P$\4\X594:Declare basic dependency-list subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{make\_known}(\|p,\39\|q:\\{pointer})$;\6
+\4\&{var} \37\|t: \37$\\{dependent}\to\\{proto\_dependent}$;\C{the previous
+type}\2\6
+\&{begin} \37$\\{prev\_dep}(\\{link}(\|q))\K\\{prev\_dep}(\|p)$;\5
+$\\{link}(\\{prev\_dep}(\|p))\K\\{link}(\|q)$;\5
+$\|t\K\\{type}(\|p)$;\5
+$\\{type}(\|p)\K\\{known}$;\5
+$\\{value}(\|p)\K\\{value}(\|q)$;\5
+$\\{free\_node}(\|q,\39\\{dep\_node\_size})$;\6
+\&{if} $\\{abs}(\\{value}(\|p))\G\\{fraction\_one}$ \1\&{then}\5
+$\\{val\_too\_big}(\\{value}(\|p))$;\2\6
+\&{if} $\\{internal}[\\{tracing\_equations}]>0$ \1\&{then}\6
+\&{if} $\\{interesting}(\|p)$ \1\&{then}\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\#\#\#\#\ "})$;\5
+$\\{print\_variable\_name}(\|p)$;\5
+$\\{print\_char}(\.{"="})$;\5
+$\\{print\_scaled}(\\{value}(\|p))$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end};\2\2\6
+\&{if} $\\{cur\_exp}=\|p$ \1\&{then}\6
+\&{if} $\\{cur\_type}=\|t$ \1\&{then}\6
+\&{begin} \37$\\{cur\_type}\K\\{known}$;\5
+$\\{cur\_exp}\K\\{value}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M604. The \\{fix\_dependencies} routine is called into action when \\{fix%
+\_needed}
+has been triggered. The program keeps a list~\|s of independent variables
+whose coefficients must be divided by~4.
+
+In unusual cases, this fixup process might reduce one or more coefficients
+to zero, so that a variable will become known more or less by default.
+
+\Y\P$\4\X594:Declare basic dependency-list subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{fix\_dependencies};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\|s,\39\|t$: \37\\{pointer};\C{list
+manipulation registers}\6
+\|x: \37\\{pointer};\C{an independent variable}\2\6
+\&{begin} \37$\|r\K\\{link}(\\{dep\_head})$;\5
+$\|s\K\\{null}$;\6
+\&{while} $\|r\I\\{dep\_head}$ \1\&{do}\6
+\&{begin} \37$\|t\K\|r$;\5
+\X605:Run through the dependency list for variable \|t, fixing all nodes, and
+ending with final link~\|q\X;\6
+$\|r\K\\{link}(\|q)$;\6
+\&{if} $\|q=\\{dep\_list}(\|t)$ \1\&{then}\5
+$\\{make\_known}(\|t,\39\|q)$;\2\6
+\&{end};\2\6
+\&{while} $\|s\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\|p\K\\{link}(\|s)$;\5
+$\|x\K\\{info}(\|s)$;\5
+$\\{free\_avail}(\|s)$;\5
+$\|s\K\|p$;\5
+$\\{type}(\|x)\K\\{independent}$;\5
+$\\{value}(\|x)\K\\{value}(\|x)+2$;\6
+\&{end};\2\6
+$\\{fix\_needed}\K\\{false}$;\6
+\&{end};\par
+\fi
+
+\M605. \P\D \37$\\{independent\_being\_fixed}=1$\C{this variable already
+appears in \|s}\par
+\Y\P$\4\X605:Run through the dependency list for variable \|t, fixing all
+nodes, and ending with final link~\|q\X\S$\6
+$\|r\K\\{value\_loc}(\|t)$;\C{$\\{link}(\|r)=\\{dep\_list}(\|t)$}\6
+\~ \1\&{loop}\ \&{begin} \37$\|q\K\\{link}(\|r)$;\5
+$\|x\K\\{info}(\|q)$;\6
+\&{if} $\|x=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\\{type}(\|x)\L\\{independent\_being\_fixed}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{type}(\|x)<\\{independent\_being\_fixed}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{get\_avail}$;\5
+$\\{link}(\|p)\K\|s$;\5
+$\|s\K\|p$;\5
+$\\{info}(\|s)\K\|x$;\5
+$\\{type}(\|x)\K\\{independent\_being\_fixed}$;\6
+\&{end};\2\6
+$\\{value}(\|q)\K\\{value}(\|q)\mathbin{\&{div}}4$;\6
+\&{if} $\\{value}(\|q)=0$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|r)\K\\{link}(\|q)$;\5
+$\\{free\_node}(\|q,\39\\{dep\_node\_size})$;\5
+$\|q\K\|r$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\|r\K\|q$;\6
+\&{end};\2\6
+\4\\{done}: \37\par
+\U604.\fi
+
+\M606. The \\{new\_dep} routine installs a dependency list~\|p into the value
+node~\|q,
+linking it into the list of all known dependencies. We assume that
+\\{dep\_final} points to the final node of list~\|p.
+
+\Y\P\4\&{procedure}\1\ \37$\\{new\_dep}(\|q,\39\|p:\\{pointer})$;\6
+\4\&{var} \37\|r: \37\\{pointer};\C{what used to be the first dependency}\2\6
+\&{begin} \37$\\{dep\_list}(\|q)\K\|p$;\5
+$\\{prev\_dep}(\|q)\K\\{dep\_head}$;\5
+$\|r\K\\{link}(\\{dep\_head})$;\5
+$\\{link}(\\{dep\_final})\K\|r$;\5
+$\\{prev\_dep}(\|r)\K\\{dep\_final}$;\5
+$\\{link}(\\{dep\_head})\K\|q$;\6
+\&{end};\par
+\fi
+
+\M607. Here is one of the ways a dependency list gets started.
+The \\{const\_dependency} routine produces a list that has nothing but
+a constant term.
+
+\Y\P\4\&{function}\1\ \37$\\{const\_dependency}(\|v:\\{scaled})$: \37%
+\\{pointer};\2\6
+\&{begin} \37$\\{dep\_final}\K\\{get\_node}(\\{dep\_node\_size})$;\5
+$\\{value}(\\{dep\_final})\K\|v$;\5
+$\\{info}(\\{dep\_final})\K\\{null}$;\5
+$\\{const\_dependency}\K\\{dep\_final}$;\6
+\&{end};\par
+\fi
+
+\M608. And here's a more interesting way to start a dependency list from
+scratch:
+The parameter to \\{single\_dependency} is the location of an
+independent variable~\|x, and the result is the simple dependency list
+`$\|x+0$'.
+
+In the unlikely event that the given independent variable has been doubled so
+often that we can't refer to it with a nonzero coefficient,
+\\{single\_dependency} returns the simple list `0'. This case can be
+recognized by testing that the returned list pointer is equal to
+\\{dep\_final}.
+
+\Y\P\4\&{function}\1\ \37$\\{single\_dependency}(\|p:\\{pointer})$: \37%
+\\{pointer};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the new dependency list}\6
+\|m: \37\\{integer};\C{the number of doublings}\2\6
+\&{begin} \37$\|m\K\\{value}(\|p)\mathbin{\&{mod}}\\{s\_scale}$;\6
+\&{if} $\|m>28$ \1\&{then}\5
+$\\{single\_dependency}\K\\{const\_dependency}(0)$\6
+\4\&{else} \&{begin} \37$\|q\K\\{get\_node}(\\{dep\_node\_size})$;\5
+$\\{value}(\|q)\K\\{two\_to\_the}[28-\|m]$;\5
+$\\{info}(\|q)\K\|p$;\6
+$\\{link}(\|q)\K\\{const\_dependency}(0)$;\5
+$\\{single\_dependency}\K\|q$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M609. We sometimes need to make an exact copy of a dependency list.
+
+\Y\P\4\&{function}\1\ \37$\\{copy\_dep\_list}(\|p:\\{pointer})$: \37%
+\\{pointer};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the new dependency list}\2\6
+\&{begin} \37$\|q\K\\{get\_node}(\\{dep\_node\_size})$;\5
+$\\{dep\_final}\K\|q$;\6
+\~ \1\&{loop}\ \&{begin} \37$\\{info}(\\{dep\_final})\K\\{info}(\|p)$;\5
+$\\{value}(\\{dep\_final})\K\\{value}(\|p)$;\6
+\&{if} $\\{info}(\\{dep\_final})=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{link}(\\{dep\_final})\K\\{get\_node}(\\{dep\_node\_size})$;\5
+$\\{dep\_final}\K\\{link}(\\{dep\_final})$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{copy\_dep\_list}\K\|q$;\6
+\&{end};\par
+\fi
+
+\M610. But how do variables normally become known? Ah, now we get to the heart
+of the
+equation-solving mechanism. The \\{linear\_eq} procedure is given a %
+\\{dependent}
+or \\{proto\_dependent} list,~\|p, in which at least one independent variable
+appears. It equates this list to zero, by choosing an independent variable
+with the largest coefficient and making it dependent on the others. The
+newly dependent variable is eliminated from all current dependencies,
+thereby possibly making other dependent variables known.
+
+The given list \|p is, of course, totally destroyed by all this processing.
+
+\Y\P\4\&{procedure}\1\ \37$\\{linear\_eq}(\|p:\\{pointer};\,\35\|t:\\{small%
+\_number})$;\6
+\4\&{var} \37$\|q,\39\|r,\39\|s$: \37\\{pointer};\C{for link manipulation}\6
+\|x: \37\\{pointer};\C{the variable that loses its independence}\6
+\|n: \37\\{integer};\C{the number of times \|x had been halved}\6
+\|v: \37\\{integer};\C{the coefficient of \|x in list \|p}\6
+\\{prev\_r}: \37\\{pointer};\C{lags one step behind \|r}\6
+\\{final\_node}: \37\\{pointer};\C{the constant term of the new dependency
+list}\6
+\|w: \37\\{integer};\C{a tentative coefficient}\2\6
+\&{begin} \37\X611:Find a node \|q in list \|p whose coefficient \|v is largest%
+\X;\6
+$\|x\K\\{info}(\|q)$;\5
+$\|n\K\\{value}(\|x)\mathbin{\&{mod}}\\{s\_scale}$;\6
+\X612:Divide list \|p by $-\|v$, removing node \|q\X;\6
+\&{if} $\\{internal}[\\{tracing\_equations}]>0$ \1\&{then}\5
+\X613:Display the new dependency\X;\2\6
+\X614:Simplify all existing dependencies by substituting for \|x\X;\6
+\X615:Change variable \|x from \\{independent} to \\{dependent} or \\{known}\X;%
+\6
+\&{if} $\\{fix\_needed}$ \1\&{then}\5
+\\{fix\_dependencies};\2\6
+\&{end};\par
+\fi
+
+\M611. \P$\X611:Find a node \|q in list \|p whose coefficient \|v is largest\X%
+\S$\6
+$\|q\K\|p$;\5
+$\|r\K\\{link}(\|p)$;\5
+$\|v\K\\{value}(\|q)$;\6
+\&{while} $\\{info}(\|r)\I\\{null}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{abs}(\\{value}(\|r))>\\{abs}(\|v)$ \1\&{then}\6
+\&{begin} \37$\|q\K\|r$;\5
+$\|v\K\\{value}(\|r)$;\6
+\&{end};\2\6
+$\|r\K\\{link}(\|r)$;\6
+\&{end}\2\par
+\U610.\fi
+
+\M612. Here we want to change the coefficients from \\{scaled} to \\{fraction},
+except in the constant term. In the common case of a trivial equation
+like `\.{x=3.14}', we will have $\|v=-\\{fraction\_one}$, $\|q=\|p$, and $\|t=%
+\\{dependent}$.
+
+\Y\P$\4\X612:Divide list \|p by $-\|v$, removing node \|q\X\S$\6
+$\|s\K\\{temp\_head}$;\5
+$\\{link}(\|s)\K\|p$;\5
+$\|r\K\|p$;\6
+\1\&{repeat} \37\&{if} $\|r=\|q$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|s)\K\\{link}(\|r)$;\5
+$\\{free\_node}(\|r,\39\\{dep\_node\_size})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|w\K\\{make\_fraction}(\\{value}(\|r),\39\|v)$;\6
+\&{if} $\\{abs}(\|w)\L\\{half\_fraction\_threshold}$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|s)\K\\{link}(\|r)$;\5
+$\\{free\_node}(\|r,\39\\{dep\_node\_size})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{value}(\|r)\K-\|w$;\5
+$\|s\K\|r$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\|r\K\\{link}(\|s)$;\6
+\4\&{until}\5
+$\\{info}(\|r)=\\{null}$;\2\6
+\&{if} $\|t=\\{proto\_dependent}$ \1\&{then}\5
+$\\{value}(\|r)\K-\\{make\_scaled}(\\{value}(\|r),\39\|v)$\6
+\4\&{else} \&{if} $\|v\I-\\{fraction\_one}$ \1\&{then}\5
+$\\{value}(\|r)\K-\\{make\_fraction}(\\{value}(\|r),\39\|v)$;\2\2\6
+$\\{final\_node}\K\|r$;\5
+$\|p\K\\{link}(\\{temp\_head})$\par
+\U610.\fi
+
+\M613. \P$\X613:Display the new dependency\X\S$\6
+\&{if} $\\{interesting}(\|x)$ \1\&{then}\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\#\#\ "})$;\5
+$\\{print\_variable\_name}(\|x)$;\5
+$\|w\K\|n$;\6
+\&{while} $\|w>0$ \1\&{do}\6
+\&{begin} \37$\\{print}(\.{"*4"})$;\5
+$\|w\K\|w-2$;\6
+\&{end};\2\6
+$\\{print\_char}(\.{"="})$;\5
+$\\{print\_dependency}(\|p,\39\\{dependent})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\2\par
+\U610.\fi
+
+\M614. \P$\X614:Simplify all existing dependencies by substituting for \|x\X\S$%
+\6
+$\\{prev\_r}\K\\{dep\_head}$;\5
+$\|r\K\\{link}(\\{dep\_head})$;\6
+\&{while} $\|r\I\\{dep\_head}$ \1\&{do}\6
+\&{begin} \37$\|s\K\\{dep\_list}(\|r)$;\5
+$\|q\K\\{p\_with\_x\_becoming\_q}(\|s,\39\|x,\39\|p,\39\\{type}(\|r))$;\6
+\&{if} $\\{info}(\|q)=\\{null}$ \1\&{then}\5
+$\\{make\_known}(\|r,\39\|q)$\6
+\4\&{else} \&{begin} \37$\\{dep\_list}(\|r)\K\|q$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\\{info}(\|q)=\\{null}$;\2\6
+$\\{prev\_r}\K\|q$;\6
+\&{end};\2\6
+$\|r\K\\{link}(\\{prev\_r})$;\6
+\&{end}\2\par
+\U610.\fi
+
+\M615. \P$\X615:Change variable \|x from \\{independent} to \\{dependent} or %
+\\{known}\X\S$\6
+\&{if} $\|n>0$ \1\&{then}\5
+\X616:Divide list \|p by $2^n$\X;\2\6
+\&{if} $\\{info}(\|p)=\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{type}(\|x)\K\\{known}$;\5
+$\\{value}(\|x)\K\\{value}(\|p)$;\6
+\&{if} $\\{abs}(\\{value}(\|x))\G\\{fraction\_one}$ \1\&{then}\5
+$\\{val\_too\_big}(\\{value}(\|x))$;\2\6
+$\\{free\_node}(\|p,\39\\{dep\_node\_size})$;\6
+\&{if} $\\{cur\_exp}=\|x$ \1\&{then}\6
+\&{if} $\\{cur\_type}=\\{independent}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_exp}\K\\{value}(\|x)$;\5
+$\\{cur\_type}\K\\{known}$;\5
+$\\{free\_node}(\|x,\39\\{value\_node\_size})$;\6
+\&{end};\2\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{type}(\|x)\K\\{dependent}$;\5
+$\\{dep\_final}\K\\{final\_node}$;\5
+$\\{new\_dep}(\|x,\39\|p)$;\6
+\&{if} $\\{cur\_exp}=\|x$ \1\&{then}\6
+\&{if} $\\{cur\_type}=\\{independent}$ \1\&{then}\5
+$\\{cur\_type}\K\\{dependent}$;\2\2\6
+\&{end}\2\par
+\U610.\fi
+
+\M616. \P$\X616:Divide list \|p by $2^n$\X\S$\6
+\&{begin} \37$\|s\K\\{temp\_head}$;\5
+$\\{link}(\\{temp\_head})\K\|p$;\5
+$\|r\K\|p$;\6
+\1\&{repeat} \37\&{if} $\|n>30$ \1\&{then}\5
+$\|w\K0$\6
+\4\&{else} $\|w\K\\{value}(\|r)\mathbin{\&{div}}\\{two\_to\_the}[\|n]$;\2\6
+\&{if} $(\\{abs}(\|w)\L\\{half\_fraction\_threshold})\W(\\{info}(\|r)\I%
+\\{null})$ \1\&{then}\6
+\&{begin} \37$\\{link}(\|s)\K\\{link}(\|r)$;\5
+$\\{free\_node}(\|r,\39\\{dep\_node\_size})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{value}(\|r)\K\|w$;\5
+$\|s\K\|r$;\6
+\&{end};\2\6
+$\|r\K\\{link}(\|s)$;\6
+\4\&{until}\5
+$\\{info}(\|s)=\\{null}$;\2\6
+$\|p\K\\{link}(\\{temp\_head})$;\6
+\&{end}\par
+\U615.\fi
+
+\M617. The \\{check\_mem} procedure, which is used only when \MF\ is being
+debugged, makes sure that the current dependency lists are well formed.
+
+\Y\P$\4\X617:Check the list of linear dependencies\X\S$\6
+$\|q\K\\{dep\_head}$;\5
+$\|p\K\\{link}(\|q)$;\6
+\&{while} $\|p\I\\{dep\_head}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{prev\_dep}(\|p)\I\|q$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"Bad\ PREVDEP\ at\ "})$;\5
+$\\{print\_int}(\|p)$;\6
+\&{end};\2\6
+$\|p\K\\{dep\_list}(\|p)$;\5
+$\|r\K\\{inf\_val}$;\6
+\1\&{repeat} \37\&{if} $\\{value}(\\{info}(\|p))\G\\{value}(\|r)$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"Out\ of\ order\ at\ "})$;\5
+$\\{print\_int}(\|p)$;\6
+\&{end};\2\6
+$\|r\K\\{info}(\|p)$;\5
+$\|q\K\|p$;\5
+$\|p\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\|r=\\{null}$;\2\6
+\&{end}\2\par
+\U180.\fi
+
+\N618. \[29] Dynamic nonlinear equations.
+Variables of numeric type are maintained by the general scheme of
+independent, dependent, and known values that we have just studied;
+and the components of pair and transform variables are handled in the
+same way. But \MF\ also has five other types of values: \&{boolean},
+\&{string}, \&{pen}, \&{path}, and \&{picture}; what about them?
+
+Equations are allowed between nonlinear quantities, but only in a
+simple form. Two variables that haven't yet been assigned values are
+either equal to each other, or they're not.
+
+Before a boolean variable has received a value, its type is \\{unknown%
+\_boolean};
+similarly, there are variables whose type is \\{unknown\_string}, \\{unknown%
+\_pen},
+\\{unknown\_path}, and \\{unknown\_picture}. In such cases the value is either
+\\{null} (which means that no other variables are equivalent to this one), or
+it points to another variable of the same undefined type. The pointers in the
+latter case form a cycle of nodes, which we shall call a ``ring.''
+Rings of undefined variables may include capsules, which arise as
+intermediate results within expressions or as \&{expr} parameters to macros.
+
+When one member of a ring receives a value, the same value is given to
+all the other members. In the case of paths and pictures, this implies
+making separate copies of a potentially large data structure; users should
+restrain their enthusiasm for such generality, unless they have lots and
+lots of memory space.
+
+\fi
+
+\M619. The following procedure is called when a capsule node is being
+added to a ring (e.g., when an unknown variable is mentioned in an expression).
+
+\Y\P\4\&{function}\1\ \37$\\{new\_ring\_entry}(\|p:\\{pointer})$: \37%
+\\{pointer};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the new capsule node}\2\6
+\&{begin} \37$\|q\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{name\_type}(\|q)\K\\{capsule}$;\5
+$\\{type}(\|q)\K\\{type}(\|p)$;\6
+\&{if} $\\{value}(\|p)=\\{null}$ \1\&{then}\5
+$\\{value}(\|q)\K\|p$\ \&{else} $\\{value}(\|q)\K\\{value}(\|p)$;\2\6
+$\\{value}(\|p)\K\|q$;\5
+$\\{new\_ring\_entry}\K\|q$;\6
+\&{end};\par
+\fi
+
+\M620. Conversely, we might delete a capsule or a variable before it becomes
+known.
+The following procedure simply detaches a quantity from its ring,
+without recycling the storage.
+
+\Y\P$\4\X268:Declare the recycling subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{ring\_delete}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\2\6
+\&{begin} \37$\|q\K\\{value}(\|p)$;\6
+\&{if} $\|q\I\\{null}$ \1\&{then}\6
+\&{if} $\|q\I\|p$ \1\&{then}\6
+\&{begin} \37\&{while} $\\{value}(\|q)\I\|p$ \1\&{do}\5
+$\|q\K\\{value}(\|q)$;\2\6
+$\\{value}(\|q)\K\\{value}(\|p)$;\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M621. Eventually there might be an equation that assigns values to all of the
+variables in a ring. The \\{nonlinear\_eq} subroutine does the necessary
+propagation of values.
+
+If the parameter \\{flush\_p} is \\{true}, node \|p itself needn't receive a
+value; it will soon be recycled.
+
+\Y\P\4\&{procedure}\1\ \37$\\{nonlinear\_eq}(\|v:\\{integer};\,\35\|p:%
+\\{pointer};\,\35\\{flush\_p}:\\{boolean})$;\6
+\4\&{var} \37\|t: \37\\{small\_number};\C{the type of ring \|p}\6
+$\|q,\39\|r$: \37\\{pointer};\C{link manipulation registers}\2\6
+\&{begin} \37$\|t\K\\{type}(\|p)-\\{unknown\_tag}$;\5
+$\|q\K\\{value}(\|p)$;\6
+\&{if} $\\{flush\_p}$ \1\&{then}\5
+$\\{type}(\|p)\K\\{vacuous}$\ \&{else} $\|p\K\|q$;\2\6
+\1\&{repeat} \37$\|r\K\\{value}(\|q)$;\5
+$\\{type}(\|q)\K\|t$;\6
+\&{case} $\|t$ \1\&{of}\6
+\4\\{boolean\_type}: \37$\\{value}(\|q)\K\|v$;\6
+\4\\{string\_type}: \37\&{begin} \37$\\{value}(\|q)\K\|v$;\5
+$\\{add\_str\_ref}(\|v)$;\6
+\&{end};\6
+\4\\{pen\_type}: \37\&{begin} \37$\\{value}(\|q)\K\|v$;\5
+$\\{add\_pen\_ref}(\|v)$;\6
+\&{end};\6
+\4\\{path\_type}: \37$\\{value}(\|q)\K\\{copy\_path}(\|v)$;\6
+\4\\{picture\_type}: \37$\\{value}(\|q)\K\\{copy\_edges}(\|v)$;\2\6
+\&{end};\C{there ain't no more cases}\6
+$\|q\K\|r$;\6
+\4\&{until}\5
+$\|q=\|p$;\2\6
+\&{end};\par
+\fi
+
+\M622. If two members of rings are equated, and if they have the same type,
+the \\{ring\_merge} procedure is called on to make them equivalent.
+
+\Y\P\4\&{procedure}\1\ \37$\\{ring\_merge}(\|p,\39\|q:\\{pointer})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|r: \37\\{pointer};\C{traverses one list}\2\6
+\&{begin} \37$\|r\K\\{value}(\|p)$;\6
+\&{while} $\|r\I\|p$ \1\&{do}\6
+\&{begin} \37\&{if} $\|r=\|q$ \1\&{then}\6
+\&{begin} \37\X623:Exclaim about a redundant equation\X;\6
+\&{return};\6
+\&{end};\2\6
+$\|r\K\\{value}(\|r)$;\6
+\&{end};\2\6
+$\|r\K\\{value}(\|p)$;\5
+$\\{value}(\|p)\K\\{value}(\|q)$;\5
+$\\{value}(\|q)\K\|r$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M623. \P$\X623:Exclaim about a redundant equation\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Redundant\ equation"})$;\6
+$\\{help2}(\.{"I\ already\ knew\ that\ this\ equation\ was\ true."})$\6
+$(\.{"But\ perhaps\ no\ harm\ has\ been\ done;\ let\'s\ continue."})$;\6
+\\{put\_get\_error};\6
+\&{end}\par
+\Us622, 1004\ETs1008.\fi
+
+\N624. \[30] Introduction to the syntactic routines.
+Let's pause a moment now and try to look at the Big Picture.
+The \MF\ program consists of three main parts: syntactic routines,
+semantic routines, and output routines. The chief purpose of the
+syntactic routines is to deliver the user's input to the semantic routines,
+while parsing expressions and locating operators and operands. The
+semantic routines act as an interpreter responding to these operators,
+which may be regarded as commands. And the output routines are
+periodically called on to produce compact font descriptions that can be
+used for typesetting or for making interim proof drawings. We have
+discussed the basic data structures and many of the details of semantic
+operations, so we are good and ready to plunge into the part of \MF\ that
+actually controls the activities.
+
+Our current goal is to come to grips with the \\{get\_next} procedure,
+which is the keystone of \MF's input mechanism. Each call of \\{get\_next}
+sets the value of three variables \\{cur\_cmd}, \\{cur\_mod}, and \\{cur\_sym},
+representing the next input token.
+$$\vbox{\halign{#\hfil\cr
+\hbox{\\{cur\_cmd} denotes a command code from the long list of codes
+given earlier;}\cr
+\hbox{\\{cur\_mod} denotes a modifier of the command code;}\cr
+\hbox{\\{cur\_sym} is the hash address of the symbolic token that was
+just scanned,}\cr
+\hbox{\qquad or zero in the case of a numeric or string
+or capsule token.}\cr}}$$
+Underlying this external behavior of \\{get\_next} is all the machinery
+necessary to convert from character files to tokens. At a given time we
+may be only partially finished with the reading of several files (for
+which \&{input} was specified), and partially finished with the expansion
+of some user-defined macros and/or some macro parameters, and partially
+finished reading some text that the user has inserted online,
+and so on. When reading a character file, the characters must be
+converted to tokens; comments and blank spaces must
+be removed, numeric and string tokens must be evaluated.
+
+To handle these situations, which might all be present simultaneously,
+\MF\ uses various stacks that hold information about the incomplete
+activities, and there is a finite state control for each level of the
+input mechanism. These stacks record the current state of an implicitly
+recursive process, but the \\{get\_next} procedure is not recursive.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{cur\_cmd}: \37\\{eight\_bits};\C{current command set by \\{get\_next}}\6
+\4\\{cur\_mod}: \37\\{integer};\C{operand of current command}\6
+\4\\{cur\_sym}: \37\\{halfword};\C{hash address of current symbol}\par
+\fi
+
+\M625. The \\{print\_cmd\_mod} routine prints a symbolic interpretation of a
+command code and its modifier.
+It consists of a rather tedious sequence of print
+commands, and most of it is essentially an inverse to the \\{primitive}
+routine that enters a \MF\ primitive into \\{hash} and \\{eqtb}. Therefore
+almost
+all of this procedure appears elsewhere in the program, together with the
+corresponding \\{primitive} calls.
+
+\Y\P$\4\X625:Declare the procedure called \\{print\_cmd\_mod}\X\S$\6
+\4\&{procedure}\1\ \37$\\{print\_cmd\_mod}(\|c,\39\|m:\\{integer})$;\2\6
+\&{begin} \37\&{case} $\|c$ \1\&{of}\6
+\hbox{\4}\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of primitives%
+\X\6
+\4\&{othercases} \37$\\{print}(\.{"[unknown\ command\ code!]"})$\2\6
+\&{endcases};\6
+\&{end};\par
+\U227.\fi
+
+\M626. Here is a procedure that displays a given command in braces, in the
+user's transcript file.
+
+\Y\P\D \37$\\{show\_cur\_cmd\_mod}\S\\{show\_cmd\_mod}(\\{cur\_cmd},\39\\{cur%
+\_mod})$\par
+\Y\P\4\&{procedure}\1\ \37$\\{show\_cmd\_mod}(\|c,\39\|m:\\{integer})$;\2\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{"})$;\5
+$\\{print\_cmd\_mod}(\|c,\39\|m)$;\5
+$\\{print\_char}(\.{"\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end};\par
+\fi
+
+\N627. \[31] Input stacks and states.
+The state of \MF's input mechanism appears in the input stack, whose
+entries are records with five fields, called \\{index}, \\{start}, \\{loc},
+\\{limit}, and \\{name}. The top element of this stack is maintained in a
+global variable for which no subscripting needs to be done; the other
+elements of the stack appear in an array. Hence the stack is declared thus:
+
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{in\_state\_record}=$\1\5
+\1\&{record} \37\\{index\_field}: \37\\{quarterword};\6
+\4$\\{start\_field},\39\\{loc\_field},\39\\{limit\_field},\39\\{name\_field}$: %
+\37\\{halfword};\2\6
+\&{end};\2\par
+\fi
+
+\M628. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{input\_stack}: \37\&{array} $[0\to\\{stack\_size}]$ \1\&{of}\5
+\\{in\_state\_record};\2\6
+\4\\{input\_ptr}: \37$0\to\\{stack\_size}$;\C{first unused location of \\{input%
+\_stack}}\6
+\4\\{max\_in\_stack}: \37$0\to\\{stack\_size}$;\C{largest value of \\{input%
+\_ptr} when pushing}\6
+\4\\{cur\_input}: \37\\{in\_state\_record};\C{the ``top'' input state}\par
+\fi
+
+\M629. We've already defined the special variable $\\{loc}\S\\{cur\_input}.%
+\\{loc\_field}$
+in our discussion of basic input-output routines. The other components of
+\\{cur\_input} are defined in the same way:
+
+\Y\P\D \37$\\{index}\S\\{cur\_input}.\\{index\_field}$\C{reference for buffer
+information}\par
+\P\D \37$\\{start}\S\\{cur\_input}.\\{start\_field}$\C{starting position in %
+\\{buffer}}\par
+\P\D \37$\\{limit}\S\\{cur\_input}.\\{limit\_field}$\C{end of current line in %
+\\{buffer}}\par
+\P\D \37$\\{name}\S\\{cur\_input}.\\{name\_field}$\C{name of the current file}%
+\par
+\fi
+
+\M630. Let's look more closely now at the five control variables
+(\\{index},~\\{start},~\\{loc},~\\{limit},~\\{name}),
+assuming that \MF\ is reading a line of characters that have been input
+from some file or from the user's terminal. There is an array called
+\\{buffer} that acts as a stack of all lines of characters that are
+currently being read from files, including all lines on subsidiary
+levels of the input stack that are not yet completed. \MF\ will return to
+the other lines when it is finished with the present input file.
+
+(Incidentally, on a machine with byte-oriented addressing, it would be
+appropriate to combine \\{buffer} with the \\{str\_pool} array,
+letting the buffer entries grow downward from the top of the string pool
+and checking that these two tables don't bump into each other.)
+
+The line we are currently working on begins in position \\{start} of the
+buffer; the next character we are about to read is $\\{buffer}[\\{loc}]$; and
+\\{limit} is the location of the last character present. We always have
+$\\{loc}\L\\{limit}$. For convenience, $\\{buffer}[\\{limit}]$ has been set to %
+\.{"\%"}, so
+that the end of a line is easily sensed.
+
+The \\{name} variable is a string number that designates the name of
+the current file, if we are reading a text file. It is 0 if we
+are reading from the terminal for normal input, or 1 if we are executing a
+\&{readstring} command, or 2 if we are reading a string that was
+moved into the buffer by \&{scantokens}.
+
+\fi
+
+\M631. Additional information about the current line is available via the
+\\{index} variable, which counts how many lines of characters are present
+in the buffer below the current level. We have $\\{index}=0$ when reading
+from the terminal and prompting the user for each line; then if the user types,
+e.g., `\.{input font}', we will have $\\{index}=1$ while reading
+the file \.{font.mf}. However, it does not follow that \\{index} is the
+same as the input stack pointer, since many of the levels on the input
+stack may come from token lists.
+
+The global variable \\{in\_open} is equal to the \\{index}
+value of the highest non-token-list level. Thus, the number of partially read
+lines in the buffer is $\\{in\_open}+1$, and we have $\\{in\_open}=\\{index}$
+when we are not reading a token list.
+
+If we are not currently reading from the terminal,
+we are reading from the file variable $\\{input\_file}[\\{index}]$. We use
+the notation \\{terminal\_input} as a convenient abbreviation for $\\{name}=0$,
+and \\{cur\_file} as an abbreviation for $\\{input\_file}[\\{index}]$.
+
+The global variable \\{line} contains the line number in the topmost
+open file, for use in error messages. If we are not reading from
+the terminal, $\\{line\_stack}[\\{index}]$ holds the line number for the
+enclosing level, so that \\{line} can be restored when the current
+file has been read.
+
+If more information about the input state is needed, it can be
+included in small arrays like those shown here. For example,
+the current page or segment number in the input file might be
+put into a variable \\{page}, maintained for enclosing levels in
+`\ignorespaces \\{page\_stack}: \&{array} $[1\to\\{max\_in\_open}]$ \&{of} %
+\\{integer}\unskip'
+by analogy with \\{line\_stack}.
+
+\Y\P\D \37$\\{terminal\_input}\S(\\{name}=0)$\C{are we reading from the
+terminal?}\par
+\P\D \37$\\{cur\_file}\S\\{input\_file}[\\{index}]$\C{the current \\{alpha%
+\_file} variable}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{in\_open}: \37$0\to\\{max\_in\_open}$;\C{the number of lines in the
+buffer, less one}\6
+\4\\{open\_parens}: \37$0\to\\{max\_in\_open}$;\C{the number of open text
+files}\6
+\4\\{input\_file}: \37\&{array} $[1\to\\{max\_in\_open}]$ \1\&{of}\5
+\\{alpha\_file};\2\6
+\4\\{line}: \37\\{integer};\C{current line number in the current source file}\6
+\4\\{line\_stack}: \37\&{array} $[1\to\\{max\_in\_open}]$ \1\&{of}\5
+\\{integer};\2\par
+\fi
+
+\M632. However, all this discussion about input state really applies only to
+the
+case that we are inputting from a file. There is another important case,
+namely when we are currently getting input from a token list. In this case
+$\\{index}>\\{max\_in\_open}$, and the conventions about the other state
+variables
+are different:
+
+\yskip\hang\\{loc} is a pointer to the current node in the token list, i.e.,
+the node that will be read next. If $\\{loc}=\\{null}$, the token list has been
+fully read.
+
+\yskip\hang\\{start} points to the first node of the token list; this node
+may or may not contain a reference count, depending on the type of token
+list involved.
+
+\yskip\hang\\{token\_type}, which takes the place of \\{index} in the
+discussion above, is a code number that explains what kind of token list
+is being scanned.
+
+\yskip\hang\\{name} points to the \\{eqtb} address of the control sequence
+being expanded, if the current token list is a macro not defined by
+\&{vardef}. Macros defined by \&{vardef} have $\\{name}=\\{null}$; their name
+can be deduced by looking at their first two parameters.
+
+\yskip\hang\\{param\_start}, which takes the place of \\{limit}, tells where
+the parameters of the current macro or loop text begin in the \\{param\_stack}.
+
+\yskip\noindent The \\{token\_type} can take several values, depending on
+where the current token list came from:
+
+\yskip
+\indent\\{forever\_text}, if the token list being scanned is the body of
+a \&{forever} loop;
+
+\indent\\{loop\_text}, if the token list being scanned is the body of
+a \&{for} or \&{forsuffixes} loop;
+
+\indent\\{parameter}, if a \&{text} or \&{suffix} parameter is being scanned;
+
+\indent\\{backed\_up}, if the token list being scanned has been inserted as
+`to be read again'.
+
+\indent\\{inserted}, if the token list being scanned has been inserted as
+part of error recovery;
+
+\indent\\{macro}, if the expansion of a user-defined symbolic token is being
+scanned.
+
+\yskip\noindent
+The token list begins with a reference count if and only if $\\{token\_type}=%
+\\{macro}$.
+
+\Y\P\D \37$\\{token\_type}\S\\{index}$\C{type of current token list}\par
+\P\D \37$\\{token\_state}\S(\\{index}>\\{max\_in\_open})$\C{are we scanning a
+token list?}\par
+\P\D \37$\\{file\_state}\S(\\{index}\L\\{max\_in\_open})$\C{are we scanning a
+file line?}\par
+\P\D \37$\\{param\_start}\S\\{limit}$\C{base of macro parameters in \\{param%
+\_stack}}\par
+\P\D \37$\\{forever\_text}=\\{max\_in\_open}+1$\C{\\{token\_type} code for loop
+texts}\par
+\P\D \37$\\{loop\_text}=\\{max\_in\_open}+2$\C{\\{token\_type} code for loop
+texts}\par
+\P\D \37$\\{parameter}=\\{max\_in\_open}+3$\C{\\{token\_type} code for
+parameter texts}\par
+\P\D \37$\\{backed\_up}=\\{max\_in\_open}+4$\C{\\{token\_type} code for texts
+to be reread}\par
+\P\D \37$\\{inserted}=\\{max\_in\_open}+5$\C{\\{token\_type} code for inserted
+texts}\par
+\P\D \37$\\{macro}=\\{max\_in\_open}+6$\C{\\{token\_type} code for macro
+replacement texts}\par
+\fi
+
+\M633. The \\{param\_stack} is an auxiliary array used to hold pointers to the
+token
+lists for parameters at the current level and subsidiary levels of input.
+This stack grows at a different rate from the others.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{param\_stack}: \37\&{array} $[0\to\\{param\_size}]$ \1\&{of}\5
+\\{pointer};\C{token list pointers for parameters}\2\6
+\4\\{param\_ptr}: \37$0\to\\{param\_size}$;\C{first unused entry in \\{param%
+\_stack}}\6
+\4\\{max\_param\_stack}: \37\\{integer};\C{largest value of \\{param\_ptr}}\par
+\fi
+
+\M634. Thus, the ``current input state'' can be very complicated indeed; there
+can be many levels and each level can arise in a variety of ways. The
+\\{show\_context} procedure, which is used by \MF's error-reporting routine to
+print out the current input state on all levels down to the most recent
+line of characters from an input file, illustrates most of these conventions.
+The global variable \\{file\_ptr} contains the lowest level that was
+displayed by this procedure.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{file\_ptr}: \37$0\to\\{stack\_size}$;\C{shallowest level shown by \\{show%
+\_context}}\par
+\fi
+
+\M635. The status at each level is indicated by printing two lines, where the
+first
+line indicates what was read so far and the second line shows what remains
+to be read. The context is cropped, if necessary, so that the first line
+contains at most \\{half\_error\_line} characters, and the second contains
+at most \\{error\_line}. Non-current input levels whose \\{token\_type} is
+`\\{backed\_up}' are shown only if they have not been fully read.
+
+\Y\P\4\&{procedure}\1\ \37\\{show\_context};\C{prints where the scanner is}\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\\{old\_setting}: \37$0\to\\{max\_selector}$;\C{saved \\{selector}
+setting}\6
+\X641:Local variables for formatting calculations\X\2\6
+\&{begin} \37$\\{file\_ptr}\K\\{input\_ptr}$;\5
+$\\{input\_stack}[\\{file\_ptr}]\K\\{cur\_input}$;\C{store current state}\6
+\~ \1\&{loop}\ \&{begin} \37$\\{cur\_input}\K\\{input\_stack}[\\{file\_ptr}]$;%
+\C{enter into the context}\6
+\X636:Display the current context\X;\6
+\&{if} $\\{file\_state}$ \1\&{then}\6
+\&{if} $(\\{name}>2)\V(\\{file\_ptr}=0)$ \1\&{then}\5
+\&{goto} \37\\{done};\2\2\6
+$\\{decr}(\\{file\_ptr})$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{cur\_input}\K\\{input\_stack}[\\{input\_ptr}]$;\C{restore
+original state}\6
+\&{end};\par
+\fi
+
+\M636. \P$\X636:Display the current context\X\S$\6
+\&{if} $(\\{file\_ptr}=\\{input\_ptr})\V\\{file\_state}\V(\\{token\_type}\I%
+\\{backed\_up})\V(\\{loc}\I\\{null})$ \1\&{then}\C{we omit backed-up token
+lists that have already been read}\6
+\&{begin} \37$\\{tally}\K0$;\C{get ready to count characters}\6
+$\\{old\_setting}\K\\{selector}$;\6
+\&{if} $\\{file\_state}$ \1\&{then}\6
+\&{begin} \37\X637:Print location of current line\X;\6
+\X644:Pseudoprint the line\X;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\X638:Print type of token list\X;\6
+\X645:Pseudoprint the token list\X;\6
+\&{end};\2\6
+$\\{selector}\K\\{old\_setting}$;\C{stop pseudoprinting}\6
+\X643:Print two lines using the tricky pseudoprinted information\X;\6
+\&{end}\2\par
+\U635.\fi
+
+\M637. This routine should be changed, if necessary, to give the best possible
+indication of where the current line resides in the input file.
+For example, on some systems it is best to print both a page and line number.
+
+\Y\P$\4\X637:Print location of current line\X\S$\6
+\&{if} $\\{name}\L1$ \1\&{then}\6
+\&{if} $\\{terminal\_input}\W(\\{file\_ptr}=0)$ \1\&{then}\5
+$\\{print\_nl}(\.{"<*>"})$\6
+\4\&{else} $\\{print\_nl}(\.{"<insert>"})$\2\6
+\4\&{else} \&{if} $\\{name}=2$ \1\&{then}\5
+$\\{print\_nl}(\.{"<scantokens>"})$\6
+\4\&{else} \&{begin} \37$\\{print\_nl}(\.{"l."})$;\5
+$\\{print\_int}(\\{line})$;\6
+\&{end};\2\2\6
+$\\{print\_char}(\.{"\ "})$\par
+\U636.\fi
+
+\M638. \P$\X638:Print type of token list\X\S$\6
+\&{case} $\\{token\_type}$ \1\&{of}\6
+\4\\{forever\_text}: \37$\\{print\_nl}(\.{"<forever>\ "})$;\6
+\4\\{loop\_text}: \37\X639:Print the current loop value\X;\6
+\4\\{parameter}: \37$\\{print\_nl}(\.{"<argument>\ "})$;\6
+\4\\{backed\_up}: \37\&{if} $\\{loc}=\\{null}$ \1\&{then}\5
+$\\{print\_nl}(\.{"<recently\ read>\ "})$\6
+\4\&{else} $\\{print\_nl}(\.{"<to\ be\ read\ again>\ "})$;\2\6
+\4\\{inserted}: \37$\\{print\_nl}(\.{"<inserted\ text>\ "})$;\6
+\4\\{macro}: \37\&{begin} \37\\{print\_ln};\6
+\&{if} $\\{name}\I\\{null}$ \1\&{then}\5
+$\\{slow\_print}(\\{text}(\\{name}))$\6
+\4\&{else} \X640:Print the name of a \&{vardef}'d macro\X;\2\6
+$\\{print}(\.{"->"})$;\6
+\&{end};\6
+\4\&{othercases} \37$\\{print\_nl}(\.{"?"})$\C{this should never happen}\2\6
+\&{endcases}\par
+\U636.\fi
+
+\M639. The parameter that corresponds to a loop text is either a token list
+(in the case of \&{forsuffixes}) or a ``capsule'' (in the case of \&{for}).
+We'll discuss capsules later; for now, all we need to know is that
+the \\{link} field in a capsule parameter is \\{void} and that
+$\\{print\_exp}(\|p,0)$ displays the value of capsule~\|p in abbreviated form.
+
+\Y\P$\4\X639:Print the current loop value\X\S$\6
+\&{begin} \37$\\{print\_nl}(\.{"<for("})$;\5
+$\|p\K\\{param\_stack}[\\{param\_start}]$;\6
+\&{if} $\|p\I\\{null}$ \1\&{then}\6
+\&{if} $\\{link}(\|p)=\\{void}$ \1\&{then}\5
+$\\{print\_exp}(\|p,\390)$\C{we're in a \&{for} loop}\6
+\4\&{else} $\\{show\_token\_list}(\|p,\39\\{null},\3920,\39\\{tally})$;\2\2\6
+$\\{print}(\.{")>\ "})$;\6
+\&{end}\par
+\U638.\fi
+
+\M640. The first two parameters of a macro defined by \&{vardef} will be token
+lists representing the macro's prefix and ``at point.'' By putting these
+together, we get the macro's full name.
+
+\Y\P$\4\X640:Print the name of a \&{vardef}'d macro\X\S$\6
+\&{begin} \37$\|p\K\\{param\_stack}[\\{param\_start}]$;\6
+\&{if} $\|p=\\{null}$ \1\&{then}\5
+$\\{show\_token\_list}(\\{param\_stack}[\\{param\_start}+1],\39\\{null},\3920,%
+\39\\{tally})$\6
+\4\&{else} \&{begin} \37$\|q\K\|p$;\6
+\&{while} $\\{link}(\|q)\I\\{null}$ \1\&{do}\5
+$\|q\K\\{link}(\|q)$;\2\6
+$\\{link}(\|q)\K\\{param\_stack}[\\{param\_start}+1]$;\5
+$\\{show\_token\_list}(\|p,\39\\{null},\3920,\39\\{tally})$;\5
+$\\{link}(\|q)\K\\{null}$;\6
+\&{end};\2\6
+\&{end}\par
+\U638.\fi
+
+\M641. Now it is necessary to explain a little trick. We don't want to store a
+long
+string that corresponds to a token list, because that string might take up
+lots of memory; and we are printing during a time when an error message is
+being given, so we dare not do anything that might overflow one of \MF's
+tables. So `pseudoprinting' is the answer: We enter a mode of printing
+that stores characters into a buffer of length \\{error\_line}, where character
+$k+1$ is placed into \hbox{$\\{trick\_buf}[\|k\mathbin{\&{mod}}\\{error%
+\_line}]$} if
+$\|k<\\{trick\_count}$, otherwise character \|k is dropped. Initially we set
+$\\{tally}\K0$ and $\\{trick\_count}\K1000000$; then when we reach the
+point where transition from line 1 to line 2 should occur, we
+set $\\{first\_count}\K\\{tally}$ and $\\{trick\_count}\K\hbox{max}(\\{error%
+\_line},\\{tally}+1+\\{error\_line}-\\{half\_error\_line})$. At the end of the
+pseudoprinting, the values of \\{first\_count}, \\{tally}, and
+\\{trick\_count} give us all the information we need to print the two lines,
+and all of the necessary text is in \\{trick\_buf}.
+
+Namely, let \|l be the length of the descriptive information that appears
+on the first line. The length of the context information gathered for that
+line is $\|k=\\{first\_count}$, and the length of the context information
+gathered for line~2 is $m=\min(\\{tally}, \\{trick\_count})-k$. If $\|l+\|k\L%
+\|h$,
+where $\|h=\\{half\_error\_line}$, we print $\\{trick\_buf}[0\to\|k-1]$ after
+the
+descriptive information on line~1, and set $\|n\K\|l+\|k$; here \|n is the
+length of line~1. If $l+k>h$, some cropping is necessary, so we set $\|n\K\|h$
+and print `\.{...}' followed by
+$$\hbox{$\\{trick\_buf}[(\|l+\|k-\|h+3)\to\|k-1]$,}$$
+where subscripts of \\{trick\_buf} are circular modulo \\{error\_line}. The
+second line consists of \|n~spaces followed by $\\{trick\_buf}[\|k\to(\|k+%
+\|m-1)]$,
+unless $\|n+\|m>\\{error\_line}$; in the latter case, further cropping is done.
+This is easier to program than to explain.
+
+\Y\P$\4\X641:Local variables for formatting calculations\X\S$\6
+\4\|i: \37$0\to\\{buf\_size}$;\C{index into \\{buffer}}\6
+\4\|l: \37\\{integer};\C{length of descriptive information on line 1}\6
+\4\|m: \37\\{integer};\C{context information gathered for line 2}\6
+\4\|n: \37$0\to\\{error\_line}$;\C{length of line 1}\6
+\4\|p: \37\\{integer};\C{starting or ending place in \\{trick\_buf}}\6
+\4\|q: \37\\{integer};\C{temporary index}\par
+\U635.\fi
+
+\M642. The following code tells the print routines to gather
+the desired information.
+
+\Y\P\D \37$\\{begin\_pseudoprint}\S$\1\6
+\&{begin} \37$\|l\K\\{tally}$;\5
+$\\{tally}\K0$;\5
+$\\{selector}\K\\{pseudo}$;\5
+$\\{trick\_count}\K1000000$;\6
+\&{end}\2\par
+\P\D \37$\\{set\_trick\_count}\S$\1\6
+\&{begin} \37$\\{first\_count}\K\\{tally}$;\5
+$\\{trick\_count}\K\\{tally}+1+\\{error\_line}-\\{half\_error\_line}$;\6
+\&{if} $\\{trick\_count}<\\{error\_line}$ \1\&{then}\5
+$\\{trick\_count}\K\\{error\_line}$;\2\6
+\&{end}\2\par
+\fi
+
+\M643. And the following code uses the information after it has been gathered.
+
+\Y\P$\4\X643:Print two lines using the tricky pseudoprinted information\X\S$\6
+\&{if} $\\{trick\_count}=1000000$ \1\&{then}\5
+\\{set\_trick\_count};\C{\\{set\_trick\_count} must be performed}\2\6
+\&{if} $\\{tally}<\\{trick\_count}$ \1\&{then}\5
+$\|m\K\\{tally}-\\{first\_count}$\6
+\4\&{else} $\|m\K\\{trick\_count}-\\{first\_count}$;\C{context on line 2}\2\6
+\&{if} $\|l+\\{first\_count}\L\\{half\_error\_line}$ \1\&{then}\6
+\&{begin} \37$\|p\K0$;\5
+$\|n\K\|l+\\{first\_count}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print}(\.{"..."})$;\5
+$\|p\K\|l+\\{first\_count}-\\{half\_error\_line}+3$;\5
+$\|n\K\\{half\_error\_line}$;\6
+\&{end};\2\6
+\&{for} $\|q\K\|p\mathrel{\&{to}}\\{first\_count}-1$ \1\&{do}\5
+$\\{print\_char}(\\{trick\_buf}[\|q\mathbin{\&{mod}}\\{error\_line}])$;\2\6
+\\{print\_ln};\6
+\&{for} $\|q\K1\mathrel{\&{to}}\|n$ \1\&{do}\5
+$\\{print\_char}(\.{"\ "})$;\C{print \|n spaces to begin line~2}\2\6
+\&{if} $\|m+\|n\L\\{error\_line}$ \1\&{then}\5
+$\|p\K\\{first\_count}+\|m$\6
+\4\&{else} $\|p\K\\{first\_count}+(\\{error\_line}-\|n-3)$;\2\6
+\&{for} $\|q\K\\{first\_count}\mathrel{\&{to}}\|p-1$ \1\&{do}\5
+$\\{print\_char}(\\{trick\_buf}[\|q\mathbin{\&{mod}}\\{error\_line}])$;\2\6
+\&{if} $\|m+\|n>\\{error\_line}$ \1\&{then}\5
+$\\{print}(\.{"..."})$\2\par
+\U636.\fi
+
+\M644. But the trick is distracting us from our current goal, which is to
+understand the input state. So let's concentrate on the data structures that
+are being pseudoprinted as we finish up the \\{show\_context} procedure.
+
+\Y\P$\4\X644:Pseudoprint the line\X\S$\6
+\\{begin\_pseudoprint};\6
+\&{if} $\\{limit}>0$ \1\&{then}\6
+\&{for} $\|i\K\\{start}\mathrel{\&{to}}\\{limit}-1$ \1\&{do}\6
+\&{begin} \37\&{if} $\|i=\\{loc}$ \1\&{then}\5
+\\{set\_trick\_count};\2\6
+$\\{print}(\\{buffer}[\|i])$;\6
+\&{end}\2\2\par
+\U636.\fi
+
+\M645. \P$\X645:Pseudoprint the token list\X\S$\6
+\\{begin\_pseudoprint};\6
+\&{if} $\\{token\_type}\I\\{macro}$ \1\&{then}\5
+$\\{show\_token\_list}(\\{start},\39\\{loc},\39100000,\390)$\6
+\4\&{else} $\\{show\_macro}(\\{start},\39\\{loc},\39100000)$\2\par
+\U636.\fi
+
+\M646. Here is the missing piece of \\{show\_token\_list} that is activated
+when the
+token beginning line~2 is about to be shown:
+
+\Y\P$\4\X646:Do magic computation\X\S$\6
+\\{set\_trick\_count}\par
+\U217.\fi
+
+\N647. \[32] Maintaining the input stacks.
+The following subroutines change the input status in commonly needed ways.
+
+First comes \\{push\_input}, which stores the current state and creates a
+new level (having, initially, the same properties as the old).
+
+\Y\P\D \37$\\{push\_input}\S\hbox{}$\C{enter a new input level, save the old}\6
+\&{begin} \37\&{if} $\\{input\_ptr}>\\{max\_in\_stack}$ \1\&{then}\6
+\&{begin} \37$\\{max\_in\_stack}\K\\{input\_ptr}$;\6
+\&{if} $\\{input\_ptr}=\\{stack\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"input\ stack\ size"},\39\\{stack\_size})$;\2\6
+\&{end};\2\6
+$\\{input\_stack}[\\{input\_ptr}]\K\\{cur\_input}$;\C{stack the record}\6
+$\\{incr}(\\{input\_ptr})$;\6
+\&{end}\par
+\fi
+
+\M648. And of course what goes up must come down.
+
+\Y\P\D \37$\\{pop\_input}\S\hbox{}$\C{leave an input level, re-enter the old}\6
+\&{begin} \37$\\{decr}(\\{input\_ptr})$;\5
+$\\{cur\_input}\K\\{input\_stack}[\\{input\_ptr}]$;\6
+\&{end}\par
+\fi
+
+\M649. Here is a procedure that starts a new level of token-list input, given
+a token list \|p and its type \|t. If $\|t=\\{macro}$, the calling routine
+should
+set \\{name}, reset~\\{loc}, and increase the macro's reference count.
+
+\Y\P\D \37$\\{back\_list}(\#)\S\\{begin\_token\_list}(\#,\39\\{backed\_up})$%
+\C{backs up a simple token list}\par
+\Y\P\4\&{procedure}\1\ \37$\\{begin\_token\_list}(\|p:\\{pointer};\,\35\|t:%
+\\{quarterword})$;\2\6
+\&{begin} \37\\{push\_input};\5
+$\\{start}\K\|p$;\5
+$\\{token\_type}\K\|t$;\5
+$\\{param\_start}\K\\{param\_ptr}$;\5
+$\\{loc}\K\|p$;\6
+\&{end};\par
+\fi
+
+\M650. When a token list has been fully scanned, the following computations
+should be done as we leave that level of input.
+
+\Y\P\4\&{procedure}\1\ \37\\{end\_token\_list};\C{leave a token-list input
+level}\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\\{token\_type}\G\\{backed\_up}$ \1\&{then}\C{token list
+to be deleted}\6
+\&{if} $\\{token\_type}\L\\{inserted}$ \1\&{then}\6
+\&{begin} \37$\\{flush\_token\_list}(\\{start})$;\5
+\&{goto} \37\\{done};\6
+\&{end}\6
+\4\&{else} $\\{delete\_mac\_ref}(\\{start})$;\C{update reference count}\2\2\6
+\&{while} $\\{param\_ptr}>\\{param\_start}$ \1\&{do}\C{parameters must be
+flushed}\6
+\&{begin} \37$\\{decr}(\\{param\_ptr})$;\5
+$\|p\K\\{param\_stack}[\\{param\_ptr}]$;\6
+\&{if} $\|p\I\\{null}$ \1\&{then}\6
+\&{if} $\\{link}(\|p)=\\{void}$ \1\&{then}\C{it's an \&{expr} parameter}\6
+\&{begin} \37$\\{recycle\_value}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\6
+\&{end}\6
+\4\&{else} $\\{flush\_token\_list}(\|p)$;\C{it's a \&{suffix} or \&{text}
+parameter}\2\2\6
+\&{end};\2\6
+\4\\{done}: \37\\{pop\_input};\5
+\\{check\_interrupt};\6
+\&{end};\par
+\fi
+
+\M651. The contents of $\\{cur\_cmd},\\{cur\_mod},\\{cur\_sym}$ are placed into
+an equivalent
+token by the \\{cur\_tok} routine.
+
+\Y\P\hbox{\4}\X855:Declare the procedure called \\{make\_exp\_copy}\X\6
+\4\&{function}\1\ \37\\{cur\_tok}: \37\\{pointer};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{a new token node}\6
+\\{save\_type}: \37\\{small\_number};\C{\\{cur\_type} to be restored}\6
+\\{save\_exp}: \37\\{integer};\C{\\{cur\_exp} to be restored}\2\6
+\&{begin} \37\&{if} $\\{cur\_sym}=0$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}=\\{capsule\_token}$ \1\&{then}\6
+\&{begin} \37$\\{save\_type}\K\\{cur\_type}$;\5
+$\\{save\_exp}\K\\{cur\_exp}$;\5
+$\\{make\_exp\_copy}(\\{cur\_mod})$;\5
+$\|p\K\\{stash\_cur\_exp}$;\5
+$\\{link}(\|p)\K\\{null}$;\5
+$\\{cur\_type}\K\\{save\_type}$;\5
+$\\{cur\_exp}\K\\{save\_exp}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|p\K\\{get\_node}(\\{token\_node\_size})$;\5
+$\\{value}(\|p)\K\\{cur\_mod}$;\5
+$\\{name\_type}(\|p)\K\\{token}$;\6
+\&{if} $\\{cur\_cmd}=\\{numeric\_token}$ \1\&{then}\5
+$\\{type}(\|p)\K\\{known}$\6
+\4\&{else} $\\{type}(\|p)\K\\{string\_type}$;\2\6
+\&{end}\2\6
+\4\&{else} \&{begin} \37$\\{fast\_get\_avail}(\|p)$;\5
+$\\{info}(\|p)\K\\{cur\_sym}$;\6
+\&{end};\2\6
+$\\{cur\_tok}\K\|p$;\6
+\&{end};\par
+\fi
+
+\M652. Sometimes \MF\ has read too far and wants to ``unscan'' what it has
+seen. The \\{back\_input} procedure takes care of this by putting the token
+just scanned back into the input stream, ready to be read again.
+If $\\{cur\_sym}\I0$, the values of \\{cur\_cmd} and \\{cur\_mod} are
+irrelevant.
+
+\Y\P\4\&{procedure}\1\ \37\\{back\_input};\C{undoes one token of input}\6
+\4\&{var} \37\|p: \37\\{pointer};\C{a token list of length one}\2\6
+\&{begin} \37$\|p\K\\{cur\_tok}$;\6
+\&{while} $\\{token\_state}\W(\\{loc}=\\{null})$ \1\&{do}\5
+\\{end\_token\_list};\C{conserve stack space}\2\6
+$\\{back\_list}(\|p)$;\6
+\&{end};\par
+\fi
+
+\M653. The \\{back\_error} routine is used when we want to restore or replace
+an
+offending token just before issuing an error message. We disable interrupts
+during the call of \\{back\_input} so that the help message won't be lost.
+
+\Y\P\4\&{procedure}\1\ \37\\{back\_error};\C{back up one token and call %
+\\{error}}\2\6
+\&{begin} \37$\\{OK\_to\_interrupt}\K\\{false}$;\5
+\\{back\_input};\5
+$\\{OK\_to\_interrupt}\K\\{true}$;\5
+\\{error};\6
+\&{end};\7
+\4\&{procedure}\1\ \37\\{ins\_error};\C{back up one inserted token and call %
+\\{error}}\2\6
+\&{begin} \37$\\{OK\_to\_interrupt}\K\\{false}$;\5
+\\{back\_input};\5
+$\\{token\_type}\K\\{inserted}$;\5
+$\\{OK\_to\_interrupt}\K\\{true}$;\5
+\\{error};\6
+\&{end};\par
+\fi
+
+\M654. The \\{begin\_file\_reading} procedure starts a new level of input for
+lines
+of characters to be read from a file, or as an insertion from the
+terminal. It does not take care of opening the file, nor does it set \\{loc}
+or \\{limit} or \\{line}.
+
+\Y\P\4\&{procedure}\1\ \37\\{begin\_file\_reading};\2\6
+\&{begin} \37\&{if} $\\{in\_open}=\\{max\_in\_open}$ \1\&{then}\5
+$\\{overflow}(\.{"text\ input\ levels"},\39\\{max\_in\_open})$;\2\6
+\&{if} $\\{first}=\\{buf\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"buffer\ size"},\39\\{buf\_size})$;\2\6
+$\\{incr}(\\{in\_open})$;\5
+\\{push\_input};\5
+$\\{index}\K\\{in\_open}$;\5
+$\\{line\_stack}[\\{index}]\K\\{line}$;\5
+$\\{start}\K\\{first}$;\5
+$\\{name}\K0$;\C{\\{terminal\_input} is now \\{true}}\6
+\&{end};\par
+\fi
+
+\M655. Conversely, the variables must be downdated when such a level of input
+is finished:
+
+\Y\P\4\&{procedure}\1\ \37\\{end\_file\_reading};\2\6
+\&{begin} \37$\\{first}\K\\{start}$;\5
+$\\{line}\K\\{line\_stack}[\\{index}]$;\6
+\&{if} $\\{index}\I\\{in\_open}$ \1\&{then}\5
+$\\{confusion}(\.{"endinput"})$;\2\6
+\&{if} $\\{name}>2$ \1\&{then}\5
+$\\{a\_close}(\\{cur\_file})$;\C{forget it}\2\6
+\\{pop\_input};\5
+$\\{decr}(\\{in\_open})$;\6
+\&{end};\par
+\fi
+
+\M656. In order to keep the stack from overflowing during a long sequence of
+inserted `\.{show}' commands, the following routine removes completed
+error-inserted lines from memory.
+
+\Y\P\4\&{procedure}\1\ \37\\{clear\_for\_error\_prompt};\2\6
+\&{begin} \37\&{while} $\\{file\_state}\W\\{terminal\_input}\W\30(\\{input%
+\_ptr}>0)\W(\\{loc}=\\{limit})$ \1\&{do}\5
+\\{end\_file\_reading};\2\6
+\\{print\_ln};\5
+\\{clear\_terminal};\6
+\&{end};\par
+\fi
+
+\M657. To get \MF's whole input mechanism going, we perform the following
+actions.
+
+\Y\P$\4\X657:Initialize the input routines\X\S$\6
+\&{begin} \37$\\{input\_ptr}\K0$;\5
+$\\{max\_in\_stack}\K0$;\5
+$\\{in\_open}\K0$;\5
+$\\{open\_parens}\K0$;\5
+$\\{max\_buf\_stack}\K0$;\5
+$\\{param\_ptr}\K0$;\5
+$\\{max\_param\_stack}\K0$;\5
+$\\{first}\K1$;\5
+$\\{start}\K1$;\5
+$\\{index}\K0$;\5
+$\\{line}\K0$;\5
+$\\{name}\K0$;\5
+$\\{force\_eof}\K\\{false}$;\6
+\&{if} $\R\\{init\_terminal}$ \1\&{then}\5
+\&{goto} \37\\{final\_end};\2\6
+$\\{limit}\K\\{last}$;\5
+$\\{first}\K\\{last}+1$;\C{\\{init\_terminal} has set \\{loc} and \\{last}}\6
+\&{end};\par
+\A660.
+\U1211.\fi
+
+\N658. \[33] Getting the next token.
+The heart of \MF's input mechanism is the \\{get\_next} procedure, which
+we shall develop in the next few sections of the program. Perhaps we
+shouldn't actually call it the ``heart,'' however; it really acts as \MF's
+eyes and mouth, reading the source files and gobbling them up. And it also
+helps \MF\ to regurgitate stored token lists that are to be processed again.
+
+The main duty of \\{get\_next} is to input one token and to set \\{cur\_cmd}
+and \\{cur\_mod} to that token's command code and modifier. Furthermore, if
+the input token is a symbolic token, that token's \\{hash} address
+is stored in \\{cur\_sym}; otherwise \\{cur\_sym} is set to zero.
+
+Underlying this simple description is a certain amount of complexity
+because of all the cases that need to be handled.
+However, the inner loop of \\{get\_next} is reasonably short and fast.
+
+\fi
+
+\M659. Before getting into \\{get\_next}, we need to consider a mechanism by
+which
+\MF\ helps keep errors from propagating too far. Whenever the program goes
+into a mode where it keeps calling \\{get\_next} repeatedly until a certain
+condition is met, it sets \\{scanner\_status} to some value other than %
+\\{normal}.
+Then if an input file ends, or if an `\&{outer}' symbol appears,
+an appropriate error recovery will be possible.
+
+The global variable \\{warning\_info} helps in this error recovery by providing
+additional information. For example, \\{warning\_info} might indicate the
+name of a macro whose replacement text is being scanned.
+
+\Y\P\D \37$\\{normal}=0$\C{\\{scanner\_status} at ``quiet times''}\par
+\P\D \37$\\{skipping}=1$\C{\\{scanner\_status} when false conditional text is
+being skipped}\par
+\P\D \37$\\{flushing}=2$\C{\\{scanner\_status} when junk after a statement is
+being ignored}\par
+\P\D \37$\\{absorbing}=3$\C{\\{scanner\_status} when a \&{text} parameter is
+being scanned}\par
+\P\D \37$\\{var\_defining}=4$\C{\\{scanner\_status} when a \&{vardef} is being
+scanned}\par
+\P\D \37$\\{op\_defining}=5$\C{\\{scanner\_status} when a macro \&{def} is
+being scanned}\par
+\P\D \37$\\{loop\_defining}=6$\C{\\{scanner\_status} when a \&{for} loop is
+being scanned}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{scanner\_status}: \37$\\{normal}\to\\{loop\_defining}$;\C{are we scanning
+at high speed?}\6
+\4\\{warning\_info}: \37\\{integer};\C{if so, what else do we need to know,
+in case an error occurs?}\par
+\fi
+
+\M660. \P$\X657:Initialize the input routines\X\mathrel{+}\S$\6
+$\\{scanner\_status}\K\\{normal}$;\par
+\fi
+
+\M661. The following subroutine
+is called when an `\&{outer}' symbolic token has been scanned or
+when the end of a file has been reached. These two cases are distinguished
+by \\{cur\_sym}, which is zero at the end of a file.
+
+\Y\P\4\&{function}\1\ \37\\{check\_outer\_validity}: \37\\{boolean};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{points to inserted token list}\2\6
+\&{begin} \37\&{if} $\\{scanner\_status}=\\{normal}$ \1\&{then}\5
+$\\{check\_outer\_validity}\K\\{true}$\6
+\4\&{else} \&{begin} \37$\\{deletions\_allowed}\K\\{false}$;\5
+\X662:Back up an outer symbolic token so that it can be reread\X;\6
+\&{if} $\\{scanner\_status}>\\{skipping}$ \1\&{then}\5
+\X663:Tell the user what has run away and try to recover\X\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Incomplete\ if;\ all\ text\ was\
+ignored\ after\ line\ "})$;\5
+$\\{print\_int}(\\{warning\_info})$;\6
+$\\{help3}(\.{"A\ forbidden\ \`outer\'\ token\ occurred\ in\ skipped\ text."})$%
+\6
+$(\.{"This\ kind\ of\ error\ happens\ when\ you\ say\ \`if...\'\ and\
+forget"})$\6
+$(\.{"the\ matching\ \`fi\'.\ I\'ve\ inserted\ a\ \`fi\';\ this\ might\
+work."})$;\6
+\&{if} $\\{cur\_sym}=0$ \1\&{then}\5
+$\\{help\_line}[2]\K\30\.{"The\ file\ ended\ while\ I\ was\ skipping\
+conditional\ text."}$;\2\6
+$\\{cur\_sym}\K\\{frozen\_fi}$;\5
+\\{ins\_error};\6
+\&{end};\2\6
+$\\{deletions\_allowed}\K\\{true}$;\5
+$\\{check\_outer\_validity}\K\\{false}$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M662. \P$\X662:Back up an outer symbolic token so that it can be reread\X\S$\6
+\&{if} $\\{cur\_sym}\I0$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{get\_avail}$;\5
+$\\{info}(\|p)\K\\{cur\_sym}$;\5
+$\\{back\_list}(\|p)$;\C{prepare to read the symbolic token again}\6
+\&{end}\2\par
+\U661.\fi
+
+\M663. \P$\X663:Tell the user what has run away and try to recover\X\S$\6
+\&{begin} \37\\{runaway};\C{print the definition-so-far}\6
+\&{if} $\\{cur\_sym}=0$ \1\&{then}\5
+$\\{print\_err}(\.{"File\ ended"})$\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Forbidden\ token\ found"})$;\6
+\&{end};\2\6
+$\\{print}(\.{"\ while\ scanning\ "})$;\5
+$\\{help4}(\.{"I\ suspect\ you\ have\ forgotten\ an\ \`enddef\',"})$\6
+$(\.{"causing\ me\ to\ read\ past\ where\ you\ wanted\ me\ to\ stop."})$\6
+$(\.{"I\'ll\ try\ to\ recover;\ but\ if\ the\ error\ is\ serious,"})$\6
+$(\.{"you\'d\ better\ type\ \`E\'\ or\ \`X\'\ now\ and\ fix\ your\ file."})$;\6
+\&{case} $\\{scanner\_status}$ \1\&{of}\6
+\hbox{\4}\X664:Complete the error message, and set \\{cur\_sym} to a token that
+might help recover from the error\X\2\6
+\&{end};\C{there are no other cases}\6
+\\{ins\_error};\6
+\&{end}\par
+\U661.\fi
+
+\M664. As we consider various kinds of errors, it is also appropriate to
+change the first line of the help message just given; $\\{help\_line}[3]$
+points to the string that might be changed.
+
+\Y\P$\4\X664:Complete the error message, and set \\{cur\_sym} to a token that
+might help recover from the error\X\S$\6
+\4\\{flushing}: \37\&{begin} \37$\\{print}(\.{"to\ the\ end\ of\ the\
+statement"})$;\5
+$\\{help\_line}[3]\K\.{"A\ previous\ error\ seems\ to\ have\ propagated,"}$;\5
+$\\{cur\_sym}\K\\{frozen\_semicolon}$;\6
+\&{end};\6
+\4\\{absorbing}: \37\&{begin} \37$\\{print}(\.{"a\ text\ argument"})$;\5
+$\\{help\_line}[3]\K\.{"It\ seems\ that\ a\ right\ delimiter\ was\ left\
+out,"}$;\6
+\&{if} $\\{warning\_info}=0$ \1\&{then}\5
+$\\{cur\_sym}\K\\{frozen\_end\_group}$\6
+\4\&{else} \&{begin} \37$\\{cur\_sym}\K\\{frozen\_right\_delimiter}$;\5
+$\\{equiv}(\\{frozen\_right\_delimiter})\K\\{warning\_info}$;\6
+\&{end};\2\6
+\&{end};\6
+\4$\\{var\_defining},\39\\{op\_defining}$: \37\&{begin} \37$\\{print}(\.{"the\
+definition\ of\ "})$;\6
+\&{if} $\\{scanner\_status}=\\{op\_defining}$ \1\&{then}\5
+$\\{slow\_print}(\\{text}(\\{warning\_info}))$\6
+\4\&{else} $\\{print\_variable\_name}(\\{warning\_info})$;\2\6
+$\\{cur\_sym}\K\\{frozen\_end\_def}$;\6
+\&{end};\6
+\4\\{loop\_defining}: \37\&{begin} \37$\\{print}(\.{"the\ text\ of\ a\ "})$;\5
+$\\{slow\_print}(\\{text}(\\{warning\_info}))$;\5
+$\\{print}(\.{"\ loop"})$;\5
+$\\{help\_line}[3]\K\.{"I\ suspect\ you\ have\ forgotten\ an\ \`endfor\',"}$;\5
+$\\{cur\_sym}\K\\{frozen\_end\_for}$;\6
+\&{end};\par
+\U663.\fi
+
+\M665. The \\{runaway} procedure displays the first part of the text that
+occurred
+when \MF\ began its special \\{scanner\_status}, if that text has been saved.
+
+\Y\P$\4\X665:Declare the procedure called \\{runaway}\X\S$\6
+\4\&{procedure}\1\ \37\\{runaway};\2\6
+\&{begin} \37\&{if} $\\{scanner\_status}>\\{flushing}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"Runaway\ "})$;\6
+\&{case} $\\{scanner\_status}$ \1\&{of}\6
+\4\\{absorbing}: \37$\\{print}(\.{"text?"})$;\6
+\4$\\{var\_defining},\39\\{op\_defining}$: \37$\\{print}(\.{"definition?"})$;\6
+\4\\{loop\_defining}: \37$\\{print}(\.{"loop?"})$;\2\6
+\&{end};\C{there are no other cases}\6
+\\{print\_ln};\5
+$\\{show\_token\_list}(\\{link}(\\{hold\_head}),\39\\{null},\39\\{error%
+\_line}-10,\390)$;\6
+\&{end};\2\6
+\&{end};\par
+\U162.\fi
+
+\M666. We need to mention a procedure that may be called by \\{get\_next}.
+
+\Y\P\4\&{procedure}\1\ \37\\{firm\_up\_the\_line};\5
+\\{forward};\par
+\fi
+
+\M667. And now we're ready to take the plunge into \\{get\_next} itself.
+
+\Y\P\D \37$\\{switch}=25$\C{a label in \\{get\_next}}\par
+\P\D \37$\\{start\_numeric\_token}=85$\C{another}\par
+\P\D \37$\\{start\_decimal\_token}=86$\C{and another}\par
+\P\D \37$\\{fin\_numeric\_token}=87$\C{and still another, although \&{goto} is
+considered harmful}\par
+\Y\P\4\&{procedure}\1\ \37\\{get\_next};\C{sets \\{cur\_cmd}, \\{cur\_mod}, %
+\\{cur\_sym} to next token}\6
+\4\&{label} \37$\\{restart},\39$\C{go here to get the next input token}\6
+$\\{exit},\39$\C{go here when the next input token has been got}\6
+$\\{found},\39$\C{go here when the end of a symbolic token has been found}\6
+$\\{switch},\39$\C{go here to branch on the class of an input character}\6
+$\\{start\_numeric\_token},\39\\{start\_decimal\_token},\39\\{fin\_numeric%
+\_token},\39\\{done}$;\C{go here at crucial stages when scanning a number}\6
+\4\&{var} \37\|k: \37$0\to\\{buf\_size}$;\C{an index into \\{buffer}}\6
+\|c: \37\\{ASCII\_code};\C{the current character in the buffer}\6
+\\{class}: \37\\{ASCII\_code};\C{its class number}\6
+$\|n,\39\|f$: \37\\{integer};\C{registers for decimal-to-binary conversion}\2\6
+\&{begin} \37\\{restart}: \37$\\{cur\_sym}\K0$;\6
+\&{if} $\\{file\_state}$ \1\&{then}\5
+\X669:Input from external file; \&{goto} \\{restart} if no input found, or %
+\&{return} if a non-symbolic token is found\X\6
+\4\&{else} \X676:Input from token list; \&{goto} \\{restart} if end of list or
+if a parameter needs to be expanded, or \&{return} if a non-symbolic token is
+found\X;\2\6
+\X668:Finish getting the symbolic token in \\{cur\_sym}; \&{goto} \\{restart}
+if it is illegal\X;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M668. When a symbolic token is declared to be `\&{outer}', its command code
+is increased by \\{outer\_tag}.
+
+\Y\P$\4\X668:Finish getting the symbolic token in \\{cur\_sym}; \&{goto} %
+\\{restart} if it is illegal\X\S$\6
+$\\{cur\_cmd}\K\\{eq\_type}(\\{cur\_sym})$;\5
+$\\{cur\_mod}\K\\{equiv}(\\{cur\_sym})$;\6
+\&{if} $\\{cur\_cmd}\G\\{outer\_tag}$ \1\&{then}\6
+\&{if} $\\{check\_outer\_validity}$ \1\&{then}\5
+$\\{cur\_cmd}\K\\{cur\_cmd}-\\{outer\_tag}$\6
+\4\&{else} \&{goto} \37\\{restart}\2\2\par
+\U667.\fi
+
+\M669. A percent sign appears in $\\{buffer}[\\{limit}]$; this makes it
+unnecessary
+to have a special test for end-of-line.
+
+\Y\P$\4\X669:Input from external file; \&{goto} \\{restart} if no input found,
+or \&{return} if a non-symbolic token is found\X\S$\6
+\&{begin} \37\\{switch}: \37$\|c\K\\{buffer}[\\{loc}]$;\5
+$\\{incr}(\\{loc})$;\5
+$\\{class}\K\\{char\_class}[\|c]$;\6
+\&{case} $\\{class}$ \1\&{of}\6
+\4\\{digit\_class}: \37\&{goto} \37\\{start\_numeric\_token};\6
+\4\\{period\_class}: \37\&{begin} \37$\\{class}\K\\{char\_class}[\\{buffer}[%
+\\{loc}]]$;\6
+\&{if} $\\{class}>\\{period\_class}$ \1\&{then}\5
+\&{goto} \37\\{switch}\6
+\4\&{else} \&{if} $\\{class}<\\{period\_class}$ \1\&{then}\C{$\\{class}=%
+\\{digit\_class}$}\6
+\&{begin} \37$\|n\K0$;\5
+\&{goto} \37\\{start\_decimal\_token};\6
+\&{end};\2\2\6
+\&{end};\6
+\4\\{space\_class}: \37\&{goto} \37\\{switch};\6
+\4\\{percent\_class}: \37\&{begin} \37\X679:Move to next line of file, or %
+\&{goto} \\{restart} if there is no next line\X;\6
+\\{check\_interrupt};\5
+\&{goto} \37\\{switch};\6
+\&{end};\6
+\4\\{string\_class}: \37\X671:Get a string token and \&{return}\X;\6
+\4\\{isolated\_classes}: \37\&{begin} \37$\|k\K\\{loc}-1$;\5
+\&{goto} \37\\{found};\6
+\&{end};\6
+\4\\{invalid\_class}: \37\X670:Decry the invalid character and \&{goto} %
+\\{restart}\X;\6
+\4\&{othercases} \37\\{do\_nothing}\C{letters, etc.}\2\6
+\&{endcases};\6
+$\|k\K\\{loc}-1$;\6
+\&{while} $\\{char\_class}[\\{buffer}[\\{loc}]]=\\{class}$ \1\&{do}\5
+$\\{incr}(\\{loc})$;\2\6
+\&{goto} \37\\{found};\6
+\4\\{start\_numeric\_token}: \37\X673:Get the integer part \|n of a numeric
+token; set $\|f\K0$ and \&{goto} \\{fin\_numeric\_token} if there is no decimal
+point\X;\6
+\4\\{start\_decimal\_token}: \37\X674:Get the fraction part \|f of a numeric
+token\X;\6
+\4\\{fin\_numeric\_token}: \37\X675:Pack the numeric and fraction parts of a
+numeric token and \&{return}\X;\6
+\4\\{found}: \37$\\{cur\_sym}\K\\{id\_lookup}(\|k,\39\\{loc}-\|k)$;\6
+\&{end}\par
+\U667.\fi
+
+\M670. We go to \\{restart} instead of to \\{switch}, because \\{state} might
+equal
+\\{token\_list} after the error has been dealt with
+(cf.\ \\{clear\_for\_error\_prompt}).
+
+\Y\P$\4\X670:Decry the invalid character and \&{goto} \\{restart}\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Text\ line\ contains\ an\ invalid\
+character"})$;\5
+$\\{help2}(\.{"A\ funny\ symbol\ that\ I\ can\'t\ read\ has\ just\ been\
+input."})$\6
+$(\.{"Continue,\ and\ I\'ll\ forget\ that\ it\ ever\ happened."})$;\6
+$\\{deletions\_allowed}\K\\{false}$;\5
+\\{error};\5
+$\\{deletions\_allowed}\K\\{true}$;\5
+\&{goto} \37\\{restart};\6
+\&{end}\par
+\U669.\fi
+
+\M671. \P$\X671:Get a string token and \&{return}\X\S$\6
+\&{begin} \37\&{if} $\\{buffer}[\\{loc}]=\.{""}\.{""}$ \1\&{then}\5
+$\\{cur\_mod}\K\.{""}$\6
+\4\&{else} \&{begin} \37$\|k\K\\{loc}$;\5
+$\\{buffer}[\\{limit}+1]\K\.{""}\.{""}$;\6
+\1\&{repeat} \37$\\{incr}(\\{loc})$;\6
+\4\&{until}\5
+$\\{buffer}[\\{loc}]=\.{""}\.{""}$;\2\6
+\&{if} $\\{loc}>\\{limit}$ \1\&{then}\5
+\X672:Decry the missing string delimiter and \&{goto} \\{restart}\X;\2\6
+\&{if} $(\\{loc}=\|k+1)\W(\\{length}(\\{buffer}[\|k])=1)$ \1\&{then}\5
+$\\{cur\_mod}\K\\{buffer}[\|k]$\6
+\4\&{else} \&{begin} \37$\\{str\_room}(\\{loc}-\|k)$;\6
+\1\&{repeat} \37$\\{append\_char}(\\{buffer}[\|k])$;\5
+$\\{incr}(\|k)$;\6
+\4\&{until}\5
+$\|k=\\{loc}$;\2\6
+$\\{cur\_mod}\K\\{make\_string}$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\\{incr}(\\{loc})$;\5
+$\\{cur\_cmd}\K\\{string\_token}$;\5
+\&{return};\6
+\&{end}\par
+\U669.\fi
+
+\M672. We go to \\{restart} after this error message, not to \\{switch},
+because the \\{clear\_for\_error\_prompt} routine might have reinstated
+\\{token\_state} after \\{error} has finished.
+
+\Y\P$\4\X672:Decry the missing string delimiter and \&{goto} \\{restart}\X\S$\6
+\&{begin} \37$\\{loc}\K\\{limit}$;\C{the next character to be read on this line
+will be \.{"\%"}}\6
+$\\{print\_err}(\.{"Incomplete\ string\ token\ has\ been\ flushed"})$;\5
+$\\{help3}(\.{"Strings\ should\ finish\ on\ the\ same\ line\ as\ they\
+began."})$\6
+$(\.{"I\'ve\ deleted\ the\ partial\ string;\ you\ might\ want\ to"})$\6
+$(\.{"insert\ another\ by\ typing,\ e.g.,\ \`I"}\.{"new\ string"}\.{"\'."})$;\6
+$\\{deletions\_allowed}\K\\{false}$;\5
+\\{error};\5
+$\\{deletions\_allowed}\K\\{true}$;\5
+\&{goto} \37\\{restart};\6
+\&{end}\par
+\U671.\fi
+
+\M673. \P$\X673:Get the integer part \|n of a numeric token; set $\|f\K0$ and %
+\&{goto} \\{fin\_numeric\_token} if there is no decimal point\X\S$\6
+$\|n\K\|c-\.{"0"}$;\6
+\&{while} $\\{char\_class}[\\{buffer}[\\{loc}]]=\\{digit\_class}$ \1\&{do}\6
+\&{begin} \37\&{if} $\|n<4096$ \1\&{then}\5
+$\|n\K10\ast\|n+\\{buffer}[\\{loc}]-\.{"0"}$;\2\6
+$\\{incr}(\\{loc})$;\6
+\&{end};\2\6
+\&{if} $\\{buffer}[\\{loc}]=\.{"."}$ \1\&{then}\6
+\&{if} $\\{char\_class}[\\{buffer}[\\{loc}+1]]=\\{digit\_class}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\2\6
+$\|f\K0$;\5
+\&{goto} \37\\{fin\_numeric\_token};\6
+\4\\{done}: \37$\\{incr}(\\{loc})$\par
+\U669.\fi
+
+\M674. \P$\X674:Get the fraction part \|f of a numeric token\X\S$\6
+$\|k\K0$;\6
+\1\&{repeat} \37\&{if} $\|k<17$ \1\&{then}\C{digits for $\|k\G17$ cannot affect
+the result}\6
+\&{begin} \37$\\{dig}[\|k]\K\\{buffer}[\\{loc}]-\.{"0"}$;\5
+$\\{incr}(\|k)$;\6
+\&{end};\2\6
+$\\{incr}(\\{loc})$;\6
+\4\&{until}\5
+$\\{char\_class}[\\{buffer}[\\{loc}]]\I\\{digit\_class}$;\2\6
+$\|f\K\\{round\_decimals}(\|k)$;\6
+\&{if} $\|f=\\{unity}$ \1\&{then}\6
+\&{begin} \37$\\{incr}(\|n)$;\5
+$\|f\K0$;\6
+\&{end}\2\par
+\U669.\fi
+
+\M675. \P$\X675:Pack the numeric and fraction parts of a numeric token and %
+\&{return}\X\S$\6
+\&{if} $\|n<4096$ \1\&{then}\5
+$\\{cur\_mod}\K\|n\ast\\{unity}+\|f$\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Enormous\ number\ has\ been\
+reduced"})$;\5
+$\\{help2}(\.{"I\ can\'t\ handle\ numbers\ bigger\ than\ about\ 4095.99998;"})$%
+\6
+$(\.{"so\ I\'ve\ changed\ your\ constant\ to\ that\ maximum\ amount."})$;\6
+$\\{deletions\_allowed}\K\\{false}$;\5
+\\{error};\5
+$\\{deletions\_allowed}\K\\{true}$;\5
+$\\{cur\_mod}\K\O{1777777777}$;\6
+\&{end};\2\6
+$\\{cur\_cmd}\K\\{numeric\_token}$;\5
+\&{return}\par
+\U669.\fi
+
+\M676. Let's consider now what happens when \\{get\_next} is looking at a token
+list.
+
+\Y\P$\4\X676:Input from token list; \&{goto} \\{restart} if end of list or if a
+parameter needs to be expanded, or \&{return} if a non-symbolic token is found%
+\X\S$\6
+\&{if} $\\{loc}\G\\{hi\_mem\_min}$ \1\&{then}\C{one-word token}\6
+\&{begin} \37$\\{cur\_sym}\K\\{info}(\\{loc})$;\5
+$\\{loc}\K\\{link}(\\{loc})$;\C{move to next}\6
+\&{if} $\\{cur\_sym}\G\\{expr\_base}$ \1\&{then}\6
+\&{if} $\\{cur\_sym}\G\\{suffix\_base}$ \1\&{then}\5
+\X677:Insert a suffix or text parameter and \&{goto} \\{restart}\X\6
+\4\&{else} \&{begin} \37$\\{cur\_cmd}\K\\{capsule\_token}$;\5
+$\\{cur\_mod}\K\\{param\_stack}[\\{param\_start}+\\{cur\_sym}-(\\{expr%
+\_base})]$;\5
+$\\{cur\_sym}\K0$;\5
+\&{return};\6
+\&{end};\2\2\6
+\&{end}\6
+\4\&{else} \&{if} $\\{loc}>\\{null}$ \1\&{then}\5
+\X678:Get a stored numeric or string or capsule token and \&{return}\X\6
+\4\&{else} \&{begin} \37\C{we are done with this token list}\6
+\\{end\_token\_list};\5
+\&{goto} \37\\{restart};\C{resume previous level}\6
+\&{end}\2\2\par
+\U667.\fi
+
+\M677. \P$\X677:Insert a suffix or text parameter and \&{goto} \\{restart}\X\S$%
+\6
+\&{begin} \37\&{if} $\\{cur\_sym}\G\\{text\_base}$ \1\&{then}\5
+$\\{cur\_sym}\K\\{cur\_sym}-\\{param\_size}$;\C{$\\{param\_size}=\\{text%
+\_base}-\\{suffix\_base}$}\2\6
+$\\{begin\_token\_list}(\\{param\_stack}[\\{param\_start}+\\{cur\_sym}-(%
+\\{suffix\_base})],\39\\{parameter})$;\5
+\&{goto} \37\\{restart};\6
+\&{end}\par
+\U676.\fi
+
+\M678. \P$\X678:Get a stored numeric or string or capsule token and \&{return}%
+\X\S$\6
+\&{begin} \37\&{if} $\\{name\_type}(\\{loc})=\\{token}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_mod}\K\\{value}(\\{loc})$;\6
+\&{if} $\\{type}(\\{loc})=\\{known}$ \1\&{then}\5
+$\\{cur\_cmd}\K\\{numeric\_token}$\6
+\4\&{else} \&{begin} \37$\\{cur\_cmd}\K\\{string\_token}$;\5
+$\\{add\_str\_ref}(\\{cur\_mod})$;\6
+\&{end};\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{cur\_mod}\K\\{loc}$;\5
+$\\{cur\_cmd}\K\\{capsule\_token}$;\6
+\&{end};\2\6
+$\\{loc}\K\\{link}(\\{loc})$;\5
+\&{return};\6
+\&{end}\par
+\U676.\fi
+
+\M679. All of the easy branches of \\{get\_next} have now been taken care of.
+There is one more branch.
+
+\Y\P$\4\X679:Move to next line of file, or \&{goto} \\{restart} if there is no
+next line\X\S$\6
+\&{if} $\\{name}>2$ \1\&{then}\5
+\X681:Read next line of file into \\{buffer}, or \&{goto} \\{restart} if the
+file has ended\X\6
+\4\&{else} \&{begin} \37\&{if} $\\{input\_ptr}>0$ \1\&{then}\C{text was
+inserted during error recovery or by \&{scantokens}}\6
+\&{begin} \37\\{end\_file\_reading};\5
+\&{goto} \37\\{restart};\C{resume previous level}\6
+\&{end};\2\6
+\&{if} $\\{selector}<\\{log\_only}$ \1\&{then}\5
+\\{open\_log\_file};\2\6
+\&{if} $\\{interaction}>\\{nonstop\_mode}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{limit}=\\{start}$ \1\&{then}\C{previous line was empty}%
+\6
+$\\{print\_nl}(\.{"(Please\ type\ a\ command\ or\ say\ \`end\')"})$;\2\6
+\\{print\_ln};\5
+$\\{first}\K\\{start}$;\5
+$\\{prompt\_input}(\.{"*"})$;\C{input on-line into \\{buffer}}\6
+$\\{limit}\K\\{last}$;\5
+$\\{buffer}[\\{limit}]\K\.{"\%"}$;\5
+$\\{first}\K\\{limit}+1$;\5
+$\\{loc}\K\\{start}$;\6
+\&{end}\6
+\4\&{else} $\\{fatal\_error}(\.{"***\ (job\ aborted,\ no\ legal\ end\
+found)"})$;\C{nonstop mode, which is intended for overnight batch processing,
+ never waits for on-line input}\2\6
+\&{end}\2\par
+\U669.\fi
+
+\M680. The global variable \\{force\_eof} is normally \\{false}; it is set %
+\\{true}
+by an \&{endinput} command.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{force\_eof}: \37\\{boolean};\C{should the next \&{input} be aborted
+early?}\par
+\fi
+
+\M681. \P$\X681:Read next line of file into \\{buffer}, or \&{goto} \\{restart}
+if the file has ended\X\S$\6
+\&{begin} \37$\\{incr}(\\{line})$;\5
+$\\{first}\K\\{start}$;\6
+\&{if} $\R\\{force\_eof}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{input\_ln}(\\{cur\_file},\39\\{true})$ \1\&{then}\C{not
+end of file}\6
+\\{firm\_up\_the\_line}\C{this sets \\{limit}}\6
+\4\&{else} $\\{force\_eof}\K\\{true}$;\2\6
+\&{end};\2\6
+\&{if} $\\{force\_eof}$ \1\&{then}\6
+\&{begin} \37$\\{print\_char}(\.{")"})$;\5
+$\\{decr}(\\{open\_parens})$;\5
+\\{update\_terminal};\C{show user that file has been read}\6
+$\\{force\_eof}\K\\{false}$;\5
+\\{end\_file\_reading};\C{resume previous level}\6
+\&{if} $\\{check\_outer\_validity}$ \1\&{then}\5
+\&{goto} \37\\{restart}\ \&{else} \&{goto} \37\\{restart};\2\6
+\&{end};\2\6
+$\\{buffer}[\\{limit}]\K\.{"\%"}$;\5
+$\\{first}\K\\{limit}+1$;\5
+$\\{loc}\K\\{start}$;\C{ready to read}\6
+\&{end}\par
+\U679.\fi
+
+\M682. If the user has set the \\{pausing} parameter to some positive value,
+and if nonstop mode has not been selected, each line of input is displayed
+on the terminal and the transcript file, followed by `\.{=>}'.
+\MF\ waits for a response. If the response is null (i.e., if nothing is
+typed except perhaps a few blank spaces), the original
+line is accepted as it stands; otherwise the line typed is
+used instead of the line in the file.
+
+\Y\P\4\&{procedure}\1\ \37\\{firm\_up\_the\_line};\6
+\4\&{var} \37\|k: \37$0\to\\{buf\_size}$;\C{an index into \\{buffer}}\2\6
+\&{begin} \37$\\{limit}\K\\{last}$;\6
+\&{if} $\\{internal}[\\{pausing}]>0$ \1\&{then}\6
+\&{if} $\\{interaction}>\\{nonstop\_mode}$ \1\&{then}\6
+\&{begin} \37\\{wake\_up\_terminal};\5
+\\{print\_ln};\6
+\&{if} $\\{start}<\\{limit}$ \1\&{then}\6
+\&{for} $\|k\K\\{start}\mathrel{\&{to}}\\{limit}-1$ \1\&{do}\5
+$\\{print}(\\{buffer}[\|k])$;\2\2\6
+$\\{first}\K\\{limit}$;\5
+$\\{prompt\_input}(\.{"=>"})$;\C{wait for user response}\6
+\&{if} $\\{last}>\\{first}$ \1\&{then}\6
+\&{begin} \37\&{for} $\|k\K\\{first}\mathrel{\&{to}}\\{last}-1$ \1\&{do}\C{move
+line down in buffer}\6
+$\\{buffer}[\|k+\\{start}-\\{first}]\K\\{buffer}[\|k]$;\2\6
+$\\{limit}\K\\{start}+\\{last}-\\{first}$;\6
+\&{end};\2\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\N683. \[34] Scanning macro definitions.
+\MF\ has a variety of ways to tuck tokens away into token lists for later
+use: Macros can be defined with \&{def}, \&{vardef}, \&{primarydef}, etc.;
+repeatable code can be defined with \&{for}, \&{forever}, \&{forsuffixes}.
+All such operations are handled by the routines in this part of the program.
+
+The modifier part of each command code is zero for the ``ending delimiters''
+like \&{enddef} and \&{endfor}.
+
+\Y\P\D \37$\\{start\_def}=1$\C{command modifier for \&{def}}\par
+\P\D \37$\\{var\_def}=2$\C{command modifier for \&{vardef}}\par
+\P\D \37$\\{end\_def}=0$\C{command modifier for \&{enddef}}\par
+\P\D \37$\\{start\_forever}=1$\C{command modifier for \&{forever}}\par
+\P\D \37$\\{end\_for}=0$\C{command modifier for \&{endfor}}\par
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"def"},\39\\{macro\_def},\39\\{start\_def})$;\6
+$\\{primitive}(\.{"vardef"},\39\\{macro\_def},\39\\{var\_def})$;\6
+$\\{primitive}(\.{"primarydef"},\39\\{macro\_def},\39\\{secondary\_primary%
+\_macro})$;\6
+$\\{primitive}(\.{"secondarydef"},\39\\{macro\_def},\39\\{tertiary\_secondary%
+\_macro})$;\6
+$\\{primitive}(\.{"tertiarydef"},\39\\{macro\_def},\39\\{expression\_tertiary%
+\_macro})$;\6
+$\\{primitive}(\.{"enddef"},\39\\{macro\_def},\39\\{end\_def})$;\5
+$\\{eqtb}[\\{frozen\_end\_def}]\K\\{eqtb}[\\{cur\_sym}]$;\7
+$\\{primitive}(\.{"for"},\39\\{iteration},\39\\{expr\_base})$;\6
+$\\{primitive}(\.{"forsuffixes"},\39\\{iteration},\39\\{suffix\_base})$;\6
+$\\{primitive}(\.{"forever"},\39\\{iteration},\39\\{start\_forever})$;\6
+$\\{primitive}(\.{"endfor"},\39\\{iteration},\39\\{end\_for})$;\5
+$\\{eqtb}[\\{frozen\_end\_for}]\K\\{eqtb}[\\{cur\_sym}]$;\par
+\fi
+
+\M684. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{macro\_def}: \37\&{if} $\|m\L\\{var\_def}$ \1\&{then}\6
+\&{if} $\|m=\\{start\_def}$ \1\&{then}\5
+$\\{print}(\.{"def"})$\6
+\4\&{else} \&{if} $\|m<\\{start\_def}$ \1\&{then}\5
+$\\{print}(\.{"enddef"})$\6
+\4\&{else} $\\{print}(\.{"vardef"})$\2\2\6
+\4\&{else} \&{if} $\|m=\\{secondary\_primary\_macro}$ \1\&{then}\5
+$\\{print}(\.{"primarydef"})$\6
+\4\&{else} \&{if} $\|m=\\{tertiary\_secondary\_macro}$ \1\&{then}\5
+$\\{print}(\.{"secondarydef"})$\6
+\4\&{else} $\\{print}(\.{"tertiarydef"})$;\2\2\2\6
+\4\\{iteration}: \37\&{if} $\|m\L\\{start\_forever}$ \1\&{then}\6
+\&{if} $\|m=\\{start\_forever}$ \1\&{then}\5
+$\\{print}(\.{"forever"})$\ \&{else} $\\{print}(\.{"endfor"})$\2\6
+\4\&{else} \&{if} $\|m=\\{expr\_base}$ \1\&{then}\5
+$\\{print}(\.{"for"})$\ \&{else} $\\{print}(\.{"forsuffixes"})$;\2\2\par
+\fi
+
+\M685. Different macro-absorbing operations have different syntaxes, but they
+also have a lot in common. There is a list of special symbols that are to
+be replaced by parameter tokens; there is a special command code that
+ends the definition; the quotation conventions are identical. Therefore
+it makes sense to have most of the work done by a single subroutine. That
+subroutine is called \\{scan\_toks}.
+
+The first parameter to \\{scan\_toks} is the command code that will
+terminate scanning (either \\{macro\_def}, \\{loop\_repeat}, or \\{iteration}).
+
+The second parameter, \\{subst\_list}, points to a (possibly empty) list
+of two-word nodes whose \\{info} and \\{value} fields specify symbol tokens
+before and after replacement. The list will be returned to free storage
+by \\{scan\_toks}.
+
+The third parameter is simply appended to the token list that is built.
+And the final parameter tells how many of the special operations
+\.{\#\AT!}, \.{\AT!}, and \.{\AT!\#} are to be replaced by suffix parameters.
+When such parameters are present, they are called \.{(SUFFIX0)},
+\.{(SUFFIX1)}, and \.{(SUFFIX2)}.
+
+\Y\P\4\&{function}\1\ \37$\\{scan\_toks}(\\{terminator}:\\{command\_code};\,%
+\35\\{subst\_list},\39\\{tail\_end}:\\{pointer};\,\35\\{suffix\_count}:\\{small%
+\_number})$: \37\\{pointer};\6
+\4\&{label} \37$\\{done},\39\\{found}$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{tail of the token list being built}\6
+\|q: \37\\{pointer};\C{temporary for link management}\6
+\\{balance}: \37\\{integer};\C{left delimiters minus right delimiters}\2\6
+\&{begin} \37$\|p\K\\{hold\_head}$;\5
+$\\{balance}\K1$;\5
+$\\{link}(\\{hold\_head})\K\\{null}$;\6
+\~ \1\&{loop}\ \&{begin} \37\\{get\_next};\6
+\&{if} $\\{cur\_sym}>0$ \1\&{then}\6
+\&{begin} \37\X686:Substitute for \\{cur\_sym}, if it's on the \\{subst\_list}%
+\X;\6
+\&{if} $\\{cur\_cmd}=\\{terminator}$ \1\&{then}\5
+\X687:Adjust the balance; \&{goto} \\{done} if it's zero\X\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{macro\_special}$ \1\&{then}\5
+\X690:Handle quoted symbols, \.{\#\AT!}, \.{\AT!}, or \.{\AT!\#}\X;\2\2\6
+\&{end};\2\6
+$\\{link}(\|p)\K\\{cur\_tok}$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{link}(\|p)\K\\{tail\_end}$;\5
+$\\{flush\_node\_list}(\\{subst\_list})$;\5
+$\\{scan\_toks}\K\\{link}(\\{hold\_head})$;\6
+\&{end};\par
+\fi
+
+\M686. \P$\X686:Substitute for \\{cur\_sym}, if it's on the \\{subst\_list}\X%
+\S$\6
+\&{begin} \37$\|q\K\\{subst\_list}$;\6
+\&{while} $\|q\I\\{null}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{info}(\|q)=\\{cur\_sym}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_sym}\K\\{value}(\|q)$;\5
+$\\{cur\_cmd}\K\\{relax}$;\5
+\&{goto} \37\\{found};\6
+\&{end};\2\6
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+\4\\{found}: \37\&{end}\par
+\U685.\fi
+
+\M687. \P$\X687:Adjust the balance; \&{goto} \\{done} if it's zero\X\S$\6
+\&{if} $\\{cur\_mod}>0$ \1\&{then}\5
+$\\{incr}(\\{balance})$\6
+\4\&{else} \&{begin} \37$\\{decr}(\\{balance})$;\6
+\&{if} $\\{balance}=0$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{end}\2\par
+\U685.\fi
+
+\M688. Four commands are intended to be used only within macro texts: %
+\&{quote},
+\.{\#\AT!}, \.{\AT!}, and \.{\AT!\#}. They are variants of a single command
+code called \\{macro\_special}.
+
+\Y\P\D \37$\\{quote}=0$\C{\\{macro\_special} modifier for \&{quote}}\par
+\P\D \37$\\{macro\_prefix}=1$\C{\\{macro\_special} modifier for \.{\#\AT!}}\par
+\P\D \37$\\{macro\_at}=2$\C{\\{macro\_special} modifier for \.{\AT!}}\par
+\P\D \37$\\{macro\_suffix}=3$\C{\\{macro\_special} modifier for \.{\AT!\#}}\par
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"quote"},\39\\{macro\_special},\39\\{quote})$;\6
+$\\{primitive}(\.{"\#@"},\39\\{macro\_special},\39\\{macro\_prefix})$;\6
+$\\{primitive}(\.{"@"},\39\\{macro\_special},\39\\{macro\_at})$;\6
+$\\{primitive}(\.{"@\#"},\39\\{macro\_special},\39\\{macro\_suffix})$;\par
+\fi
+
+\M689. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{macro\_special}: \37\&{case} $\|m$ \1\&{of}\6
+\4\\{macro\_prefix}: \37$\\{print}(\.{"\#@"})$;\6
+\4\\{macro\_at}: \37$\\{print\_char}(\.{"@"})$;\6
+\4\\{macro\_suffix}: \37$\\{print}(\.{"@\#"})$;\6
+\4\&{othercases} \37$\\{print}(\.{"quote"})$\2\6
+\&{endcases};\par
+\fi
+
+\M690. \P$\X690:Handle quoted symbols, \.{\#\AT!}, \.{\AT!}, or \.{\AT!\#}\X\S$%
+\6
+\&{begin} \37\&{if} $\\{cur\_mod}=\\{quote}$ \1\&{then}\5
+\\{get\_next}\6
+\4\&{else} \&{if} $\\{cur\_mod}\L\\{suffix\_count}$ \1\&{then}\5
+$\\{cur\_sym}\K\\{suffix\_base}-1+\\{cur\_mod}$;\2\2\6
+\&{end}\par
+\U685.\fi
+
+\M691. Here is a routine that's used whenever a token will be redefined. If
+the user's token is unredefinable, the `\\{frozen\_inaccessible}' token is
+substituted; the latter is redefinable but essentially impossible to use,
+hence \MF's tables won't get fouled up.
+
+\Y\P\4\&{procedure}\1\ \37\\{get\_symbol};\C{sets \\{cur\_sym} to a safe
+symbol}\6
+\4\&{label} \37\\{restart};\2\6
+\&{begin} \37\\{restart}: \37\\{get\_next};\6
+\&{if} $(\\{cur\_sym}=0)\V(\\{cur\_sym}>\\{frozen\_inaccessible})$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Missing\ symbolic\ token\ inserted"})$;\5
+$\\{help3}(\.{"Sorry:\ You\ can\'t\ redefine\ a\ number,\ string,\ or\
+expr."})$\6
+$(\.{"I\'ve\ inserted\ an\ inaccessible\ symbol\ so\ that\ your"})$\6
+$(\.{"definition\ will\ be\ completed\ without\ mixing\ me\ up\ too\
+badly."})$;\6
+\&{if} $\\{cur\_sym}>0$ \1\&{then}\5
+$\\{help\_line}[2]\K\.{"Sorry:\ You\ can\'t\ redefine\ my\ error-recovery\
+tokens."}$\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{string\_token}$ \1\&{then}\5
+$\\{delete\_str\_ref}(\\{cur\_mod})$;\2\2\6
+$\\{cur\_sym}\K\\{frozen\_inaccessible}$;\5
+\\{ins\_error};\5
+\&{goto} \37\\{restart};\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M692. Before we actually redefine a symbolic token, we need to clear away its
+former value, if it was a variable. The following stronger version of
+\\{get\_symbol} does that.
+
+\Y\P\4\&{procedure}\1\ \37\\{get\_clear\_symbol};\2\6
+\&{begin} \37\\{get\_symbol};\5
+$\\{clear\_symbol}(\\{cur\_sym},\39\\{false})$;\6
+\&{end};\par
+\fi
+
+\M693. Here's another little subroutine; it checks that an equals sign
+or assignment sign comes along at the proper place in a macro definition.
+
+\Y\P\4\&{procedure}\1\ \37\\{check\_equals};\2\6
+\&{begin} \37\&{if} $\\{cur\_cmd}\I\\{equals}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}\I\\{assignment}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"="})$;\6
+$\\{help5}(\.{"The\ next\ thing\ in\ this\ \`def\'\ should\ have\ been\ \`=%
+\',"})$\6
+$(\.{"because\ I\'ve\ already\ looked\ at\ the\ definition\ heading."})$\6
+$(\.{"But\ don\'t\ worry;\ I\'ll\ pretend\ that\ an\ equals\ sign"})$\6
+$(\.{"was\ present.\ Everything\ from\ here\ to\ \`enddef\'"})$\6
+$(\.{"will\ be\ the\ replacement\ text\ of\ this\ macro."})$;\5
+\\{back\_error};\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M694. A \&{primarydef}, \&{secondarydef}, or \&{tertiarydef} is rather easily
+handled now that we have \\{scan\_toks}. In this case there are
+two parameters, which will be \.{EXPR0} and \.{EXPR1} (i.e.,
+\\{expr\_base} and $\\{expr\_base}+1$).
+
+\Y\P\4\&{procedure}\1\ \37\\{make\_op\_def};\6
+\4\&{var} \37\|m: \37\\{command\_code};\C{the type of definition}\6
+$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{for list manipulation}\2\6
+\&{begin} \37$\|m\K\\{cur\_mod}$;\6
+\\{get\_symbol};\5
+$\|q\K\\{get\_node}(\\{token\_node\_size})$;\5
+$\\{info}(\|q)\K\\{cur\_sym}$;\5
+$\\{value}(\|q)\K\\{expr\_base}$;\6
+\\{get\_clear\_symbol};\5
+$\\{warning\_info}\K\\{cur\_sym}$;\6
+\\{get\_symbol};\5
+$\|p\K\\{get\_node}(\\{token\_node\_size})$;\5
+$\\{info}(\|p)\K\\{cur\_sym}$;\5
+$\\{value}(\|p)\K\\{expr\_base}+1$;\5
+$\\{link}(\|p)\K\|q$;\6
+\\{get\_next};\5
+\\{check\_equals};\6
+$\\{scanner\_status}\K\\{op\_defining}$;\5
+$\|q\K\\{get\_avail}$;\5
+$\\{ref\_count}(\|q)\K\\{null}$;\5
+$\|r\K\\{get\_avail}$;\5
+$\\{link}(\|q)\K\|r$;\5
+$\\{info}(\|r)\K\\{general\_macro}$;\5
+$\\{link}(\|r)\K\\{scan\_toks}(\\{macro\_def},\39\|p,\39\\{null},\390)$;\5
+$\\{scanner\_status}\K\\{normal}$;\5
+$\\{eq\_type}(\\{warning\_info})\K\|m$;\5
+$\\{equiv}(\\{warning\_info})\K\|q$;\5
+\\{get\_x\_next};\6
+\&{end};\par
+\fi
+
+\M695. Parameters to macros are introduced by the keywords \&{expr},
+\&{suffix}, \&{text}, \&{primary}, \&{secondary}, and \&{tertiary}.
+
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"expr"},\39\\{param\_type},\39\\{expr\_base})$;\6
+$\\{primitive}(\.{"suffix"},\39\\{param\_type},\39\\{suffix\_base})$;\6
+$\\{primitive}(\.{"text"},\39\\{param\_type},\39\\{text\_base})$;\6
+$\\{primitive}(\.{"primary"},\39\\{param\_type},\39\\{primary\_macro})$;\6
+$\\{primitive}(\.{"secondary"},\39\\{param\_type},\39\\{secondary\_macro})$;\6
+$\\{primitive}(\.{"tertiary"},\39\\{param\_type},\39\\{tertiary\_macro})$;\par
+\fi
+
+\M696. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{param\_type}: \37\&{if} $\|m\G\\{expr\_base}$ \1\&{then}\6
+\&{if} $\|m=\\{expr\_base}$ \1\&{then}\5
+$\\{print}(\.{"expr"})$\6
+\4\&{else} \&{if} $\|m=\\{suffix\_base}$ \1\&{then}\5
+$\\{print}(\.{"suffix"})$\6
+\4\&{else} $\\{print}(\.{"text"})$\2\2\6
+\4\&{else} \&{if} $\|m<\\{secondary\_macro}$ \1\&{then}\5
+$\\{print}(\.{"primary"})$\6
+\4\&{else} \&{if} $\|m=\\{secondary\_macro}$ \1\&{then}\5
+$\\{print}(\.{"secondary"})$\6
+\4\&{else} $\\{print}(\.{"tertiary"})$;\2\2\2\par
+\fi
+
+\M697. Let's turn next to the more complex processing associated with \&{def}
+and \&{vardef}. When the following procedure is called, \\{cur\_mod}
+should be either \\{start\_def} or \\{var\_def}.
+
+\Y\P\hbox{\4}\X1032:Declare the procedure called \\{check\_delimiter}\X\6
+\hbox{\4}\X1011:Declare the function called \\{scan\_declared\_variable}\X\6
+\4\&{procedure}\1\ \37\\{scan\_def};\6
+\4\&{var} \37\|m: \37$\\{start\_def}\to\\{var\_def}$;\C{the type of definition}%
+\6
+\|n: \37$0\to3$;\C{the number of special suffix parameters}\6
+\|k: \37$0\to\\{param\_size}$;\C{the total number of parameters}\6
+\|c: \37$\\{general\_macro}\to\\{text\_macro}$;\C{the kind of macro we're
+defining}\6
+\|r: \37\\{pointer};\C{parameter-substitution list}\6
+\|q: \37\\{pointer};\C{tail of the macro token list}\6
+\|p: \37\\{pointer};\C{temporary storage}\6
+\\{base}: \37\\{halfword};\C{\\{expr\_base}, \\{suffix\_base}, or \\{text%
+\_base}}\6
+$\\{l\_delim},\39\\{r\_delim}$: \37\\{pointer};\C{matching delimiters}\2\6
+\&{begin} \37$\|m\K\\{cur\_mod}$;\5
+$\|c\K\\{general\_macro}$;\5
+$\\{link}(\\{hold\_head})\K\\{null}$;\6
+$\|q\K\\{get\_avail}$;\5
+$\\{ref\_count}(\|q)\K\\{null}$;\5
+$\|r\K\\{null}$;\6
+\X700:Scan the token or variable to be defined; set \|n, \\{scanner\_status},
+and \\{warning\_info}\X;\6
+$\|k\K\|n$;\6
+\&{if} $\\{cur\_cmd}=\\{left\_delimiter}$ \1\&{then}\5
+\X703:Absorb delimited parameters, putting them into lists \|q and \|r\X;\2\6
+\&{if} $\\{cur\_cmd}=\\{param\_type}$ \1\&{then}\5
+\X705:Absorb undelimited parameters, putting them into list \|r\X;\2\6
+\\{check\_equals};\5
+$\|p\K\\{get\_avail}$;\5
+$\\{info}(\|p)\K\|c$;\5
+$\\{link}(\|q)\K\|p$;\5
+\X698:Attach the replacement text to the tail of node \|p\X;\6
+$\\{scanner\_status}\K\\{normal}$;\5
+\\{get\_x\_next};\6
+\&{end};\par
+\fi
+
+\M698. We don't put `\\{frozen\_end\_group}' into the replacement text of
+a \&{vardef}, because the user may want to redefine `\.{endgroup}'.
+
+\Y\P$\4\X698:Attach the replacement text to the tail of node \|p\X\S$\6
+\&{if} $\|m=\\{start\_def}$ \1\&{then}\5
+$\\{link}(\|p)\K\\{scan\_toks}(\\{macro\_def},\39\|r,\39\\{null},\39\|n)$\6
+\4\&{else} \&{begin} \37$\|q\K\\{get\_avail}$;\5
+$\\{info}(\|q)\K\\{bg\_loc}$;\5
+$\\{link}(\|p)\K\|q$;\5
+$\|p\K\\{get\_avail}$;\5
+$\\{info}(\|p)\K\\{eg\_loc}$;\5
+$\\{link}(\|q)\K\\{scan\_toks}(\\{macro\_def},\39\|r,\39\|p,\39\|n)$;\6
+\&{end};\2\6
+\&{if} $\\{warning\_info}=\\{bad\_vardef}$ \1\&{then}\5
+$\\{flush\_token\_list}(\\{value}(\\{bad\_vardef}))$\2\par
+\U697.\fi
+
+\M699. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{bg\_loc},\39\\{eg\_loc}$: \37$1\to\\{hash\_end}$;\C{hash addresses of `%
+\.{begingroup}' and `\.{endgroup}'}\par
+\fi
+
+\M700. \P$\X700:Scan the token or variable to be defined; set \|n, \\{scanner%
+\_status}, and \\{warning\_info}\X\S$\6
+\&{if} $\|m=\\{start\_def}$ \1\&{then}\6
+\&{begin} \37\\{get\_clear\_symbol};\5
+$\\{warning\_info}\K\\{cur\_sym}$;\5
+\\{get\_next};\5
+$\\{scanner\_status}\K\\{op\_defining}$;\5
+$\|n\K0$;\5
+$\\{eq\_type}(\\{warning\_info})\K\\{defined\_macro}$;\5
+$\\{equiv}(\\{warning\_info})\K\|q$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|p\K\\{scan\_declared\_variable}$;\5
+$\\{flush\_variable}(\\{equiv}(\\{info}(\|p)),\39\\{link}(\|p),\39\\{true})$;\5
+$\\{warning\_info}\K\\{find\_variable}(\|p)$;\5
+$\\{flush\_list}(\|p)$;\6
+\&{if} $\\{warning\_info}=\\{null}$ \1\&{then}\5
+\X701:Change to `\.{a bad variable}'\X;\2\6
+$\\{scanner\_status}\K\\{var\_defining}$;\5
+$\|n\K2$;\6
+\&{if} $\\{cur\_cmd}=\\{macro\_special}$ \1\&{then}\6
+\&{if} $\\{cur\_mod}=\\{macro\_suffix}$ \1\&{then}\C{\.{\AT!\#}}\6
+\&{begin} \37$\|n\K3$;\5
+\\{get\_next};\6
+\&{end};\2\2\6
+$\\{type}(\\{warning\_info})\K\\{unsuffixed\_macro}-2+\|n$;\5
+$\\{value}(\\{warning\_info})\K\|q$;\6
+\&{end}\C{$\\{suffixed\_macro}=\\{unsuffixed\_macro}+1$}\2\par
+\U697.\fi
+
+\M701. \P$\X701:Change to `\.{a bad variable}'\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"This\ variable\ already\ starts\ with\ a\
+macro"})$;\5
+$\\{help2}(\.{"After\ \`vardef\ a\'\ you\ can\'t\ say\ \`vardef\ a.b\'."})$\6
+$(\.{"So\ I\'ll\ have\ to\ discard\ this\ definition."})$;\5
+\\{error};\5
+$\\{warning\_info}\K\\{bad\_vardef}$;\6
+\&{end}\par
+\U700.\fi
+
+\M702. \P$\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}%
+\S$\6
+$\\{name\_type}(\\{bad\_vardef})\K\\{root}$;\5
+$\\{link}(\\{bad\_vardef})\K\\{frozen\_bad\_vardef}$;\5
+$\\{equiv}(\\{frozen\_bad\_vardef})\K\\{bad\_vardef}$;\5
+$\\{eq\_type}(\\{frozen\_bad\_vardef})\K\\{tag\_token}$;\par
+\fi
+
+\M703. \P$\X703:Absorb delimited parameters, putting them into lists \|q and %
+\|r\X\S$\6
+\1\&{repeat} \37$\\{l\_delim}\K\\{cur\_sym}$;\5
+$\\{r\_delim}\K\\{cur\_mod}$;\5
+\\{get\_next};\6
+\&{if} $(\\{cur\_cmd}=\\{param\_type})\W(\\{cur\_mod}\G\\{expr\_base})$ \1%
+\&{then}\5
+$\\{base}\K\\{cur\_mod}$\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Missing\ parameter\ type;\ \`expr\'%
+\ will\ be\ assumed"})$;\5
+$\\{help1}(\.{"You\ should\'ve\ had\ \`expr\'\ or\ \`suffix\'\ or\ \`text\'\
+here."})$;\5
+\\{back\_error};\5
+$\\{base}\K\\{expr\_base}$;\6
+\&{end};\2\6
+\X704:Absorb parameter tokens for type \\{base}\X;\6
+$\\{check\_delimiter}(\\{l\_delim},\39\\{r\_delim})$;\5
+\\{get\_next};\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{left\_delimiter}$\2\par
+\U697.\fi
+
+\M704. \P$\X704:Absorb parameter tokens for type \\{base}\X\S$\6
+\1\&{repeat} \37$\\{link}(\|q)\K\\{get\_avail}$;\5
+$\|q\K\\{link}(\|q)$;\5
+$\\{info}(\|q)\K\\{base}+\|k$;\6
+\\{get\_symbol};\5
+$\|p\K\\{get\_node}(\\{token\_node\_size})$;\5
+$\\{value}(\|p)\K\\{base}+\|k$;\5
+$\\{info}(\|p)\K\\{cur\_sym}$;\6
+\&{if} $\|k=\\{param\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"parameter\ stack\ size"},\39\\{param\_size})$;\2\6
+$\\{incr}(\|k)$;\5
+$\\{link}(\|p)\K\|r$;\5
+$\|r\K\|p$;\5
+\\{get\_next};\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$\2\par
+\U703.\fi
+
+\M705. \P$\X705:Absorb undelimited parameters, putting them into list \|r\X\S$\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{token\_node\_size})$;\6
+\&{if} $\\{cur\_mod}<\\{expr\_base}$ \1\&{then}\6
+\&{begin} \37$\|c\K\\{cur\_mod}$;\5
+$\\{value}(\|p)\K\\{expr\_base}+\|k$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{value}(\|p)\K\\{cur\_mod}+\|k$;\6
+\&{if} $\\{cur\_mod}=\\{expr\_base}$ \1\&{then}\5
+$\|c\K\\{expr\_macro}$\6
+\4\&{else} \&{if} $\\{cur\_mod}=\\{suffix\_base}$ \1\&{then}\5
+$\|c\K\\{suffix\_macro}$\6
+\4\&{else} $\|c\K\\{text\_macro}$;\2\2\6
+\&{end};\2\6
+\&{if} $\|k=\\{param\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"parameter\ stack\ size"},\39\\{param\_size})$;\2\6
+$\\{incr}(\|k)$;\5
+\\{get\_symbol};\5
+$\\{info}(\|p)\K\\{cur\_sym}$;\5
+$\\{link}(\|p)\K\|r$;\5
+$\|r\K\|p$;\5
+\\{get\_next};\6
+\&{if} $\|c=\\{expr\_macro}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}=\\{of\_token}$ \1\&{then}\6
+\&{begin} \37$\|c\K\\{of\_macro}$;\5
+$\|p\K\\{get\_node}(\\{token\_node\_size})$;\6
+\&{if} $\|k=\\{param\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"parameter\ stack\ size"},\39\\{param\_size})$;\2\6
+$\\{value}(\|p)\K\\{expr\_base}+\|k$;\5
+\\{get\_symbol};\5
+$\\{info}(\|p)\K\\{cur\_sym}$;\5
+$\\{link}(\|p)\K\|r$;\5
+$\|r\K\|p$;\5
+\\{get\_next};\6
+\&{end};\2\2\6
+\&{end}\par
+\U697.\fi
+
+\N706. \[35] Expanding the next token.
+Only a few command codes $<\\{min\_command}$ can possibly be returned by
+\\{get\_next}; in increasing order, they are
+\\{if\_test}, \\{fi\_or\_else}, \\{input}, \\{iteration}, \\{repeat\_loop},
+\\{exit\_test}, \\{relax}, \\{scan\_tokens}, \\{expand\_after}, and \\{defined%
+\_macro}.
+
+\MF\ usually gets the next token of input by saying \\{get\_x\_next}. This is
+like \\{get\_next} except that it keeps getting more tokens until
+finding $\\{cur\_cmd}\G\\{min\_command}$. In other words, \\{get\_x\_next}
+expands
+macros and removes conditionals or iterations or input instructions that
+might be present.
+
+It follows that \\{get\_x\_next} might invoke itself recursively. In fact,
+there is massive recursion, since macro expansion can involve the
+scanning of arbitrarily complex expressions, which in turn involve
+macro expansion and conditionals, etc.
+
+Therefore it's necessary to declare a whole bunch of \\{forward}
+procedures at this point, and to insert some other procedures
+that will be invoked by \\{get\_x\_next}.
+
+\Y\P\4\&{procedure}\1\ \37\\{scan\_primary};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{scan\_secondary};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{scan\_tertiary};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{scan\_expression};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{scan\_suffix};\5
+\\{forward};\5
+\hbox{\2}\6
+\hbox{\4}\X720:Declare the procedure called \\{macro\_call}\X\6
+\4\&{procedure}\1\ \37\\{get\_boolean};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{pass\_text};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{conditional};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{start\_input};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{begin\_iteration};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{resume\_iteration};\5
+\\{forward}; \hbox{\2} \6
+\4\&{procedure}\1\ \37\\{stop\_iteration};\5
+\\{forward};\5
+\hbox{\2}\par
+\fi
+
+\M707. An auxiliary subroutine called \\{expand} is used by \\{get\_x\_next}
+when it has to do exotic expansion commands.
+
+\Y\P\4\&{procedure}\1\ \37\\{expand};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{for list manipulation}\6
+\|k: \37\\{integer};\C{something that we hope is $\L\\{buf\_size}$}\6
+\|j: \37\\{pool\_pointer};\C{index into \\{str\_pool}}\2\6
+\&{begin} \37\&{if} $\\{internal}[\\{tracing\_commands}]>\\{unity}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}\I\\{defined\_macro}$ \1\&{then}\5
+\\{show\_cur\_cmd\_mod};\2\2\6
+\&{case} $\\{cur\_cmd}$ \1\&{of}\6
+\4\\{if\_test}: \37\\{conditional};\C{this procedure is discussed in Part 36
+below}\6
+\4\\{fi\_or\_else}: \37\X751:Terminate the current conditional and skip to %
+\&{fi}\X;\6
+\4\\{input}: \37\X711:Initiate or terminate input from a file\X;\6
+\4\\{iteration}: \37\&{if} $\\{cur\_mod}=\\{end\_for}$ \1\&{then}\5
+\X708:Scold the user for having an extra \&{endfor}\X\6
+\4\&{else} \\{begin\_iteration};\C{this procedure is discussed in Part 37
+below}\2\6
+\4\\{repeat\_loop}: \37\X712:Repeat a loop\X;\6
+\4\\{exit\_test}: \37\X713:Exit a loop if the proper time has come\X;\6
+\4\\{relax}: \37\\{do\_nothing};\6
+\4\\{expand\_after}: \37\X715:Expand the token after the next token\X;\6
+\4\\{scan\_tokens}: \37\X716:Put a string into the input buffer\X;\6
+\4\\{defined\_macro}: \37$\\{macro\_call}(\\{cur\_mod},\39\\{null},\39\\{cur%
+\_sym})$;\2\6
+\&{end};\C{there are no other cases}\6
+\&{end};\par
+\fi
+
+\M708. \P$\X708:Scold the user for having an extra \&{endfor}\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Extra\ \`endfor\'"})$;\5
+$\\{help2}(\.{"I\'m\ not\ currently\ working\ on\ a\ for\ loop,"})$\6
+$(\.{"so\ I\ had\ better\ not\ try\ to\ end\ anything."})$;\6
+\\{error};\6
+\&{end}\par
+\U707.\fi
+
+\M709. The processing of \&{input} involves the \\{start\_input} subroutine,
+which will be declared later; the processing of \&{endinput} is trivial.
+
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"input"},\39\\{input},\390)$;\6
+$\\{primitive}(\.{"endinput"},\39\\{input},\391)$;\par
+\fi
+
+\M710. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{input}: \37\&{if} $\|m=0$ \1\&{then}\5
+$\\{print}(\.{"input"})$\ \&{else} $\\{print}(\.{"endinput"})$;\2\par
+\fi
+
+\M711. \P$\X711:Initiate or terminate input from a file\X\S$\6
+\&{if} $\\{cur\_mod}>0$ \1\&{then}\5
+$\\{force\_eof}\K\\{true}$\6
+\4\&{else} \\{start\_input}\2\par
+\U707.\fi
+
+\M712. We'll discuss the complicated parts of loop operations later. For now
+it suffices to know that there's a global variable called \\{loop\_ptr}
+that will be \\{null} if no loop is in progress.
+
+\Y\P$\4\X712:Repeat a loop\X\S$\6
+\&{begin} \37\&{while} $\\{token\_state}\W(\\{loc}=\\{null})$ \1\&{do}\5
+\\{end\_token\_list};\C{conserve stack space}\2\6
+\&{if} $\\{loop\_ptr}=\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Lost\ loop"})$;\5
+$\\{help2}(\.{"I\'m\ confused;\ after\ exiting\ from\ a\ loop,\ I\ still\
+seem"})$\6
+$(\.{"to\ want\ to\ repeat\ it.\ I\'ll\ try\ to\ forget\ the\ problem."})$;\6
+\\{error};\6
+\&{end}\6
+\4\&{else} \\{resume\_iteration};\C{this procedure is in Part 37 below}\2\6
+\&{end}\par
+\U707.\fi
+
+\M713. \P$\X713:Exit a loop if the proper time has come\X\S$\6
+\&{begin} \37\\{get\_boolean};\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>\\{unity}$ \1\&{then}\5
+$\\{show\_cmd\_mod}(\\{nullary},\39\\{cur\_exp})$;\2\6
+\&{if} $\\{cur\_exp}=\\{true\_code}$ \1\&{then}\6
+\&{if} $\\{loop\_ptr}=\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"No\ loop\ is\ in\ progress"})$;\5
+$\\{help1}(\.{"Why\ say\ \`exitif\'\ when\ there\'s\ nothing\ to\ exit\
+from?"})$;\6
+\&{if} $\\{cur\_cmd}=\\{semicolon}$ \1\&{then}\5
+\\{error}\ \&{else} \\{back\_error};\2\6
+\&{end}\6
+\4\&{else} \X714:Exit prematurely from an iteration\X\2\6
+\4\&{else} \&{if} $\\{cur\_cmd}\I\\{semicolon}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{";"})$;\6
+$\\{help2}(\.{"After\ \`exitif\ <boolean\ exp>\'\ I\ expect\ to\ see\ a\
+semicolon."})$\6
+$(\.{"I\ shall\ pretend\ that\ one\ was\ there."})$;\5
+\\{back\_error};\6
+\&{end};\2\2\6
+\&{end}\par
+\U707.\fi
+
+\M714. Here we use the fact that \\{forever\_text} is the only \\{token\_type}
+that
+is less than \\{loop\_text}.
+
+\Y\P$\4\X714:Exit prematurely from an iteration\X\S$\6
+\&{begin} \37$\|p\K\\{null}$;\6
+\1\&{repeat} \37\&{if} $\\{file\_state}$ \1\&{then}\5
+\\{end\_file\_reading}\6
+\4\&{else} \&{begin} \37\&{if} $\\{token\_type}\L\\{loop\_text}$ \1\&{then}\5
+$\|p\K\\{start}$;\2\6
+\\{end\_token\_list};\6
+\&{end};\2\6
+\4\&{until}\5
+$\|p\I\\{null}$;\2\6
+\&{if} $\|p\I\\{info}(\\{loop\_ptr})$ \1\&{then}\5
+$\\{fatal\_error}(\.{"***\ (loop\ confusion)"})$;\2\6
+\\{stop\_iteration};\C{this procedure is in Part 37 below}\6
+\&{end}\par
+\U713.\fi
+
+\M715. \P$\X715:Expand the token after the next token\X\S$\6
+\&{begin} \37\\{get\_next};\5
+$\|p\K\\{cur\_tok}$;\5
+\\{get\_next};\6
+\&{if} $\\{cur\_cmd}<\\{min\_command}$ \1\&{then}\5
+\\{expand}\6
+\4\&{else} \\{back\_input};\2\6
+$\\{back\_list}(\|p)$;\6
+\&{end}\par
+\U707.\fi
+
+\M716. \P$\X716:Put a string into the input buffer\X\S$\6
+\&{begin} \37\\{get\_x\_next};\5
+\\{scan\_primary};\6
+\&{if} $\\{cur\_type}\I\\{string\_type}$ \1\&{then}\6
+\&{begin} \37$\\{disp\_err}(\\{null},\39\.{"Not\ a\ string"})$;\5
+$\\{help2}(\.{"I\'m\ going\ to\ flush\ this\ expression,\ since"})$\6
+$(\.{"scantokens\ should\ be\ followed\ by\ a\ known\ string."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\\{back\_input};\6
+\&{if} $\\{length}(\\{cur\_exp})>0$ \1\&{then}\5
+\X717:Pretend we're reading a new one-line file\X;\2\6
+\&{end};\2\6
+\&{end}\par
+\U707.\fi
+
+\M717. \P$\X717:Pretend we're reading a new one-line file\X\S$\6
+\&{begin} \37\\{begin\_file\_reading};\5
+$\\{name}\K2$;\5
+$\|k\K\\{first}+\\{length}(\\{cur\_exp})$;\6
+\&{if} $\|k\G\\{max\_buf\_stack}$ \1\&{then}\6
+\&{begin} \37\&{if} $\|k\G\\{buf\_size}$ \1\&{then}\6
+\&{begin} \37$\\{max\_buf\_stack}\K\\{buf\_size}$;\5
+$\\{overflow}(\.{"buffer\ size"},\39\\{buf\_size})$;\6
+\&{end};\2\6
+$\\{max\_buf\_stack}\K\|k+1$;\6
+\&{end};\2\6
+$\|j\K\\{str\_start}[\\{cur\_exp}]$;\5
+$\\{limit}\K\|k$;\6
+\&{while} $\\{first}<\\{limit}$ \1\&{do}\6
+\&{begin} \37$\\{buffer}[\\{first}]\K\\{so}(\\{str\_pool}[\|j])$;\5
+$\\{incr}(\|j)$;\5
+$\\{incr}(\\{first})$;\6
+\&{end};\2\6
+$\\{buffer}[\\{limit}]\K\.{"\%"}$;\5
+$\\{first}\K\\{limit}+1$;\5
+$\\{loc}\K\\{start}$;\5
+$\\{flush\_cur\_exp}(0)$;\6
+\&{end}\par
+\U716.\fi
+
+\M718. Here finally is \\{get\_x\_next}.
+
+The expression scanning routines to be considered later
+communicate via the global quantities \\{cur\_type} and \\{cur\_exp};
+we must be very careful to save and restore these quantities while
+macros are being expanded.
+
+\Y\P\4\&{procedure}\1\ \37\\{get\_x\_next};\6
+\4\&{var} \37\\{save\_exp}: \37\\{pointer};\C{a capsule to save \\{cur\_type}
+and \\{cur\_exp}}\2\6
+\&{begin} \37\\{get\_next};\6
+\&{if} $\\{cur\_cmd}<\\{min\_command}$ \1\&{then}\6
+\&{begin} \37$\\{save\_exp}\K\\{stash\_cur\_exp}$;\6
+\1\&{repeat} \37\&{if} $\\{cur\_cmd}=\\{defined\_macro}$ \1\&{then}\5
+$\\{macro\_call}(\\{cur\_mod},\39\\{null},\39\\{cur\_sym})$\6
+\4\&{else} \\{expand};\2\6
+\\{get\_next};\6
+\4\&{until}\5
+$\\{cur\_cmd}\G\\{min\_command}$;\2\6
+$\\{unstash\_cur\_exp}(\\{save\_exp})$;\C{that restores \\{cur\_type} and %
+\\{cur\_exp}}\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M719. Now let's consider the \\{macro\_call} procedure, which is used to start
+up
+all user-defined macros. Since the arguments to a macro might be expressions,
+\\{macro\_call} is recursive.
+
+The first parameter to \\{macro\_call} points to the reference count of the
+token list that defines the macro. The second parameter contains any
+arguments that have already been parsed (see below). The third parameter
+points to the symbolic token that names the macro. If the third parameter
+is \\{null}, the macro was defined by \&{vardef}, so its name can be
+reconstructed from the prefix and ``at'' arguments found within the
+second parameter.
+
+What is this second parameter? It's simply a linked list of one-word items,
+whose \\{info} fields point to the arguments. In other words, if $\\{arg%
+\_list}=\\{null}$,
+no arguments have been scanned yet; otherwise $\\{info}(\\{arg\_list})$ points
+to
+the first scanned argument, and $\\{link}(\\{arg\_list})$ points to the list of
+further arguments (if any).
+
+Arguments of type \&{expr} are so-called capsules, which we will
+discuss later when we concentrate on expressions; they can be
+recognized easily because their \\{link} field is \\{void}. Arguments of type
+\&{suffix} and \&{text} are token lists without reference counts.
+
+\fi
+
+\M720. After argument scanning is complete, the arguments are moved to the
+\\{param\_stack}. (They can't be put on that stack any sooner, because
+the stack is growing and shrinking in unpredictable ways as more arguments
+are being acquired.) Then the macro body is fed to the scanner; i.e.,
+the replacement text of the macro is placed at the top of the \MF's
+input stack, so that \\{get\_next} will proceed to read it next.
+
+\Y\P$\4\X720:Declare the procedure called \\{macro\_call}\X\S$\6
+\hbox{\4}\X722:Declare the procedure called \\{print\_macro\_name}\X\6
+\hbox{\4}\X723:Declare the procedure called \\{print\_arg}\X\6
+\hbox{\4}\X730:Declare the procedure called \\{scan\_text\_arg}\X\6
+\4\&{procedure}\1\ \37$\\{macro\_call}(\\{def\_ref},\39\\{arg\_list},\39%
+\\{macro\_name}:\\{pointer})$;\C{invokes a user-defined control sequence}\6
+\4\&{label} \37\\{found};\6
+\4\&{var} \37\|r: \37\\{pointer};\C{current node in the macro's token list}\6
+$\|p,\39\|q$: \37\\{pointer};\C{for list manipulation}\6
+\|n: \37\\{integer};\C{the number of arguments}\6
+$\\{l\_delim},\39\\{r\_delim}$: \37\\{pointer};\C{a delimiter pair}\6
+\\{tail}: \37\\{pointer};\C{tail of the argument list}\2\6
+\&{begin} \37$\|r\K\\{link}(\\{def\_ref})$;\5
+$\\{add\_mac\_ref}(\\{def\_ref})$;\6
+\&{if} $\\{arg\_list}=\\{null}$ \1\&{then}\5
+$\|n\K0$\6
+\4\&{else} \X724:Determine the number \|n of arguments already supplied, and
+set \\{tail} to the tail of \\{arg\_list}\X;\2\6
+\&{if} $\\{internal}[\\{tracing\_macros}]>0$ \1\&{then}\5
+\X721:Show the text of the macro being expanded, and the existing arguments\X;%
+\2\6
+\X725:Scan the remaining arguments, if any; set \|r to the first token of the
+replacement text\X;\6
+\X736:Feed the arguments and replacement text to the scanner\X;\6
+\&{end};\par
+\U706.\fi
+
+\M721. \P$\X721:Show the text of the macro being expanded, and the existing
+arguments\X\S$\6
+\&{begin} \37\\{begin\_diagnostic};\5
+\\{print\_ln};\5
+$\\{print\_macro\_name}(\\{arg\_list},\39\\{macro\_name})$;\6
+\&{if} $\|n=3$ \1\&{then}\5
+$\\{print}(\.{"@\#"})$;\C{indicate a suffixed macro}\2\6
+$\\{show\_macro}(\\{def\_ref},\39\\{null},\39100000)$;\6
+\&{if} $\\{arg\_list}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\|n\K0$;\5
+$\|p\K\\{arg\_list}$;\6
+\1\&{repeat} \37$\|q\K\\{info}(\|p)$;\5
+$\\{print\_arg}(\|q,\39\|n,\390)$;\5
+$\\{incr}(\|n)$;\5
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\|p=\\{null}$;\2\6
+\&{end};\2\6
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\par
+\U720.\fi
+
+\M722. \P$\X722:Declare the procedure called \\{print\_macro\_name}\X\S$\6
+\4\&{procedure}\1\ \37$\\{print\_macro\_name}(\|a,\39\|n:\\{pointer})$;\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{they traverse the first part of %
+\|a}\2\6
+\&{begin} \37\&{if} $\|n\I\\{null}$ \1\&{then}\5
+$\\{slow\_print}(\\{text}(\|n))$\6
+\4\&{else} \&{begin} \37$\|p\K\\{info}(\|a)$;\6
+\&{if} $\|p=\\{null}$ \1\&{then}\5
+$\\{slow\_print}(\\{text}(\\{info}(\\{info}(\\{link}(\|a)))))$\6
+\4\&{else} \&{begin} \37$\|q\K\|p$;\6
+\&{while} $\\{link}(\|q)\I\\{null}$ \1\&{do}\5
+$\|q\K\\{link}(\|q)$;\2\6
+$\\{link}(\|q)\K\\{info}(\\{link}(\|a))$;\5
+$\\{show\_token\_list}(\|p,\39\\{null},\391000,\390)$;\5
+$\\{link}(\|q)\K\\{null}$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\par
+\U720.\fi
+
+\M723. \P$\X723:Declare the procedure called \\{print\_arg}\X\S$\6
+\4\&{procedure}\1\ \37$\\{print\_arg}(\|q:\\{pointer};\,\35\|n:\\{integer};\,%
+\35\|b:\\{pointer})$;\2\6
+\&{begin} \37\&{if} $\\{link}(\|q)=\\{void}$ \1\&{then}\5
+$\\{print\_nl}(\.{"(EXPR"})$\6
+\4\&{else} \&{if} $(\|b<\\{text\_base})\W(\|b\I\\{text\_macro})$ \1\&{then}\5
+$\\{print\_nl}(\.{"(SUFFIX"})$\6
+\4\&{else} $\\{print\_nl}(\.{"(TEXT"})$;\2\2\6
+$\\{print\_int}(\|n)$;\5
+$\\{print}(\.{")<-"})$;\6
+\&{if} $\\{link}(\|q)=\\{void}$ \1\&{then}\5
+$\\{print\_exp}(\|q,\391)$\6
+\4\&{else} $\\{show\_token\_list}(\|q,\39\\{null},\391000,\390)$;\2\6
+\&{end};\par
+\U720.\fi
+
+\M724. \P$\X724:Determine the number \|n of arguments already supplied, and set
+\\{tail} to the tail of \\{arg\_list}\X\S$\6
+\&{begin} \37$\|n\K1$;\5
+$\\{tail}\K\\{arg\_list}$;\6
+\&{while} $\\{link}(\\{tail})\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\\{incr}(\|n)$;\5
+$\\{tail}\K\\{link}(\\{tail})$;\6
+\&{end};\2\6
+\&{end}\par
+\U720.\fi
+
+\M725. \P$\X725:Scan the remaining arguments, if any; set \|r to the first
+token of the replacement text\X\S$\6
+$\\{cur\_cmd}\K\\{comma}+1$;\C{anything $\I\\{comma}$ will do}\6
+\&{while} $\\{info}(\|r)\G\\{expr\_base}$ \1\&{do}\6
+\&{begin} \37\X726:Scan the delimited argument represented by $\\{info}(\|r)$%
+\X;\6
+$\|r\K\\{link}(\|r)$;\6
+\&{end};\2\6
+\&{if} $\\{cur\_cmd}=\\{comma}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Too\ many\ arguments\ to\ "})$;\5
+$\\{print\_macro\_name}(\\{arg\_list},\39\\{macro\_name})$;\5
+$\\{print\_char}(\.{";"})$;\5
+$\\{print\_nl}(\.{"\ \ Missing\ \`"})$;\5
+$\\{slow\_print}(\\{text}(\\{r\_delim}))$;\5
+$\\{print}(\.{"\'\ has\ been\ inserted"})$;\5
+$\\{help3}(\.{"I\'m\ going\ to\ assume\ that\ the\ comma\ I\ just\ read\ was\
+a"})$\6
+$(\.{"right\ delimiter,\ and\ then\ I\'ll\ begin\ expanding\ the\ macro."})$\6
+$(\.{"You\ might\ want\ to\ delete\ some\ tokens\ before\ continuing."})$;\5
+\\{error};\6
+\&{end};\2\6
+\&{if} $\\{info}(\|r)\I\\{general\_macro}$ \1\&{then}\5
+\X733:Scan undelimited argument(s)\X;\2\6
+$\|r\K\\{link}(\|r)$\par
+\U720.\fi
+
+\M726. At this point, the reader will find it advisable to review the
+explanation
+of token list format that was presented earlier, paying special attention to
+the conventions that apply only at the beginning of a macro's token list.
+
+On the other hand, the reader will have to take the expression-parsing
+aspects of the following program on faith; we will explain \\{cur\_type}
+and \\{cur\_exp} later. (Several things in this program depend on each other,
+and it's necessary to jump into the circle somewhere.)
+
+\Y\P$\4\X726:Scan the delimited argument represented by $\\{info}(\|r)$\X\S$\6
+\&{if} $\\{cur\_cmd}\I\\{comma}$ \1\&{then}\6
+\&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}\I\\{left\_delimiter}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Missing\ argument\ to\ "})$;\5
+$\\{print\_macro\_name}(\\{arg\_list},\39\\{macro\_name})$;\5
+$\\{help3}(\.{"That\ macro\ has\ more\ parameters\ than\ you\ thought."})$\6
+$(\.{"I\'ll\ continue\ by\ pretending\ that\ each\ missing\ argument"})$\6
+$(\.{"is\ either\ zero\ or\ null."})$;\6
+\&{if} $\\{info}(\|r)\G\\{suffix\_base}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_exp}\K\\{null}$;\5
+$\\{cur\_type}\K\\{token\_list}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{cur\_exp}\K0$;\5
+$\\{cur\_type}\K\\{known}$;\6
+\&{end};\2\6
+\\{back\_error};\5
+$\\{cur\_cmd}\K\\{right\_delimiter}$;\5
+\&{goto} \37\\{found};\6
+\&{end};\2\6
+$\\{l\_delim}\K\\{cur\_sym}$;\5
+$\\{r\_delim}\K\\{cur\_mod}$;\6
+\&{end};\2\6
+\X729:Scan the argument represented by $\\{info}(\|r)$\X;\6
+\&{if} $\\{cur\_cmd}\I\\{comma}$ \1\&{then}\5
+\X727:Check that the proper right delimiter was present\X;\2\6
+\4\\{found}: \37\X728:Append the current expression to \\{arg\_list}\X\par
+\U725.\fi
+
+\M727. \P$\X727:Check that the proper right delimiter was present\X\S$\6
+\&{if} $(\\{cur\_cmd}\I\\{right\_delimiter})\V(\\{cur\_mod}\I\\{l\_delim})$ \1%
+\&{then}\6
+\&{if} $\\{info}(\\{link}(\|r))\G\\{expr\_base}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{","})$;\5
+$\\{help3}(\.{"I\'ve\ finished\ reading\ a\ macro\ argument\ and\ am\ about\
+to"})$\6
+$(\.{"read\ another;\ the\ arguments\ weren\'t\ delimited\ correctly."})$\6
+$(\.{"You\ might\ want\ to\ delete\ some\ tokens\ before\ continuing."})$;\5
+\\{back\_error};\5
+$\\{cur\_cmd}\K\\{comma}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{missing\_err}(\\{text}(\\{r\_delim}))$;\5
+$\\{help2}(\.{"I\'ve\ gotten\ to\ the\ end\ of\ the\ macro\ parameter\
+list."})$\6
+$(\.{"You\ might\ want\ to\ delete\ some\ tokens\ before\ continuing."})$;\5
+\\{back\_error};\6
+\&{end}\2\2\par
+\U726.\fi
+
+\M728. A \&{suffix} or \&{text} parameter will be have been scanned as
+a token list pointed to by \\{cur\_exp}, in which case we will have
+$\\{cur\_type}=\\{token\_list}$.
+
+\Y\P$\4\X728:Append the current expression to \\{arg\_list}\X\S$\6
+\&{begin} \37$\|p\K\\{get\_avail}$;\6
+\&{if} $\\{cur\_type}=\\{token\_list}$ \1\&{then}\5
+$\\{info}(\|p)\K\\{cur\_exp}$\6
+\4\&{else} $\\{info}(\|p)\K\\{stash\_cur\_exp}$;\2\6
+\&{if} $\\{internal}[\\{tracing\_macros}]>0$ \1\&{then}\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_arg}(\\{info}(\|p),\39\|n,\39\\{info}(\|r))$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end};\2\6
+\&{if} $\\{arg\_list}=\\{null}$ \1\&{then}\5
+$\\{arg\_list}\K\|p$\6
+\4\&{else} $\\{link}(\\{tail})\K\|p$;\2\6
+$\\{tail}\K\|p$;\5
+$\\{incr}(\|n)$;\6
+\&{end}\par
+\Us726\ET733.\fi
+
+\M729. \P$\X729:Scan the argument represented by $\\{info}(\|r)$\X\S$\6
+\&{if} $\\{info}(\|r)\G\\{text\_base}$ \1\&{then}\5
+$\\{scan\_text\_arg}(\\{l\_delim},\39\\{r\_delim})$\6
+\4\&{else} \&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{info}(\|r)\G\\{suffix\_base}$ \1\&{then}\5
+\\{scan\_suffix}\6
+\4\&{else} \\{scan\_expression};\2\6
+\&{end}\2\par
+\U726.\fi
+
+\M730. The parameters to \\{scan\_text\_arg} are either a pair of delimiters
+or zero; the latter case is for undelimited text arguments, which
+end with the first semicolon or \&{endgroup} or \&{end} that is not
+contained in a group.
+
+\Y\P$\4\X730:Declare the procedure called \\{scan\_text\_arg}\X\S$\6
+\4\&{procedure}\1\ \37$\\{scan\_text\_arg}(\\{l\_delim},\39\\{r\_delim}:%
+\\{pointer})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\\{balance}: \37\\{integer};\C{excess of \\{l\_delim} over \\{r%
+\_delim}}\6
+\|p: \37\\{pointer};\C{list tail}\2\6
+\&{begin} \37$\\{warning\_info}\K\\{l\_delim}$;\5
+$\\{scanner\_status}\K\\{absorbing}$;\5
+$\|p\K\\{hold\_head}$;\5
+$\\{balance}\K1$;\5
+$\\{link}(\\{hold\_head})\K\\{null}$;\6
+\~ \1\&{loop}\ \&{begin} \37\\{get\_next};\6
+\&{if} $\\{l\_delim}=0$ \1\&{then}\5
+\X732:Adjust the balance for an undelimited argument; \&{goto} \\{done} if done%
+\X\6
+\4\&{else} \X731:Adjust the balance for a delimited argument; \&{goto} \\{done}
+if done\X;\2\6
+$\\{link}(\|p)\K\\{cur\_tok}$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{cur\_exp}\K\\{link}(\\{hold\_head})$;\5
+$\\{cur\_type}\K\\{token\_list}$;\5
+$\\{scanner\_status}\K\\{normal}$;\6
+\&{end};\par
+\U720.\fi
+
+\M731. \P$\X731:Adjust the balance for a delimited argument; \&{goto} \\{done}
+if done\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_cmd}=\\{right\_delimiter}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{cur\_mod}=\\{l\_delim}$ \1\&{then}\6
+\&{begin} \37$\\{decr}(\\{balance})$;\6
+\&{if} $\\{balance}=0$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{end};\2\6
+\&{end}\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{left\_delimiter}$ \1\&{then}\6
+\&{if} $\\{cur\_mod}=\\{r\_delim}$ \1\&{then}\5
+$\\{incr}(\\{balance})$;\2\2\2\6
+\&{end}\par
+\U730.\fi
+
+\M732. \P$\X732:Adjust the balance for an undelimited argument; \&{goto} %
+\\{done} if done\X\S$\6
+\&{begin} \37\&{if} $\\{end\_of\_statement}$ \1\&{then}\C{$\\{cur\_cmd}=%
+\\{semicolon}$, \\{end\_group}, or \\{stop}}\6
+\&{begin} \37\&{if} $\\{balance}=1$ \1\&{then}\5
+\&{goto} \37\\{done}\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{end\_group}$ \1\&{then}\5
+$\\{decr}(\\{balance})$;\2\2\6
+\&{end}\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{begin\_group}$ \1\&{then}\5
+$\\{incr}(\\{balance})$;\2\2\6
+\&{end}\par
+\U730.\fi
+
+\M733. \P$\X733:Scan undelimited argument(s)\X\S$\6
+\&{begin} \37\&{if} $\\{info}(\|r)<\\{text\_macro}$ \1\&{then}\6
+\&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{info}(\|r)\I\\{suffix\_macro}$ \1\&{then}\6
+\&{if} $(\\{cur\_cmd}=\\{equals})\V(\\{cur\_cmd}=\\{assignment})$ \1\&{then}\5
+\\{get\_x\_next};\2\2\6
+\&{end};\2\6
+\&{case} $\\{info}(\|r)$ \1\&{of}\6
+\4\\{primary\_macro}: \37\\{scan\_primary};\6
+\4\\{secondary\_macro}: \37\\{scan\_secondary};\6
+\4\\{tertiary\_macro}: \37\\{scan\_tertiary};\6
+\4\\{expr\_macro}: \37\\{scan\_expression};\6
+\4\\{of\_macro}: \37\X734:Scan an expression followed by `\&{of} $%
+\langle$primary$\rangle$'\X;\6
+\4\\{suffix\_macro}: \37\X735:Scan a suffix with optional delimiters\X;\6
+\4\\{text\_macro}: \37$\\{scan\_text\_arg}(0,\390)$;\2\6
+\&{end};\C{there are no other cases}\6
+\\{back\_input};\5
+\X728:Append the current expression to \\{arg\_list}\X;\6
+\&{end}\par
+\U725.\fi
+
+\M734. \P$\X734:Scan an expression followed by `\&{of} $\langle$primary$%
+\rangle$'\X\S$\6
+\&{begin} \37\\{scan\_expression};\5
+$\|p\K\\{get\_avail}$;\5
+$\\{info}(\|p)\K\\{stash\_cur\_exp}$;\6
+\&{if} $\\{internal}[\\{tracing\_macros}]>0$ \1\&{then}\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_arg}(\\{info}(\|p),\39\|n,\390)$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end};\2\6
+\&{if} $\\{arg\_list}=\\{null}$ \1\&{then}\5
+$\\{arg\_list}\K\|p$\ \&{else} $\\{link}(\\{tail})\K\|p$;\2\6
+$\\{tail}\K\|p$;\5
+$\\{incr}(\|n)$;\6
+\&{if} $\\{cur\_cmd}\I\\{of\_token}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"of"})$;\5
+$\\{print}(\.{"\ for\ "})$;\5
+$\\{print\_macro\_name}(\\{arg\_list},\39\\{macro\_name})$;\5
+$\\{help1}(\.{"I\'ve\ got\ the\ first\ argument;\ will\ look\ now\ for\ the\
+other."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+\\{scan\_primary};\6
+\&{end}\par
+\U733.\fi
+
+\M735. \P$\X735:Scan a suffix with optional delimiters\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_cmd}\I\\{left\_delimiter}$ \1\&{then}\5
+$\\{l\_delim}\K\\{null}$\6
+\4\&{else} \&{begin} \37$\\{l\_delim}\K\\{cur\_sym}$;\5
+$\\{r\_delim}\K\\{cur\_mod}$;\5
+\\{get\_x\_next};\6
+\&{end};\2\6
+\\{scan\_suffix};\6
+\&{if} $\\{l\_delim}\I\\{null}$ \1\&{then}\6
+\&{begin} \37\&{if} $(\\{cur\_cmd}\I\\{right\_delimiter})\V(\\{cur\_mod}\I\\{l%
+\_delim})$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\\{text}(\\{r\_delim}))$;\5
+$\\{help2}(\.{"I\'ve\ gotten\ to\ the\ end\ of\ the\ macro\ parameter\
+list."})$\6
+$(\.{"You\ might\ want\ to\ delete\ some\ tokens\ before\ continuing."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+\\{get\_x\_next};\6
+\&{end};\2\6
+\&{end}\par
+\U733.\fi
+
+\M736. Before we put a new token list on the input stack, it is wise to clean
+off
+all token lists that have recently been depleted. Then a user macro that ends
+with a call to itself will not require unbounded stack space.
+
+\Y\P$\4\X736:Feed the arguments and replacement text to the scanner\X\S$\6
+\&{while} $\\{token\_state}\W(\\{loc}=\\{null})$ \1\&{do}\5
+\\{end\_token\_list};\C{conserve stack space}\2\6
+\&{if} $\\{param\_ptr}+\|n>\\{max\_param\_stack}$ \1\&{then}\6
+\&{begin} \37$\\{max\_param\_stack}\K\\{param\_ptr}+\|n$;\6
+\&{if} $\\{max\_param\_stack}>\\{param\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"parameter\ stack\ size"},\39\\{param\_size})$;\2\6
+\&{end};\2\6
+$\\{begin\_token\_list}(\\{def\_ref},\39\\{macro})$;\5
+$\\{name}\K\\{macro\_name}$;\5
+$\\{loc}\K\|r$;\6
+\&{if} $\|n>0$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{arg\_list}$;\6
+\1\&{repeat} \37$\\{param\_stack}[\\{param\_ptr}]\K\\{info}(\|p)$;\5
+$\\{incr}(\\{param\_ptr})$;\5
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\|p=\\{null}$;\2\6
+$\\{flush\_list}(\\{arg\_list})$;\6
+\&{end}\2\par
+\U720.\fi
+
+\M737. It's sometimes necessary to put a single argument onto \\{param\_stack}.
+The \\{stack\_argument} subroutine does this.
+
+\Y\P\4\&{procedure}\1\ \37$\\{stack\_argument}(\|p:\\{pointer})$;\2\6
+\&{begin} \37\&{if} $\\{param\_ptr}=\\{max\_param\_stack}$ \1\&{then}\6
+\&{begin} \37$\\{incr}(\\{max\_param\_stack})$;\6
+\&{if} $\\{max\_param\_stack}>\\{param\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"parameter\ stack\ size"},\39\\{param\_size})$;\2\6
+\&{end};\2\6
+$\\{param\_stack}[\\{param\_ptr}]\K\|p$;\5
+$\\{incr}(\\{param\_ptr})$;\6
+\&{end};\par
+\fi
+
+\N738. \[36] Conditional processing.
+Let's consider now the way \&{if} commands are handled.
+
+Conditions can be inside conditions, and this nesting has a stack
+that is independent of other stacks.
+Four global variables represent the top of the condition stack:
+\\{cond\_ptr} points to pushed-down entries, if~any; \\{cur\_if} tells whether
+we are processing \&{if} or \&{elseif}; \\{if\_limit} specifies
+the largest code of a \\{fi\_or\_else} command that is syntactically legal;
+and \\{if\_line} is the line number at which the current conditional began.
+
+If no conditions are currently in progress, the condition stack has the
+special state $\\{cond\_ptr}=\\{null}$, $\\{if\_limit}=\\{normal}$, $\\{cur%
+\_if}=0$, $\\{if\_line}=0$.
+Otherwise \\{cond\_ptr} points to a two-word node; the \\{type}, \\{name%
+\_type}, and
+\\{link} fields of the first word contain \\{if\_limit}, \\{cur\_if}, and
+\\{cond\_ptr} at the next level, and the second word contains the
+corresponding \\{if\_line}.
+
+\Y\P\D \37$\\{if\_node\_size}=2$\C{number of words in stack entry for
+conditionals}\par
+\P\D \37$\\{if\_line\_field}(\#)\S\\{mem}[\#+1].\\{int}$\par
+\P\D \37$\\{if\_code}=1$\C{code for \&{if} being evaluated}\par
+\P\D \37$\\{fi\_code}=2$\C{code for \&{fi}}\par
+\P\D \37$\\{else\_code}=3$\C{code for \&{else}}\par
+\P\D \37$\\{else\_if\_code}=4$\C{code for \&{elseif}}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{cond\_ptr}: \37\\{pointer};\C{top of the condition stack}\6
+\4\\{if\_limit}: \37$\\{normal}\to\\{else\_if\_code}$;\C{upper bound on \\{fi%
+\_or\_else} codes}\6
+\4\\{cur\_if}: \37\\{small\_number};\C{type of conditional being worked on}\6
+\4\\{if\_line}: \37\\{integer};\C{line where that conditional began}\par
+\fi
+
+\M739. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{cond\_ptr}\K\\{null}$;\5
+$\\{if\_limit}\K\\{normal}$;\5
+$\\{cur\_if}\K0$;\5
+$\\{if\_line}\K0$;\par
+\fi
+
+\M740. \P$\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}%
+\S$\6
+$\\{primitive}(\.{"if"},\39\\{if\_test},\39\\{if\_code})$;\6
+$\\{primitive}(\.{"fi"},\39\\{fi\_or\_else},\39\\{fi\_code})$;\5
+$\\{eqtb}[\\{frozen\_fi}]\K\\{eqtb}[\\{cur\_sym}]$;\6
+$\\{primitive}(\.{"else"},\39\\{fi\_or\_else},\39\\{else\_code})$;\6
+$\\{primitive}(\.{"elseif"},\39\\{fi\_or\_else},\39\\{else\_if\_code})$;\par
+\fi
+
+\M741. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4$\\{if\_test},\39\\{fi\_or\_else}$: \37\&{case} $\|m$ \1\&{of}\6
+\4\\{if\_code}: \37$\\{print}(\.{"if"})$;\6
+\4\\{fi\_code}: \37$\\{print}(\.{"fi"})$;\6
+\4\\{else\_code}: \37$\\{print}(\.{"else"})$;\6
+\4\&{othercases} \37$\\{print}(\.{"elseif"})$\2\6
+\&{endcases};\par
+\fi
+
+\M742. Here is a procedure that ignores text until coming to an \&{elseif},
+\&{else}, or \&{fi} at level zero of $\&{if}\ldots\&{fi}$
+nesting. After it has acted, \\{cur\_mod} will indicate the token that
+was found.
+
+\MF's smallest two command codes are \\{if\_test} and \\{fi\_or\_else}; this
+makes the skipping process a bit simpler.
+
+\Y\P\4\&{procedure}\1\ \37\\{pass\_text};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|l: \37\\{integer};\2\6
+\&{begin} \37$\\{scanner\_status}\K\\{skipping}$;\5
+$\|l\K0$;\5
+$\\{warning\_info}\K\\{line}$;\6
+\~ \1\&{loop}\ \&{begin} \37\\{get\_next};\6
+\&{if} $\\{cur\_cmd}\L\\{fi\_or\_else}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}<\\{fi\_or\_else}$ \1\&{then}\5
+$\\{incr}(\|l)$\6
+\4\&{else} \&{begin} \37\&{if} $\|l=0$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\\{cur\_mod}=\\{fi\_code}$ \1\&{then}\5
+$\\{decr}(\|l)$;\2\6
+\&{end}\2\6
+\4\&{else} \X743:Decrease the string reference count, if the current token is a
+string\X;\2\6
+\&{end};\2\6
+\4\\{done}: \37$\\{scanner\_status}\K\\{normal}$;\6
+\&{end};\par
+\fi
+
+\M743. \P$\X743:Decrease the string reference count, if the current token is a
+string\X\S$\6
+\&{if} $\\{cur\_cmd}=\\{string\_token}$ \1\&{then}\5
+$\\{delete\_str\_ref}(\\{cur\_mod})$\2\par
+\Us83, 742, 991\ETs1016.\fi
+
+\M744. When we begin to process a new \&{if}, we set $\\{if\_limit}\K\\{if%
+\_code}$; then
+if \&{elseif} or \&{else} or \&{fi} occurs before the current \&{if}
+condition has been evaluated, a colon will be inserted.
+A construction like `\.{if fi}' would otherwise get \MF\ confused.
+
+\Y\P$\4\X744:Push the condition stack\X\S$\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{if\_node\_size})$;\5
+$\\{link}(\|p)\K\\{cond\_ptr}$;\5
+$\\{type}(\|p)\K\\{if\_limit}$;\5
+$\\{name\_type}(\|p)\K\\{cur\_if}$;\5
+$\\{if\_line\_field}(\|p)\K\\{if\_line}$;\5
+$\\{cond\_ptr}\K\|p$;\5
+$\\{if\_limit}\K\\{if\_code}$;\5
+$\\{if\_line}\K\\{line}$;\5
+$\\{cur\_if}\K\\{if\_code}$;\6
+\&{end}\par
+\U748.\fi
+
+\M745. \P$\X745:Pop the condition stack\X\S$\6
+\&{begin} \37$\|p\K\\{cond\_ptr}$;\5
+$\\{if\_line}\K\\{if\_line\_field}(\|p)$;\5
+$\\{cur\_if}\K\\{name\_type}(\|p)$;\5
+$\\{if\_limit}\K\\{type}(\|p)$;\5
+$\\{cond\_ptr}\K\\{link}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{if\_node\_size})$;\6
+\&{end}\par
+\Us748, 749\ETs751.\fi
+
+\M746. Here's a procedure that changes the \\{if\_limit} code corresponding to
+a given value of \\{cond\_ptr}.
+
+\Y\P\4\&{procedure}\1\ \37$\\{change\_if\_limit}(\|l:\\{small\_number};\,\35%
+\|p:\\{pointer})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|q: \37\\{pointer};\2\6
+\&{begin} \37\&{if} $\|p=\\{cond\_ptr}$ \1\&{then}\5
+$\\{if\_limit}\K\|l$\C{that's the easy case}\6
+\4\&{else} \&{begin} \37$\|q\K\\{cond\_ptr}$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\|q=\\{null}$ \1\&{then}\5
+$\\{confusion}(\.{"if"})$;\2\6
+\&{if} $\\{link}(\|q)=\|p$ \1\&{then}\6
+\&{begin} \37$\\{type}(\|q)\K\|l$;\5
+\&{return};\6
+\&{end};\2\6
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M747. The user is supposed to put colons into the proper parts of conditional
+statements. Therefore, \MF\ has to check for their presence.
+
+\Y\P\4\&{procedure}\1\ \37\\{check\_colon};\2\6
+\&{begin} \37\&{if} $\\{cur\_cmd}\I\\{colon}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{":"})$;\6
+$\\{help2}(\.{"There\ should\'ve\ been\ a\ colon\ after\ the\ condition."})$\6
+$(\.{"I\ shall\ pretend\ that\ one\ was\ there."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M748. A condition is started when the \\{get\_x\_next} procedure encounters
+an \\{if\_test} command; in that case \\{get\_x\_next} calls \\{conditional},
+which is a recursive procedure.
+
+\Y\P\4\&{procedure}\1\ \37\\{conditional};\6
+\4\&{label} \37$\\{exit},\39\\{done},\39\\{reswitch},\39\\{found}$;\6
+\4\&{var} \37\\{save\_cond\_ptr}: \37\\{pointer};\C{\\{cond\_ptr} corresponding
+to this conditional}\6
+\\{new\_if\_limit}: \37$\\{fi\_code}\to\\{else\_if\_code}$;\C{future value of %
+\\{if\_limit}}\6
+\|p: \37\\{pointer};\C{temporary register}\2\6
+\&{begin} \37\X744:Push the condition stack\X;\ $\\{save\_cond\_ptr}\K\\{cond%
+\_ptr}$;\6
+\4\\{reswitch}: \37\\{get\_boolean};\5
+$\\{new\_if\_limit}\K\\{else\_if\_code}$;\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>\\{unity}$ \1\&{then}\5
+\X750:Display the boolean value of \\{cur\_exp}\X;\2\6
+\4\\{found}: \37\\{check\_colon};\6
+\&{if} $\\{cur\_exp}=\\{true\_code}$ \1\&{then}\6
+\&{begin} \37$\\{change\_if\_limit}(\\{new\_if\_limit},\39\\{save\_cond%
+\_ptr})$;\5
+\&{return};\C{wait for \&{elseif}, \&{else}, or \&{fi}}\6
+\&{end};\2\6
+\X749:Skip to \&{elseif} or \&{else} or \&{fi}, then \&{goto} \\{done}\X;\6
+\4\\{done}: \37$\\{cur\_if}\K\\{cur\_mod}$;\5
+$\\{if\_line}\K\\{line}$;\6
+\&{if} $\\{cur\_mod}=\\{fi\_code}$ \1\&{then}\5
+\X745:Pop the condition stack\X\6
+\4\&{else} \&{if} $\\{cur\_mod}=\\{else\_if\_code}$ \1\&{then}\5
+\&{goto} \37\\{reswitch}\6
+\4\&{else} \&{begin} \37$\\{cur\_exp}\K\\{true\_code}$;\5
+$\\{new\_if\_limit}\K\\{fi\_code}$;\5
+\\{get\_x\_next};\5
+\&{goto} \37\\{found};\6
+\&{end};\2\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M749. In a construction like `\&{if} \&{if} \&{true}: $0=1$: \\{foo}
+\&{else}: \\{bar} \&{fi}', the first \&{else}
+that we come to after learning that the \&{if} is false is not the
+\&{else} we're looking for. Hence the following curious logic is needed.
+
+\Y\P$\4\X749:Skip to \&{elseif} or \&{else} or \&{fi}, then \&{goto} \\{done}\X%
+\S$\6
+\~ \1\&{loop}\ \&{begin} \37\\{pass\_text};\6
+\&{if} $\\{cond\_ptr}=\\{save\_cond\_ptr}$ \1\&{then}\5
+\&{goto} \37\\{done}\6
+\4\&{else} \&{if} $\\{cur\_mod}=\\{fi\_code}$ \1\&{then}\5
+\X745:Pop the condition stack\X;\2\2\6
+\&{end}\2\par
+\U748.\fi
+
+\M750. \P$\X750:Display the boolean value of \\{cur\_exp}\X\S$\6
+\&{begin} \37\\{begin\_diagnostic};\6
+\&{if} $\\{cur\_exp}=\\{true\_code}$ \1\&{then}\5
+$\\{print}(\.{"\{true\}"})$\ \&{else} $\\{print}(\.{"\{false\}"})$;\2\6
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\par
+\U748.\fi
+
+\M751. The processing of conditionals is complete except for the following
+code, which is actually part of \\{get\_x\_next}. It comes into play when
+\&{elseif}, \&{else}, or \&{fi} is scanned.
+
+\Y\P$\4\X751:Terminate the current conditional and skip to \&{fi}\X\S$\6
+\&{if} $\\{cur\_mod}>\\{if\_limit}$ \1\&{then}\6
+\&{if} $\\{if\_limit}=\\{if\_code}$ \1\&{then}\C{condition not yet evaluated}\6
+\&{begin} \37$\\{missing\_err}(\.{":"})$;\5
+\\{back\_input};\5
+$\\{cur\_sym}\K\\{frozen\_colon}$;\5
+\\{ins\_error};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Extra\ "})$;\5
+$\\{print\_cmd\_mod}(\\{fi\_or\_else},\39\\{cur\_mod})$;\5
+$\\{help1}(\.{"I\'m\ ignoring\ this;\ it\ doesn\'t\ match\ any\ if."})$;\5
+\\{error};\6
+\&{end}\2\6
+\4\&{else} \&{begin} \37\&{while} $\\{cur\_mod}\I\\{fi\_code}$ \1\&{do}\5
+\\{pass\_text};\C{skip to \&{fi}}\2\6
+\X745:Pop the condition stack\X;\6
+\&{end}\2\par
+\U707.\fi
+
+\N752. \[37] Iterations.
+To bring our treatment of \\{get\_x\_next} to a close, we need to consider what
+\MF\ does when it sees \&{for}, \&{forsuffixes}, and \&{forever}.
+
+There's a global variable \\{loop\_ptr} that keeps track of the \&{for} loops
+that are currently active. If $\\{loop\_ptr}=\\{null}$, no loops are in
+progress;
+otherwise $\\{info}(\\{loop\_ptr})$ points to the iterative text of the current
+(innermost) loop, and $\\{link}(\\{loop\_ptr})$ points to the data for any
+other
+loops that enclose the current one.
+
+A loop-control node also has two other fields, called \\{loop\_type} and
+\\{loop\_list}, whose contents depend on the type of loop:
+
+\yskip\indent$\\{loop\_type}(\\{loop\_ptr})=\\{null}$ means that $\\{loop%
+\_list}(\\{loop\_ptr})$
+points to a list of one-word nodes whose \\{info} fields point to the
+remaining argument values of a suffix list and expression list.
+
+\yskip\indent$\\{loop\_type}(\\{loop\_ptr})=\\{void}$ means that the current
+loop is
+`\&{forever}'.
+
+\yskip\indent$\\{loop\_type}(\\{loop\_ptr})=\|p>\\{void}$ means that $%
+\\{value}(\|p)$,
+$\\{step\_size}(\|p)$, and $\\{final\_value}(\|p)$ contain the data for an
+arithmetic
+progression.
+
+\yskip\noindent In the latter case, \|p points to a ``progression node''
+whose first word is not used. (No value could be stored there because the
+link field of words in the dynamic memory area cannot be arbitrary.)
+
+\Y\P\D \37$\\{loop\_list\_loc}(\#)\S\#+1$\C{where the \\{loop\_list} field
+resides}\par
+\P\D \37$\\{loop\_type}(\#)\S\\{info}(\\{loop\_list\_loc}(\#))$\C{the type of %
+\&{for} loop}\par
+\P\D \37$\\{loop\_list}(\#)\S\\{link}(\\{loop\_list\_loc}(\#))$\C{the remaining
+list elements}\par
+\P\D \37$\\{loop\_node\_size}=2$\C{the number of words in a loop control node}%
+\par
+\P\D \37$\\{progression\_node\_size}=4$\C{the number of words in a progression
+node}\par
+\P\D \37$\\{step\_size}(\#)\S\\{mem}[\#+2].\\{sc}$\C{the step size in an
+arithmetic progression}\par
+\P\D \37$\\{final\_value}(\#)\S\\{mem}[\#+3].\\{sc}$\C{the final value in an
+arithmetic progression}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{loop\_ptr}: \37\\{pointer};\C{top of the loop-control-node stack}\par
+\fi
+
+\M753. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{loop\_ptr}\K\\{null}$;\par
+\fi
+
+\M754. If the expressions that define an arithmetic progression in
+a \&{for} loop don't have known numeric values, the \\{bad\_for}
+subroutine screams at the user.
+
+\Y\P\4\&{procedure}\1\ \37$\\{bad\_for}(\|s:\\{str\_number})$;\2\6
+\&{begin} \37$\\{disp\_err}(\\{null},\39\.{"Improper\ "})$;\C{show the bad
+expression above the message}\6
+$\\{print}(\|s)$;\5
+$\\{print}(\.{"\ has\ been\ replaced\ by\ 0"})$;\5
+$\\{help4}(\.{"When\ you\ say\ \`for\ x=a\ step\ b\ until\ c\',"})$\6
+$(\.{"the\ initial\ value\ \`a\'\ and\ the\ step\ size\ \`b\'"})$\6
+$(\.{"and\ the\ final\ value\ \`c\'\ must\ have\ known\ numeric\ values."})$\6
+$(\.{"I\'m\ zeroing\ this\ one.\ Proceed,\ with\ fingers\ crossed."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end};\par
+\fi
+
+\M755. Here's what \MF\ does when \&{for}, \&{forsuffixes}, or \&{forever}
+has just been scanned. (This code requires slight familiarity with
+expression-parsing routines that we have not yet discussed; but it seems
+to belong in the present part of the program, even though the author
+didn't write it until later. The reader may wish to come back to it.)
+
+\Y\P\4\&{procedure}\1\ \37\\{begin\_iteration};\6
+\4\&{label} \37$\\{continue},\39\\{done},\39\\{found}$;\6
+\4\&{var} \37\|m: \37\\{halfword};\C{\\{expr\_base} (\&{for}) or \\{suffix%
+\_base} (\&{forsuffixes})}\6
+\|n: \37\\{halfword};\C{hash address of the current symbol}\6
+$\|p,\39\|q,\39\|s,\39\\{pp}$: \37\\{pointer};\C{link manipulation registers}\2%
+\6
+\&{begin} \37$\|m\K\\{cur\_mod}$;\5
+$\|n\K\\{cur\_sym}$;\5
+$\|s\K\\{get\_node}(\\{loop\_node\_size})$;\6
+\&{if} $\|m=\\{start\_forever}$ \1\&{then}\6
+\&{begin} \37$\\{loop\_type}(\|s)\K\\{void}$;\5
+$\|p\K\\{null}$;\5
+\\{get\_x\_next};\5
+\&{goto} \37\\{found};\6
+\&{end};\2\6
+\\{get\_symbol};\5
+$\|p\K\\{get\_node}(\\{token\_node\_size})$;\5
+$\\{info}(\|p)\K\\{cur\_sym}$;\5
+$\\{value}(\|p)\K\|m$;\6
+\\{get\_x\_next};\6
+\&{if} $(\\{cur\_cmd}\I\\{equals})\W(\\{cur\_cmd}\I\\{assignment})$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"="})$;\6
+$\\{help3}(\.{"The\ next\ thing\ in\ this\ loop\ should\ have\ been\ \`=\'\ or\
+\`:=\'."})$\6
+$(\.{"But\ don\'t\ worry;\ I\'ll\ pretend\ that\ an\ equals\ sign"})$\6
+$(\.{"was\ present,\ and\ I\'ll\ look\ for\ the\ values\ next."})$;\6
+\\{back\_error};\6
+\&{end};\2\6
+\X764:Scan the values to be used in the loop\X;\6
+\4\\{found}: \37\X756:Check for the presence of a colon\X;\6
+\X758:Scan the loop text and put it on the loop control stack\X;\6
+\\{resume\_iteration};\6
+\&{end};\par
+\fi
+
+\M756. \P$\X756:Check for the presence of a colon\X\S$\6
+\&{if} $\\{cur\_cmd}\I\\{colon}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{":"})$;\6
+$\\{help3}(\.{"The\ next\ thing\ in\ this\ loop\ should\ have\ been\ a\ \`:%
+\'."})$\6
+$(\.{"So\ I\'ll\ pretend\ that\ a\ colon\ was\ present;"})$\6
+$(\.{"everything\ from\ here\ to\ \`endfor\'\ will\ be\ iterated."})$;\5
+\\{back\_error};\6
+\&{end}\2\par
+\U755.\fi
+
+\M757. We append a special \\{frozen\_repeat\_loop} token in place of the
+`\&{endfor}' at the end of the loop. This will come through \MF's scanner
+at the proper time to cause the loop to be repeated.
+
+(If the user tries some shenanigan like `\&{for} $\ldots$ \&{let} \&{endfor}',
+he will be foiled by the \\{get\_symbol} routine, which keeps frozen
+tokens unchanged. Furthermore the \\{frozen\_repeat\_loop} is an \&{outer}
+token, so it won't be lost accidentally.)
+
+\fi
+
+\M758. \P$\X758:Scan the loop text and put it on the loop control stack\X\S$\6
+$\|q\K\\{get\_avail}$;\5
+$\\{info}(\|q)\K\\{frozen\_repeat\_loop}$;\5
+$\\{scanner\_status}\K\\{loop\_defining}$;\5
+$\\{warning\_info}\K\|n$;\5
+$\\{info}(\|s)\K\\{scan\_toks}(\\{iteration},\39\|p,\39\|q,\390)$;\5
+$\\{scanner\_status}\K\\{normal}$;\6
+$\\{link}(\|s)\K\\{loop\_ptr}$;\5
+$\\{loop\_ptr}\K\|s$\par
+\U755.\fi
+
+\M759. \P$\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}%
+\S$\6
+$\\{eq\_type}(\\{frozen\_repeat\_loop})\K\\{repeat\_loop}+\\{outer\_tag}$;\5
+$\\{text}(\\{frozen\_repeat\_loop})\K\.{"\ ENDFOR"}$;\par
+\fi
+
+\M760. The loop text is inserted into \MF's scanning apparatus by the
+\\{resume\_iteration} routine.
+
+\Y\P\4\&{procedure}\1\ \37\\{resume\_iteration};\6
+\4\&{label} \37$\\{not\_found},\39\\{exit}$;\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{link registers}\2\6
+\&{begin} \37$\|p\K\\{loop\_type}(\\{loop\_ptr})$;\6
+\&{if} $\|p>\\{void}$ \1\&{then}\C{\|p points to a progression node}\6
+\&{begin} \37$\\{cur\_exp}\K\\{value}(\|p)$;\6
+\&{if} $\X761:The arithmetic progression has ended\X$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\\{cur\_type}\K\\{known}$;\5
+$\|q\K\\{stash\_cur\_exp}$;\C{make \|q an \&{expr} argument}\6
+$\\{value}(\|p)\K\\{cur\_exp}+\\{step\_size}(\|p)$;\C{set $\\{value}(\|p)$ for
+the next iteration}\6
+\&{end}\6
+\4\&{else} \&{if} $\|p<\\{void}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{loop\_list}(\\{loop\_ptr})$;\6
+\&{if} $\|p=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\\{loop\_list}(\\{loop\_ptr})\K\\{link}(\|p)$;\5
+$\|q\K\\{info}(\|p)$;\5
+$\\{free\_avail}(\|p)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{begin\_token\_list}(\\{info}(\\{loop\_ptr}),\39%
+\\{forever\_text})$;\5
+\&{return};\6
+\&{end};\2\2\6
+$\\{begin\_token\_list}(\\{info}(\\{loop\_ptr}),\39\\{loop\_text})$;\5
+$\\{stack\_argument}(\|q)$;\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>\\{unity}$ \1\&{then}\5
+\X762:Trace the start of a loop\X;\2\6
+\&{return};\6
+\4\\{not\_found}: \37\\{stop\_iteration};\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M761. \P$\X761:The arithmetic progression has ended\X\S$\6
+$((\\{step\_size}(\|p)>0)\W(\\{cur\_exp}>\\{final\_value}(\|p)))\V\30((\\{step%
+\_size}(\|p)<0)\W(\\{cur\_exp}<\\{final\_value}(\|p)))$\par
+\U760.\fi
+
+\M762. \P$\X762:Trace the start of a loop\X\S$\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{loop\ value="})$;\6
+\&{if} $(\|q\I\\{null})\W(\\{link}(\|q)=\\{void})$ \1\&{then}\5
+$\\{print\_exp}(\|q,\391)$\6
+\4\&{else} $\\{show\_token\_list}(\|q,\39\\{null},\3950,\390)$;\2\6
+$\\{print\_char}(\.{"\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\par
+\U760.\fi
+
+\M763. A level of loop control disappears when \\{resume\_iteration} has
+decided
+not to resume, or when an \&{exitif} construction has removed the loop text
+from the input stack.
+
+\Y\P\4\&{procedure}\1\ \37\\{stop\_iteration};\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{the usual}\2\6
+\&{begin} \37$\|p\K\\{loop\_type}(\\{loop\_ptr})$;\6
+\&{if} $\|p>\\{void}$ \1\&{then}\5
+$\\{free\_node}(\|p,\39\\{progression\_node\_size})$\6
+\4\&{else} \&{if} $\|p<\\{void}$ \1\&{then}\6
+\&{begin} \37$\|q\K\\{loop\_list}(\\{loop\_ptr})$;\6
+\&{while} $\|q\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\|p\K\\{info}(\|q)$;\6
+\&{if} $\|p\I\\{null}$ \1\&{then}\6
+\&{if} $\\{link}(\|p)=\\{void}$ \1\&{then}\C{it's an \&{expr} parameter}\6
+\&{begin} \37$\\{recycle\_value}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\6
+\&{end}\6
+\4\&{else} $\\{flush\_token\_list}(\|p)$;\C{it's a \&{suffix} or \&{text}
+parameter}\2\2\6
+$\|p\K\|q$;\5
+$\|q\K\\{link}(\|q)$;\5
+$\\{free\_avail}(\|p)$;\6
+\&{end};\2\6
+\&{end};\2\2\6
+$\|p\K\\{loop\_ptr}$;\5
+$\\{loop\_ptr}\K\\{link}(\|p)$;\5
+$\\{flush\_token\_list}(\\{info}(\|p))$;\5
+$\\{free\_node}(\|p,\39\\{loop\_node\_size})$;\6
+\&{end};\par
+\fi
+
+\M764. Now that we know all about loop control, we can finish up
+the missing portion of \\{begin\_iteration} and we'll be done.
+
+The following code is performed after the `\.=' has been scanned in
+a \&{for} construction (if $\|m=\\{expr\_base}$) or a \&{forsuffixes}
+construction
+(if $\|m=\\{suffix\_base}$).
+
+\Y\P$\4\X764:Scan the values to be used in the loop\X\S$\6
+$\\{loop\_type}(\|s)\K\\{null}$;\5
+$\|q\K\\{loop\_list\_loc}(\|s)$;\5
+$\\{link}(\|q)\K\\{null}$;\C{$\\{link}(\|q)=\\{loop\_list}(\|s)$}\6
+\1\&{repeat} \37\\{get\_x\_next};\6
+\&{if} $\|m\I\\{expr\_base}$ \1\&{then}\5
+\\{scan\_suffix}\6
+\4\&{else} \&{begin} \37\&{if} $\\{cur\_cmd}\G\\{colon}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}\L\\{comma}$ \1\&{then}\5
+\&{goto} \37\\{continue};\2\2\6
+\\{scan\_expression};\6
+\&{if} $\\{cur\_cmd}=\\{step\_token}$ \1\&{then}\6
+\&{if} $\|q=\\{loop\_list\_loc}(\|s)$ \1\&{then}\5
+\X765:Prepare for step-until construction and \&{goto} \\{done}\X;\2\2\6
+$\\{cur\_exp}\K\\{stash\_cur\_exp}$;\6
+\&{end};\2\6
+$\\{link}(\|q)\K\\{get\_avail}$;\5
+$\|q\K\\{link}(\|q)$;\5
+$\\{info}(\|q)\K\\{cur\_exp}$;\5
+$\\{cur\_type}\K\\{vacuous}$;\6
+\4\\{continue}: \37\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$;\2\6
+\4\\{done}: \37\par
+\U755.\fi
+
+\M765. \P$\X765:Prepare for step-until construction and \&{goto} \\{done}\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+$\\{bad\_for}(\.{"initial\ value"})$;\2\6
+$\\{pp}\K\\{get\_node}(\\{progression\_node\_size})$;\5
+$\\{value}(\\{pp})\K\\{cur\_exp}$;\6
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+$\\{bad\_for}(\.{"step\ size"})$;\2\6
+$\\{step\_size}(\\{pp})\K\\{cur\_exp}$;\6
+\&{if} $\\{cur\_cmd}\I\\{until\_token}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"until"})$;\6
+$\\{help2}(\.{"I\ assume\ you\ meant\ to\ say\ \`until\'\ after\ \`step\'."})$\6
+$(\.{"So\ I\'ll\ look\ for\ the\ final\ value\ and\ colon\ next."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+$\\{bad\_for}(\.{"final\ value"})$;\2\6
+$\\{final\_value}(\\{pp})\K\\{cur\_exp}$;\5
+$\\{loop\_type}(\|s)\K\\{pp}$;\5
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U764.\fi
+
+\N766. \[38] File names.
+It's time now to fret about file names. Besides the fact that different
+operating systems treat files in different ways, we must cope with the
+fact that completely different naming conventions are used by different
+groups of people. The following programs show what is required for one
+particular operating system; similar routines for other systems are not
+difficult to devise.
+
+\MF\ assumes that a file name has three parts: the name proper; its
+``extension''; and a ``file area'' where it is found in an external file
+system. The extension of an input file is assumed to be
+`\.{.mf}' unless otherwise specified; it is `\.{.log}' on the
+transcript file that records each run of \MF; it is `\.{.tfm}' on the font
+metric files that describe characters in the fonts \MF\ creates; it is
+`\.{.gf}' on the output files that specify generic font information; and it
+is `\.{.base}' on the base files written by \.{INIMF} to initialize \MF.
+The file area can be arbitrary on input files, but files are usually
+output to the user's current area. If an input file cannot be
+found on the specified area, \MF\ will look for it on a special system
+area; this special area is intended for commonly used input files.
+
+Simple uses of \MF\ refer only to file names that have no explicit
+extension or area. For example, a person usually says `\.{input} \.{cmr10}'
+instead of `\.{input} \.{cmr10.new}'. Simple file
+names are best, because they make the \MF\ source files portable;
+whenever a file name consists entirely of letters and digits, it should be
+treated in the same way by all implementations of \MF. However, users
+need the ability to refer to other files in their environment, especially
+when responding to error messages concerning unopenable files; therefore
+we want to let them use the syntax that appears in their favorite
+operating system.
+
+\fi
+
+\M767. \MF\ uses the same conventions that have proved to be satisfactory for
+\TeX. In order to isolate the system-dependent aspects of file names, the
+system-independent parts of \MF\ are expressed in terms
+of three system-dependent
+procedures called \\{begin\_name}, \\{more\_name}, and \\{end\_name}. In
+essence, if the user-specified characters of the file name are $c_1\ldots c_n$,
+the system-independent driver program does the operations
+$$\\{begin\_name};\,\\{more\_name}(c_1);\,\ldots\,;\\{more\_name}(c_n);
+\,\\{end\_name}.$$
+These three procedures communicate with each other via global variables.
+Afterwards the file name will appear in the string pool as three strings
+called \\{cur\_name}\penalty10000\hskip-.05em,
+\\{cur\_area}, and \\{cur\_ext}; the latter two are null (i.e.,
+\.{""}), unless they were explicitly specified by the user.
+
+Actually the situation is slightly more complicated, because \MF\ needs
+to know when the file name ends. The \\{more\_name} routine is a function
+(with side effects) that returns \\{true} on the calls \\{more\_name}$(c_1)$,
+\dots, \\{more\_name}$(c_{n-1})$. The final call \\{more\_name}$(c_n)$
+returns \\{false}; or, it returns \\{true} and $c_n$ is the last character
+on the current input line. In other words,
+\\{more\_name} is supposed to return \\{true} unless it is sure that the
+file name has been completely scanned; and \\{end\_name} is supposed to be able
+to finish the assembly of \\{cur\_name}, \\{cur\_area}, and \\{cur\_ext}
+regardless of
+whether $\\{more\_name}(c_n)$ returned \\{true} or \\{false}.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{cur\_name}: \37\\{str\_number};\C{name of file just scanned}\6
+\4\\{cur\_area}: \37\\{str\_number};\C{file area just scanned, or \.{""}}\6
+\4\\{cur\_ext}: \37\\{str\_number};\C{file extension just scanned, or \.{""}}%
+\par
+\fi
+
+\M768. The file names we shall deal with for illustrative purposes have the
+following structure: If the name contains `\.>' or `\.:', the file area
+consists of all characters up to and including the final such character;
+otherwise the file area is null. If the remaining file name contains
+`\..', the file extension consists of all such characters from the first
+remaining `\..' to the end, otherwise the file extension is null.
+
+We can scan such file names easily by using two global variables that keep
+track
+of the occurrences of area and extension delimiters:
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{area\_delimiter}: \37\\{pool\_pointer};\C{the most recent `\.>' or `\.:',
+if any}\6
+\4\\{ext\_delimiter}: \37\\{pool\_pointer};\C{the relevant `\..', if any}\par
+\fi
+
+\M769. Input files that can't be found in the user's area may appear in a
+standard
+system area called \\{MF\_area}.
+This system area name will, of course, vary from place to place.
+
+\Y\P\D \37$\\{MF\_area}\S\.{"MFinputs:"}$\par
+\fi
+
+\M770. Here now is the first of the system-dependent routines for file name
+scanning.
+
+\Y\P\4\&{procedure}\1\ \37\\{begin\_name};\2\6
+\&{begin} \37$\\{area\_delimiter}\K0$;\5
+$\\{ext\_delimiter}\K0$;\6
+\&{end};\par
+\fi
+
+\M771. And here's the second.
+
+\Y\P\4\&{function}\1\ \37$\\{more\_name}(\|c:\\{ASCII\_code})$: \37%
+\\{boolean};\2\6
+\&{begin} \37\&{if} $\|c=\.{"\ "}$ \1\&{then}\5
+$\\{more\_name}\K\\{false}$\6
+\4\&{else} \&{begin} \37\&{if} $(\|c=\.{">"})\V(\|c=\.{":"})$ \1\&{then}\6
+\&{begin} \37$\\{area\_delimiter}\K\\{pool\_ptr}$;\5
+$\\{ext\_delimiter}\K0$;\6
+\&{end}\6
+\4\&{else} \&{if} $(\|c=\.{"."})\W(\\{ext\_delimiter}=0)$ \1\&{then}\5
+$\\{ext\_delimiter}\K\\{pool\_ptr}$;\2\2\6
+$\\{str\_room}(1)$;\5
+$\\{append\_char}(\|c)$;\C{contribute \|c to the current string}\6
+$\\{more\_name}\K\\{true}$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M772. The third.
+
+\Y\P\4\&{procedure}\1\ \37\\{end\_name};\2\6
+\&{begin} \37\&{if} $\\{str\_ptr}+3>\\{max\_str\_ptr}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{str\_ptr}+3>\\{max\_strings}$ \1\&{then}\5
+$\\{overflow}(\.{"number\ of\ strings"},\39\\{max\_strings}-\\{init\_str%
+\_ptr})$;\2\6
+$\\{max\_str\_ptr}\K\\{str\_ptr}+3$;\6
+\&{end};\2\6
+\&{if} $\\{area\_delimiter}=0$ \1\&{then}\5
+$\\{cur\_area}\K\.{""}$\6
+\4\&{else} \&{begin} \37$\\{cur\_area}\K\\{str\_ptr}$;\5
+$\\{incr}(\\{str\_ptr})$;\5
+$\\{str\_start}[\\{str\_ptr}]\K\\{area\_delimiter}+1$;\6
+\&{end};\2\6
+\&{if} $\\{ext\_delimiter}=0$ \1\&{then}\6
+\&{begin} \37$\\{cur\_ext}\K\.{""}$;\5
+$\\{cur\_name}\K\\{make\_string}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{cur\_name}\K\\{str\_ptr}$;\5
+$\\{incr}(\\{str\_ptr})$;\5
+$\\{str\_start}[\\{str\_ptr}]\K\\{ext\_delimiter}$;\5
+$\\{cur\_ext}\K\\{make\_string}$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M773. Conversely, here is a routine that takes three strings and prints a file
+name that might have produced them. (The routine is system dependent, because
+some operating systems put the file area last instead of first.)
+
+\Y\P$\4\X57:Basic printing procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_file\_name}(\|n,\39\|a,\39\|e:\\{integer})$;%
+\2\6
+\&{begin} \37$\\{slow\_print}(\|a)$;\5
+$\\{slow\_print}(\|n)$;\5
+$\\{slow\_print}(\|e)$;\6
+\&{end};\par
+\fi
+
+\M774. Another system-dependent routine is needed to convert three internal
+\MF\ strings
+to the \\{name\_of\_file} value that is used to open files. The present code
+allows both lowercase and uppercase letters in the file name.
+
+\Y\P\D \37$\\{append\_to\_name}(\#)\S$\1\6
+\&{begin} \37$\|c\K\#$;\5
+$\\{incr}(\|k)$;\6
+\&{if} $\|k\L\\{file\_name\_size}$ \1\&{then}\5
+$\\{name\_of\_file}[\|k]\K\\{xchr}[\|c]$;\2\6
+\&{end}\2\par
+\Y\P\4\&{procedure}\1\ \37$\\{pack\_file\_name}(\|n,\39\|a,\39\|e:\\{str%
+\_number})$;\6
+\4\&{var} \37\|k: \37\\{integer};\C{number of positions filled in \\{name\_of%
+\_file}}\6
+\|c: \37\\{ASCII\_code};\C{character being packed}\6
+\|j: \37\\{pool\_pointer};\C{index into \\{str\_pool}}\2\6
+\&{begin} \37$\|k\K0$;\6
+\&{for} $\|j\K\\{str\_start}[\|a]\mathrel{\&{to}}\\{str\_start}[\|a+1]-1$ \1%
+\&{do}\5
+$\\{append\_to\_name}(\\{so}(\\{str\_pool}[\|j]))$;\2\6
+\&{for} $\|j\K\\{str\_start}[\|n]\mathrel{\&{to}}\\{str\_start}[\|n+1]-1$ \1%
+\&{do}\5
+$\\{append\_to\_name}(\\{so}(\\{str\_pool}[\|j]))$;\2\6
+\&{for} $\|j\K\\{str\_start}[\|e]\mathrel{\&{to}}\\{str\_start}[\|e+1]-1$ \1%
+\&{do}\5
+$\\{append\_to\_name}(\\{so}(\\{str\_pool}[\|j]))$;\2\6
+\&{if} $\|k\L\\{file\_name\_size}$ \1\&{then}\5
+$\\{name\_length}\K\|k$\ \&{else} $\\{name\_length}\K\\{file\_name\_size}$;\2\6
+\&{for} $\|k\K\\{name\_length}+1\mathrel{\&{to}}\\{file\_name\_size}$ \1\&{do}\5
+$\\{name\_of\_file}[\|k]\K\.{\'\ \'}$;\2\6
+\&{end};\par
+\fi
+
+\M775. A messier routine is also needed, since base file names must be scanned
+before \MF's string mechanism has been initialized. We shall use the
+global variable \\{MF\_base\_default} to supply the text for default system
+areas
+and extensions related to base files.
+
+\Y\P\D \37$\\{base\_default\_length}=18$\C{length of the \\{MF\_base\_default}
+string}\par
+\P\D \37$\\{base\_area\_length}=8$\C{length of its area part}\par
+\P\D \37$\\{base\_ext\_length}=5$\C{length of its `\.{.base}' part}\par
+\P\D \37$\\{base\_extension}=\.{".base"}$\C{the extension, as a \.{WEB}
+constant}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{MF\_base\_default}: \37\&{packed} \37\&{array} $[1\to\\{base\_default%
+\_length}]$ \1\&{of}\5
+\\{char};\2\par
+\fi
+
+\M776. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{MF\_base\_default}\K\.{\'MFbases:plain.base\'}$;\par
+\fi
+
+\M777. \P$\X14:Check the ``constant'' values for consistency\X\mathrel{+}\S$\6
+\&{if} $\\{base\_default\_length}>\\{file\_name\_size}$ \1\&{then}\5
+$\\{bad}\K41$;\2\par
+\fi
+
+\M778. Here is the messy routine that was just mentioned. It sets \\{name\_of%
+\_file}
+from the first \|n characters of \\{MF\_base\_default}, followed by
+$\\{buffer}[\|a\to\|b]$, followed by the last \\{base\_ext\_length} characters
+of
+\\{MF\_base\_default}.
+
+We dare not give error messages here, since \MF\ calls this routine before
+the \\{error} routine is ready to roll. Instead, we simply drop excess
+characters,
+since the error will be detected in another way when a strange file name
+isn't found.
+
+\Y\P\4\&{procedure}\1\ \37$\\{pack\_buffered\_name}(\|n:\\{small\_number};\,%
+\35\|a,\39\|b:\\{integer})$;\6
+\4\&{var} \37\|k: \37\\{integer};\C{number of positions filled in \\{name\_of%
+\_file}}\6
+\|c: \37\\{ASCII\_code};\C{character being packed}\6
+\|j: \37\\{integer};\C{index into \\{buffer} or \\{MF\_base\_default}}\2\6
+\&{begin} \37\&{if} $\|n+\|b-\|a+1+\\{base\_ext\_length}>\\{file\_name\_size}$ %
+\1\&{then}\5
+$\|b\K\|a+\\{file\_name\_size}-\|n-1-\\{base\_ext\_length}$;\2\6
+$\|k\K0$;\6
+\&{for} $\|j\K1\mathrel{\&{to}}\|n$ \1\&{do}\5
+$\\{append\_to\_name}(\\{xord}[\\{MF\_base\_default}[\|j]])$;\2\6
+\&{for} $\|j\K\|a\mathrel{\&{to}}\|b$ \1\&{do}\5
+$\\{append\_to\_name}(\\{buffer}[\|j])$;\2\6
+\&{for} $\|j\K\\{base\_default\_length}-\\{base\_ext\_length}+1\mathrel{\&{to}}%
+\\{base\_default\_length}$ \1\&{do}\5
+$\\{append\_to\_name}(\\{xord}[\\{MF\_base\_default}[\|j]])$;\2\6
+\&{if} $\|k\L\\{file\_name\_size}$ \1\&{then}\5
+$\\{name\_length}\K\|k$\ \&{else} $\\{name\_length}\K\\{file\_name\_size}$;\2\6
+\&{for} $\|k\K\\{name\_length}+1\mathrel{\&{to}}\\{file\_name\_size}$ \1\&{do}\5
+$\\{name\_of\_file}[\|k]\K\.{\'\ \'}$;\2\6
+\&{end};\par
+\fi
+
+\M779. Here is the only place we use \\{pack\_buffered\_name}. This part of the
+program
+becomes active when a ``virgin'' \MF\ is trying to get going, just after
+the preliminary initialization, or when the user is substituting another
+base file by typing `\.\&' after the initial `\.{**}' prompt. The buffer
+contains the first line of input in $\\{buffer}[\\{loc}\to(\\{last}-1)]$, where
+$\\{loc}<\\{last}$ and $\\{buffer}[\\{loc}]\I\.{"\ "}$.
+
+\Y\P$\4\X779:Declare the function called \\{open\_base\_file}\X\S$\6
+\4\&{function}\1\ \37\\{open\_base\_file}: \37\\{boolean};\6
+\4\&{label} \37$\\{found},\39\\{exit}$;\6
+\4\&{var} \37\|j: \37$0\to\\{buf\_size}$;\C{the first space after the file
+name}\2\6
+\&{begin} \37$\|j\K\\{loc}$;\6
+\&{if} $\\{buffer}[\\{loc}]=\.{"\&"}$ \1\&{then}\6
+\&{begin} \37$\\{incr}(\\{loc})$;\5
+$\|j\K\\{loc}$;\5
+$\\{buffer}[\\{last}]\K\.{"\ "}$;\6
+\&{while} $\\{buffer}[\|j]\I\.{"\ "}$ \1\&{do}\5
+$\\{incr}(\|j)$;\2\6
+$\\{pack\_buffered\_name}(0,\39\\{loc},\39\|j-1)$;\C{try first without the
+system file area}\6
+\&{if} $\\{w\_open\_in}(\\{base\_file})$ \1\&{then}\5
+\&{goto} \37\\{found};\2\6
+$\\{pack\_buffered\_name}(\\{base\_area\_length},\39\\{loc},\39\|j-1)$;\C{now
+try the system base file area}\6
+\&{if} $\\{w\_open\_in}(\\{base\_file})$ \1\&{then}\5
+\&{goto} \37\\{found};\2\6
+\\{wake\_up\_terminal};\5
+$\\{wterm\_ln}(\.{\'Sorry,\ I\ can\'}\.{\'t\ find\ that\ base;\'},\39\.{\'\
+will\ try\ PLAIN.\'})$;\5
+\\{update\_terminal};\6
+\&{end};\C{now pull out all the stops: try for the system \.{plain} file}\2\6
+$\\{pack\_buffered\_name}(\\{base\_default\_length}-\\{base\_ext\_length},\391,%
+\390)$;\6
+\&{if} $\R\\{w\_open\_in}(\\{base\_file})$ \1\&{then}\6
+\&{begin} \37\\{wake\_up\_terminal};\5
+$\\{wterm\_ln}(\.{\'I\ can\'}\.{\'t\ find\ the\ PLAIN\ base\ file!\'})$;\5
+$\\{open\_base\_file}\K\\{false}$;\5
+\&{return};\6
+\&{end};\2\6
+\4\\{found}: \37$\\{loc}\K\|j$;\5
+$\\{open\_base\_file}\K\\{true}$;\6
+\4\\{exit}: \37\&{end};\par
+\U1187.\fi
+
+\M780. Operating systems often make it possible to determine the exact name
+(and
+possible version number) of a file that has been opened. The following routine,
+which simply makes a \MF\ string from the value of \\{name\_of\_file}, should
+ideally be changed to deduce the full name of file~\|f, which is the file
+most recently opened, if it is possible to do this in a \PASCAL\ program.
+
+This routine might be called after string memory has overflowed, hence
+we dare not use `\\{str\_room}'.
+
+\Y\P\4\&{function}\1\ \37\\{make\_name\_string}: \37\\{str\_number};\6
+\4\&{var} \37\|k: \37$1\to\\{file\_name\_size}$;\C{index into \\{name\_of%
+\_file}}\2\6
+\&{begin} \37\&{if} $(\\{pool\_ptr}+\\{name\_length}>\\{pool\_size})\V(\\{str%
+\_ptr}=\\{max\_strings})$ \1\&{then}\5
+$\\{make\_name\_string}\K\.{"?"}$\6
+\4\&{else} \&{begin} \37\&{for} $\|k\K1\mathrel{\&{to}}\\{name\_length}$ \1%
+\&{do}\5
+$\\{append\_char}(\\{xord}[\\{name\_of\_file}[\|k]])$;\2\6
+$\\{make\_name\_string}\K\\{make\_string}$;\6
+\&{end};\2\6
+\&{end};\6
+\4\&{function}\1\ \37$\\{a\_make\_name\_string}(\mathop{\&{var}}\|f:\\{alpha%
+\_file})$: \37\\{str\_number};\2\6
+\&{begin} \37$\\{a\_make\_name\_string}\K\\{make\_name\_string}$;\6
+\&{end};\6
+\4\&{function}\1\ \37$\\{b\_make\_name\_string}(\mathop{\&{var}}\|f:\\{byte%
+\_file})$: \37\\{str\_number};\2\6
+\&{begin} \37$\\{b\_make\_name\_string}\K\\{make\_name\_string}$;\6
+\&{end};\6
+\4\&{function}\1\ \37$\\{w\_make\_name\_string}(\mathop{\&{var}}\|f:\\{word%
+\_file})$: \37\\{str\_number};\2\6
+\&{begin} \37$\\{w\_make\_name\_string}\K\\{make\_name\_string}$;\6
+\&{end};\par
+\fi
+
+\M781. Now let's consider the ``driver''
+routines by which \MF\ deals with file names
+in a system-independent manner. First comes a procedure that looks for a
+file name in the input by taking the information from the input buffer.
+(We can't use \\{get\_next}, because the conversion to tokens would
+destroy necessary information.)
+
+This procedure doesn't allow semicolons or percent signs to be part of
+file names, because of other conventions of \MF. The manual doesn't
+use semicolons or percents immediately after file names, but some users
+no doubt will find it natural to do so; therefore system-dependent
+changes to allow such characters in file names should probably
+be made with reluctance, and only when an entire file name that
+includes special characters is ``quoted'' somehow.
+
+\Y\P\4\&{procedure}\1\ \37\\{scan\_file\_name};\6
+\4\&{label} \37\\{done};\2\6
+\&{begin} \37\\{begin\_name};\6
+\&{while} $\\{buffer}[\\{loc}]=\.{"\ "}$ \1\&{do}\5
+$\\{incr}(\\{loc})$;\2\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $(\\{buffer}[\\{loc}]=\.{";"})\V(\\{buffer}[%
+\\{loc}]=\.{"\%"})$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\R\\{more\_name}(\\{buffer}[\\{loc}])$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{incr}(\\{loc})$;\6
+\&{end};\2\6
+\4\\{done}: \37\\{end\_name};\6
+\&{end};\par
+\fi
+
+\M782. The global variable \\{job\_name} contains the file name that was first
+\&{input} by the user. This name is extended by `\.{.log}' and `\.{.gf}' and
+`\.{.base}' and `\.{.tfm}' in the names of \MF's output files.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{job\_name}: \37\\{str\_number};\C{principal file name}\6
+\4\\{log\_opened}: \37\\{boolean};\C{has the transcript file been opened?}\6
+\4\\{log\_name}: \37\\{str\_number};\C{full name of the log file}\par
+\fi
+
+\M783. Initially $\\{job\_name}=0$; it becomes nonzero as soon as the true name
+is known.
+We have $\\{job\_name}=0$ if and only if the `\.{log}' file has not been
+opened,
+except of course for a short time just after \\{job\_name} has become nonzero.
+
+\Y\P$\4\X55:Initialize the output routines\X\mathrel{+}\S$\6
+$\\{job\_name}\K0$;\5
+$\\{log\_opened}\K\\{false}$;\par
+\fi
+
+\M784. Here is a routine that manufactures the output file names, assuming that
+$\\{job\_name}\I0$. It ignores and changes the current settings of \\{cur%
+\_area}
+and \\{cur\_ext}.
+
+\Y\P\D \37$\\{pack\_cur\_name}\S\\{pack\_file\_name}(\\{cur\_name},\39\\{cur%
+\_area},\39\\{cur\_ext})$\par
+\Y\P\4\&{procedure}\1\ \37$\\{pack\_job\_name}(\|s:\\{str\_number})$;\C{$\|s=%
+\.{".log"}$, \.{".gf"}, \.{".tfm"}, or \\{base\_extension}}\2\6
+\&{begin} \37$\\{cur\_area}\K\.{""}$;\5
+$\\{cur\_ext}\K\|s$;\5
+$\\{cur\_name}\K\\{job\_name}$;\5
+\\{pack\_cur\_name};\6
+\&{end};\par
+\fi
+
+\M785. Actually the main output file extension is usually something like
+\.{".300gf"} instead of just \.{".gf"}; the additional number indicates the
+resolution in pixels per inch, based on the setting of \\{hppp} when
+the file is opened.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{gf\_ext}: \37\\{str\_number};\C{default extension for the output file}\par
+\fi
+
+\M786. If some trouble arises when \MF\ tries to open a file, the following
+routine calls upon the user to supply another file name. Parameter~\|s
+is used in the error message to identify the type of file; parameter~\|e
+is the default extension if none is given. Upon exit from the routine,
+variables \\{cur\_name}, \\{cur\_area}, \\{cur\_ext}, and \\{name\_of\_file}
+are
+ready for another attempt at file opening.
+
+\Y\P\4\&{procedure}\1\ \37$\\{prompt\_file\_name}(\|s,\39\|e:\\{str%
+\_number})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|k: \37$0\to\\{buf\_size}$;\C{index into \\{buffer}}\2\6
+\&{begin} \37\&{if} $\\{interaction}=\\{scroll\_mode}$ \1\&{then}\5
+\\{wake\_up\_terminal};\2\6
+\&{if} $\|s=\.{"input\ file\ name"}$ \1\&{then}\5
+$\\{print\_err}(\.{"I\ can\'t\ find\ file\ \`"})$\6
+\4\&{else} $\\{print\_err}(\.{"I\ can\'t\ write\ on\ file\ \`"})$;\2\6
+$\\{print\_file\_name}(\\{cur\_name},\39\\{cur\_area},\39\\{cur\_ext})$;\5
+$\\{print}(\.{"\'."})$;\6
+\&{if} $\|e=\.{".mf"}$ \1\&{then}\5
+\\{show\_context};\2\6
+$\\{print\_nl}(\.{"Please\ type\ another\ "})$;\5
+$\\{print}(\|s)$;\6
+\&{if} $\\{interaction}<\\{scroll\_mode}$ \1\&{then}\5
+$\\{fatal\_error}(\.{"***\ (job\ aborted,\ file\ error\ in\ nonstop\ mode)"})$;%
+\2\6
+\\{clear\_terminal};\5
+$\\{prompt\_input}(\.{":\ "})$;\5
+\X787:Scan file name in the buffer\X;\6
+\&{if} $\\{cur\_ext}=\.{""}$ \1\&{then}\5
+$\\{cur\_ext}\K\|e$;\2\6
+\\{pack\_cur\_name};\6
+\&{end};\par
+\fi
+
+\M787. \P$\X787:Scan file name in the buffer\X\S$\6
+\&{begin} \37\\{begin\_name};\5
+$\|k\K\\{first}$;\6
+\&{while} $(\\{buffer}[\|k]=\.{"\ "})\W(\|k<\\{last})$ \1\&{do}\5
+$\\{incr}(\|k)$;\2\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\|k=\\{last}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\R\\{more\_name}(\\{buffer}[\|k])$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\\{incr}(\|k)$;\6
+\&{end};\2\6
+\4\\{done}: \37\\{end\_name};\6
+\&{end}\par
+\U786.\fi
+
+\M788. The \\{open\_log\_file} routine is used to open the transcript file and
+to help
+it catch up to what has previously been printed on the terminal.
+
+\Y\P\4\&{procedure}\1\ \37\\{open\_log\_file};\6
+\4\&{var} \37\\{old\_setting}: \37$0\to\\{max\_selector}$;\C{previous %
+\\{selector} setting}\6
+\|k: \37$0\to\\{buf\_size}$;\C{index into \\{months} and \\{buffer}}\6
+\|l: \37$0\to\\{buf\_size}$;\C{end of first input line}\6
+\|m: \37\\{integer};\C{the current month}\6
+\\{months}: \37\&{packed} \37\&{array} $[1\to36]$ \1\&{of}\5
+\\{char};\C{abbreviations of month names}\2\2\6
+\&{begin} \37$\\{old\_setting}\K\\{selector}$;\6
+\&{if} $\\{job\_name}=0$ \1\&{then}\5
+$\\{job\_name}\K\.{"mfput"}$;\2\6
+$\\{pack\_job\_name}(\.{".log"})$;\6
+\&{while} $\R\\{a\_open\_out}(\\{log\_file})$ \1\&{do}\5
+\X789:Try to get a different log file name\X;\2\6
+$\\{log\_name}\K\\{a\_make\_name\_string}(\\{log\_file})$;\5
+$\\{selector}\K\\{log\_only}$;\5
+$\\{log\_opened}\K\\{true}$;\5
+\X790:Print the banner line, including the date and time\X;\6
+$\\{input\_stack}[\\{input\_ptr}]\K\\{cur\_input}$;\C{make sure bottom level is
+in memory}\6
+$\\{print\_nl}(\.{"**"})$;\5
+$\|l\K\\{input\_stack}[0].\\{limit\_field}-1$;\C{last position of first line}\6
+\&{for} $\|k\K1\mathrel{\&{to}}\|l$ \1\&{do}\5
+$\\{print}(\\{buffer}[\|k])$;\2\6
+\\{print\_ln};\C{now the transcript file contains the first line of input}\6
+$\\{selector}\K\\{old\_setting}+2$;\C{\\{log\_only} or \\{term\_and\_log}}\6
+\&{end};\par
+\fi
+
+\M789. Sometimes \\{open\_log\_file} is called at awkward moments when \MF\ is
+unable to print error messages or even to \\{show\_context}.
+The \\{prompt\_file\_name} routine can result in a \\{fatal\_error}, but the %
+\\{error}
+routine will not be invoked because \\{log\_opened} will be false.
+
+The normal idea of \\{batch\_mode} is that nothing at all should be written
+on the terminal. However, in the unusual case that
+no log file could be opened, we make an exception and allow
+an explanatory message to be seen.
+
+Incidentally, the program always refers to the log file as a `\.{transcript
+file}', because some systems cannot use the extension `\.{.log}' for
+this file.
+
+\Y\P$\4\X789:Try to get a different log file name\X\S$\6
+\&{begin} \37$\\{selector}\K\\{term\_only}$;\5
+$\\{prompt\_file\_name}(\.{"transcript\ file\ name"},\39\.{".log"})$;\6
+\&{end}\par
+\U788.\fi
+
+\M790. \P$\X790:Print the banner line, including the date and time\X\S$\6
+\&{begin} \37$\\{wlog}(\\{banner})$;\5
+$\\{slow\_print}(\\{base\_ident})$;\5
+$\\{print}(\.{"\ \ "})$;\5
+$\\{print\_int}(\\{round\_unscaled}(\\{internal}[\\{day}]))$;\5
+$\\{print\_char}(\.{"\ "})$;\5
+$\\{months}\K\.{\'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC\'}$;\5
+$\|m\K\\{round\_unscaled}(\\{internal}[\\{month}])$;\6
+\&{for} $\|k\K3\ast\|m-2\mathrel{\&{to}}3\ast\|m$ \1\&{do}\5
+$\\{wlog}(\\{months}[\|k])$;\2\6
+$\\{print\_char}(\.{"\ "})$;\5
+$\\{print\_int}(\\{round\_unscaled}(\\{internal}[\\{year}]))$;\5
+$\\{print\_char}(\.{"\ "})$;\5
+$\|m\K\\{round\_unscaled}(\\{internal}[\\{time}])$;\5
+$\\{print\_dd}(\|m\mathbin{\&{div}}60)$;\5
+$\\{print\_char}(\.{":"})$;\5
+$\\{print\_dd}(\|m\mathbin{\&{mod}}60)$;\6
+\&{end}\par
+\U788.\fi
+
+\M791. Here's an example of how these file-name-parsing routines work in
+practice.
+We shall use the macro \\{set\_output\_file\_name} when it is time to
+crank up the output file.
+
+\Y\P\D \37$\\{set\_output\_file\_name}\S$\1\6
+\&{begin} \37\&{if} $\\{job\_name}=0$ \1\&{then}\5
+\\{open\_log\_file};\2\6
+$\\{pack\_job\_name}(\\{gf\_ext})$;\6
+\&{while} $\R\\{b\_open\_out}(\\{gf\_file})$ \1\&{do}\5
+$\\{prompt\_file\_name}(\.{"file\ name\ for\ output"},\39\\{gf\_ext})$;\2\6
+$\\{output\_file\_name}\K\\{b\_make\_name\_string}(\\{gf\_file})$;\6
+\&{end}\2\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{gf\_file}: \37\\{byte\_file};\C{the generic font output goes here}\6
+\4\\{output\_file\_name}: \37\\{str\_number};\C{full name of the output file}%
+\par
+\fi
+
+\M792. \P$\X55:Initialize the output routines\X\mathrel{+}\S$\6
+$\\{output\_file\_name}\K0$;\par
+\fi
+
+\M793. Let's turn now to the procedure that is used to initiate file reading
+when an `\.{input}' command is being processed.
+
+\Y\P\4\&{procedure}\1\ \37\\{start\_input};\C{\MF\ will \.{input} something}\6
+\4\&{label} \37\\{done};\2\6
+\&{begin} \37\X795:Put the desired file name in $(\\{cur\_name},\\{cur\_ext},%
+\\{cur\_area})$\X;\6
+\&{if} $\\{cur\_ext}=\.{""}$ \1\&{then}\5
+$\\{cur\_ext}\K\.{".mf"}$;\2\6
+\\{pack\_cur\_name};\6
+\~ \1\&{loop}\ \&{begin} \37\\{begin\_file\_reading};\C{set up \\{cur\_file}
+and new level of input}\6
+\&{if} $\\{a\_open\_in}(\\{cur\_file})$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\\{cur\_area}=\.{""}$ \1\&{then}\6
+\&{begin} \37$\\{pack\_file\_name}(\\{cur\_name},\39\\{MF\_area},\39\\{cur%
+\_ext})$;\6
+\&{if} $\\{a\_open\_in}(\\{cur\_file})$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{end};\2\6
+\\{end\_file\_reading};\C{remove the level that didn't work}\6
+$\\{prompt\_file\_name}(\.{"input\ file\ name"},\39\.{".mf"})$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{name}\K\\{a\_make\_name\_string}(\\{cur\_file})$;\5
+$\\{str\_ref}[\\{cur\_name}]\K\\{max\_str\_ref}$;\6
+\&{if} $\\{job\_name}=0$ \1\&{then}\6
+\&{begin} \37$\\{job\_name}\K\\{cur\_name}$;\5
+\\{open\_log\_file};\6
+\&{end};\C{\\{open\_log\_file} doesn't \\{show\_context}, so \\{limit} and %
+\\{loc} needn't be set to meaningful values yet}\2\6
+\&{if} $\\{term\_offset}+\\{length}(\\{name})>\\{max\_print\_line}-2$ \1%
+\&{then}\5
+\\{print\_ln}\6
+\4\&{else} \&{if} $(\\{term\_offset}>0)\V(\\{file\_offset}>0)$ \1\&{then}\5
+$\\{print\_char}(\.{"\ "})$;\2\2\6
+$\\{print\_char}(\.{"("})$;\5
+$\\{incr}(\\{open\_parens})$;\5
+$\\{slow\_print}(\\{name})$;\5
+\\{update\_terminal};\6
+\&{if} $\\{name}=\\{str\_ptr}-1$ \1\&{then}\C{we can conserve string pool space
+now}\6
+\&{begin} \37$\\{flush\_string}(\\{name})$;\5
+$\\{name}\K\\{cur\_name}$;\6
+\&{end};\2\6
+\X794:Read the first line of the new file\X;\6
+\&{end};\par
+\fi
+
+\M794. Here we have to remember to tell the \\{input\_ln} routine not to
+start with a \\{get}. If the file is empty, it is considered to
+contain a single blank line.
+
+\Y\P$\4\X794:Read the first line of the new file\X\S$\6
+\&{begin} \37$\\{line}\K1$;\6
+\&{if} $\\{input\_ln}(\\{cur\_file},\39\\{false})$ \1\&{then}\5
+\\{do\_nothing};\2\6
+\\{firm\_up\_the\_line};\5
+$\\{buffer}[\\{limit}]\K\.{"\%"}$;\5
+$\\{first}\K\\{limit}+1$;\5
+$\\{loc}\K\\{start}$;\6
+\&{end}\par
+\U793.\fi
+
+\M795. \P$\X795:Put the desired file name in $(\\{cur\_name},\\{cur\_ext},%
+\\{cur\_area})$\X\S$\6
+\&{while} $\\{token\_state}\W(\\{loc}=\\{null})$ \1\&{do}\5
+\\{end\_token\_list};\2\6
+\&{if} $\\{token\_state}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"File\ names\ can\'t\ appear\ within\
+macros"})$;\5
+$\\{help3}(\.{"Sorry...I\'ve\ converted\ what\ follows\ to\ tokens,"})$\6
+$(\.{"possibly\ garbaging\ the\ name\ you\ gave."})$\6
+$(\.{"Please\ delete\ the\ tokens\ and\ insert\ the\ name\ again."})$;\6
+\\{error};\6
+\&{end};\2\6
+\&{if} $\\{file\_state}$ \1\&{then}\5
+\\{scan\_file\_name}\6
+\4\&{else} \&{begin} \37$\\{cur\_name}\K\.{""}$;\5
+$\\{cur\_ext}\K\.{""}$;\5
+$\\{cur\_area}\K\.{""}$;\6
+\&{end}\2\par
+\U793.\fi
+
+\N796. \[39] Introduction to the parsing routines.
+We come now to the central nervous system that sparks many of \MF's activities.
+By evaluating expressions, from their primary constituents to ever larger
+subexpressions, \MF\ builds the structures that ultimately define fonts of
+type.
+
+Four mutually recursive subroutines are involved in this process: We call them
+$$\hbox{\\{scan\_primary}, \\{scan\_secondary}, \\{scan\_tertiary},
+and \\{scan\_expression}.}$$
+Each of them is parameterless and begins with the first token to be scanned
+already represented in \\{cur\_cmd}, \\{cur\_mod}, and \\{cur\_sym}. After
+execution,
+the value of the primary or secondary or tertiary or expression that was
+found will appear in the global variables \\{cur\_type} and \\{cur\_exp}. The
+token following the expression will be represented in \\{cur\_cmd}, \\{cur%
+\_mod},
+and \\{cur\_sym}.
+
+Technically speaking, the parsing algorithms are ``LL(1),'' more or less;
+backup mechanisms have been added in order to provide reasonable error
+recovery.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{cur\_type}: \37\\{small\_number};\C{the type of the expression just found}%
+\6
+\4\\{cur\_exp}: \37\\{integer};\C{the value of the expression just found}\par
+\fi
+
+\M797. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{cur\_exp}\K0$;\par
+\fi
+
+\M798. Many different kinds of expressions are possible, so it is wise to have
+precise descriptions of what \\{cur\_type} and \\{cur\_exp} mean in all cases:
+
+\smallskip\hang
+$\\{cur\_type}=\\{vacuous}$ means that this expression didn't turn out to have
+a
+value at all, because it arose from a \&{begingroup}$\,\ldots\,$\&{endgroup}
+construction in which there was no expression before the \&{endgroup}.
+In this case \\{cur\_exp} has some irrelevant value.
+
+\smallskip\hang
+$\\{cur\_type}=\\{boolean\_type}$ means that \\{cur\_exp} is either \\{true%
+\_code}
+or \\{false\_code}.
+
+\smallskip\hang
+$\\{cur\_type}=\\{unknown\_boolean}$ means that \\{cur\_exp} points to a
+capsule
+node that is in the ring of variables equivalent
+to at least one undefined boolean variable.
+
+\smallskip\hang
+$\\{cur\_type}=\\{string\_type}$ means that \\{cur\_exp} is a string number
+(i.e., an
+integer in the range $0\L\\{cur\_exp}<\\{str\_ptr}$). That string's reference
+count
+includes this particular reference.
+
+\smallskip\hang
+$\\{cur\_type}=\\{unknown\_string}$ means that \\{cur\_exp} points to a capsule
+node that is in the ring of variables equivalent
+to at least one undefined string variable.
+
+\smallskip\hang
+$\\{cur\_type}=\\{pen\_type}$ means that \\{cur\_exp} points to a pen header
+node. This
+node contains a reference count, which takes account of this particular
+reference.
+
+\smallskip\hang
+$\\{cur\_type}=\\{unknown\_pen}$ means that \\{cur\_exp} points to a capsule
+node that is in the ring of variables equivalent
+to at least one undefined pen variable.
+
+\smallskip\hang
+$\\{cur\_type}=\\{future\_pen}$ means that \\{cur\_exp} points to a knot list
+that
+should eventually be made into a pen. Nobody else points to this particular
+knot list. The \\{future\_pen} option occurs only as an output of \\{scan%
+\_primary}
+and \\{scan\_secondary}, not as an output of \\{scan\_tertiary} or \\{scan%
+\_expression}.
+
+\smallskip\hang
+$\\{cur\_type}=\\{path\_type}$ means that \\{cur\_exp} points to a the first
+node of
+a path; nobody else points to this particular path. The control points of
+the path will have been chosen.
+
+\smallskip\hang
+$\\{cur\_type}=\\{unknown\_path}$ means that \\{cur\_exp} points to a capsule
+node that is in the ring of variables equivalent
+to at least one undefined path variable.
+
+\smallskip\hang
+$\\{cur\_type}=\\{picture\_type}$ means that \\{cur\_exp} points to an edges
+header node.
+Nobody else points to this particular set of edges.
+
+\smallskip\hang
+$\\{cur\_type}=\\{unknown\_picture}$ means that \\{cur\_exp} points to a
+capsule
+node that is in the ring of variables equivalent
+to at least one undefined picture variable.
+
+\smallskip\hang
+$\\{cur\_type}=\\{transform\_type}$ means that \\{cur\_exp} points to a %
+\\{transform\_type}
+capsule node. The \\{value} part of this capsule
+points to a transform node that contains six numeric values,
+each of which is \\{independent}, \\{dependent}, \\{proto\_dependent}, or %
+\\{known}.
+
+\smallskip\hang
+$\\{cur\_type}=\\{pair\_type}$ means that \\{cur\_exp} points to a capsule
+node whose type is \\{pair\_type}. The \\{value} part of this capsule
+points to a pair node that contains two numeric values,
+each of which is \\{independent}, \\{dependent}, \\{proto\_dependent}, or %
+\\{known}.
+
+\smallskip\hang
+$\\{cur\_type}=\\{known}$ means that \\{cur\_exp} is a \\{scaled} value.
+
+\smallskip\hang
+$\\{cur\_type}=\\{dependent}$ means that \\{cur\_exp} points to a capsule node
+whose type
+is \\{dependent}. The \\{dep\_list} field in this capsule points to the
+associated
+dependency list.
+
+\smallskip\hang
+$\\{cur\_type}=\\{proto\_dependent}$ means that \\{cur\_exp} points to a %
+\\{proto\_dependent}
+capsule node . The \\{dep\_list} field in this capsule
+points to the associated dependency list.
+
+\smallskip\hang
+$\\{cur\_type}=\\{independent}$ means that \\{cur\_exp} points to a capsule
+node
+whose type is \\{independent}. This somewhat unusual case can arise, for
+example, in the expression
+`$x+\&{begingroup}\penalty0\,\&{string}\,x; 0\,\&{endgroup}$'.
+
+\smallskip\hang
+$\\{cur\_type}=\\{token\_list}$ means that \\{cur\_exp} points to a linked list
+of
+tokens. This case arises only on the left-hand side of an assignment
+(`\.{:=}') operation, under very special circumstances.
+
+\smallskip\noindent
+The possible settings of \\{cur\_type} have been listed here in increasing
+numerical order. Notice that \\{cur\_type} will never be \\{numeric\_type} or
+\\{suffixed\_macro} or \\{unsuffixed\_macro}, although variables of those types
+are allowed. Conversely, \MF\ has no variables of type \\{vacuous} or
+\\{token\_list}.
+
+\fi
+
+\M799. Capsules are two-word nodes that have a similar meaning
+to \\{cur\_type} and \\{cur\_exp}. Such nodes have $\\{name\_type}=\\{capsule}$
+and $\\{link}\L\\{void}$; and their \\{type} field is one of the possibilities
+for
+\\{cur\_type} listed above.
+
+The \\{value} field of a capsule is, in most cases, the value that
+corresponds to its \\{type}, as \\{cur\_exp} corresponds to \\{cur\_type}.
+However, when \\{cur\_exp} would point to a capsule,
+no extra layer of indirection is present; the \\{value}
+field is what would have been called $\\{value}(\\{cur\_exp})$ if it had not
+been
+encapsulated. Furthermore, if the type is \\{dependent} or
+\\{proto\_dependent}, the \\{value} field of a capsule is replaced by
+\\{dep\_list} and \\{prev\_dep} fields, since dependency lists in capsules are
+always part of the general \\{dep\_list} structure.
+
+The \\{get\_x\_next} routine is careful not to change the values of \\{cur%
+\_type}
+and \\{cur\_exp} when it gets an expanded token. However, \\{get\_x\_next}
+might
+call a macro, which might parse an expression, which might execute lots of
+commands in a group; hence it's possible that \\{cur\_type} might change
+from, say, \\{unknown\_boolean} to \\{boolean\_type}, or from \\{dependent} to
+\\{known} or \\{independent}, during the time \\{get\_x\_next} is called. The
+programs below are careful to stash sensitive intermediate results in
+capsules, so that \MF's generality doesn't cause trouble.
+
+Here's a procedure that illustrates these conventions. It takes
+the contents of $(\\{cur\_type}\kern-.3pt,\\{cur\_exp}\kern-.3pt)$
+and stashes them away in a
+capsule. It is not used when $\\{cur\_type}=\\{token\_list}$.
+After the operation, $\\{cur\_type}=\\{vacuous}$; hence there is no need to
+copy path lists or to update reference counts, etc.
+
+The special link \\{void} is put on the capsule returned by
+\\{stash\_cur\_exp}, because this procedure is used to store macro parameters
+that must be easily distinguishable from token lists.
+
+\Y\P$\4\X799:Declare the stashing/unstashing routines\X\S$\6
+\4\&{function}\1\ \37\\{stash\_cur\_exp}: \37\\{pointer};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the capsule that will be returned}\2\6
+\&{begin} \37\&{case} $\\{cur\_type}$ \1\&{of}\6
+\4$\\{unknown\_types},\39\\{transform\_type},\39\\{pair\_type},\39%
+\\{dependent},\39\\{proto\_dependent},\39\\{independent}$: \37$\|p\K\\{cur%
+\_exp}$;\6
+\4\&{othercases} \37\&{begin} \37$\|p\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{name\_type}(\|p)\K\\{capsule}$;\5
+$\\{type}(\|p)\K\\{cur\_type}$;\5
+$\\{value}(\|p)\K\\{cur\_exp}$;\6
+\&{end}\2\6
+\&{endcases};\6
+$\\{cur\_type}\K\\{vacuous}$;\5
+$\\{link}(\|p)\K\\{void}$;\5
+$\\{stash\_cur\_exp}\K\|p$;\6
+\&{end};\par
+\A800.
+\U801.\fi
+
+\M800. The inverse of \\{stash\_cur\_exp} is the following procedure, which
+deletes an unnecessary capsule and puts its contents into \\{cur\_type}
+and \\{cur\_exp}.
+
+The program steps of \MF\ can be divided into two categories: those in
+which \\{cur\_type} and \\{cur\_exp} are ``alive'' and those in which they are
+``dead,'' in the sense that \\{cur\_type} and \\{cur\_exp} contain relevant
+information or not. It's important not to ignore them when they're alive,
+and it's important not to pay attention to them when they're dead.
+
+There's also an intermediate category: If $\\{cur\_type}=\\{vacuous}$, then
+\\{cur\_exp} is irrelevant, hence we can proceed without caring if \\{cur%
+\_type}
+and \\{cur\_exp} are alive or dead. In such cases we say that \\{cur\_type}
+and \\{cur\_exp} are {\sl dormant}. It is permissible to call \\{get\_x\_next}
+only when they are alive or dormant.
+
+The \\{stash} procedure above assumes that \\{cur\_type} and \\{cur\_exp}
+are alive or dormant. The \\{unstash} procedure assumes that they are
+dead or dormant; it resuscitates them.
+
+\Y\P$\4\X799:Declare the stashing/unstashing routines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{unstash\_cur\_exp}(\|p:\\{pointer})$;\2\6
+\&{begin} \37$\\{cur\_type}\K\\{type}(\|p)$;\6
+\&{case} $\\{cur\_type}$ \1\&{of}\6
+\4$\\{unknown\_types},\39\\{transform\_type},\39\\{pair\_type},\39%
+\\{dependent},\39\\{proto\_dependent},\39\\{independent}$: \37$\\{cur\_exp}\K%
+\|p$;\6
+\4\&{othercases} \37\&{begin} \37$\\{cur\_exp}\K\\{value}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\6
+\&{end}\2\6
+\&{endcases};\6
+\&{end};\par
+\fi
+
+\M801. The following procedure prints the values of expressions in an
+abbreviated format. If its first parameter \|p is null, the value of
+$(\\{cur\_type},\\{cur\_exp})$ is displayed; otherwise \|p should be a capsule
+containing the desired value. The second parameter controls the amount of
+output. If it is~0, dependency lists will be abbreviated to
+`\.{linearform}' unless they consist of a single term. If it is greater
+than~1, complicated structures (pens, pictures, and paths) will be displayed
+in full.
+
+\Y\P$\4\X257:Declare subroutines for printing expressions\X\mathrel{+}\S$\6
+\hbox{\4}\X805:Declare the procedure called \\{print\_dp}\X\6
+\hbox{\4}\X799:Declare the stashing/unstashing routines\X\6
+\4\&{procedure}\1\ \37$\\{print\_exp}(\|p:\\{pointer};\,\35\\{verbosity}:%
+\\{small\_number})$;\6
+\4\&{var} \37\\{restore\_cur\_exp}: \37\\{boolean};\C{should \\{cur\_exp} be
+restored?}\6
+\|t: \37\\{small\_number};\C{the type of the expression}\6
+\|v: \37\\{integer};\C{the value of the expression}\6
+\|q: \37\\{pointer};\C{a big node being displayed}\2\6
+\&{begin} \37\&{if} $\|p\I\\{null}$ \1\&{then}\5
+$\\{restore\_cur\_exp}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+$\\{restore\_cur\_exp}\K\\{true}$;\6
+\&{end};\2\6
+$\|t\K\\{type}(\|p)$;\6
+\&{if} $\|t<\\{dependent}$ \1\&{then}\5
+$\|v\K\\{value}(\|p)$\ \&{else} \&{if} $\|t<\\{independent}$ \1\&{then}\5
+$\|v\K\\{dep\_list}(\|p)$;\2\2\6
+\X802:Print an abbreviated value of \|v with format depending on \|t\X;\6
+\&{if} $\\{restore\_cur\_exp}$ \1\&{then}\5
+$\\{unstash\_cur\_exp}(\|p)$;\2\6
+\&{end};\par
+\fi
+
+\M802. \P$\X802:Print an abbreviated value of \|v with format depending on \|t%
+\X\S$\6
+\&{case} $\|t$ \1\&{of}\6
+\4\\{vacuous}: \37$\\{print}(\.{"vacuous"})$;\6
+\4\\{boolean\_type}: \37\&{if} $\|v=\\{true\_code}$ \1\&{then}\5
+$\\{print}(\.{"true"})$\ \&{else} $\\{print}(\.{"false"})$;\2\6
+\4$\\{unknown\_types},\39\\{numeric\_type}$: \37\X806:Display a variable that's
+been declared but not defined\X;\6
+\4\\{string\_type}: \37\&{begin} \37$\\{print\_char}(\.{""}\.{""})$;\5
+$\\{slow\_print}(\|v)$;\5
+$\\{print\_char}(\.{""}\.{""})$;\6
+\&{end};\6
+\4$\\{pen\_type},\39\\{future\_pen},\39\\{path\_type},\39\\{picture\_type}$: %
+\37\X804:Display a complex type\X;\6
+\4$\\{transform\_type},\39\\{pair\_type}$: \37\&{if} $\|v=\\{null}$ \1\&{then}\5
+$\\{print\_type}(\|t)$\6
+\4\&{else} \X803:Display a big node\X;\2\6
+\4\\{known}: \37$\\{print\_scaled}(\|v)$;\6
+\4$\\{dependent},\39\\{proto\_dependent}$: \37$\\{print\_dp}(\|t,\39\|v,\39%
+\\{verbosity})$;\6
+\4\\{independent}: \37$\\{print\_variable\_name}(\|p)$;\6
+\4\&{othercases} \37$\\{confusion}(\.{"exp"})$\2\6
+\&{endcases}\par
+\U801.\fi
+
+\M803. \P$\X803:Display a big node\X\S$\6
+\&{begin} \37$\\{print\_char}(\.{"("})$;\5
+$\|q\K\|v+\\{big\_node\_size}[\|t]$;\6
+\1\&{repeat} \37\&{if} $\\{type}(\|v)=\\{known}$ \1\&{then}\5
+$\\{print\_scaled}(\\{value}(\|v))$\6
+\4\&{else} \&{if} $\\{type}(\|v)=\\{independent}$ \1\&{then}\5
+$\\{print\_variable\_name}(\|v)$\6
+\4\&{else} $\\{print\_dp}(\\{type}(\|v),\39\\{dep\_list}(\|v),\39%
+\\{verbosity})$;\2\2\6
+$\|v\K\|v+2$;\6
+\&{if} $\|v\I\|q$ \1\&{then}\5
+$\\{print\_char}(\.{","})$;\2\6
+\4\&{until}\5
+$\|v=\|q$;\2\6
+$\\{print\_char}(\.{")"})$;\6
+\&{end}\par
+\U802.\fi
+
+\M804. Values of type \&{picture}, \&{path}, and \&{pen} are displayed
+verbosely
+in the log file only, unless the user has given a positive value to
+\\{tracingonline}.
+
+\Y\P$\4\X804:Display a complex type\X\S$\6
+\&{if} $\\{verbosity}\L1$ \1\&{then}\5
+$\\{print\_type}(\|t)$\6
+\4\&{else} \&{begin} \37\&{if} $\\{selector}=\\{term\_and\_log}$ \1\&{then}\6
+\&{if} $\\{internal}[\\{tracing\_online}]\L0$ \1\&{then}\6
+\&{begin} \37$\\{selector}\K\\{term\_only}$;\5
+$\\{print\_type}(\|t)$;\5
+$\\{print}(\.{"\ (see\ the\ transcript\ file)"})$;\5
+$\\{selector}\K\\{term\_and\_log}$;\6
+\&{end};\2\2\6
+\&{case} $\|t$ \1\&{of}\6
+\4\\{pen\_type}: \37$\\{print\_pen}(\|v,\39\.{""},\39\\{false})$;\6
+\4\\{future\_pen}: \37$\\{print\_path}(\|v,\39\.{"\ (future\ pen)"},\39%
+\\{false})$;\6
+\4\\{path\_type}: \37$\\{print\_path}(\|v,\39\.{""},\39\\{false})$;\6
+\4\\{picture\_type}: \37\&{begin} \37$\\{cur\_edges}\K\|v$;\5
+$\\{print\_edges}(\.{""},\39\\{false},\390,\390)$;\6
+\&{end};\2\6
+\&{end};\C{there are no other cases}\6
+\&{end}\2\par
+\U802.\fi
+
+\M805. \P$\X805:Declare the procedure called \\{print\_dp}\X\S$\6
+\4\&{procedure}\1\ \37$\\{print\_dp}(\|t:\\{small\_number};\,\35\|p:%
+\\{pointer};\,\35\\{verbosity}:\\{small\_number})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the node following \|p}\2\6
+\&{begin} \37$\|q\K\\{link}(\|p)$;\6
+\&{if} $(\\{info}(\|q)=\\{null})\V(\\{verbosity}>0)$ \1\&{then}\5
+$\\{print\_dependency}(\|p,\39\|t)$\6
+\4\&{else} $\\{print}(\.{"linearform"})$;\2\6
+\&{end};\par
+\U801.\fi
+
+\M806. The displayed name of a variable in a ring will not be a capsule unless
+the ring consists entirely of capsules.
+
+\Y\P$\4\X806:Display a variable that's been declared but not defined\X\S$\6
+\&{begin} \37$\\{print\_type}(\|t)$;\6
+\&{if} $\|v\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{print\_char}(\.{"\ "})$;\6
+\&{while} $(\\{name\_type}(\|v)=\\{capsule})\W(\|v\I\|p)$ \1\&{do}\5
+$\|v\K\\{value}(\|v)$;\2\6
+$\\{print\_variable\_name}(\|v)$;\6
+\&{end};\2\6
+\&{end}\par
+\U802.\fi
+
+\M807. When errors are detected during parsing, it is often helpful to
+display an expression just above the error message, using \\{exp\_err}
+or \\{disp\_err} instead of \\{print\_err}.
+
+\Y\P\D \37$\\{exp\_err}(\#)\S\\{disp\_err}(\\{null},\39\#)$\C{displays the
+current expression}\par
+\Y\P$\4\X257:Declare subroutines for printing expressions\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{disp\_err}(\|p:\\{pointer};\,\35\|s:\\{str%
+\_number})$;\2\6
+\&{begin} \37\&{if} $\\{interaction}=\\{error\_stop\_mode}$ \1\&{then}\5
+\\{wake\_up\_terminal};\2\6
+$\\{print\_nl}(\.{">>\ "})$;\5
+$\\{print\_exp}(\|p,\391)$;\C{``medium verbose'' printing of the expression}\6
+\&{if} $\|s\I\.{""}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"!\ "})$;\5
+$\\{print}(\|s)$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M808. If \\{cur\_type} and \\{cur\_exp} contain relevant information that
+should
+be recycled, we will use the following procedure, which changes \\{cur\_type}
+to \\{known} and stores a given value in \\{cur\_exp}. We can think of \\{cur%
+\_type}
+and \\{cur\_exp} as either alive or dormant after this has been done,
+because \\{cur\_exp} will not contain a pointer value.
+
+\Y\P$\4\X808:Declare the procedure called \\{flush\_cur\_exp}\X\S$\6
+\4\&{procedure}\1\ \37$\\{flush\_cur\_exp}(\|v:\\{scaled})$;\2\6
+\&{begin} \37\&{case} $\\{cur\_type}$ \1\&{of}\6
+\4$\\{unknown\_types},\39\\{transform\_type},\39\\{pair\_type},\39\30%
+\\{dependent},\39\\{proto\_dependent},\39\\{independent}$: \37\&{begin} \37$%
+\\{recycle\_value}(\\{cur\_exp})$;\5
+$\\{free\_node}(\\{cur\_exp},\39\\{value\_node\_size})$;\6
+\&{end};\6
+\4\\{pen\_type}: \37$\\{delete\_pen\_ref}(\\{cur\_exp})$;\6
+\4\\{string\_type}: \37$\\{delete\_str\_ref}(\\{cur\_exp})$;\6
+\4$\\{future\_pen},\39\\{path\_type}$: \37$\\{toss\_knot\_list}(\\{cur\_exp})$;%
+\6
+\4\\{picture\_type}: \37$\\{toss\_edges}(\\{cur\_exp})$;\6
+\4\&{othercases} \37\\{do\_nothing}\2\6
+\&{endcases};\6
+$\\{cur\_type}\K\\{known}$;\5
+$\\{cur\_exp}\K\|v$;\6
+\&{end};\par
+\A820.
+\U246.\fi
+
+\M809. There's a much more general procedure that is capable of releasing
+the storage associated with any two-word value packet.
+
+\Y\P$\4\X268:Declare the recycling subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{recycle\_value}(\|p:\\{pointer})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|t: \37\\{small\_number};\C{a type code}\6
+\|v: \37\\{integer};\C{a value}\6
+\\{vv}: \37\\{integer};\C{another value}\6
+$\|q,\39\|r,\39\|s,\39\\{pp}$: \37\\{pointer};\C{link manipulation registers}\2%
+\6
+\&{begin} \37$\|t\K\\{type}(\|p)$;\6
+\&{if} $\|t<\\{dependent}$ \1\&{then}\5
+$\|v\K\\{value}(\|p)$;\2\6
+\&{case} $\|t$ \1\&{of}\6
+\4$\\{undefined},\39\\{vacuous},\39\\{boolean\_type},\39\\{known},\39\\{numeric%
+\_type}$: \37\\{do\_nothing};\6
+\4\\{unknown\_types}: \37$\\{ring\_delete}(\|p)$;\6
+\4\\{string\_type}: \37$\\{delete\_str\_ref}(\|v)$;\6
+\4\\{pen\_type}: \37$\\{delete\_pen\_ref}(\|v)$;\6
+\4$\\{path\_type},\39\\{future\_pen}$: \37$\\{toss\_knot\_list}(\|v)$;\6
+\4\\{picture\_type}: \37$\\{toss\_edges}(\|v)$;\6
+\4$\\{pair\_type},\39\\{transform\_type}$: \37\X810:Recycle a big node\X;\6
+\4$\\{dependent},\39\\{proto\_dependent}$: \37\X811:Recycle a dependency list%
+\X;\6
+\4\\{independent}: \37\X812:Recycle an independent variable\X;\6
+\4$\\{token\_list},\39\\{structured}$: \37$\\{confusion}(\.{"recycle"})$;\6
+\4$\\{unsuffixed\_macro},\39\\{suffixed\_macro}$: \37$\\{delete\_mac\_ref}(%
+\\{value}(\|p))$;\2\6
+\&{end};\C{there are no other cases}\6
+$\\{type}(\|p)\K\\{undefined}$;\6
+\&{end};\par
+\fi
+
+\M810. \P$\X810:Recycle a big node\X\S$\6
+\&{if} $\|v\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\|q\K\|v+\\{big\_node\_size}[\|t]$;\6
+\1\&{repeat} \37$\|q\K\|q-2$;\5
+$\\{recycle\_value}(\|q)$;\6
+\4\&{until}\5
+$\|q=\|v$;\2\6
+$\\{free\_node}(\|v,\39\\{big\_node\_size}[\|t])$;\6
+\&{end}\2\par
+\U809.\fi
+
+\M811. \P$\X811:Recycle a dependency list\X\S$\6
+\&{begin} \37$\|q\K\\{dep\_list}(\|p)$;\6
+\&{while} $\\{info}(\|q)\I\\{null}$ \1\&{do}\5
+$\|q\K\\{link}(\|q)$;\2\6
+$\\{link}(\\{prev\_dep}(\|p))\K\\{link}(\|q)$;\5
+$\\{prev\_dep}(\\{link}(\|q))\K\\{prev\_dep}(\|p)$;\5
+$\\{link}(\|q)\K\\{null}$;\5
+$\\{flush\_node\_list}(\\{dep\_list}(\|p))$;\6
+\&{end}\par
+\U809.\fi
+
+\M812. When an independent variable disappears, it simply fades away, unless
+something depends on it. In the latter case, a dependent variable whose
+coefficient of dependence is maximal will take its place.
+The relevant algorithm is due to Ignacio~A. Zabala, who implemented it
+as part of his Ph.D. thesis (Stanford University, December 1982).
+
+For example, suppose that variable $x$ is being recycled, and that the
+only variables depending on~$x$ are $y=2x+a$ and $z=x+b$. In this case
+we want to make $y$ independent and $z=.5y-.5a+b$; no other variables
+will depend on~$y$. If $\\{tracingequations}>0$ in this situation,
+we will print `\.{\#\#\# -2x=-y+a}'.
+
+There's a slight complication, however: An independent variable $x$
+can occur both in dependency lists and in proto-dependency lists.
+This makes it necessary to be careful when deciding which coefficient
+is maximal.
+
+Furthermore, this complication is not so slight when
+a proto-dependent variable is chosen to become independent. For example,
+suppose that $y=2x+100a$ is proto-dependent while $z=x+b$ is dependent;
+then we must change $z=.5y-50a+b$ to a proto-dependency, because of the
+large coefficient `50'.
+
+In order to deal with these complications without wasting too much time,
+we shall link together the occurrences of~$x$ among all the linear
+dependencies, maintaining separate lists for the dependent and
+proto-dependent cases.
+
+\Y\P$\4\X812:Recycle an independent variable\X\S$\6
+\&{begin} \37$\\{max\_c}[\\{dependent}]\K0$;\5
+$\\{max\_c}[\\{proto\_dependent}]\K0$;\6
+$\\{max\_link}[\\{dependent}]\K\\{null}$;\5
+$\\{max\_link}[\\{proto\_dependent}]\K\\{null}$;\6
+$\|q\K\\{link}(\\{dep\_head})$;\6
+\&{while} $\|q\I\\{dep\_head}$ \1\&{do}\6
+\&{begin} \37$\|s\K\\{value\_loc}(\|q)$;\C{now $\\{link}(\|s)=\\{dep\_list}(%
+\|q)$}\6
+\~ \1\&{loop}\ \&{begin} \37$\|r\K\\{link}(\|s)$;\6
+\&{if} $\\{info}(\|r)=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\\{info}(\|r)\I\|p$ \1\&{then}\5
+$\|s\K\|r$\6
+\4\&{else} \&{begin} \37$\|t\K\\{type}(\|q)$;\5
+$\\{link}(\|s)\K\\{link}(\|r)$;\5
+$\\{info}(\|r)\K\|q$;\6
+\&{if} $\\{abs}(\\{value}(\|r))>\\{max\_c}[\|t]$ \1\&{then}\5
+\X814:Record a new maximum coefficient of type \|t\X\6
+\4\&{else} \&{begin} \37$\\{link}(\|r)\K\\{max\_link}[\|t]$;\5
+$\\{max\_link}[\|t]\K\|r$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\2\6
+\4\\{done}: \37$\|q\K\\{link}(\|r)$;\6
+\&{end};\2\6
+\&{if} $(\\{max\_c}[\\{dependent}]>0)\V(\\{max\_c}[\\{proto\_dependent}]>0)$ \1%
+\&{then}\5
+\X815:Choose a dependent variable to take the place of the disappearing
+independent variable, and change all remaining dependencies accordingly\X;\2\6
+\&{end}\par
+\U809.\fi
+
+\M813. The code for independency removal makes use of three two-word arrays.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{max\_c}: \37\&{array} $[\\{dependent}\to\\{proto\_dependent}]$ \1\&{of}\5
+\\{integer};\C{max coefficient magnitude}\2\6
+\4\\{max\_ptr}: \37\&{array} $[\\{dependent}\to\\{proto\_dependent}]$ \1\&{of}\5
+\\{pointer};\C{where \|p occurs with \\{max\_c}}\2\6
+\4\\{max\_link}: \37\&{array} $[\\{dependent}\to\\{proto\_dependent}]$ \1\&{of}%
+\5
+\\{pointer};\C{other occurrences of \|p}\2\par
+\fi
+
+\M814. \P$\X814:Record a new maximum coefficient of type \|t\X\S$\6
+\&{begin} \37\&{if} $\\{max\_c}[\|t]>0$ \1\&{then}\6
+\&{begin} \37$\\{link}(\\{max\_ptr}[\|t])\K\\{max\_link}[\|t]$;\5
+$\\{max\_link}[\|t]\K\\{max\_ptr}[\|t]$;\6
+\&{end};\2\6
+$\\{max\_c}[\|t]\K\\{abs}(\\{value}(\|r))$;\5
+$\\{max\_ptr}[\|t]\K\|r$;\6
+\&{end}\par
+\U812.\fi
+
+\M815. \P$\X815:Choose a dependent variable to take the place of the
+disappearing independent variable, and change all remaining dependencies
+accordingly\X\S$\6
+\&{begin} \37\&{if} $(\\{max\_c}[\\{dependent}]\mathbin{\&{div}}\O{10000}\G%
+\\{max\_c}[\\{proto\_dependent}])$ \1\&{then}\5
+$\|t\K\\{dependent}$\6
+\4\&{else} $\|t\K\\{proto\_dependent}$;\2\6
+\X816:Determine the dependency list \|s to substitute for the independent
+variable~\|p\X;\6
+$\|t\K\\{dependent}+\\{proto\_dependent}-\|t$;\C{complement \|t}\6
+\&{if} $\\{max\_c}[\|t]>0$ \1\&{then}\C{we need to pick up an unchosen
+dependency}\6
+\&{begin} \37$\\{link}(\\{max\_ptr}[\|t])\K\\{max\_link}[\|t]$;\5
+$\\{max\_link}[\|t]\K\\{max\_ptr}[\|t]$;\6
+\&{end};\2\6
+\&{if} $\|t\I\\{dependent}$ \1\&{then}\5
+\X818:Substitute new dependencies in place of \|p\X\6
+\4\&{else} \X819:Substitute new proto-dependencies in place of \|p\X;\2\6
+$\\{flush\_node\_list}(\|s)$;\6
+\&{if} $\\{fix\_needed}$ \1\&{then}\5
+\\{fix\_dependencies};\2\6
+\\{check\_arith};\6
+\&{end}\par
+\U812.\fi
+
+\M816. Let $\|s=\\{max\_ptr}[\|t]$. At this point we have $\\{value}(s)=\pm%
+\\{max\_c}[t]$,
+and $\\{info}(\|s)$ points to the dependent variable~\\{pp} of type~\|t from
+whose dependency list we have removed node~\|s. We must reinsert
+node~\|s into the dependency list, with coefficient $-1.0$, and with
+\\{pp} as the new independent variable. Since \\{pp} will have a larger serial
+number than any other variable, we can put node \|s at the head of the
+list.
+
+\Y\P$\4\X816:Determine the dependency list \|s to substitute for the
+independent variable~\|p\X\S$\6
+$\|s\K\\{max\_ptr}[\|t]$;\5
+$\\{pp}\K\\{info}(\|s)$;\5
+$\|v\K\\{value}(\|s)$;\6
+\&{if} $\|t=\\{dependent}$ \1\&{then}\5
+$\\{value}(\|s)\K-\\{fraction\_one}$\ \&{else} $\\{value}(\|s)\K-\\{unity}$;\2\6
+$\|r\K\\{dep\_list}(\\{pp})$;\5
+$\\{link}(\|s)\K\|r$;\6
+\&{while} $\\{info}(\|r)\I\\{null}$ \1\&{do}\5
+$\|r\K\\{link}(\|r)$;\2\6
+$\|q\K\\{link}(\|r)$;\5
+$\\{link}(\|r)\K\\{null}$;\5
+$\\{prev\_dep}(\|q)\K\\{prev\_dep}(\\{pp})$;\5
+$\\{link}(\\{prev\_dep}(\\{pp}))\K\|q$;\5
+$\\{new\_indep}(\\{pp})$;\6
+\&{if} $\\{cur\_exp}=\\{pp}$ \1\&{then}\6
+\&{if} $\\{cur\_type}=\|t$ \1\&{then}\5
+$\\{cur\_type}\K\\{independent}$;\2\2\6
+\&{if} $\\{internal}[\\{tracing\_equations}]>0$ \1\&{then}\5
+\X817:Show the transformed dependency\X\2\par
+\U815.\fi
+
+\M817. Now $(-v)$ times the formerly independent variable~\|p is being replaced
+by the dependency list~\|s.
+
+\Y\P$\4\X817:Show the transformed dependency\X\S$\6
+\&{if} $\\{interesting}(\|p)$ \1\&{then}\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\#\#\#\ "})$;\6
+\&{if} $\|v>0$ \1\&{then}\5
+$\\{print\_char}(\.{"-"})$;\2\6
+\&{if} $\|t=\\{dependent}$ \1\&{then}\5
+$\\{vv}\K\\{round\_fraction}(\\{max\_c}[\\{dependent}])$\6
+\4\&{else} $\\{vv}\K\\{max\_c}[\\{proto\_dependent}]$;\2\6
+\&{if} $\\{vv}\I\\{unity}$ \1\&{then}\5
+$\\{print\_scaled}(\\{vv})$;\2\6
+$\\{print\_variable\_name}(\|p)$;\6
+\&{while} $\\{value}(\|p)\mathbin{\&{mod}}\\{s\_scale}>0$ \1\&{do}\6
+\&{begin} \37$\\{print}(\.{"*4"})$;\5
+$\\{value}(\|p)\K\\{value}(\|p)-2$;\6
+\&{end};\2\6
+\&{if} $\|t=\\{dependent}$ \1\&{then}\5
+$\\{print\_char}(\.{"="})$\ \&{else} $\\{print}(\.{"\ =\ "})$;\2\6
+$\\{print\_dependency}(\|s,\39\|t)$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\2\par
+\U816.\fi
+
+\M818. Finally, there are dependent and proto-dependent variables whose
+dependency lists must be brought up to date.
+
+\Y\P$\4\X818:Substitute new dependencies in place of \|p\X\S$\6
+\&{for} $\|t\K\\{dependent}\mathrel{\&{to}}\\{proto\_dependent}$ \1\&{do}\6
+\&{begin} \37$\|r\K\\{max\_link}[\|t]$;\6
+\&{while} $\|r\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{info}(\|r)$;\5
+$\\{dep\_list}(\|q)\K\\{p\_plus\_fq}(\\{dep\_list}(\|q),\39\30\\{make%
+\_fraction}(\\{value}(\|r),\39-\|v),\39\|s,\39\|t,\39\\{dependent})$;\6
+\&{if} $\\{dep\_list}(\|q)=\\{dep\_final}$ \1\&{then}\5
+$\\{make\_known}(\|q,\39\\{dep\_final})$;\2\6
+$\|q\K\|r$;\5
+$\|r\K\\{link}(\|r)$;\5
+$\\{free\_node}(\|q,\39\\{dep\_node\_size})$;\6
+\&{end};\2\6
+\&{end}\2\par
+\U815.\fi
+
+\M819. \P$\X819:Substitute new proto-dependencies in place of \|p\X\S$\6
+\&{for} $\|t\K\\{dependent}\mathrel{\&{to}}\\{proto\_dependent}$ \1\&{do}\6
+\&{begin} \37$\|r\K\\{max\_link}[\|t]$;\6
+\&{while} $\|r\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{info}(\|r)$;\6
+\&{if} $\|t=\\{dependent}$ \1\&{then}\C{for safety's sake, we change \|q to %
+\\{proto\_dependent}}\6
+\&{begin} \37\&{if} $\\{cur\_exp}=\|q$ \1\&{then}\6
+\&{if} $\\{cur\_type}=\\{dependent}$ \1\&{then}\5
+$\\{cur\_type}\K\\{proto\_dependent}$;\2\2\6
+$\\{dep\_list}(\|q)\K\\{p\_over\_v}(\\{dep\_list}(\|q),\39\\{unity},\39%
+\\{dependent},\39\\{proto\_dependent})$;\5
+$\\{type}(\|q)\K\\{proto\_dependent}$;\5
+$\\{value}(\|r)\K\\{round\_fraction}(\\{value}(\|r))$;\6
+\&{end};\2\6
+$\\{dep\_list}(\|q)\K\\{p\_plus\_fq}(\\{dep\_list}(\|q),\39\30\\{make\_scaled}(%
+\\{value}(\|r),\39-\|v),\39\|s,\39\\{proto\_dependent},\39\\{proto%
+\_dependent})$;\6
+\&{if} $\\{dep\_list}(\|q)=\\{dep\_final}$ \1\&{then}\5
+$\\{make\_known}(\|q,\39\\{dep\_final})$;\2\6
+$\|q\K\|r$;\5
+$\|r\K\\{link}(\|r)$;\5
+$\\{free\_node}(\|q,\39\\{dep\_node\_size})$;\6
+\&{end};\2\6
+\&{end}\2\par
+\U815.\fi
+
+\M820. Here are some routines that provide handy combinations of actions
+that are often needed during error recovery. For example,
+`\\{flush\_error}' flushes the current expression, replaces it by
+a given value, and calls \\{error}.
+
+Errors often are detected after an extra token has already been scanned.
+The `\\{put\_get}' routines put that token back before calling \\{error};
+then they get it back again. (Or perhaps they get another token, if
+the user has changed things.)
+
+\Y\P$\4\X808:Declare the procedure called \\{flush\_cur\_exp}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{flush\_error}(\|v:\\{scaled})$;\ \2\6
+\&{begin} \37\\{error};\5
+$\\{flush\_cur\_exp}(\|v)$;\ \&{end};\7
+\4\&{procedure}\1\ \37\\{back\_error};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{get\_x\_next};\5
+\\{forward};\5
+\hbox{\2}\7
+\4\&{procedure}\1\ \37\\{put\_get\_error};\ \2\6
+\&{begin} \37\\{back\_error};\5
+\\{get\_x\_next};\ \&{end};\7
+\4\&{procedure}\1\ \37$\\{put\_get\_flush\_error}(\|v:\\{scaled})$;\ \2\6
+\&{begin} \37\\{put\_get\_error};\5
+$\\{flush\_cur\_exp}(\|v)$;\ \&{end};\par
+\fi
+
+\M821. A global variable called \\{var\_flag} is set to a special command code
+just before \MF\ calls \\{scan\_expression}, if the expression should be
+treated as a variable when this command code immediately follows. For
+example, \\{var\_flag} is set to \\{assignment} at the beginning of a
+statement, because we want to know the {\sl location\/} of a variable at
+the left of `\.{:=}', not the {\sl value\/} of that variable.
+
+The \\{scan\_expression} subroutine calls \\{scan\_tertiary},
+which calls \\{scan\_secondary}, which calls \\{scan\_primary}, which sets
+$\\{var\_flag}\K0$. In this way each of the scanning routines ``knows''
+when it has been called with a special \\{var\_flag}, but \\{var\_flag} is
+usually zero.
+
+A variable preceding a command that equals \\{var\_flag} is converted to a
+token list rather than a value. Furthermore, an `\.{=}' sign following an
+expression with $\\{var\_flag}=\\{assignment}$ is not considered to be a
+relation
+that produces boolean expressions.
+
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{var\_flag}: \37$0\to\\{max\_command\_code}$;\C{command that wants a
+variable}\par
+\fi
+
+\M822. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{var\_flag}\K0$;\par
+\fi
+
+\N823. \[40] Parsing primary expressions.
+The first parsing routine, \\{scan\_primary}, is also the most complicated one,
+since it involves so many different cases. But each case---with one
+exception---is fairly simple by itself.
+
+When \\{scan\_primary} begins, the first token of the primary to be scanned
+should already appear in \\{cur\_cmd}, \\{cur\_mod}, and \\{cur\_sym}. The
+values
+of \\{cur\_type} and \\{cur\_exp} should be either dead or dormant, as
+explained
+earlier. If \\{cur\_cmd} is not between \\{min\_primary\_command} and
+\\{max\_primary\_command}, inclusive, a syntax error will be signalled.
+
+\Y\P$\4\X823:Declare the basic parsing subroutines\X\S$\6
+\4\&{procedure}\1\ \37\\{scan\_primary};\6
+\4\&{label} \37$\\{restart},\39\\{done},\39\\{done1},\39\\{done2}$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{for list manipulation}\6
+\|c: \37\\{quarterword};\C{a primitive operation code}\6
+\\{my\_var\_flag}: \37$0\to\\{max\_command\_code}$;\C{initial value of \\{my%
+\_var\_flag}}\6
+$\\{l\_delim},\39\\{r\_delim}$: \37\\{pointer};\C{hash addresses of a delimiter
+pair}\6
+\X831:Other local variables for \\{scan\_primary}\X\2\6
+\&{begin} \37$\\{my\_var\_flag}\K\\{var\_flag}$;\5
+$\\{var\_flag}\K0$;\6
+\4\\{restart}: \37\\{check\_arith};\5
+\X825:Supply diagnostic information, if requested\X;\6
+\&{case} $\\{cur\_cmd}$ \1\&{of}\6
+\4\\{left\_delimiter}: \37\X826:Scan a delimited primary\X;\6
+\4\\{begin\_group}: \37\X832:Scan a grouped primary\X;\6
+\4\\{string\_token}: \37\X833:Scan a string constant\X;\6
+\4\\{numeric\_token}: \37\X837:Scan a primary that starts with a numeric token%
+\X;\6
+\4\\{nullary}: \37\X834:Scan a nullary operation\X;\6
+\4$\\{unary},\39\\{type\_name},\39\\{cycle},\39\\{plus\_or\_minus}$: \37%
+\X835:Scan a unary operation\X;\6
+\4\\{primary\_binary}: \37\X839:Scan a binary operation with `\&{of}' between
+its operands\X;\6
+\4\\{str\_op}: \37\X840:Convert a suffix to a string\X;\6
+\4\\{internal\_quantity}: \37\X841:Scan an internal numeric quantity\X;\6
+\4\\{capsule\_token}: \37$\\{make\_exp\_copy}(\\{cur\_mod})$;\6
+\4\\{tag\_token}: \37\X844:Scan a variable primary; \&{goto} \\{restart} if it
+turns out to be a macro\X;\6
+\4\&{othercases} \37\&{begin} \37$\\{bad\_exp}(\.{"A\ primary"})$;\5
+\&{goto} \37\\{restart};\6
+\&{end}\2\6
+\&{endcases};\6
+\\{get\_x\_next};\C{the routines \&{goto} \\{done} if they don't want this}\6
+\4\\{done}: \37\&{if} $\\{cur\_cmd}=\\{left\_bracket}$ \1\&{then}\6
+\&{if} $\\{cur\_type}\G\\{known}$ \1\&{then}\5
+\X859:Scan a mediation construction\X;\2\2\6
+\&{end};\par
+\As860, 862, 864, 868\ETs892.
+\U1202.\fi
+
+\M824. Errors at the beginning of expressions are flagged by \\{bad\_exp}.
+
+\Y\P\4\&{procedure}\1\ \37$\\{bad\_exp}(\|s:\\{str\_number})$;\6
+\4\&{var} \37\\{save\_flag}: \37$0\to\\{max\_command\_code}$;\2\6
+\&{begin} \37$\\{print\_err}(\|s)$;\5
+$\\{print}(\.{"\ expression\ can\'t\ begin\ with\ \`"})$;\5
+$\\{print\_cmd\_mod}(\\{cur\_cmd},\39\\{cur\_mod})$;\5
+$\\{print\_char}(\.{"\'"})$;\5
+$\\{help4}(\.{"I\'m\ afraid\ I\ need\ some\ sort\ of\ value\ in\ order\ to\
+continue,"})$\6
+$(\.{"so\ I\'ve\ tentatively\ inserted\ \`0\'.\ You\ may\ want\ to"})$\6
+$(\.{"delete\ this\ zero\ and\ insert\ something\ else;"})$\6
+$(\.{"see\ Chapter\ 27\ of\ The\ METAFONTbook\ for\ an\ example."})$;\5
+\\{back\_input};\5
+$\\{cur\_sym}\K0$;\5
+$\\{cur\_cmd}\K\\{numeric\_token}$;\5
+$\\{cur\_mod}\K0$;\5
+\\{ins\_error};\6
+$\\{save\_flag}\K\\{var\_flag}$;\5
+$\\{var\_flag}\K0$;\5
+\\{get\_x\_next};\5
+$\\{var\_flag}\K\\{save\_flag}$;\6
+\&{end};\par
+\fi
+
+\M825. \P$\X825:Supply diagnostic information, if requested\X\S$\6
+\&{debug} \37\&{if} $\\{panicking}$ \1\&{then}\5
+$\\{check\_mem}(\\{false})$;\ \2\6
+\&{gubed}\6
+\&{if} $\\{interrupt}\I0$ \1\&{then}\6
+\&{if} $\\{OK\_to\_interrupt}$ \1\&{then}\6
+\&{begin} \37\\{back\_input};\5
+\\{check\_interrupt};\5
+\\{get\_x\_next};\6
+\&{end}\2\2\par
+\U823.\fi
+
+\M826. \P$\X826:Scan a delimited primary\X\S$\6
+\&{begin} \37$\\{l\_delim}\K\\{cur\_sym}$;\5
+$\\{r\_delim}\K\\{cur\_mod}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $(\\{cur\_cmd}=\\{comma})\W(\\{cur\_type}\G\\{known})$ \1\&{then}\5
+\X830:Scan the second of a pair of numerics\X\6
+\4\&{else} $\\{check\_delimiter}(\\{l\_delim},\39\\{r\_delim})$;\2\6
+\&{end}\par
+\U823.\fi
+
+\M827. The \\{stash\_in} subroutine puts the current (numeric) expression into
+a field
+within a ``big node.''
+
+\Y\P\4\&{procedure}\1\ \37$\\{stash\_in}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{temporary register}\2\6
+\&{begin} \37$\\{type}(\|p)\K\\{cur\_type}$;\6
+\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\5
+$\\{value}(\|p)\K\\{cur\_exp}$\6
+\4\&{else} \&{begin} \37\&{if} $\\{cur\_type}=\\{independent}$ \1\&{then}\5
+\X829:Stash an independent \\{cur\_exp} into a big node\X\6
+\4\&{else} \&{begin} \37$\\{mem}[\\{value\_loc}(\|p)]\K\\{mem}[\\{value\_loc}(%
+\\{cur\_exp})]$;\C{$\\{dep\_list}(\|p)\K\\{dep\_list}(\\{cur\_exp})$ and $%
+\\{prev\_dep}(\|p)\K\\{prev\_dep}(\\{cur\_exp})$}\6
+$\\{link}(\\{prev\_dep}(\|p))\K\|p$;\6
+\&{end};\2\6
+$\\{free\_node}(\\{cur\_exp},\39\\{value\_node\_size})$;\6
+\&{end};\2\6
+$\\{cur\_type}\K\\{vacuous}$;\6
+\&{end};\par
+\fi
+
+\M828. In rare cases the current expression can become \\{independent}. There
+may be many dependency lists pointing to such an independent capsule,
+so we can't simply move it into place within a big node. Instead,
+we copy it, then recycle it.
+
+\fi
+
+\M829. \P$\X829:Stash an independent \\{cur\_exp} into a big node\X\S$\6
+\&{begin} \37$\|q\K\\{single\_dependency}(\\{cur\_exp})$;\6
+\&{if} $\|q=\\{dep\_final}$ \1\&{then}\6
+\&{begin} \37$\\{type}(\|p)\K\\{known}$;\5
+$\\{value}(\|p)\K0$;\5
+$\\{free\_node}(\|q,\39\\{dep\_node\_size})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{type}(\|p)\K\\{dependent}$;\5
+$\\{new\_dep}(\|p,\39\|q)$;\6
+\&{end};\2\6
+$\\{recycle\_value}(\\{cur\_exp})$;\6
+\&{end}\par
+\U827.\fi
+
+\M830. \P$\X830:Scan the second of a pair of numerics\X\S$\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{type}(\|p)\K\\{pair\_type}$;\5
+$\\{name\_type}(\|p)\K\\{capsule}$;\5
+$\\{init\_big\_node}(\|p)$;\5
+$\|q\K\\{value}(\|p)$;\5
+$\\{stash\_in}(\\{x\_part\_loc}(\|q))$;\6
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}<\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Nonnumeric\ ypart\ has\ been\ replaced\ by\
+0"})$;\5
+$\\{help4}(\.{"I\ thought\ you\ were\ giving\ me\ a\ pair\ \`(x,y)\';\ but"})$\6
+$(\.{"after\ finding\ a\ nice\ xpart\ \`x\'\ I\ found\ a\ ypart\ \`y\'"})$\6
+$(\.{"that\ isn\'t\ of\ numeric\ type.\ So\ I\'ve\ changed\ y\ to\ zero."})$\6
+$(\.{"(The\ y\ that\ I\ didn\'t\ like\ appears\ above\ the\ error\
+message.)"})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end};\2\6
+$\\{stash\_in}(\\{y\_part\_loc}(\|q))$;\5
+$\\{check\_delimiter}(\\{l\_delim},\39\\{r\_delim})$;\5
+$\\{cur\_type}\K\\{pair\_type}$;\5
+$\\{cur\_exp}\K\|p$;\6
+\&{end}\par
+\U826.\fi
+
+\M831. The local variable \\{group\_line} keeps track of the line
+where a \&{begingroup} command occurred; this will be useful
+in an error message if the group doesn't actually end.
+
+\Y\P$\4\X831:Other local variables for \\{scan\_primary}\X\S$\6
+\4\\{group\_line}: \37\\{integer};\C{where a group began}\par
+\As836\ET843.
+\U823.\fi
+
+\M832. \P$\X832:Scan a grouped primary\X\S$\6
+\&{begin} \37$\\{group\_line}\K\\{line}$;\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>0$ \1\&{then}\5
+\\{show\_cur\_cmd\_mod};\2\6
+$\\{save\_boundary\_item}(\|p)$;\6
+\1\&{repeat} \37\\{do\_statement};\C{ends with $\\{cur\_cmd}\G\\{semicolon}$}\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{semicolon}$;\2\6
+\&{if} $\\{cur\_cmd}\I\\{end\_group}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"A\ group\ begun\ on\ line\ "})$;\5
+$\\{print\_int}(\\{group\_line})$;\5
+$\\{print}(\.{"\ never\ ended"})$;\5
+$\\{help2}(\.{"I\ saw\ a\ \`begingroup\'\ back\ there\ that\ hasn\'t\ been\
+matched"})$\6
+$(\.{"by\ \`endgroup\'.\ So\ I\'ve\ inserted\ \`endgroup\'\ now."})$;\5
+\\{back\_error};\5
+$\\{cur\_cmd}\K\\{end\_group}$;\6
+\&{end};\2\6
+\\{unsave};\C{this might change \\{cur\_type}, if independent variables are
+recycled}\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>0$ \1\&{then}\5
+\\{show\_cur\_cmd\_mod};\2\6
+\&{end}\par
+\U823.\fi
+
+\M833. \P$\X833:Scan a string constant\X\S$\6
+\&{begin} \37$\\{cur\_type}\K\\{string\_type}$;\5
+$\\{cur\_exp}\K\\{cur\_mod}$;\6
+\&{end}\par
+\U823.\fi
+
+\M834. Later we'll come to procedures that perform actual operations like
+addition, square root, and so on; our purpose now is to do the parsing.
+But we might as well mention those future procedures now, so that the
+suspense won't be too bad:
+
+\smallskip
+$\\{do\_nullary}(\|c)$ does primitive operations that have no operands (e.g.,
+`\&{true}' or `\&{pencircle}');
+
+\smallskip
+$\\{do\_unary}(\|c)$ applies a primitive operation to the current expression;
+
+\smallskip
+$\\{do\_binary}(\|p,\|c)$ applies a primitive operation to the capsule~\|p
+and the current expression.
+
+\Y\P$\4\X834:Scan a nullary operation\X\S$\6
+$\\{do\_nullary}(\\{cur\_mod})$\par
+\U823.\fi
+
+\M835. \P$\X835:Scan a unary operation\X\S$\6
+\&{begin} \37$\|c\K\\{cur\_mod}$;\5
+\\{get\_x\_next};\5
+\\{scan\_primary};\5
+$\\{do\_unary}(\|c)$;\5
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U823.\fi
+
+\M836. A numeric token might be a primary by itself, or it might be the
+numerator of a fraction composed solely of numeric tokens, or it might
+multiply the primary that follows (provided that the primary doesn't begin
+with a plus sign or a minus sign). The code here uses the facts that
+$\\{max\_primary\_command}=\\{plus\_or\_minus}$ and
+$\\{max\_primary\_command}-1=\\{numeric\_token}$. If a fraction is found that
+is less
+than unity, we try to retain higher precision when we use it in scalar
+multiplication.
+
+\Y\P$\4\X831:Other local variables for \\{scan\_primary}\X\mathrel{+}\S$\6
+\4$\\{num},\39\\{denom}$: \37\\{scaled};\C{for primaries that are fractions,
+like `1/2'}\par
+\fi
+
+\M837. \P$\X837:Scan a primary that starts with a numeric token\X\S$\6
+\&{begin} \37$\\{cur\_exp}\K\\{cur\_mod}$;\5
+$\\{cur\_type}\K\\{known}$;\5
+\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}\I\\{slash}$ \1\&{then}\6
+\&{begin} \37$\\{num}\K0$;\5
+$\\{denom}\K0$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}\I\\{numeric\_token}$ \1\&{then}\6
+\&{begin} \37\\{back\_input};\5
+$\\{cur\_cmd}\K\\{slash}$;\5
+$\\{cur\_mod}\K\\{over}$;\5
+$\\{cur\_sym}\K\\{frozen\_slash}$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+$\\{num}\K\\{cur\_exp}$;\5
+$\\{denom}\K\\{cur\_mod}$;\6
+\&{if} $\\{denom}=0$ \1\&{then}\5
+\X838:Protest division by zero\X\6
+\4\&{else} $\\{cur\_exp}\K\\{make\_scaled}(\\{num},\39\\{denom})$;\2\6
+\\{check\_arith};\5
+\\{get\_x\_next};\6
+\&{end};\2\6
+\&{if} $\\{cur\_cmd}\G\\{min\_primary\_command}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}<\\{numeric\_token}$ \1\&{then}\C{in particular, $\\{cur%
+\_cmd}\I\\{plus\_or\_minus}$}\6
+\&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+\\{scan\_primary};\6
+\&{if} $(\\{abs}(\\{num})\G\\{abs}(\\{denom}))\V(\\{cur\_type}<\\{pair\_type})$
+\1\&{then}\5
+$\\{do\_binary}(\|p,\39\\{times})$\6
+\4\&{else} \&{begin} \37$\\{frac\_mult}(\\{num},\39\\{denom})$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\6
+\&{end};\2\6
+\&{end};\2\2\6
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U823.\fi
+
+\M838. \P$\X838:Protest division by zero\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Division\ by\ zero"})$;\5
+$\\{help1}(\.{"I\'ll\ pretend\ that\ you\ meant\ to\ divide\ by\ 1."})$;\5
+\\{error};\6
+\&{end}\par
+\U837.\fi
+
+\M839. \P$\X839:Scan a binary operation with `\&{of}' between its operands\X\S$%
+\6
+\&{begin} \37$\|c\K\\{cur\_mod}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_cmd}\I\\{of\_token}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"of"})$;\5
+$\\{print}(\.{"\ for\ "})$;\5
+$\\{print\_cmd\_mod}(\\{primary\_binary},\39\|c)$;\5
+$\\{help1}(\.{"I\'ve\ got\ the\ first\ argument;\ will\ look\ now\ for\ the\
+other."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+$\|p\K\\{stash\_cur\_exp}$;\5
+\\{get\_x\_next};\5
+\\{scan\_primary};\5
+$\\{do\_binary}(\|p,\39\|c)$;\5
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U823.\fi
+
+\M840. \P$\X840:Convert a suffix to a string\X\S$\6
+\&{begin} \37\\{get\_x\_next};\5
+\\{scan\_suffix};\5
+$\\{old\_setting}\K\\{selector}$;\5
+$\\{selector}\K\\{new\_string}$;\5
+$\\{show\_token\_list}(\\{cur\_exp},\39\\{null},\39100000,\390)$;\5
+$\\{flush\_token\_list}(\\{cur\_exp})$;\5
+$\\{cur\_exp}\K\\{make\_string}$;\5
+$\\{selector}\K\\{old\_setting}$;\5
+$\\{cur\_type}\K\\{string\_type}$;\5
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U823.\fi
+
+\M841. If an internal quantity appears all by itself on the left of an
+assignment, we return a token list of length one, containing the address
+of the internal quantity plus \\{hash\_end}. (This accords with the conventions
+of the save stack, as described earlier.)
+
+\Y\P$\4\X841:Scan an internal numeric quantity\X\S$\6
+\&{begin} \37$\|q\K\\{cur\_mod}$;\6
+\&{if} $\\{my\_var\_flag}=\\{assignment}$ \1\&{then}\6
+\&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}=\\{assignment}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_exp}\K\\{get\_avail}$;\5
+$\\{info}(\\{cur\_exp})\K\|q+\\{hash\_end}$;\5
+$\\{cur\_type}\K\\{token\_list}$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\\{back\_input};\6
+\&{end};\2\6
+$\\{cur\_type}\K\\{known}$;\5
+$\\{cur\_exp}\K\\{internal}[\|q]$;\6
+\&{end}\par
+\U823.\fi
+
+\M842. The most difficult part of \\{scan\_primary} has been saved for last,
+since
+it was necessary to build up some confidence first. We can now face the task
+of scanning a variable.
+
+As we scan a variable, we build a token list containing the relevant
+names and subscript values, simultaneously following along in the
+``collective'' structure to see if we are actually dealing with a macro
+instead of a value.
+
+The local variables \\{pre\_head} and \\{post\_head} will point to the
+beginning
+of the prefix and suffix lists; \\{tail} will point to the end of the list
+that is currently growing.
+
+Another local variable, \\{tt}, contains partial information about the
+declared type of the variable-so-far. If $\\{tt}\G\\{unsuffixed\_macro}$, the
+relation $\\{tt}=\\{type}(\|q)$ will always hold. If $\\{tt}=\\{undefined}$,
+the routine
+doesn't bother to update its information about type. And if
+$\\{undefined}<\\{tt}<\\{unsuffixed\_macro}$, the precise value of \\{tt} isn't
+critical.
+
+\fi
+
+\M843. \P$\X831:Other local variables for \\{scan\_primary}\X\mathrel{+}\S$\6
+\4$\\{pre\_head},\39\\{post\_head},\39\\{tail}$: \37\\{pointer};\C{prefix and
+suffix list variables}\6
+\4\\{tt}: \37\\{small\_number};\C{approximation to the type of the
+variable-so-far}\6
+\4\|t: \37\\{pointer};\C{a token}\6
+\4\\{macro\_ref}: \37\\{pointer};\C{reference count for a suffixed macro}\par
+\fi
+
+\M844. \P$\X844:Scan a variable primary; \&{goto} \\{restart} if it turns out
+to be a macro\X\S$\6
+\&{begin} \37$\\{fast\_get\_avail}(\\{pre\_head})$;\5
+$\\{tail}\K\\{pre\_head}$;\5
+$\\{post\_head}\K\\{null}$;\5
+$\\{tt}\K\\{vacuous}$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|t\K\\{cur\_tok}$;\5
+$\\{link}(\\{tail})\K\|t$;\6
+\&{if} $\\{tt}\I\\{undefined}$ \1\&{then}\6
+\&{begin} \37\X850:Find the approximate type \\{tt} and corresponding~\|q\X;\6
+\&{if} $\\{tt}\G\\{unsuffixed\_macro}$ \1\&{then}\5
+\X845:Either begin an unsuffixed macro call or prepare for a suffixed one\X;\2\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+$\\{tail}\K\|t$;\6
+\&{if} $\\{cur\_cmd}=\\{left\_bracket}$ \1\&{then}\5
+\X846:Scan for a subscript; replace \\{cur\_cmd} by \\{numeric\_token} if found%
+\X;\2\6
+\&{if} $\\{cur\_cmd}>\\{max\_suffix\_token}$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+\&{if} $\\{cur\_cmd}<\\{min\_suffix\_token}$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+\&{end};\C{now \\{cur\_cmd} is \\{internal\_quantity}, \\{tag\_token}, or %
+\\{numeric\_token}}\2\6
+\4\\{done1}: \37\X852:Handle unusual cases that masquerade as variables, and %
+\&{goto} \\{restart} or \&{goto} \\{done} if appropriate; otherwise make a copy
+of the variable and \&{goto} \\{done}\X;\6
+\&{end}\par
+\U823.\fi
+
+\M845. \P$\X845:Either begin an unsuffixed macro call or prepare for a suffixed
+one\X\S$\6
+\&{begin} \37$\\{link}(\\{tail})\K\\{null}$;\6
+\&{if} $\\{tt}>\\{unsuffixed\_macro}$ \1\&{then}\C{$\\{tt}=\\{suffixed%
+\_macro}$}\6
+\&{begin} \37$\\{post\_head}\K\\{get\_avail}$;\5
+$\\{tail}\K\\{post\_head}$;\5
+$\\{link}(\\{tail})\K\|t$;\6
+$\\{tt}\K\\{undefined}$;\5
+$\\{macro\_ref}\K\\{value}(\|q)$;\5
+$\\{add\_mac\_ref}(\\{macro\_ref})$;\6
+\&{end}\6
+\4\&{else} \X853:Set up unsuffixed macro call and \&{goto} \\{restart}\X;\2\6
+\&{end}\par
+\U844.\fi
+
+\M846. \P$\X846:Scan for a subscript; replace \\{cur\_cmd} by \\{numeric%
+\_token} if found\X\S$\6
+\&{begin} \37\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_cmd}\I\\{right\_bracket}$ \1\&{then}\5
+\X847:Put the left bracket and the expression back to be rescanned\X\6
+\4\&{else} \&{begin} \37\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+\\{bad\_subscript};\2\6
+$\\{cur\_cmd}\K\\{numeric\_token}$;\5
+$\\{cur\_mod}\K\\{cur\_exp}$;\5
+$\\{cur\_sym}\K0$;\6
+\&{end};\2\6
+\&{end}\par
+\U844.\fi
+
+\M847. The left bracket that we thought was introducing a subscript might have
+actually been the left bracket in a mediation construction like `\.{x[a,b]}'.
+So we don't issue an error message at this point; but we do want to back up
+so as to avoid any embarrassment about our incorrect assumption.
+
+\Y\P$\4\X847:Put the left bracket and the expression back to be rescanned\X\S$\6
+\&{begin} \37\\{back\_input};\C{that was the token following the current
+expression}\6
+\\{back\_expr};\5
+$\\{cur\_cmd}\K\\{left\_bracket}$;\5
+$\\{cur\_mod}\K0$;\5
+$\\{cur\_sym}\K\\{frozen\_left\_bracket}$;\6
+\&{end}\par
+\Us846\ET859.\fi
+
+\M848. Here's a routine that puts the current expression back to be read again.
+
+\Y\P\4\&{procedure}\1\ \37\\{back\_expr};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{capsule token}\2\6
+\&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+$\\{link}(\|p)\K\\{null}$;\5
+$\\{back\_list}(\|p)$;\6
+\&{end};\par
+\fi
+
+\M849. Unknown subscripts lead to the following error message.
+
+\Y\P\4\&{procedure}\1\ \37\\{bad\_subscript};\2\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ subscript\ has\ been\ replaced\ by\
+zero"})$;\5
+$\\{help3}(\.{"A\ bracketed\ subscript\ must\ have\ a\ known\ numeric\
+value;"})$\6
+$(\.{"unfortunately,\ what\ I\ found\ was\ the\ value\ that\ appears\ just"})$\6
+$(\.{"above\ this\ error\ message.\ So\ I\'ll\ try\ a\ zero\ subscript."})$;\5
+$\\{flush\_error}(0)$;\6
+\&{end};\par
+\fi
+
+\M850. Every time we call \\{get\_x\_next}, there's a chance that the variable
+we've
+been looking at will disappear. Thus, we cannot safely keep \|q pointing
+into the variable structure; we need to start searching from the root each
+time.
+
+\Y\P$\4\X850:Find the approximate type \\{tt} and corresponding~\|q\X\S$\6
+\&{begin} \37$\|p\K\\{link}(\\{pre\_head})$;\5
+$\|q\K\\{info}(\|p)$;\5
+$\\{tt}\K\\{undefined}$;\6
+\&{if} $\\{eq\_type}(\|q)\mathbin{\&{mod}}\\{outer\_tag}=\\{tag\_token}$ \1%
+\&{then}\6
+\&{begin} \37$\|q\K\\{equiv}(\|q)$;\6
+\&{if} $\|q=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done2};\2\6
+\~ \1\&{loop}\ \&{begin} \37$\|p\K\\{link}(\|p)$;\6
+\&{if} $\|p=\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{tt}\K\\{type}(\|q)$;\5
+\&{goto} \37\\{done2};\6
+\&{end};\2\6
+\&{if} $\\{type}(\|q)\I\\{structured}$ \1\&{then}\5
+\&{goto} \37\\{done2};\2\6
+$\|q\K\\{link}(\\{attr\_head}(\|q))$;\C{the \\{collective\_subscript}
+attribute}\6
+\&{if} $\|p\G\\{hi\_mem\_min}$ \1\&{then}\C{it's not a subscript}\6
+\&{begin} \37\1\&{repeat} \37$\|q\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\\{attr\_loc}(\|q)\G\\{info}(\|p)$;\2\6
+\&{if} $\\{attr\_loc}(\|q)>\\{info}(\|p)$ \1\&{then}\5
+\&{goto} \37\\{done2};\2\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\2\6
+\4\\{done2}: \37\&{end}\par
+\U844.\fi
+
+\M851. How do things stand now? Well, we have scanned an entire variable name,
+including possible subscripts and/or attributes; \\{cur\_cmd}, \\{cur\_mod},
+and
+\\{cur\_sym} represent the token that follows. If $\\{post\_head}=\\{null}$, a
+token list for this variable name starts at $\\{link}(\\{pre\_head})$, with all
+subscripts evaluated. But if $\\{post\_head}\I\\{null}$, the variable turned
+out
+to be a suffixed macro; \\{pre\_head} is the head of the prefix list, while
+\\{post\_head} is the head of a token list containing both `\.{\AT!}' and
+the suffix.
+
+Our immediate problem is to see if this variable still exists. (Variable
+structures can change drastically whenever we call \\{get\_x\_next}; users
+aren't supposed to do this, but the fact that it is possible means that
+we must be cautious.)
+
+The following procedure prints an error message when a variable
+unexpectedly disappears. Its help message isn't quite right for
+our present purposes, but we'll be able to fix that up.
+
+\Y\P\4\&{procedure}\1\ \37$\\{obliterated}(\|q:\\{pointer})$;\2\6
+\&{begin} \37$\\{print\_err}(\.{"Variable\ "})$;\5
+$\\{show\_token\_list}(\|q,\39\\{null},\391000,\390)$;\5
+$\\{print}(\.{"\ has\ been\ obliterated"})$;\5
+$\\{help5}(\.{"It\ seems\ you\ did\ a\ nasty\ thing---probably\ by\
+accident,"})$\6
+$(\.{"but\ nevertheless\ you\ nearly\ hornswoggled\ me..."})$\6
+$(\.{"While\ I\ was\ evaluating\ the\ right-hand\ side\ of\ this"})$\6
+$(\.{"command,\ something\ happened,\ and\ the\ left-hand\ side"})$\6
+$(\.{"is\ no\ longer\ a\ variable!\ So\ I\ won\'t\ change\ anything."})$;\6
+\&{end};\par
+\fi
+
+\M852. If the variable does exist, we also need to check
+for a few other special cases before deciding that a plain old ordinary
+variable has, indeed, been scanned.
+
+\Y\P$\4\X852:Handle unusual cases that masquerade as variables, and \&{goto} %
+\\{restart} or \&{goto} \\{done} if appropriate; otherwise make a copy of the
+variable and \&{goto} \\{done}\X\S$\6
+\&{if} $\\{post\_head}\I\\{null}$ \1\&{then}\5
+\X854:Set up suffixed macro call and \&{goto} \\{restart}\X;\2\6
+$\|q\K\\{link}(\\{pre\_head})$;\5
+$\\{free\_avail}(\\{pre\_head})$;\6
+\&{if} $\\{cur\_cmd}=\\{my\_var\_flag}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_type}\K\\{token\_list}$;\5
+$\\{cur\_exp}\K\|q$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+$\|p\K\\{find\_variable}(\|q)$;\6
+\&{if} $\|p\I\\{null}$ \1\&{then}\5
+$\\{make\_exp\_copy}(\|p)$\6
+\4\&{else} \&{begin} \37$\\{obliterated}(\|q)$;\6
+$\\{help\_line}[2]\K\.{"While\ I\ was\ evaluating\ the\ suffix\ of\ this\
+variable,"}$;\5
+$\\{help\_line}[1]\K\.{"something\ was\ redefined,\ and\ it\'s\ no\ longer\ a\
+variable!"}$;\5
+$\\{help\_line}[0]\K\.{"In\ order\ to\ get\ back\ on\ my\ feet,\ I\'ve\
+inserted\ \`0\'\ instead."}$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end};\2\6
+$\\{flush\_node\_list}(\|q)$;\5
+\&{goto} \37\\{done}\par
+\U844.\fi
+
+\M853. The only complication associated with macro calling is that the prefix
+and ``at'' parameters must be packaged in an appropriate list of lists.
+
+\Y\P$\4\X853:Set up unsuffixed macro call and \&{goto} \\{restart}\X\S$\6
+\&{begin} \37$\|p\K\\{get\_avail}$;\5
+$\\{info}(\\{pre\_head})\K\\{link}(\\{pre\_head})$;\5
+$\\{link}(\\{pre\_head})\K\|p$;\5
+$\\{info}(\|p)\K\|t$;\5
+$\\{macro\_call}(\\{value}(\|q),\39\\{pre\_head},\39\\{null})$;\5
+\\{get\_x\_next};\5
+\&{goto} \37\\{restart};\6
+\&{end}\par
+\U845.\fi
+
+\M854. If the ``variable'' that turned out to be a suffixed macro no longer
+exists,
+we don't care, because we have reserved a pointer (\\{macro\_ref}) to its
+token list.
+
+\Y\P$\4\X854:Set up suffixed macro call and \&{goto} \\{restart}\X\S$\6
+\&{begin} \37\\{back\_input};\5
+$\|p\K\\{get\_avail}$;\5
+$\|q\K\\{link}(\\{post\_head})$;\5
+$\\{info}(\\{pre\_head})\K\\{link}(\\{pre\_head})$;\5
+$\\{link}(\\{pre\_head})\K\\{post\_head}$;\5
+$\\{info}(\\{post\_head})\K\|q$;\5
+$\\{link}(\\{post\_head})\K\|p$;\5
+$\\{info}(\|p)\K\\{link}(\|q)$;\5
+$\\{link}(\|q)\K\\{null}$;\5
+$\\{macro\_call}(\\{macro\_ref},\39\\{pre\_head},\39\\{null})$;\5
+$\\{decr}(\\{ref\_count}(\\{macro\_ref}))$;\5
+\\{get\_x\_next};\5
+\&{goto} \37\\{restart};\6
+\&{end}\par
+\U852.\fi
+
+\M855. Our remaining job is simply to make a copy of the value that has been
+found. Some cases are harder than others, but complexity arises solely
+because of the multiplicity of possible cases.
+
+\Y\P$\4\X855:Declare the procedure called \\{make\_exp\_copy}\X\S$\6
+\hbox{\4}\X856:Declare subroutines needed by \\{make\_exp\_copy}\X\6
+\4\&{procedure}\1\ \37$\\{make\_exp\_copy}(\|p:\\{pointer})$;\6
+\4\&{label} \37\\{restart};\6
+\4\&{var} \37$\|q,\39\|r,\39\|t$: \37\\{pointer};\C{registers for list
+manipulation}\2\6
+\&{begin} \37\\{restart}: \37$\\{cur\_type}\K\\{type}(\|p)$;\6
+\&{case} $\\{cur\_type}$ \1\&{of}\6
+\4$\\{vacuous},\39\\{boolean\_type},\39\\{known}$: \37$\\{cur\_exp}\K\\{value}(%
+\|p)$;\6
+\4\\{unknown\_types}: \37$\\{cur\_exp}\K\\{new\_ring\_entry}(\|p)$;\6
+\4\\{string\_type}: \37\&{begin} \37$\\{cur\_exp}\K\\{value}(\|p)$;\5
+$\\{add\_str\_ref}(\\{cur\_exp})$;\6
+\&{end};\6
+\4\\{pen\_type}: \37\&{begin} \37$\\{cur\_exp}\K\\{value}(\|p)$;\5
+$\\{add\_pen\_ref}(\\{cur\_exp})$;\6
+\&{end};\6
+\4\\{picture\_type}: \37$\\{cur\_exp}\K\\{copy\_edges}(\\{value}(\|p))$;\6
+\4$\\{path\_type},\39\\{future\_pen}$: \37$\\{cur\_exp}\K\\{copy\_path}(%
+\\{value}(\|p))$;\6
+\4$\\{transform\_type},\39\\{pair\_type}$: \37\X857:Copy the big node \|p\X;\6
+\4$\\{dependent},\39\\{proto\_dependent}$: \37$\\{encapsulate}(\\{copy\_dep%
+\_list}(\\{dep\_list}(\|p)))$;\6
+\4\\{numeric\_type}: \37\&{begin} \37$\\{new\_indep}(\|p)$;\5
+\&{goto} \37\\{restart};\6
+\&{end};\6
+\4\\{independent}: \37\&{begin} \37$\|q\K\\{single\_dependency}(\|p)$;\6
+\&{if} $\|q=\\{dep\_final}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_type}\K\\{known}$;\5
+$\\{cur\_exp}\K0$;\5
+$\\{free\_node}(\|q,\39\\{value\_node\_size})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{cur\_type}\K\\{dependent}$;\5
+$\\{encapsulate}(\|q)$;\6
+\&{end};\2\6
+\&{end};\6
+\4\&{othercases} \37$\\{confusion}(\.{"copy"})$\2\6
+\&{endcases};\6
+\&{end};\par
+\U651.\fi
+
+\M856. The \\{encapsulate} subroutine assumes that \\{dep\_final} is the
+tail of dependency list~\|p.
+
+\Y\P$\4\X856:Declare subroutines needed by \\{make\_exp\_copy}\X\S$\6
+\4\&{procedure}\1\ \37$\\{encapsulate}(\|p:\\{pointer})$;\2\6
+\&{begin} \37$\\{cur\_exp}\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{type}(\\{cur\_exp})\K\\{cur\_type}$;\5
+$\\{name\_type}(\\{cur\_exp})\K\\{capsule}$;\5
+$\\{new\_dep}(\\{cur\_exp},\39\|p)$;\6
+\&{end};\par
+\A858.
+\U855.\fi
+
+\M857. The most tedious case arises when the user refers to a
+\&{pair} or \&{transform} variable; we must copy several fields,
+each of which can be \\{independent}, \\{dependent}, \\{proto\_dependent},
+or \\{known}.
+
+\Y\P$\4\X857:Copy the big node \|p\X\S$\6
+\&{begin} \37\&{if} $\\{value}(\|p)=\\{null}$ \1\&{then}\5
+$\\{init\_big\_node}(\|p)$;\2\6
+$\|t\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{name\_type}(\|t)\K\\{capsule}$;\5
+$\\{type}(\|t)\K\\{cur\_type}$;\5
+$\\{init\_big\_node}(\|t)$;\6
+$\|q\K\\{value}(\|p)+\\{big\_node\_size}[\\{cur\_type}]$;\5
+$\|r\K\\{value}(\|t)+\\{big\_node\_size}[\\{cur\_type}]$;\6
+\1\&{repeat} \37$\|q\K\|q-2$;\5
+$\|r\K\|r-2$;\5
+$\\{install}(\|r,\39\|q)$;\6
+\4\&{until}\5
+$\|q=\\{value}(\|p)$;\2\6
+$\\{cur\_exp}\K\|t$;\6
+\&{end}\par
+\U855.\fi
+
+\M858. The \\{install} procedure copies a numeric field~\|q into field~\|r of
+a big node that will be part of a capsule.
+
+\Y\P$\4\X856:Declare subroutines needed by \\{make\_exp\_copy}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{install}(\|r,\39\|q:\\{pointer})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{temporary register}\2\6
+\&{begin} \37\&{if} $\\{type}(\|q)=\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{value}(\|r)\K\\{value}(\|q)$;\5
+$\\{type}(\|r)\K\\{known}$;\6
+\&{end}\6
+\4\&{else} \&{if} $\\{type}(\|q)=\\{independent}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{single\_dependency}(\|q)$;\6
+\&{if} $\|p=\\{dep\_final}$ \1\&{then}\6
+\&{begin} \37$\\{type}(\|r)\K\\{known}$;\5
+$\\{value}(\|r)\K0$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{type}(\|r)\K\\{dependent}$;\5
+$\\{new\_dep}(\|r,\39\|p)$;\6
+\&{end};\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{type}(\|r)\K\\{type}(\|q)$;\5
+$\\{new\_dep}(\|r,\39\\{copy\_dep\_list}(\\{dep\_list}(\|q)))$;\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M859. Expressions of the form `\.{a[b,c]}' are converted into
+`\.{b+a*(c-b)}', without checking the types of \.b~or~\.c,
+provided that \.a is numeric.
+
+\Y\P$\4\X859:Scan a mediation construction\X\S$\6
+\&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_cmd}\I\\{comma}$ \1\&{then}\6
+\&{begin} \37\X847:Put the left bracket and the expression back to be rescanned%
+\X;\6
+$\\{unstash\_cur\_exp}(\|p)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|q\K\\{stash\_cur\_exp}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_cmd}\I\\{right\_bracket}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"]"})$;\6
+$\\{help3}(\.{"I\'ve\ scanned\ an\ expression\ of\ the\ form\ \`a[b,c\',"})$\6
+$(\.{"so\ a\ right\ bracket\ should\ have\ come\ next."})$\6
+$(\.{"I\ shall\ pretend\ that\ one\ was\ there."})$;\6
+\\{back\_error};\6
+\&{end};\2\6
+$\|r\K\\{stash\_cur\_exp}$;\5
+$\\{make\_exp\_copy}(\|q)$;\6
+$\\{do\_binary}(\|r,\39\\{minus})$;\5
+$\\{do\_binary}(\|p,\39\\{times})$;\5
+$\\{do\_binary}(\|q,\39\\{plus})$;\5
+\\{get\_x\_next};\6
+\&{end};\2\6
+\&{end}\par
+\U823.\fi
+
+\M860. Here is a comparatively simple routine that is used to scan the
+\&{suffix} parameters of a macro.
+
+\Y\P$\4\X823:Declare the basic parsing subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{scan\_suffix};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37$\|h,\39\|t$: \37\\{pointer};\C{head and tail of the list being
+built}\6
+\|p: \37\\{pointer};\C{temporary register}\2\6
+\&{begin} \37$\|h\K\\{get\_avail}$;\5
+$\|t\K\|h$;\6
+\~ \1\&{loop}\ \&{begin} \37\&{if} $\\{cur\_cmd}=\\{left\_bracket}$ \1\&{then}\5
+\X861:Scan a bracketed subscript and set $\\{cur\_cmd}\K\\{numeric\_token}$\X;%
+\2\6
+\&{if} $\\{cur\_cmd}=\\{numeric\_token}$ \1\&{then}\5
+$\|p\K\\{new\_num\_tok}(\\{cur\_mod})$\6
+\4\&{else} \&{if} $(\\{cur\_cmd}=\\{tag\_token})\V(\\{cur\_cmd}=\\{internal%
+\_quantity})$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{get\_avail}$;\5
+$\\{info}(\|p)\K\\{cur\_sym}$;\6
+\&{end}\6
+\4\&{else} \&{goto} \37\\{done};\2\2\6
+$\\{link}(\|t)\K\|p$;\5
+$\|t\K\|p$;\5
+\\{get\_x\_next};\6
+\&{end};\2\6
+\4\\{done}: \37$\\{cur\_exp}\K\\{link}(\|h)$;\5
+$\\{free\_avail}(\|h)$;\5
+$\\{cur\_type}\K\\{token\_list}$;\6
+\&{end};\par
+\fi
+
+\M861. \P$\X861:Scan a bracketed subscript and set $\\{cur\_cmd}\K\\{numeric%
+\_token}$\X\S$\6
+\&{begin} \37\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+\\{bad\_subscript};\2\6
+\&{if} $\\{cur\_cmd}\I\\{right\_bracket}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"]"})$;\6
+$\\{help3}(\.{"I\'ve\ seen\ a\ \`[\'\ and\ a\ subscript\ value,\ in\ a\
+suffix,"})$\6
+$(\.{"so\ a\ right\ bracket\ should\ have\ come\ next."})$\6
+$(\.{"I\ shall\ pretend\ that\ one\ was\ there."})$;\6
+\\{back\_error};\6
+\&{end};\2\6
+$\\{cur\_cmd}\K\\{numeric\_token}$;\5
+$\\{cur\_mod}\K\\{cur\_exp}$;\6
+\&{end}\par
+\U860.\fi
+
+\N862. \[41] Parsing secondary and higher expressions.
+After the intricacies of \\{scan\_primary}\kern-1pt,
+the \\{scan\_secondary} routine is
+refreshingly simple. It's not trivial, but the operations are relatively
+straightforward; the main difficulty is, again, that expressions and data
+structures might change drastically every time we call \\{get\_x\_next}, so a
+cautious approach is mandatory. For example, a macro defined by
+\&{primarydef} might have disappeared by the time its second argument has
+been scanned; we solve this by increasing the reference count of its token
+list, so that the macro can be called even after it has been clobbered.
+
+\Y\P$\4\X823:Declare the basic parsing subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{scan\_secondary};\6
+\4\&{label} \37$\\{restart},\39\\{continue}$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{for list manipulation}\6
+$\|c,\39\|d$: \37\\{halfword};\C{operation codes or modifiers}\6
+\\{mac\_name}: \37\\{pointer};\C{token defined with \&{primarydef}}\2\6
+\&{begin} \37\\{restart}: \37\&{if} $(\\{cur\_cmd}<\\{min\_primary\_command})\V%
+\30(\\{cur\_cmd}>\\{max\_primary\_command})$ \1\&{then}\5
+$\\{bad\_exp}(\.{"A\ secondary"})$;\2\6
+\\{scan\_primary};\6
+\4\\{continue}: \37\&{if} $\\{cur\_cmd}\L\\{max\_secondary\_command}$ \1%
+\&{then}\6
+\&{if} $\\{cur\_cmd}\G\\{min\_secondary\_command}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+$\|c\K\\{cur\_mod}$;\5
+$\|d\K\\{cur\_cmd}$;\6
+\&{if} $\|d=\\{secondary\_primary\_macro}$ \1\&{then}\6
+\&{begin} \37$\\{mac\_name}\K\\{cur\_sym}$;\5
+$\\{add\_mac\_ref}(\|c)$;\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+\\{scan\_primary};\6
+\&{if} $\|d\I\\{secondary\_primary\_macro}$ \1\&{then}\5
+$\\{do\_binary}(\|p,\39\|c)$\6
+\4\&{else} \&{begin} \37\\{back\_input};\5
+$\\{binary\_mac}(\|p,\39\|c,\39\\{mac\_name})$;\5
+$\\{decr}(\\{ref\_count}(\|c))$;\5
+\\{get\_x\_next};\5
+\&{goto} \37\\{restart};\6
+\&{end};\2\6
+\&{goto} \37\\{continue};\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M863. The following procedure calls a macro that has two parameters,
+\|p and \\{cur\_exp}.
+
+\Y\P\4\&{procedure}\1\ \37$\\{binary\_mac}(\|p,\39\|c,\39\|n:\\{pointer})$;\6
+\4\&{var} \37$\|q,\39\|r$: \37\\{pointer};\C{nodes in the parameter list}\2\6
+\&{begin} \37$\|q\K\\{get\_avail}$;\5
+$\|r\K\\{get\_avail}$;\5
+$\\{link}(\|q)\K\|r$;\6
+$\\{info}(\|q)\K\|p$;\5
+$\\{info}(\|r)\K\\{stash\_cur\_exp}$;\6
+$\\{macro\_call}(\|c,\39\|q,\39\|n)$;\6
+\&{end};\par
+\fi
+
+\M864. The next procedure, \\{scan\_tertiary}, is pretty much the same deal.
+
+\Y\P$\4\X823:Declare the basic parsing subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{scan\_tertiary};\6
+\4\&{label} \37$\\{restart},\39\\{continue}$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{for list manipulation}\6
+$\|c,\39\|d$: \37\\{halfword};\C{operation codes or modifiers}\6
+\\{mac\_name}: \37\\{pointer};\C{token defined with \&{secondarydef}}\2\6
+\&{begin} \37\\{restart}: \37\&{if} $(\\{cur\_cmd}<\\{min\_primary\_command})\V%
+\30(\\{cur\_cmd}>\\{max\_primary\_command})$ \1\&{then}\5
+$\\{bad\_exp}(\.{"A\ tertiary"})$;\2\6
+\\{scan\_secondary};\6
+\&{if} $\\{cur\_type}=\\{future\_pen}$ \1\&{then}\5
+\\{materialize\_pen};\2\6
+\4\\{continue}: \37\&{if} $\\{cur\_cmd}\L\\{max\_tertiary\_command}$ \1\&{then}%
+\6
+\&{if} $\\{cur\_cmd}\G\\{min\_tertiary\_command}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+$\|c\K\\{cur\_mod}$;\5
+$\|d\K\\{cur\_cmd}$;\6
+\&{if} $\|d=\\{tertiary\_secondary\_macro}$ \1\&{then}\6
+\&{begin} \37$\\{mac\_name}\K\\{cur\_sym}$;\5
+$\\{add\_mac\_ref}(\|c)$;\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+\\{scan\_secondary};\6
+\&{if} $\|d\I\\{tertiary\_secondary\_macro}$ \1\&{then}\5
+$\\{do\_binary}(\|p,\39\|c)$\6
+\4\&{else} \&{begin} \37\\{back\_input};\5
+$\\{binary\_mac}(\|p,\39\|c,\39\\{mac\_name})$;\5
+$\\{decr}(\\{ref\_count}(\|c))$;\5
+\\{get\_x\_next};\5
+\&{goto} \37\\{restart};\6
+\&{end};\2\6
+\&{goto} \37\\{continue};\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M865. A \\{future\_pen} becomes a full-fledged pen here.
+
+\Y\P\4\&{procedure}\1\ \37\\{materialize\_pen};\6
+\4\&{label} \37\\{common\_ending};\6
+\4\&{var} \37$\\{a\_minus\_b},\39\\{a\_plus\_b},\39\\{major\_axis},\39\\{minor%
+\_axis}$: \37\\{scaled};\C{ellipse variables}\6
+\\{theta}: \37\\{angle};\C{amount by which the ellipse has been rotated}\6
+\|p: \37\\{pointer};\C{path traverser}\6
+\|q: \37\\{pointer};\C{the knot list to be made into a pen}\2\6
+\&{begin} \37$\|q\K\\{cur\_exp}$;\6
+\&{if} $\\{left\_type}(\|q)=\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Pen\ path\ must\ be\ a\ cycle"})$;\5
+$\\{help2}(\.{"I\ can\'t\ make\ a\ pen\ from\ the\ given\ path."})$\6
+$(\.{"So\ I\'ve\ replaced\ it\ by\ the\ trivial\ path\ \`(0,0)..cycle\'."})$;\5
+\\{put\_get\_error};\5
+$\\{cur\_exp}\K\\{null\_pen}$;\5
+\&{goto} \37\\{common\_ending};\6
+\&{end}\6
+\4\&{else} \&{if} $\\{left\_type}(\|q)=\\{open}$ \1\&{then}\5
+\X866:Change node \|q to a path for an elliptical pen\X;\2\2\6
+$\\{cur\_exp}\K\\{make\_pen}(\|q)$;\6
+\4\\{common\_ending}: \37$\\{toss\_knot\_list}(\|q)$;\5
+$\\{cur\_type}\K\\{pen\_type}$;\6
+\&{end};\par
+\fi
+
+\M866. We placed the three points $(0,0)$, $(1,0)$, $(0,1)$ into a %
+\&{pencircle},
+and they have now been transformed to $(u,v)$, $(A+u,B+v)$, $(C+u,D+v)$;
+this gives us enough information to deduce the transformation
+$(x,y)\mapsto(Ax+Cy+u,Bx+Dy+v)$.
+
+Given ($A,B,C,D)$ we can always find $(a,b,\theta,\phi)$ such that
+$$\eqalign{A&=a\cos\phi\cos\theta-b\sin\phi\sin\theta;\cr
+B&=a\cos\phi\sin\theta+b\sin\phi\cos\theta;\cr
+C&=-a\sin\phi\cos\theta-b\cos\phi\sin\theta;\cr
+D&=-a\sin\phi\sin\theta+b\cos\phi\cos\theta.\cr}$$
+In this notation, the unit circle $(\cos t,\sin t)$ is transformed into
+$$\bigl(a\cos(\phi+t)\cos\theta-b\sin(\phi+t)\sin\theta,\;
+a\cos(\phi+t)\sin\theta+b\sin(\phi+t)\cos\theta\bigr)\;+\;(u,v),$$
+which is an ellipse with semi-axes~$(a,b)$, rotated by~$\theta$ and
+shifted by~$(u,v)$. To solve the stated equations, we note that it is
+necessary and sufficient to solve
+$$\eqalign{A-D&=(a-b)\cos(\theta-\phi),\cr
+B+C&=(a-b)\sin(\theta-\phi),\cr}
+\qquad
+\eqalign{A+D&=(a+b)\cos(\theta+\phi),\cr
+B-C&=(a+b)\sin(\theta+\phi);\cr}$$
+and it is easy to find $a-b$, $a+b$, $\theta-\phi$, and $\theta+\phi$
+from these formulas.
+
+The code below uses $(\\{txx},\\{tyx},\\{txy},\\{tyy},\\{tx},\\{ty})$ to stand
+for
+$(A,B,C,D,u,v)$.
+
+\Y\P$\4\X866:Change node \|q to a path for an elliptical pen\X\S$\6
+\&{begin} \37$\\{tx}\K\\{x\_coord}(\|q)$;\5
+$\\{ty}\K\\{y\_coord}(\|q)$;\5
+$\\{txx}\K\\{left\_x}(\|q)-\\{tx}$;\5
+$\\{tyx}\K\\{left\_y}(\|q)-\\{ty}$;\5
+$\\{txy}\K\\{right\_x}(\|q)-\\{tx}$;\5
+$\\{tyy}\K\\{right\_y}(\|q)-\\{ty}$;\5
+$\\{a\_minus\_b}\K\\{pyth\_add}(\\{txx}-\\{tyy},\39\\{tyx}+\\{txy})$;\5
+$\\{a\_plus\_b}\K\\{pyth\_add}(\\{txx}+\\{tyy},\39\\{tyx}-\\{txy})$;\5
+$\\{major\_axis}\K\\{half}(\\{a\_minus\_b}+\\{a\_plus\_b})$;\5
+$\\{minor\_axis}\K\\{half}(\\{abs}(\\{a\_plus\_b}-\\{a\_minus\_b}))$;\6
+\&{if} $\\{major\_axis}=\\{minor\_axis}$ \1\&{then}\5
+$\\{theta}\K0$\C{circle}\6
+\4\&{else} $\\{theta}\K\\{half}(\\{n\_arg}(\\{txx}-\\{tyy},\39\\{tyx}+\\{txy})+%
+\\{n\_arg}(\\{txx}+\\{tyy},\39\\{tyx}-\\{txy}))$;\2\6
+$\\{free\_node}(\|q,\39\\{knot\_node\_size})$;\5
+$\|q\K\\{make\_ellipse}(\\{major\_axis},\39\\{minor\_axis},\39\\{theta})$;\6
+\&{if} $(\\{tx}\I0)\V(\\{ty}\I0)$ \1\&{then}\5
+\X867:Shift the coordinates of path \|q\X;\2\6
+\&{end}\par
+\U865.\fi
+
+\M867. \P$\X867:Shift the coordinates of path \|q\X\S$\6
+\&{begin} \37$\|p\K\|q$;\6
+\1\&{repeat} \37$\\{x\_coord}(\|p)\K\\{x\_coord}(\|p)+\\{tx}$;\5
+$\\{y\_coord}(\|p)\K\\{y\_coord}(\|p)+\\{ty}$;\5
+$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\|p=\|q$;\2\6
+\&{end}\par
+\U866.\fi
+
+\M868. Finally we reach the deepest level in our quartet of parsing routines.
+This one is much like the others; but it has an extra complication from
+paths, which materialize here.
+
+\Y\P\D \37$\\{continue\_path}=25$\C{a label inside of \\{scan\_expression}}\par
+\P\D \37$\\{finish\_path}=26$\C{another}\par
+\Y\P$\4\X823:Declare the basic parsing subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{scan\_expression};\6
+\4\&{label} \37$\\{restart},\39\\{done},\39\\{continue},\39\\{continue\_path},%
+\39\\{finish\_path},\39\\{exit}$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r,\39\\{pp},\39\\{qq}$: \37\\{pointer};\C{for
+list manipulation}\6
+$\|c,\39\|d$: \37\\{halfword};\C{operation codes or modifiers}\6
+\\{my\_var\_flag}: \37$0\to\\{max\_command\_code}$;\C{initial value of \\{var%
+\_flag}}\6
+\\{mac\_name}: \37\\{pointer};\C{token defined with \&{tertiarydef}}\6
+\\{cycle\_hit}: \37\\{boolean};\C{did a path expression just end with `%
+\&{cycle}'?}\6
+$\|x,\39\|y$: \37\\{scaled};\C{explicit coordinates or tension at a path join}\6
+\|t: \37$\\{endpoint}\to\\{open}$;\C{knot type following a path join}\2\6
+\&{begin} \37$\\{my\_var\_flag}\K\\{var\_flag}$;\6
+\4\\{restart}: \37\&{if} $(\\{cur\_cmd}<\\{min\_primary\_command})\V\30(\\{cur%
+\_cmd}>\\{max\_primary\_command})$ \1\&{then}\5
+$\\{bad\_exp}(\.{"An"})$;\2\6
+\\{scan\_tertiary};\6
+\4\\{continue}: \37\&{if} $\\{cur\_cmd}\L\\{max\_expression\_command}$ \1%
+\&{then}\6
+\&{if} $\\{cur\_cmd}\G\\{min\_expression\_command}$ \1\&{then}\6
+\&{if} $(\\{cur\_cmd}\I\\{equals})\V(\\{my\_var\_flag}\I\\{assignment})$ \1%
+\&{then}\6
+\&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+$\|c\K\\{cur\_mod}$;\5
+$\|d\K\\{cur\_cmd}$;\6
+\&{if} $\|d=\\{expression\_tertiary\_macro}$ \1\&{then}\6
+\&{begin} \37$\\{mac\_name}\K\\{cur\_sym}$;\5
+$\\{add\_mac\_ref}(\|c)$;\6
+\&{end};\2\6
+\&{if} $(\|d<\\{ampersand})\V((\|d=\\{ampersand})\W\30((\\{type}(\|p)=\\{pair%
+\_type})\V(\\{type}(\|p)=\\{path\_type})))$ \1\&{then}\5
+\X869:Scan a path construction operation; but \&{return} if \|p has the wrong
+type\X\6
+\4\&{else} \&{begin} \37\\{get\_x\_next};\5
+\\{scan\_tertiary};\6
+\&{if} $\|d\I\\{expression\_tertiary\_macro}$ \1\&{then}\5
+$\\{do\_binary}(\|p,\39\|c)$\6
+\4\&{else} \&{begin} \37\\{back\_input};\5
+$\\{binary\_mac}(\|p,\39\|c,\39\\{mac\_name})$;\5
+$\\{decr}(\\{ref\_count}(\|c))$;\5
+\\{get\_x\_next};\5
+\&{goto} \37\\{restart};\6
+\&{end};\2\6
+\&{end};\2\6
+\&{goto} \37\\{continue};\6
+\&{end};\2\2\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M869. The reader should review the data structure conventions for paths before
+hoping to understand the next part of this code.
+
+\Y\P$\4\X869:Scan a path construction operation; but \&{return} if \|p has the
+wrong type\X\S$\6
+\&{begin} \37$\\{cycle\_hit}\K\\{false}$;\5
+\X870:Convert the left operand, \|p, into a partial path ending at~\|q; but %
+\&{return} if \|p doesn't have a suitable type\X;\6
+\4\\{continue\_path}: \37\X874:Determine the path join parameters; but \&{goto}
+\\{finish\_path} if there's only a direction specifier\X;\6
+\&{if} $\\{cur\_cmd}=\\{cycle}$ \1\&{then}\5
+\X886:Get ready to close a cycle\X\6
+\4\&{else} \&{begin} \37\\{scan\_tertiary};\5
+\X885:Convert the right operand, \\{cur\_exp}, into a partial path from \\{pp}
+to~\\{qq}\X;\6
+\&{end};\2\6
+\X887:Join the partial paths and reset \|p and \|q to the head and tail of the
+result\X;\6
+\&{if} $\\{cur\_cmd}\G\\{min\_expression\_command}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}\L\\{ampersand}$ \1\&{then}\6
+\&{if} $\R\\{cycle\_hit}$ \1\&{then}\5
+\&{goto} \37\\{continue\_path};\2\2\2\6
+\4\\{finish\_path}: \37\X891:Choose control points for the path and put the
+result into \\{cur\_exp}\X;\6
+\&{end}\par
+\U868.\fi
+
+\M870. \P$\X870:Convert the left operand, \|p, into a partial path ending at~%
+\|q; but \&{return} if \|p doesn't have a suitable type\X\S$\6
+\&{begin} \37$\\{unstash\_cur\_exp}(\|p)$;\6
+\&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\5
+$\|p\K\\{new\_knot}$\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{path\_type}$ \1\&{then}\5
+$\|p\K\\{cur\_exp}$\6
+\4\&{else} \&{return};\2\2\6
+$\|q\K\|p$;\6
+\&{while} $\\{link}(\|q)\I\|p$ \1\&{do}\5
+$\|q\K\\{link}(\|q)$;\2\6
+\&{if} $\\{left\_type}(\|p)\I\\{endpoint}$ \1\&{then}\C{open up a cycle}\6
+\&{begin} \37$\|r\K\\{copy\_knot}(\|p)$;\5
+$\\{link}(\|q)\K\|r$;\5
+$\|q\K\|r$;\6
+\&{end};\2\6
+$\\{left\_type}(\|p)\K\\{open}$;\5
+$\\{right\_type}(\|q)\K\\{open}$;\6
+\&{end}\par
+\U869.\fi
+
+\M871. A pair of numeric values is changed into a knot node for a one-point
+path
+when \MF\ discovers that the pair is part of a path.
+
+\Y\P\hbox{\4}\X872:Declare the procedure called \\{known\_pair}\X\6
+\4\&{function}\1\ \37\\{new\_knot}: \37\\{pointer};\C{convert a pair to a knot
+with two endpoints}\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the new node}\2\6
+\&{begin} \37$\|q\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{left\_type}(\|q)\K\\{endpoint}$;\5
+$\\{right\_type}(\|q)\K\\{endpoint}$;\5
+$\\{link}(\|q)\K\|q$;\6
+\\{known\_pair};\5
+$\\{x\_coord}(\|q)\K\\{cur\_x}$;\5
+$\\{y\_coord}(\|q)\K\\{cur\_y}$;\5
+$\\{new\_knot}\K\|q$;\6
+\&{end};\par
+\fi
+
+\M872. The \\{known\_pair} subroutine sets \\{cur\_x} and \\{cur\_y} to the
+components
+of the current expression, assuming that the current expression is a
+pair of known numerics. Unknown components are zeroed, and the
+current expression is flushed.
+
+\Y\P$\4\X872:Declare the procedure called \\{known\_pair}\X\S$\6
+\4\&{procedure}\1\ \37\\{known\_pair};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the pair node}\2\6
+\&{begin} \37\&{if} $\\{cur\_type}\I\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Undefined\ coordinates\ have\ been\ replaced\ by%
+\ (0,0)"})$;\5
+$\\{help5}(\.{"I\ need\ x\ and\ y\ numbers\ for\ this\ part\ of\ the\ path."})$%
+\6
+$(\.{"The\ value\ I\ found\ (see\ above)\ was\ no\ good;"})$\6
+$(\.{"so\ I\'ll\ try\ to\ keep\ going\ by\ using\ zero\ instead."})$\6
+$(\.{"(Chapter\ 27\ of\ The\ METAFONTbook\ explains\ that"})$\6
+$(\.{"you\ might\ want\ to\ type\ \`I\ ???\'\ now.)"})$;\5
+$\\{put\_get\_flush\_error}(0)$;\5
+$\\{cur\_x}\K0$;\5
+$\\{cur\_y}\K0$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|p\K\\{value}(\\{cur\_exp})$;\5
+\X873:Make sure that both \|x and \|y parts of \|p are known; copy them into %
+\\{cur\_x} and \\{cur\_y}\X;\6
+$\\{flush\_cur\_exp}(0)$;\6
+\&{end};\2\6
+\&{end};\par
+\U871.\fi
+
+\M873. \P$\X873:Make sure that both \|x and \|y parts of \|p are known; copy
+them into \\{cur\_x} and \\{cur\_y}\X\S$\6
+\&{if} $\\{type}(\\{x\_part\_loc}(\|p))=\\{known}$ \1\&{then}\5
+$\\{cur\_x}\K\\{value}(\\{x\_part\_loc}(\|p))$\6
+\4\&{else} \&{begin} \37$\\{disp\_err}(\\{x\_part\_loc}(\|p),\39\.{"Undefined\
+x\ coordinate\ has\ been\ replaced\ by\ 0"})$;\5
+$\\{help5}(\.{"I\ need\ a\ \`known\'\ x\ value\ for\ this\ part\ of\ the\
+path."})$\6
+$(\.{"The\ value\ I\ found\ (see\ above)\ was\ no\ good;"})$\6
+$(\.{"so\ I\'ll\ try\ to\ keep\ going\ by\ using\ zero\ instead."})$\6
+$(\.{"(Chapter\ 27\ of\ The\ METAFONTbook\ explains\ that"})$\6
+$(\.{"you\ might\ want\ to\ type\ \`I\ ???\'\ now.)"})$;\5
+\\{put\_get\_error};\5
+$\\{recycle\_value}(\\{x\_part\_loc}(\|p))$;\5
+$\\{cur\_x}\K0$;\6
+\&{end};\2\6
+\&{if} $\\{type}(\\{y\_part\_loc}(\|p))=\\{known}$ \1\&{then}\5
+$\\{cur\_y}\K\\{value}(\\{y\_part\_loc}(\|p))$\6
+\4\&{else} \&{begin} \37$\\{disp\_err}(\\{y\_part\_loc}(\|p),\39\.{"Undefined\
+y\ coordinate\ has\ been\ replaced\ by\ 0"})$;\5
+$\\{help5}(\.{"I\ need\ a\ \`known\'\ y\ value\ for\ this\ part\ of\ the\
+path."})$\6
+$(\.{"The\ value\ I\ found\ (see\ above)\ was\ no\ good;"})$\6
+$(\.{"so\ I\'ll\ try\ to\ keep\ going\ by\ using\ zero\ instead."})$\6
+$(\.{"(Chapter\ 27\ of\ The\ METAFONTbook\ explains\ that"})$\6
+$(\.{"you\ might\ want\ to\ type\ \`I\ ???\'\ now.)"})$;\5
+\\{put\_get\_error};\5
+$\\{recycle\_value}(\\{y\_part\_loc}(\|p))$;\5
+$\\{cur\_y}\K0$;\6
+\&{end}\2\par
+\U872.\fi
+
+\M874. At this point \\{cur\_cmd} is either \\{ampersand}, \\{left\_brace}, or %
+\\{path\_join}.
+
+\Y\P$\4\X874:Determine the path join parameters; but \&{goto} \\{finish\_path}
+if there's only a direction specifier\X\S$\6
+\&{if} $\\{cur\_cmd}=\\{left\_brace}$ \1\&{then}\5
+\X879:Put the pre-join direction information into node \|q\X;\2\6
+$\|d\K\\{cur\_cmd}$;\6
+\&{if} $\|d=\\{path\_join}$ \1\&{then}\5
+\X881:Determine the tension and/or control points\X\6
+\4\&{else} \&{if} $\|d\I\\{ampersand}$ \1\&{then}\5
+\&{goto} \37\\{finish\_path};\2\2\6
+\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}=\\{left\_brace}$ \1\&{then}\5
+\X880:Put the post-join direction information into \|x and \|t\X\6
+\4\&{else} \&{if} $\\{right\_type}(\|q)\I\\{explicit}$ \1\&{then}\6
+\&{begin} \37$\|t\K\\{open}$;\5
+$\|x\K0$;\6
+\&{end}\2\2\par
+\U869.\fi
+
+\M875. The \\{scan\_direction} subroutine looks at the directional information
+that is enclosed in braces, and also scans ahead to the following character.
+A type code is returned, either \\{open} (if the direction was $(0,0)$),
+or \\{curl} (if the direction was a curl of known value \\{cur\_exp}), or
+\\{given} (if the direction is given by the \\{angle} value that now
+appears in \\{cur\_exp}).
+
+There's nothing difficult about this subroutine, but the program is rather
+lengthy because a variety of potential errors need to be nipped in the bud.
+
+\Y\P\4\&{function}\1\ \37\\{scan\_direction}: \37\\{small\_number};\6
+\4\&{var} \37\|t: \37$\\{given}\to\\{open}$;\C{the type of information found}\6
+\|x: \37\\{scaled};\C{an \|x coordinate}\2\6
+\&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}=\\{curl\_command}$ \1\&{then}\5
+\X876:Scan a curl specification\X\6
+\4\&{else} \X877:Scan a given direction\X;\2\6
+\&{if} $\\{cur\_cmd}\I\\{right\_brace}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"\}"})$;\6
+$\\{help3}(\.{"I\'ve\ scanned\ a\ direction\ spec\ for\ part\ of\ a\ path,"})$\6
+$(\.{"so\ a\ right\ brace\ should\ have\ come\ next."})$\6
+$(\.{"I\ shall\ pretend\ that\ one\ was\ there."})$;\6
+\\{back\_error};\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+$\\{scan\_direction}\K\|t$;\6
+\&{end};\par
+\fi
+
+\M876. \P$\X876:Scan a curl specification\X\S$\6
+\&{begin} \37\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $(\\{cur\_type}\I\\{known})\V(\\{cur\_exp}<0)$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ curl\ has\ been\ replaced\ by\ 1"})$;\5
+$\\{help1}(\.{"A\ curl\ must\ be\ a\ known,\ nonnegative\ number."})$;\5
+$\\{put\_get\_flush\_error}(\\{unity})$;\6
+\&{end};\2\6
+$\|t\K\\{curl}$;\6
+\&{end}\par
+\U875.\fi
+
+\M877. \P$\X877:Scan a given direction\X\S$\6
+\&{begin} \37\\{scan\_expression};\6
+\&{if} $\\{cur\_type}>\\{pair\_type}$ \1\&{then}\5
+\X878:Get given directions separated by commas\X\6
+\4\&{else} \\{known\_pair};\2\6
+\&{if} $(\\{cur\_x}=0)\W(\\{cur\_y}=0)$ \1\&{then}\5
+$\|t\K\\{open}$\6
+\4\&{else} \&{begin} \37$\|t\K\\{given}$;\5
+$\\{cur\_exp}\K\\{n\_arg}(\\{cur\_x},\39\\{cur\_y})$;\6
+\&{end};\2\6
+\&{end}\par
+\U875.\fi
+
+\M878. \P$\X878:Get given directions separated by commas\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Undefined\ x\ coordinate\ has\ been\ replaced\
+by\ 0"})$;\5
+$\\{help5}(\.{"I\ need\ a\ \`known\'\ x\ value\ for\ this\ part\ of\ the\
+path."})$\6
+$(\.{"The\ value\ I\ found\ (see\ above)\ was\ no\ good;"})$\6
+$(\.{"so\ I\'ll\ try\ to\ keep\ going\ by\ using\ zero\ instead."})$\6
+$(\.{"(Chapter\ 27\ of\ The\ METAFONTbook\ explains\ that"})$\6
+$(\.{"you\ might\ want\ to\ type\ \`I\ ???\'\ now.)"})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end};\2\6
+$\|x\K\\{cur\_exp}$;\6
+\&{if} $\\{cur\_cmd}\I\\{comma}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{","})$;\6
+$\\{help2}(\.{"I\'ve\ got\ the\ x\ coordinate\ of\ a\ path\ direction;"})$\6
+$(\.{"will\ look\ for\ the\ y\ coordinate\ next."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Undefined\ y\ coordinate\ has\ been\ replaced\
+by\ 0"})$;\5
+$\\{help5}(\.{"I\ need\ a\ \`known\'\ y\ value\ for\ this\ part\ of\ the\
+path."})$\6
+$(\.{"The\ value\ I\ found\ (see\ above)\ was\ no\ good;"})$\6
+$(\.{"so\ I\'ll\ try\ to\ keep\ going\ by\ using\ zero\ instead."})$\6
+$(\.{"(Chapter\ 27\ of\ The\ METAFONTbook\ explains\ that"})$\6
+$(\.{"you\ might\ want\ to\ type\ \`I\ ???\'\ now.)"})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end};\2\6
+$\\{cur\_y}\K\\{cur\_exp}$;\5
+$\\{cur\_x}\K\|x$;\6
+\&{end}\par
+\U877.\fi
+
+\M879. At this point $\\{right\_type}(\|q)$ is usually \\{open}, but it may
+have been
+set to some other value by a previous splicing operation. We must maintain
+the value of $\\{right\_type}(\|q)$ in unusual cases such as
+`\.{..z1\{z2\}\&\{z3\}z1\{0,0\}..}'.
+
+\Y\P$\4\X879:Put the pre-join direction information into node \|q\X\S$\6
+\&{begin} \37$\|t\K\\{scan\_direction}$;\6
+\&{if} $\|t\I\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{right\_type}(\|q)\K\|t$;\5
+$\\{right\_given}(\|q)\K\\{cur\_exp}$;\6
+\&{if} $\\{left\_type}(\|q)=\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{left\_type}(\|q)\K\|t$;\5
+$\\{left\_given}(\|q)\K\\{cur\_exp}$;\6
+\&{end};\C{note that $\\{left\_given}(\|q)=\\{left\_curl}(\|q)$}\2\6
+\&{end};\2\6
+\&{end}\par
+\U874.\fi
+
+\M880. Since \\{left\_tension} and \\{left\_y} share the same position in knot
+nodes,
+and since \\{left\_given} is similarly equivalent to \\{left\_x}, we use
+\|x and \|y to hold the given direction and tension information when
+there are no explicit control points.
+
+\Y\P$\4\X880:Put the post-join direction information into \|x and \|t\X\S$\6
+\&{begin} \37$\|t\K\\{scan\_direction}$;\6
+\&{if} $\\{right\_type}(\|q)\I\\{explicit}$ \1\&{then}\5
+$\|x\K\\{cur\_exp}$\6
+\4\&{else} $\|t\K\\{explicit}$;\C{the direction information is superfluous}\2\6
+\&{end}\par
+\U874.\fi
+
+\M881. \P$\X881:Determine the tension and/or control points\X\S$\6
+\&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}=\\{tension}$ \1\&{then}\5
+\X882:Set explicit tensions\X\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{controls}$ \1\&{then}\5
+\X884:Set explicit control points\X\6
+\4\&{else} \&{begin} \37$\\{right\_tension}(\|q)\K\\{unity}$;\5
+$\|y\K\\{unity}$;\5
+\\{back\_input};\C{default tension}\6
+\&{goto} \37\\{done};\6
+\&{end};\2\2\6
+\&{if} $\\{cur\_cmd}\I\\{path\_join}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{".."})$;\6
+$\\{help1}(\.{"A\ path\ join\ command\ should\ end\ with\ two\ dots."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+\4\\{done}: \37\&{end}\par
+\U874.\fi
+
+\M882. \P$\X882:Set explicit tensions\X\S$\6
+\&{begin} \37\\{get\_x\_next};\5
+$\|y\K\\{cur\_cmd}$;\6
+\&{if} $\\{cur\_cmd}=\\{at\_least}$ \1\&{then}\5
+\\{get\_x\_next};\2\6
+\\{scan\_primary};\5
+\X883:Make sure that the current expression is a valid tension setting\X;\6
+\&{if} $\|y=\\{at\_least}$ \1\&{then}\5
+$\\{negate}(\\{cur\_exp})$;\2\6
+$\\{right\_tension}(\|q)\K\\{cur\_exp}$;\6
+\&{if} $\\{cur\_cmd}=\\{and\_command}$ \1\&{then}\6
+\&{begin} \37\\{get\_x\_next};\5
+$\|y\K\\{cur\_cmd}$;\6
+\&{if} $\\{cur\_cmd}=\\{at\_least}$ \1\&{then}\5
+\\{get\_x\_next};\2\6
+\\{scan\_primary};\5
+\X883:Make sure that the current expression is a valid tension setting\X;\6
+\&{if} $\|y=\\{at\_least}$ \1\&{then}\5
+$\\{negate}(\\{cur\_exp})$;\2\6
+\&{end};\2\6
+$\|y\K\\{cur\_exp}$;\6
+\&{end}\par
+\U881.\fi
+
+\M883. \P\D \37$\\{min\_tension}\S\\{three\_quarter\_unit}$\par
+\Y\P$\4\X883:Make sure that the current expression is a valid tension setting\X%
+\S$\6
+\&{if} $(\\{cur\_type}\I\\{known})\V(\\{cur\_exp}<\\{min\_tension})$ \1\&{then}%
+\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ tension\ has\ been\ set\ to\ 1"})$;\5
+$\\{help1}(\.{"The\ expression\ above\ should\ have\ been\ a\ number\
+>=3/4."})$;\5
+$\\{put\_get\_flush\_error}(\\{unity})$;\6
+\&{end}\2\par
+\Us882\ET882.\fi
+
+\M884. \P$\X884:Set explicit control points\X\S$\6
+\&{begin} \37$\\{right\_type}(\|q)\K\\{explicit}$;\5
+$\|t\K\\{explicit}$;\5
+\\{get\_x\_next};\5
+\\{scan\_primary};\6
+\\{known\_pair};\5
+$\\{right\_x}(\|q)\K\\{cur\_x}$;\5
+$\\{right\_y}(\|q)\K\\{cur\_y}$;\6
+\&{if} $\\{cur\_cmd}\I\\{and\_command}$ \1\&{then}\6
+\&{begin} \37$\|x\K\\{right\_x}(\|q)$;\5
+$\|y\K\\{right\_y}(\|q)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\\{get\_x\_next};\5
+\\{scan\_primary};\6
+\\{known\_pair};\5
+$\|x\K\\{cur\_x}$;\5
+$\|y\K\\{cur\_y}$;\6
+\&{end};\2\6
+\&{end}\par
+\U881.\fi
+
+\M885. \P$\X885:Convert the right operand, \\{cur\_exp}, into a partial path
+from \\{pp} to~\\{qq}\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_type}\I\\{path\_type}$ \1\&{then}\5
+$\\{pp}\K\\{new\_knot}$\6
+\4\&{else} $\\{pp}\K\\{cur\_exp}$;\2\6
+$\\{qq}\K\\{pp}$;\6
+\&{while} $\\{link}(\\{qq})\I\\{pp}$ \1\&{do}\5
+$\\{qq}\K\\{link}(\\{qq})$;\2\6
+\&{if} $\\{left\_type}(\\{pp})\I\\{endpoint}$ \1\&{then}\C{open up a cycle}\6
+\&{begin} \37$\|r\K\\{copy\_knot}(\\{pp})$;\5
+$\\{link}(\\{qq})\K\|r$;\5
+$\\{qq}\K\|r$;\6
+\&{end};\2\6
+$\\{left\_type}(\\{pp})\K\\{open}$;\5
+$\\{right\_type}(\\{qq})\K\\{open}$;\6
+\&{end}\par
+\U869.\fi
+
+\M886. If a person tries to define an entire path by saying `\.{(x,y)\&cycle}',
+we silently change the specification to `\.{(x,y)..cycle}', since a cycle
+shouldn't have length zero.
+
+\Y\P$\4\X886:Get ready to close a cycle\X\S$\6
+\&{begin} \37$\\{cycle\_hit}\K\\{true}$;\5
+\\{get\_x\_next};\5
+$\\{pp}\K\|p$;\5
+$\\{qq}\K\|p$;\6
+\&{if} $\|d=\\{ampersand}$ \1\&{then}\6
+\&{if} $\|p=\|q$ \1\&{then}\6
+\&{begin} \37$\|d\K\\{path\_join}$;\5
+$\\{right\_tension}(\|q)\K\\{unity}$;\5
+$\|y\K\\{unity}$;\6
+\&{end};\2\2\6
+\&{end}\par
+\U869.\fi
+
+\M887. \P$\X887:Join the partial paths and reset \|p and \|q to the head and
+tail of the result\X\S$\6
+\&{begin} \37\&{if} $\|d=\\{ampersand}$ \1\&{then}\6
+\&{if} $(\\{x\_coord}(\|q)\I\\{x\_coord}(\\{pp}))\V(\\{y\_coord}(\|q)\I\\{y%
+\_coord}(\\{pp}))$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Paths\ don\'t\ touch;\ \`\&\'\ will\ be\
+changed\ to\ \`..\'"})$;\5
+$\\{help3}(\.{"When\ you\ join\ paths\ \`p\&q\',\ the\ ending\ point\ of\ p"})$%
+\6
+$(\.{"must\ be\ exactly\ equal\ to\ the\ starting\ point\ of\ q."})$\6
+$(\.{"So\ I\'m\ going\ to\ pretend\ that\ you\ said\ \`p..q\'\ instead."})$;\5
+\\{put\_get\_error};\5
+$\|d\K\\{path\_join}$;\5
+$\\{right\_tension}(\|q)\K\\{unity}$;\5
+$\|y\K\\{unity}$;\6
+\&{end};\2\2\6
+\X889:Plug an opening in $\\{right\_type}(\\{pp})$, if possible\X;\6
+\&{if} $\|d=\\{ampersand}$ \1\&{then}\5
+\X890:Splice independent paths together\X\6
+\4\&{else} \&{begin} \37\X888:Plug an opening in $\\{right\_type}(\|q)$, if
+possible\X;\6
+$\\{link}(\|q)\K\\{pp}$;\5
+$\\{left\_y}(\\{pp})\K\|y$;\6
+\&{if} $\|t\I\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{left\_x}(\\{pp})\K\|x$;\5
+$\\{left\_type}(\\{pp})\K\|t$;\6
+\&{end};\2\6
+\&{end};\2\6
+$\|q\K\\{qq}$;\6
+\&{end}\par
+\U869.\fi
+
+\M888. \P$\X888:Plug an opening in $\\{right\_type}(\|q)$, if possible\X\S$\6
+\&{if} $\\{right\_type}(\|q)=\\{open}$ \1\&{then}\6
+\&{if} $(\\{left\_type}(\|q)=\\{curl})\V(\\{left\_type}(\|q)=\\{given})$ \1%
+\&{then}\6
+\&{begin} \37$\\{right\_type}(\|q)\K\\{left\_type}(\|q)$;\5
+$\\{right\_given}(\|q)\K\\{left\_given}(\|q)$;\6
+\&{end}\2\2\par
+\U887.\fi
+
+\M889. \P$\X889:Plug an opening in $\\{right\_type}(\\{pp})$, if possible\X\S$\6
+\&{if} $\\{right\_type}(\\{pp})=\\{open}$ \1\&{then}\6
+\&{if} $(\|t=\\{curl})\V(\|t=\\{given})$ \1\&{then}\6
+\&{begin} \37$\\{right\_type}(\\{pp})\K\|t$;\5
+$\\{right\_given}(\\{pp})\K\|x$;\6
+\&{end}\2\2\par
+\U887.\fi
+
+\M890. \P$\X890:Splice independent paths together\X\S$\6
+\&{begin} \37\&{if} $\\{left\_type}(\|q)=\\{open}$ \1\&{then}\6
+\&{if} $\\{right\_type}(\|q)=\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{left\_type}(\|q)\K\\{curl}$;\5
+$\\{left\_curl}(\|q)\K\\{unity}$;\6
+\&{end};\2\2\6
+\&{if} $\\{right\_type}(\\{pp})=\\{open}$ \1\&{then}\6
+\&{if} $\|t=\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{right\_type}(\\{pp})\K\\{curl}$;\5
+$\\{right\_curl}(\\{pp})\K\\{unity}$;\6
+\&{end};\2\2\6
+$\\{right\_type}(\|q)\K\\{right\_type}(\\{pp})$;\5
+$\\{link}(\|q)\K\\{link}(\\{pp})$;\6
+$\\{right\_x}(\|q)\K\\{right\_x}(\\{pp})$;\5
+$\\{right\_y}(\|q)\K\\{right\_y}(\\{pp})$;\5
+$\\{free\_node}(\\{pp},\39\\{knot\_node\_size})$;\6
+\&{if} $\\{qq}=\\{pp}$ \1\&{then}\5
+$\\{qq}\K\|q$;\2\6
+\&{end}\par
+\U887.\fi
+
+\M891. \P$\X891:Choose control points for the path and put the result into %
+\\{cur\_exp}\X\S$\6
+\&{if} $\\{cycle\_hit}$ \1\&{then}\6
+\&{begin} \37\&{if} $\|d=\\{ampersand}$ \1\&{then}\5
+$\|p\K\|q$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{left\_type}(\|p)\K\\{endpoint}$;\6
+\&{if} $\\{right\_type}(\|p)=\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{right\_type}(\|p)\K\\{curl}$;\5
+$\\{right\_curl}(\|p)\K\\{unity}$;\6
+\&{end};\2\6
+$\\{right\_type}(\|q)\K\\{endpoint}$;\6
+\&{if} $\\{left\_type}(\|q)=\\{open}$ \1\&{then}\6
+\&{begin} \37$\\{left\_type}(\|q)\K\\{curl}$;\5
+$\\{left\_curl}(\|q)\K\\{unity}$;\6
+\&{end};\2\6
+$\\{link}(\|q)\K\|p$;\6
+\&{end};\2\6
+$\\{make\_choices}(\|p)$;\5
+$\\{cur\_type}\K\\{path\_type}$;\5
+$\\{cur\_exp}\K\|p$\par
+\U869.\fi
+
+\M892. Finally, we sometimes need to scan an expression whose value is
+supposed to be either \\{true\_code} or \\{false\_code}.
+
+\Y\P$\4\X823:Declare the basic parsing subroutines\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{get\_boolean};\2\6
+\&{begin} \37\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{boolean\_type}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Undefined\ condition\ will\ be\ treated\ as\ %
+\`false\'"})$;\5
+$\\{help2}(\.{"The\ expression\ shown\ above\ should\ have\ had\ a\
+definite"})$\6
+$(\.{"true-or-false\ value.\ I\'m\ changing\ it\ to\ \`false\'."})$;\6
+$\\{put\_get\_flush\_error}(\\{false\_code})$;\5
+$\\{cur\_type}\K\\{boolean\_type}$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\N893. \[42] Doing the operations.
+The purpose of parsing is primarily to permit people to avoid piles of
+parentheses. But the real work is done after the structure of an expression
+has been recognized; that's when new expressions are generated. We
+turn now to the guts of \MF, which handles individual operators that
+have come through the parsing mechanism.
+
+We'll start with the easy ones that take no operands, then work our way
+up to operators with one and ultimately two arguments. In other words,
+we will write the three procedures \\{do\_nullary}, \\{do\_unary}, and \\{do%
+\_binary}
+that are invoked periodically by the expression scanners.
+
+First let's make sure that all of the primitive operators are in the
+hash table. Although \\{scan\_primary} and its relatives made use of the
+\\{cmd} code for these operators, the \\{do} routines base everything
+on the \\{mod} code. For example, \\{do\_binary} doesn't care whether the
+operation it performs is a \\{primary\_binary} or \\{secondary\_binary}, etc.
+
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"true"},\39\\{nullary},\39\\{true\_code})$;\6
+$\\{primitive}(\.{"false"},\39\\{nullary},\39\\{false\_code})$;\6
+$\\{primitive}(\.{"nullpicture"},\39\\{nullary},\39\\{null\_picture\_code})$;\6
+$\\{primitive}(\.{"nullpen"},\39\\{nullary},\39\\{null\_pen\_code})$;\6
+$\\{primitive}(\.{"jobname"},\39\\{nullary},\39\\{job\_name\_op})$;\6
+$\\{primitive}(\.{"readstring"},\39\\{nullary},\39\\{read\_string\_op})$;\6
+$\\{primitive}(\.{"pencircle"},\39\\{nullary},\39\\{pen\_circle})$;\6
+$\\{primitive}(\.{"normaldeviate"},\39\\{nullary},\39\\{normal\_deviate})$;\6
+$\\{primitive}(\.{"odd"},\39\\{unary},\39\\{odd\_op})$;\6
+$\\{primitive}(\.{"known"},\39\\{unary},\39\\{known\_op})$;\6
+$\\{primitive}(\.{"unknown"},\39\\{unary},\39\\{unknown\_op})$;\6
+$\\{primitive}(\.{"not"},\39\\{unary},\39\\{not\_op})$;\6
+$\\{primitive}(\.{"decimal"},\39\\{unary},\39\\{decimal})$;\6
+$\\{primitive}(\.{"reverse"},\39\\{unary},\39\\{reverse})$;\6
+$\\{primitive}(\.{"makepath"},\39\\{unary},\39\\{make\_path\_op})$;\6
+$\\{primitive}(\.{"makepen"},\39\\{unary},\39\\{make\_pen\_op})$;\6
+$\\{primitive}(\.{"totalweight"},\39\\{unary},\39\\{total\_weight\_op})$;\6
+$\\{primitive}(\.{"oct"},\39\\{unary},\39\\{oct\_op})$;\6
+$\\{primitive}(\.{"hex"},\39\\{unary},\39\\{hex\_op})$;\6
+$\\{primitive}(\.{"ASCII"},\39\\{unary},\39\\{ASCII\_op})$;\6
+$\\{primitive}(\.{"char"},\39\\{unary},\39\\{char\_op})$;\6
+$\\{primitive}(\.{"length"},\39\\{unary},\39\\{length\_op})$;\6
+$\\{primitive}(\.{"turningnumber"},\39\\{unary},\39\\{turning\_op})$;\6
+$\\{primitive}(\.{"xpart"},\39\\{unary},\39\\{x\_part})$;\6
+$\\{primitive}(\.{"ypart"},\39\\{unary},\39\\{y\_part})$;\6
+$\\{primitive}(\.{"xxpart"},\39\\{unary},\39\\{xx\_part})$;\6
+$\\{primitive}(\.{"xypart"},\39\\{unary},\39\\{xy\_part})$;\6
+$\\{primitive}(\.{"yxpart"},\39\\{unary},\39\\{yx\_part})$;\6
+$\\{primitive}(\.{"yypart"},\39\\{unary},\39\\{yy\_part})$;\6
+$\\{primitive}(\.{"sqrt"},\39\\{unary},\39\\{sqrt\_op})$;\6
+$\\{primitive}(\.{"mexp"},\39\\{unary},\39\\{m\_exp\_op})$;\6
+$\\{primitive}(\.{"mlog"},\39\\{unary},\39\\{m\_log\_op})$;\6
+$\\{primitive}(\.{"sind"},\39\\{unary},\39\\{sin\_d\_op})$;\6
+$\\{primitive}(\.{"cosd"},\39\\{unary},\39\\{cos\_d\_op})$;\6
+$\\{primitive}(\.{"floor"},\39\\{unary},\39\\{floor\_op})$;\6
+$\\{primitive}(\.{"uniformdeviate"},\39\\{unary},\39\\{uniform\_deviate})$;\6
+$\\{primitive}(\.{"charexists"},\39\\{unary},\39\\{char\_exists\_op})$;\6
+$\\{primitive}(\.{"angle"},\39\\{unary},\39\\{angle\_op})$;\6
+$\\{primitive}(\.{"cycle"},\39\\{cycle},\39\\{cycle\_op})$;\6
+$\\{primitive}(\.{"+"},\39\\{plus\_or\_minus},\39\\{plus})$;\6
+$\\{primitive}(\.{"-"},\39\\{plus\_or\_minus},\39\\{minus})$;\6
+$\\{primitive}(\.{"*"},\39\\{secondary\_binary},\39\\{times})$;\6
+$\\{primitive}(\.{"/"},\39\\{slash},\39\\{over})$;\5
+$\\{eqtb}[\\{frozen\_slash}]\K\\{eqtb}[\\{cur\_sym}]$;\6
+$\\{primitive}(\.{"++"},\39\\{tertiary\_binary},\39\\{pythag\_add})$;\6
+$\\{primitive}(\.{"+-+"},\39\\{tertiary\_binary},\39\\{pythag\_sub})$;\6
+$\\{primitive}(\.{"and"},\39\\{and\_command},\39\\{and\_op})$;\6
+$\\{primitive}(\.{"or"},\39\\{tertiary\_binary},\39\\{or\_op})$;\6
+$\\{primitive}(\.{"<"},\39\\{expression\_binary},\39\\{less\_than})$;\6
+$\\{primitive}(\.{"<="},\39\\{expression\_binary},\39\\{less\_or\_equal})$;\6
+$\\{primitive}(\.{">"},\39\\{expression\_binary},\39\\{greater\_than})$;\6
+$\\{primitive}(\.{">="},\39\\{expression\_binary},\39\\{greater\_or\_equal})$;\6
+$\\{primitive}(\.{"="},\39\\{equals},\39\\{equal\_to})$;\6
+$\\{primitive}(\.{"<>"},\39\\{expression\_binary},\39\\{unequal\_to})$;\6
+$\\{primitive}(\.{"substring"},\39\\{primary\_binary},\39\\{substring\_of})$;\6
+$\\{primitive}(\.{"subpath"},\39\\{primary\_binary},\39\\{subpath\_of})$;\6
+$\\{primitive}(\.{"directiontime"},\39\\{primary\_binary},\39\\{direction\_time%
+\_of})$;\6
+$\\{primitive}(\.{"point"},\39\\{primary\_binary},\39\\{point\_of})$;\6
+$\\{primitive}(\.{"precontrol"},\39\\{primary\_binary},\39\\{precontrol\_of})$;%
+\6
+$\\{primitive}(\.{"postcontrol"},\39\\{primary\_binary},\39\\{postcontrol%
+\_of})$;\6
+$\\{primitive}(\.{"penoffset"},\39\\{primary\_binary},\39\\{pen\_offset\_of})$;%
+\6
+$\\{primitive}(\.{"\&"},\39\\{ampersand},\39\\{concatenate})$;\6
+$\\{primitive}(\.{"rotated"},\39\\{secondary\_binary},\39\\{rotated\_by})$;\6
+$\\{primitive}(\.{"slanted"},\39\\{secondary\_binary},\39\\{slanted\_by})$;\6
+$\\{primitive}(\.{"scaled"},\39\\{secondary\_binary},\39\\{scaled\_by})$;\6
+$\\{primitive}(\.{"shifted"},\39\\{secondary\_binary},\39\\{shifted\_by})$;\6
+$\\{primitive}(\.{"transformed"},\39\\{secondary\_binary},\39\\{transformed%
+\_by})$;\6
+$\\{primitive}(\.{"xscaled"},\39\\{secondary\_binary},\39\\{x\_scaled})$;\6
+$\\{primitive}(\.{"yscaled"},\39\\{secondary\_binary},\39\\{y\_scaled})$;\6
+$\\{primitive}(\.{"zscaled"},\39\\{secondary\_binary},\39\\{z\_scaled})$;\6
+$\\{primitive}(\.{"intersectiontimes"},\39\\{tertiary\_binary},\39%
+\\{intersect})$;\par
+\fi
+
+\M894. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4$\\{nullary},\39\\{unary},\39\\{primary\_binary},\39\\{secondary\_binary},\39%
+\\{tertiary\_binary},\39\\{expression\_binary},\39\\{cycle},\39\\{plus\_or%
+\_minus},\39\\{slash},\39\\{ampersand},\39\\{equals},\39\\{and\_command}$: \37$%
+\\{print\_op}(\|m)$;\par
+\fi
+
+\M895. OK, let's look at the simplest \\{do} procedure first.
+
+\Y\P\4\&{procedure}\1\ \37$\\{do\_nullary}(\|c:\\{quarterword})$;\6
+\4\&{var} \37\|k: \37\\{integer};\C{all-purpose loop index}\2\6
+\&{begin} \37\\{check\_arith};\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>\\{two}$ \1\&{then}\5
+$\\{show\_cmd\_mod}(\\{nullary},\39\|c)$;\2\6
+\&{case} $\|c$ \1\&{of}\6
+\4$\\{true\_code},\39\\{false\_code}$: \37\&{begin} \37$\\{cur\_type}\K%
+\\{boolean\_type}$;\5
+$\\{cur\_exp}\K\|c$;\6
+\&{end};\6
+\4\\{null\_picture\_code}: \37\&{begin} \37$\\{cur\_type}\K\\{picture\_type}$;\5
+$\\{cur\_exp}\K\\{get\_node}(\\{edge\_header\_size})$;\5
+$\\{init\_edges}(\\{cur\_exp})$;\6
+\&{end};\6
+\4\\{null\_pen\_code}: \37\&{begin} \37$\\{cur\_type}\K\\{pen\_type}$;\5
+$\\{cur\_exp}\K\\{null\_pen}$;\6
+\&{end};\6
+\4\\{normal\_deviate}: \37\&{begin} \37$\\{cur\_type}\K\\{known}$;\5
+$\\{cur\_exp}\K\\{norm\_rand}$;\6
+\&{end};\6
+\4\\{pen\_circle}: \37\X896:Make a special knot node for \&{pencircle}\X;\6
+\4\\{job\_name\_op}: \37\&{begin} \37\&{if} $\\{job\_name}=0$ \1\&{then}\5
+\\{open\_log\_file};\2\6
+$\\{cur\_type}\K\\{string\_type}$;\5
+$\\{cur\_exp}\K\\{job\_name}$;\6
+\&{end};\6
+\4\\{read\_string\_op}: \37\X897:Read a string from the terminal\X;\2\6
+\&{end};\C{there are no other cases}\6
+\\{check\_arith};\6
+\&{end};\par
+\fi
+
+\M896. \P$\X896:Make a special knot node for \&{pencircle}\X\S$\6
+\&{begin} \37$\\{cur\_type}\K\\{future\_pen}$;\5
+$\\{cur\_exp}\K\\{get\_node}(\\{knot\_node\_size})$;\5
+$\\{left\_type}(\\{cur\_exp})\K\\{open}$;\5
+$\\{right\_type}(\\{cur\_exp})\K\\{open}$;\5
+$\\{link}(\\{cur\_exp})\K\\{cur\_exp}$;\6
+$\\{x\_coord}(\\{cur\_exp})\K0$;\5
+$\\{y\_coord}(\\{cur\_exp})\K0$;\6
+$\\{left\_x}(\\{cur\_exp})\K\\{unity}$;\5
+$\\{left\_y}(\\{cur\_exp})\K0$;\6
+$\\{right\_x}(\\{cur\_exp})\K0$;\5
+$\\{right\_y}(\\{cur\_exp})\K\\{unity}$;\6
+\&{end}\par
+\U895.\fi
+
+\M897. \P$\X897:Read a string from the terminal\X\S$\6
+\&{begin} \37\&{if} $\\{interaction}\L\\{nonstop\_mode}$ \1\&{then}\5
+$\\{fatal\_error}(\.{"***\ (cannot\ readstring\ in\ nonstop\ modes)"})$;\2\6
+\\{begin\_file\_reading};\5
+$\\{name}\K1$;\5
+$\\{prompt\_input}(\.{""})$;\5
+$\\{str\_room}(\\{last}-\\{start})$;\6
+\&{for} $\|k\K\\{start}\mathrel{\&{to}}\\{last}-1$ \1\&{do}\5
+$\\{append\_char}(\\{buffer}[\|k])$;\2\6
+\\{end\_file\_reading};\5
+$\\{cur\_type}\K\\{string\_type}$;\5
+$\\{cur\_exp}\K\\{make\_string}$;\6
+\&{end}\par
+\U895.\fi
+
+\M898. Things get a bit more interesting when there's an operand. The
+operand to \\{do\_unary} appears in \\{cur\_type} and \\{cur\_exp}.
+
+\Y\P\hbox{\4}\X899:Declare unary action procedures\X\6
+\4\&{procedure}\1\ \37$\\{do\_unary}(\|c:\\{quarterword})$;\6
+\4\&{var} \37$\|p,\39\|q$: \37\\{pointer};\C{for list manipulation}\6
+\|x: \37\\{integer};\C{a temporary register}\2\6
+\&{begin} \37\\{check\_arith};\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>\\{two}$ \1\&{then}\5
+\X902:Trace the current unary operation\X;\2\6
+\&{case} $\|c$ \1\&{of}\6
+\4\\{plus}: \37\&{if} $\\{cur\_type}<\\{pair\_type}$ \1\&{then}\6
+\&{if} $\\{cur\_type}\I\\{picture\_type}$ \1\&{then}\5
+$\\{bad\_unary}(\\{plus})$;\2\2\6
+\4\\{minus}: \37\X903:Negate the current expression\X;\6
+\hbox{\4}\X905:Additional cases of unary operators\X\2\6
+\&{end};\C{there are no other cases}\6
+\\{check\_arith};\6
+\&{end};\par
+\fi
+
+\M899. The \\{nice\_pair} function returns \\{true} if both components of a
+pair
+are known.
+
+\Y\P$\4\X899:Declare unary action procedures\X\S$\6
+\4\&{function}\1\ \37$\\{nice\_pair}(\|p:\\{integer};\,\35\|t:%
+\\{quarterword})$: \37\\{boolean};\6
+\4\&{label} \37\\{exit};\2\6
+\&{begin} \37\&{if} $\|t=\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{value}(\|p)$;\6
+\&{if} $\\{type}(\\{x\_part\_loc}(\|p))=\\{known}$ \1\&{then}\6
+\&{if} $\\{type}(\\{y\_part\_loc}(\|p))=\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{nice\_pair}\K\\{true}$;\5
+\&{return};\6
+\&{end};\2\2\6
+\&{end};\2\6
+$\\{nice\_pair}\K\\{false}$;\6
+\4\\{exit}: \37\&{end};\par
+\As900, 901, 904, 908, 910, 913, 916\ETs919.
+\U898.\fi
+
+\M900. \P$\X899:Declare unary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{print\_known\_or\_unknown\_type}(\|t:\\{small%
+\_number};\,\35\|v:\\{integer})$;\2\6
+\&{begin} \37$\\{print\_char}(\.{"("})$;\6
+\&{if} $\|t<\\{dependent}$ \1\&{then}\6
+\&{if} $\|t\I\\{pair\_type}$ \1\&{then}\5
+$\\{print\_type}(\|t)$\6
+\4\&{else} \&{if} $\\{nice\_pair}(\|v,\39\\{pair\_type})$ \1\&{then}\5
+$\\{print}(\.{"pair"})$\6
+\4\&{else} $\\{print}(\.{"unknown\ pair"})$\2\2\6
+\4\&{else} $\\{print}(\.{"unknown\ numeric"})$;\2\6
+$\\{print\_char}(\.{")"})$;\6
+\&{end};\par
+\fi
+
+\M901. \P$\X899:Declare unary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{bad\_unary}(\|c:\\{quarterword})$;\2\6
+\&{begin} \37$\\{exp\_err}(\.{"Not\ implemented:\ "})$;\5
+$\\{print\_op}(\|c)$;\5
+$\\{print\_known\_or\_unknown\_type}(\\{cur\_type},\39\\{cur\_exp})$;\5
+$\\{help3}(\.{"I\'m\ afraid\ I\ don\'t\ know\ how\ to\ apply\ that\ operation\
+to\ that"})$\6
+$(\.{"particular\ type.\ Continue,\ and\ I\'ll\ simply\ return\ the"})$\6
+$(\.{"argument\ (shown\ above)\ as\ the\ result\ of\ the\ operation."})$;\5
+\\{put\_get\_error};\6
+\&{end};\par
+\fi
+
+\M902. \P$\X902:Trace the current unary operation\X\S$\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{"})$;\5
+$\\{print\_op}(\|c)$;\5
+$\\{print\_char}(\.{"("})$;\6
+$\\{print\_exp}(\\{null},\390)$;\C{show the operand, but not verbosely}\6
+$\\{print}(\.{")\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\par
+\U898.\fi
+
+\M903. Negation is easy except when the current expression
+is of type \\{independent}, or when it is a pair with one or more
+\\{independent} components.
+
+It is tempting to argue that the negative of an independent variable
+is an independent variable, hence we don't have to do anything when
+negating it. The fallacy is that other dependent variables pointing
+to the current expression must change the sign of their
+coefficients if we make no change to the current expression.
+
+Instead, we work around the problem by copying the current expression
+and recycling it afterwards (cf.~the \\{stash\_in} routine).
+
+\Y\P$\4\X903:Negate the current expression\X\S$\6
+\&{case} $\\{cur\_type}$ \1\&{of}\6
+\4$\\{pair\_type},\39\\{independent}$: \37\&{begin} \37$\|q\K\\{cur\_exp}$;\5
+$\\{make\_exp\_copy}(\|q)$;\6
+\&{if} $\\{cur\_type}=\\{dependent}$ \1\&{then}\5
+$\\{negate\_dep\_list}(\\{dep\_list}(\\{cur\_exp}))$\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{value}(\\{cur\_exp})$;\6
+\&{if} $\\{type}(\\{x\_part\_loc}(\|p))=\\{known}$ \1\&{then}\5
+$\\{negate}(\\{value}(\\{x\_part\_loc}(\|p)))$\6
+\4\&{else} $\\{negate\_dep\_list}(\\{dep\_list}(\\{x\_part\_loc}(\|p)))$;\2\6
+\&{if} $\\{type}(\\{y\_part\_loc}(\|p))=\\{known}$ \1\&{then}\5
+$\\{negate}(\\{value}(\\{y\_part\_loc}(\|p)))$\6
+\4\&{else} $\\{negate\_dep\_list}(\\{dep\_list}(\\{y\_part\_loc}(\|p)))$;\2\6
+\&{end};\C{if $\\{cur\_type}=\\{known}$ then $\\{cur\_exp}=0$}\2\2\6
+$\\{recycle\_value}(\|q)$;\5
+$\\{free\_node}(\|q,\39\\{value\_node\_size})$;\6
+\&{end};\6
+\4$\\{dependent},\39\\{proto\_dependent}$: \37$\\{negate\_dep\_list}(\\{dep%
+\_list}(\\{cur\_exp}))$;\6
+\4\\{known}: \37$\\{negate}(\\{cur\_exp})$;\6
+\4\\{picture\_type}: \37$\\{negate\_edges}(\\{cur\_exp})$;\6
+\4\&{othercases} \37$\\{bad\_unary}(\\{minus})$\2\6
+\&{endcases}\par
+\U898.\fi
+
+\M904. \P$\X899:Declare unary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{negate\_dep\_list}(\|p:\\{pointer})$;\6
+\4\&{label} \37\\{exit};\2\6
+\&{begin} \37\~ \1\&{loop}\ \&{begin} \37$\\{negate}(\\{value}(\|p))$;\6
+\&{if} $\\{info}(\|p)=\\{null}$ \1\&{then}\5
+\&{return};\2\6
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M905. \P$\X905:Additional cases of unary operators\X\S$\6
+\4\\{not\_op}: \37\&{if} $\\{cur\_type}\I\\{boolean\_type}$ \1\&{then}\5
+$\\{bad\_unary}(\\{not\_op})$\6
+\4\&{else} $\\{cur\_exp}\K\\{true\_code}+\\{false\_code}-\\{cur\_exp}$;\2\par
+\As906, 907, 909, 912, 915, 917, 918, 920\ETs921.
+\U898.\fi
+
+\M906. \P\D \37$\\{three\_sixty\_units}\S23592960$\C{that's $360\ast\\{unity}$}%
+\par
+\P\D \37$\\{boolean\_reset}(\#)\S$\1\6
+\&{if} $\#$ \1\&{then}\5
+$\\{cur\_exp}\K\\{true\_code}$\ \&{else} $\\{cur\_exp}\K\\{false\_code}$\2\2\par
+\Y\P$\4\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4$\\{sqrt\_op},\39\\{m\_exp\_op},\39\\{m\_log\_op},\39\\{sin\_d\_op},\39\\{cos%
+\_d\_op},\39\\{floor\_op},\39\\{uniform\_deviate},\39\\{odd\_op},\39\\{char%
+\_exists\_op}$: \37\hbox{}\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+$\\{bad\_unary}(\|c)$\6
+\4\&{else} \&{case} $\|c$ \1\&{of}\6
+\4\\{sqrt\_op}: \37$\\{cur\_exp}\K\\{square\_rt}(\\{cur\_exp})$;\6
+\4\\{m\_exp\_op}: \37$\\{cur\_exp}\K\\{m\_exp}(\\{cur\_exp})$;\6
+\4\\{m\_log\_op}: \37$\\{cur\_exp}\K\\{m\_log}(\\{cur\_exp})$;\6
+\4$\\{sin\_d\_op},\39\\{cos\_d\_op}$: \37\&{begin} \37$\\{n\_sin\_cos}((\\{cur%
+\_exp}\mathbin{\&{mod}}\\{three\_sixty\_units})\ast16)$;\6
+\&{if} $\|c=\\{sin\_d\_op}$ \1\&{then}\5
+$\\{cur\_exp}\K\\{round\_fraction}(\\{n\_sin})$\6
+\4\&{else} $\\{cur\_exp}\K\\{round\_fraction}(\\{n\_cos})$;\2\6
+\&{end};\6
+\4\\{floor\_op}: \37$\\{cur\_exp}\K\\{floor\_scaled}(\\{cur\_exp})$;\6
+\4\\{uniform\_deviate}: \37$\\{cur\_exp}\K\\{unif\_rand}(\\{cur\_exp})$;\6
+\4\\{odd\_op}: \37\&{begin} \37$\\{boolean\_reset}(\\{odd}(\\{round\_unscaled}(%
+\\{cur\_exp})))$;\5
+$\\{cur\_type}\K\\{boolean\_type}$;\6
+\&{end};\6
+\4\\{char\_exists\_op}: \37\X1181:Determine if a character has been shipped out%
+\X;\2\6
+\&{end};\C{there are no other cases}\2\par
+\fi
+
+\M907. \P$\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4\\{angle\_op}: \37\&{if} $\\{nice\_pair}(\\{cur\_exp},\39\\{cur\_type})$ \1%
+\&{then}\6
+\&{begin} \37$\|p\K\\{value}(\\{cur\_exp})$;\5
+$\|x\K\\{n\_arg}(\\{value}(\\{x\_part\_loc}(\|p)),\39\\{value}(\\{y\_part%
+\_loc}(\|p)))$;\6
+\&{if} $\|x\G0$ \1\&{then}\5
+$\\{flush\_cur\_exp}((\|x+8)\mathbin{\&{div}}16)$\6
+\4\&{else} $\\{flush\_cur\_exp}(-((-\|x+8)\mathbin{\&{div}}16))$;\2\6
+\&{end}\6
+\4\&{else} $\\{bad\_unary}(\\{angle\_op})$;\2\par
+\fi
+
+\M908. If the current expression is a pair, but the context wants it to
+be a path, we call \\{pair\_to\_path}.
+
+\Y\P$\4\X899:Declare unary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{pair\_to\_path};\2\6
+\&{begin} \37$\\{cur\_exp}\K\\{new\_knot}$;\5
+$\\{cur\_type}\K\\{path\_type}$;\6
+\&{end};\par
+\fi
+
+\M909. \P$\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4$\\{x\_part},\39\\{y\_part}$: \37\&{if} $(\\{cur\_type}\L\\{pair\_type})\W(%
+\\{cur\_type}\G\\{transform\_type})$ \1\&{then}\5
+$\\{take\_part}(\|c)$\6
+\4\&{else} $\\{bad\_unary}(\|c)$;\2\6
+\4$\\{xx\_part},\39\\{xy\_part},\39\\{yx\_part},\39\\{yy\_part}$: \37\&{if} $%
+\\{cur\_type}=\\{transform\_type}$ \1\&{then}\5
+$\\{take\_part}(\|c)$\6
+\4\&{else} $\\{bad\_unary}(\|c)$;\2\par
+\fi
+
+\M910. In the following procedure, \\{cur\_exp} points to a capsule, which
+points to
+a big node. We want to delete all but one part of the big node.
+
+\Y\P$\4\X899:Declare unary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{take\_part}(\|c:\\{quarterword})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the big node}\2\6
+\&{begin} \37$\|p\K\\{value}(\\{cur\_exp})$;\5
+$\\{value}(\\{temp\_val})\K\|p$;\5
+$\\{type}(\\{temp\_val})\K\\{cur\_type}$;\5
+$\\{link}(\|p)\K\\{temp\_val}$;\5
+$\\{free\_node}(\\{cur\_exp},\39\\{value\_node\_size})$;\5
+$\\{make\_exp\_copy}(\|p+2\ast(\|c-\\{x\_part}))$;\5
+$\\{recycle\_value}(\\{temp\_val})$;\6
+\&{end};\par
+\fi
+
+\M911. \P$\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}%
+\S$\6
+$\\{name\_type}(\\{temp\_val})\K\\{capsule}$;\par
+\fi
+
+\M912. \P$\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4\\{char\_op}: \37\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+$\\{bad\_unary}(\\{char\_op})$\6
+\4\&{else} \&{begin} \37$\\{cur\_exp}\K\\{round\_unscaled}(\\{cur\_exp})%
+\mathbin{\&{mod}}256$;\5
+$\\{cur\_type}\K\\{string\_type}$;\6
+\&{if} $\\{cur\_exp}<0$ \1\&{then}\5
+$\\{cur\_exp}\K\\{cur\_exp}+256$;\2\6
+\&{if} $\\{length}(\\{cur\_exp})\I1$ \1\&{then}\6
+\&{begin} \37$\\{str\_room}(1)$;\5
+$\\{append\_char}(\\{cur\_exp})$;\5
+$\\{cur\_exp}\K\\{make\_string}$;\6
+\&{end};\2\6
+\&{end};\2\6
+\4\\{decimal}: \37\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+$\\{bad\_unary}(\\{decimal})$\6
+\4\&{else} \&{begin} \37$\\{old\_setting}\K\\{selector}$;\5
+$\\{selector}\K\\{new\_string}$;\5
+$\\{print\_scaled}(\\{cur\_exp})$;\5
+$\\{cur\_exp}\K\\{make\_string}$;\5
+$\\{selector}\K\\{old\_setting}$;\5
+$\\{cur\_type}\K\\{string\_type}$;\6
+\&{end};\2\6
+\4$\\{oct\_op},\39\\{hex\_op},\39\\{ASCII\_op}$: \37\&{if} $\\{cur\_type}\I%
+\\{string\_type}$ \1\&{then}\5
+$\\{bad\_unary}(\|c)$\6
+\4\&{else} $\\{str\_to\_num}(\|c)$;\2\par
+\fi
+
+\M913. \P$\X899:Declare unary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{str\_to\_num}(\|c:\\{quarterword})$;\C{converts a
+string to a number}\6
+\4\&{var} \37\|n: \37\\{integer};\C{accumulator}\6
+\|m: \37\\{ASCII\_code};\C{current character}\6
+\|k: \37\\{pool\_pointer};\C{index into \\{str\_pool}}\6
+\|b: \37$8\to16$;\C{radix of conversion}\6
+\\{bad\_char}: \37\\{boolean};\C{did the string contain an invalid digit?}\2\6
+\&{begin} \37\&{if} $\|c=\\{ASCII\_op}$ \1\&{then}\6
+\&{if} $\\{length}(\\{cur\_exp})=0$ \1\&{then}\5
+$\|n\K-1$\6
+\4\&{else} $\|n\K\\{so}(\\{str\_pool}[\\{str\_start}[\\{cur\_exp}]])$\2\6
+\4\&{else} \&{begin} \37\&{if} $\|c=\\{oct\_op}$ \1\&{then}\5
+$\|b\K8$\ \&{else} $\|b\K16$;\2\6
+$\|n\K0$;\5
+$\\{bad\_char}\K\\{false}$;\6
+\&{for} $\|k\K\\{str\_start}[\\{cur\_exp}]\mathrel{\&{to}}\\{str\_start}[\\{cur%
+\_exp}+1]-1$ \1\&{do}\6
+\&{begin} \37$\|m\K\\{so}(\\{str\_pool}[\|k])$;\6
+\&{if} $(\|m\G\.{"0"})\W(\|m\L\.{"9"})$ \1\&{then}\5
+$\|m\K\|m-\.{"0"}$\6
+\4\&{else} \&{if} $(\|m\G\.{"A"})\W(\|m\L\.{"F"})$ \1\&{then}\5
+$\|m\K\|m-\.{"A"}+10$\6
+\4\&{else} \&{if} $(\|m\G\.{"a"})\W(\|m\L\.{"f"})$ \1\&{then}\5
+$\|m\K\|m-\.{"a"}+10$\6
+\4\&{else} \&{begin} \37$\\{bad\_char}\K\\{true}$;\5
+$\|m\K0$;\6
+\&{end};\2\2\2\6
+\&{if} $\|m\G\|b$ \1\&{then}\6
+\&{begin} \37$\\{bad\_char}\K\\{true}$;\5
+$\|m\K0$;\6
+\&{end};\2\6
+\&{if} $\|n<32768\mathbin{\&{div}}\|b$ \1\&{then}\5
+$\|n\K\|n\ast\|b+\|m$\ \&{else} $\|n\K32767$;\2\6
+\&{end};\2\6
+\X914:Give error messages if \\{bad\_char} or $\|n\G4096$\X;\6
+\&{end};\2\6
+$\\{flush\_cur\_exp}(\|n\ast\\{unity})$;\6
+\&{end};\par
+\fi
+
+\M914. \P$\X914:Give error messages if \\{bad\_char} or $\|n\G4096$\X\S$\6
+\&{if} $\\{bad\_char}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"String\ contains\ illegal\ digits"})$;\6
+\&{if} $\|c=\\{oct\_op}$ \1\&{then}\5
+$\\{help1}(\.{"I\ zeroed\ out\ characters\ that\ weren\'t\ in\ the\ range\
+0..7."})$\6
+\4\&{else} $\\{help1}(\.{"I\ zeroed\ out\ characters\ that\ weren\'t\ hex\
+digits."})$;\2\6
+\\{put\_get\_error};\6
+\&{end};\2\6
+\&{if} $\|n>4095$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Number\ too\ large\ ("})$;\5
+$\\{print\_int}(\|n)$;\5
+$\\{print\_char}(\.{")"})$;\5
+$\\{help1}(\.{"I\ have\ trouble\ with\ numbers\ greater\ than\ 4095;\ watch\
+out."})$;\5
+\\{put\_get\_error};\6
+\&{end}\2\par
+\U913.\fi
+
+\M915. The length operation is somewhat unusual in that it applies to a variety
+of different types of operands.
+
+\Y\P$\4\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4\\{length\_op}: \37\&{if} $\\{cur\_type}=\\{string\_type}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(\\{length}(\\{cur\_exp})\ast\\{unity})$\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{path\_type}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(\\{path\_length})$\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\5
+$\\{cur\_exp}\K\\{abs}(\\{cur\_exp})$\6
+\4\&{else} \&{if} $\\{nice\_pair}(\\{cur\_exp},\39\\{cur\_type})$ \1\&{then}\5
+$\\{flush\_cur\_exp}(\\{pyth\_add}(\\{value}(\\{x\_part\_loc}(\\{value}(\\{cur%
+\_exp}))),\39\30\\{value}(\\{y\_part\_loc}(\\{value}(\\{cur\_exp})))))$\6
+\4\&{else} $\\{bad\_unary}(\|c)$;\2\2\2\2\par
+\fi
+
+\M916. \P$\X899:Declare unary action procedures\X\mathrel{+}\S$\6
+\4\&{function}\1\ \37\\{path\_length}: \37\\{scaled};\C{computes the length of
+the current path}\6
+\4\&{var} \37\|n: \37\\{scaled};\C{the path length so far}\6
+\|p: \37\\{pointer};\C{traverser}\2\6
+\&{begin} \37$\|p\K\\{cur\_exp}$;\6
+\&{if} $\\{left\_type}(\|p)=\\{endpoint}$ \1\&{then}\5
+$\|n\K-\\{unity}$\ \&{else} $\|n\K0$;\2\6
+\1\&{repeat} \37$\|p\K\\{link}(\|p)$;\5
+$\|n\K\|n+\\{unity}$;\6
+\4\&{until}\5
+$\|p=\\{cur\_exp}$;\2\6
+$\\{path\_length}\K\|n$;\6
+\&{end};\par
+\fi
+
+\M917. The turning number is computed only with respect to null pens. A
+different
+pen might affect the turning number, in degenerate cases, because autorounding
+will produce a slightly different path, or because excessively large
+coordinates
+might be truncated.
+
+\Y\P$\4\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4\\{turning\_op}: \37\&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(0)$\6
+\4\&{else} \&{if} $\\{cur\_type}\I\\{path\_type}$ \1\&{then}\5
+$\\{bad\_unary}(\\{turning\_op})$\6
+\4\&{else} \&{if} $\\{left\_type}(\\{cur\_exp})=\\{endpoint}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(0)$\C{not a cyclic path}\6
+\4\&{else} \&{begin} \37$\\{cur\_pen}\K\\{null\_pen}$;\5
+$\\{cur\_path\_type}\K\\{contour\_code}$;\5
+$\\{cur\_exp}\K\\{make\_spec}(\\{cur\_exp},\39\\{fraction\_one}-\\{half%
+\_unit}-1-\\{el\_gordo},\390)$;\5
+$\\{flush\_cur\_exp}(\\{turning\_number}\ast\\{unity})$;\C{convert to %
+\\{scaled}}\6
+\&{end};\2\2\2\par
+\fi
+
+\M918. \P\D \37$\\{type\_test\_end}\S\\{flush\_cur\_exp}(\\{true\_code})$\6
+\4\&{else} \37$\\{flush\_cur\_exp}(\\{false\_code})$;\5
+$\\{cur\_type}\K\\{boolean\_type}$; \6
+\&{end} \par
+\P\D $\\{type\_range\_end}(\#)\S(\\{cur\_type}\L\#)$ \&{then} \\{type\_test%
+\_end}\par
+\P\D $\\{type\_range}(\#)\S$ \6
+\&{begin} \6
+\&{if} $(\\{cur\_type}\G\#)\W\\{type\_range\_end}$\par
+\P\D $\\{type\_test}(\#)\S$ \6
+\&{begin} \37\&{if} $\\{cur\_type}=\#$ \1\&{then}\5
+\\{type\_test\_end}\2\par
+\Y\P$\4\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4\\{boolean\_type}: \37$\\{type\_range}(\\{boolean\_type})(\\{unknown%
+\_boolean})$;\6
+\4\\{string\_type}: \37$\\{type\_range}(\\{string\_type})(\\{unknown%
+\_string})$;\6
+\4\\{pen\_type}: \37$\\{type\_range}(\\{pen\_type})(\\{future\_pen})$;\6
+\4\\{path\_type}: \37$\\{type\_range}(\\{path\_type})(\\{unknown\_path})$;\6
+\4\\{picture\_type}: \37$\\{type\_range}(\\{picture\_type})(\\{unknown%
+\_picture})$;\6
+\4$\\{transform\_type},\39\\{pair\_type}$: \37$\\{type\_test}(\|c)$;\6
+\4\\{numeric\_type}: \37$\\{type\_range}(\\{known})(\\{independent})$;\6
+\4$\\{known\_op},\39\\{unknown\_op}$: \37$\\{test\_known}(\|c)$;\par
+\fi
+
+\M919. \P$\X899:Declare unary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{test\_known}(\|c:\\{quarterword})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|b: \37$\\{true\_code}\to\\{false\_code}$;\C{is the current
+expression known?}\6
+$\|p,\39\|q$: \37\\{pointer};\C{locations in a big node}\2\6
+\&{begin} \37$\|b\K\\{false\_code}$;\6
+\&{case} $\\{cur\_type}$ \1\&{of}\6
+\4$\\{vacuous},\39\\{boolean\_type},\39\\{string\_type},\39\\{pen\_type},\39%
+\\{future\_pen},\39\\{path\_type},\39\\{picture\_type},\39\\{known}$: \37$\|b\K%
+\\{true\_code}$;\6
+\4$\\{transform\_type},\39\\{pair\_type}$: \37\&{begin} \37$\|p\K\\{value}(%
+\\{cur\_exp})$;\5
+$\|q\K\|p+\\{big\_node\_size}[\\{cur\_type}]$;\6
+\1\&{repeat} \37$\|q\K\|q-2$;\6
+\&{if} $\\{type}(\|q)\I\\{known}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\4\&{until}\5
+$\|q=\|p$;\2\6
+$\|b\K\\{true\_code}$;\6
+\4\\{done}: \37\&{end};\6
+\4\&{othercases} \37\\{do\_nothing}\2\6
+\&{endcases};\6
+\&{if} $\|c=\\{known\_op}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(\|b)$\6
+\4\&{else} $\\{flush\_cur\_exp}(\\{true\_code}+\\{false\_code}-\|b)$;\2\6
+$\\{cur\_type}\K\\{boolean\_type}$;\6
+\&{end};\par
+\fi
+
+\M920. \P$\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4\\{cycle\_op}: \37\&{begin} \37\&{if} $\\{cur\_type}\I\\{path\_type}$ \1%
+\&{then}\5
+$\\{flush\_cur\_exp}(\\{false\_code})$\6
+\4\&{else} \&{if} $\\{left\_type}(\\{cur\_exp})\I\\{endpoint}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(\\{true\_code})$\6
+\4\&{else} $\\{flush\_cur\_exp}(\\{false\_code})$;\2\2\6
+$\\{cur\_type}\K\\{boolean\_type}$;\6
+\&{end};\par
+\fi
+
+\M921. \P$\X905:Additional cases of unary operators\X\mathrel{+}\S$\6
+\4\\{make\_pen\_op}: \37\&{begin} \37\&{if} $\\{cur\_type}=\\{pair\_type}$ \1%
+\&{then}\5
+\\{pair\_to\_path};\2\6
+\&{if} $\\{cur\_type}=\\{path\_type}$ \1\&{then}\5
+$\\{cur\_type}\K\\{future\_pen}$\6
+\4\&{else} $\\{bad\_unary}(\\{make\_pen\_op})$;\2\6
+\&{end};\6
+\4\\{make\_path\_op}: \37\&{begin} \37\&{if} $\\{cur\_type}=\\{future\_pen}$ \1%
+\&{then}\5
+\\{materialize\_pen};\2\6
+\&{if} $\\{cur\_type}\I\\{pen\_type}$ \1\&{then}\5
+$\\{bad\_unary}(\\{make\_path\_op})$\6
+\4\&{else} \&{begin} \37$\\{flush\_cur\_exp}(\\{make\_path}(\\{cur\_exp}))$;\5
+$\\{cur\_type}\K\\{path\_type}$;\6
+\&{end};\2\6
+\&{end};\6
+\4\\{total\_weight\_op}: \37\&{if} $\\{cur\_type}\I\\{picture\_type}$ \1%
+\&{then}\5
+$\\{bad\_unary}(\\{total\_weight\_op})$\6
+\4\&{else} $\\{flush\_cur\_exp}(\\{total\_weight}(\\{cur\_exp}))$;\2\6
+\4\\{reverse}: \37\&{if} $\\{cur\_type}=\\{path\_type}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{htap\_ypoc}(\\{cur\_exp})$;\6
+\&{if} $\\{right\_type}(\|p)=\\{endpoint}$ \1\&{then}\5
+$\|p\K\\{link}(\|p)$;\2\6
+$\\{toss\_knot\_list}(\\{cur\_exp})$;\5
+$\\{cur\_exp}\K\|p$;\6
+\&{end}\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\5
+\\{pair\_to\_path}\6
+\4\&{else} $\\{bad\_unary}(\\{reverse})$;\2\2\par
+\fi
+
+\M922. Finally, we have the operations that combine a capsule~\|p
+with the current expression.
+
+\Y\P\hbox{\4}\X923:Declare binary action procedures\X\6
+\4\&{procedure}\1\ \37$\\{do\_binary}(\|p:\\{pointer};\,\35\|c:%
+\\{quarterword})$;\6
+\4\&{label} \37$\\{done},\39\\{done1},\39\\{exit}$;\6
+\4\&{var} \37$\|q,\39\|r,\39\\{rr}$: \37\\{pointer};\C{for list manipulation}\6
+$\\{old\_p},\39\\{old\_exp}$: \37\\{pointer};\C{capsules to recycle}\6
+\|v: \37\\{integer};\C{for numeric manipulation}\2\6
+\&{begin} \37\\{check\_arith};\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>\\{two}$ \1\&{then}\5
+\X924:Trace the current binary operation\X;\2\6
+\X926:Sidestep \\{independent} cases in capsule \|p\X;\6
+\X927:Sidestep \\{independent} cases in the current expression\X;\6
+\&{case} $\|c$ \1\&{of}\6
+\4$\\{plus},\39\\{minus}$: \37\X929:Add or subtract the current expression from
+\|p\X;\6
+\hbox{\4}\X936:Additional cases of binary operators\X\2\6
+\&{end};\C{there are no other cases}\6
+$\\{recycle\_value}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\C{\&{return} to avoid this}\6
+\4\\{exit}: \37\\{check\_arith};\5
+\X925:Recycle any sidestepped \\{independent} capsules\X;\6
+\&{end};\par
+\fi
+
+\M923. \P$\X923:Declare binary action procedures\X\S$\6
+\4\&{procedure}\1\ \37$\\{bad\_binary}(\|p:\\{pointer};\,\35\|c:%
+\\{quarterword})$;\2\6
+\&{begin} \37$\\{disp\_err}(\|p,\39\.{""})$;\5
+$\\{exp\_err}(\.{"Not\ implemented:\ "})$;\6
+\&{if} $\|c\G\\{min\_of}$ \1\&{then}\5
+$\\{print\_op}(\|c)$;\2\6
+$\\{print\_known\_or\_unknown\_type}(\\{type}(\|p),\39\|p)$;\6
+\&{if} $\|c\G\\{min\_of}$ \1\&{then}\5
+$\\{print}(\.{"of"})$\ \&{else} $\\{print\_op}(\|c)$;\2\6
+$\\{print\_known\_or\_unknown\_type}(\\{cur\_type},\39\\{cur\_exp})$;\6
+$\\{help3}(\.{"I\'m\ afraid\ I\ don\'t\ know\ how\ to\ apply\ that\ operation\
+to\ that"})$\6
+$(\.{"combination\ of\ types.\ Continue,\ and\ I\'ll\ return\ the\ second"})$\6
+$(\.{"argument\ (see\ above)\ as\ the\ result\ of\ the\ operation."})$;\5
+\\{put\_get\_error};\6
+\&{end};\par
+\As928, 930, 943, 946, 949, 953, 960, 961, 962, 963, 966, 976, 977, 978, 982,
+984\ETs985.
+\U922.\fi
+
+\M924. \P$\X924:Trace the current binary operation\X\S$\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{("})$;\5
+$\\{print\_exp}(\|p,\390)$;\C{show the operand, but not verbosely}\6
+$\\{print\_char}(\.{")"})$;\5
+$\\{print\_op}(\|c)$;\5
+$\\{print\_char}(\.{"("})$;\6
+$\\{print\_exp}(\\{null},\390)$;\5
+$\\{print}(\.{")\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\par
+\U922.\fi
+
+\M925. Several of the binary operations are potentially complicated by the
+fact that \\{independent} values can sneak into capsules. For example,
+we've seen an instance of this difficulty in the unary operation
+of negation. In order to reduce the number of cases that need to be
+handled, we first change the two operands (if necessary)
+to rid them of \\{independent} components. The original operands are
+put into capsules called \\{old\_p} and \\{old\_exp}, which will be
+recycled after the binary operation has been safely carried out.
+
+\Y\P$\4\X925:Recycle any sidestepped \\{independent} capsules\X\S$\6
+\&{if} $\\{old\_p}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{recycle\_value}(\\{old\_p})$;\5
+$\\{free\_node}(\\{old\_p},\39\\{value\_node\_size})$;\6
+\&{end};\2\6
+\&{if} $\\{old\_exp}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{recycle\_value}(\\{old\_exp})$;\5
+$\\{free\_node}(\\{old\_exp},\39\\{value\_node\_size})$;\6
+\&{end}\2\par
+\U922.\fi
+
+\M926. A big node is considered to be ``tarnished'' if it contains at least one
+independent component. We will define a simple function called `\\{tarnished}'
+that returns \\{null} if and only if its argument is not tarnished.
+
+\Y\P$\4\X926:Sidestep \\{independent} cases in capsule \|p\X\S$\6
+\&{case} $\\{type}(\|p)$ \1\&{of}\6
+\4$\\{transform\_type},\39\\{pair\_type}$: \37$\\{old\_p}\K\\{tarnished}(\|p)$;%
+\6
+\4\\{independent}: \37$\\{old\_p}\K\\{void}$;\6
+\4\&{othercases} \37$\\{old\_p}\K\\{null}$\2\6
+\&{endcases};\6
+\&{if} $\\{old\_p}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\|q\K\\{stash\_cur\_exp}$;\5
+$\\{old\_p}\K\|p$;\5
+$\\{make\_exp\_copy}(\\{old\_p})$;\5
+$\|p\K\\{stash\_cur\_exp}$;\5
+$\\{unstash\_cur\_exp}(\|q)$;\6
+\&{end};\2\par
+\U922.\fi
+
+\M927. \P$\X927:Sidestep \\{independent} cases in the current expression\X\S$\6
+\&{case} $\\{cur\_type}$ \1\&{of}\6
+\4$\\{transform\_type},\39\\{pair\_type}$: \37$\\{old\_exp}\K\\{tarnished}(%
+\\{cur\_exp})$;\6
+\4\\{independent}: \37$\\{old\_exp}\K\\{void}$;\6
+\4\&{othercases} \37$\\{old\_exp}\K\\{null}$\2\6
+\&{endcases};\6
+\&{if} $\\{old\_exp}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{old\_exp}\K\\{cur\_exp}$;\5
+$\\{make\_exp\_copy}(\\{old\_exp})$;\6
+\&{end}\2\par
+\U922.\fi
+
+\M928. \P$\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{function}\1\ \37$\\{tarnished}(\|p:\\{pointer})$: \37\\{pointer};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{beginning of the big node}\6
+\|r: \37\\{pointer};\C{current position in the big node}\2\6
+\&{begin} \37$\|q\K\\{value}(\|p)$;\5
+$\|r\K\|q+\\{big\_node\_size}[\\{type}(\|p)]$;\6
+\1\&{repeat} \37$\|r\K\|r-2$;\6
+\&{if} $\\{type}(\|r)=\\{independent}$ \1\&{then}\6
+\&{begin} \37$\\{tarnished}\K\\{void}$;\5
+\&{return};\6
+\&{end};\2\6
+\4\&{until}\5
+$\|r=\|q$;\2\6
+$\\{tarnished}\K\\{null}$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M929. \P$\X929:Add or subtract the current expression from \|p\X\S$\6
+\&{if} $(\\{cur\_type}<\\{pair\_type})\V(\\{type}(\|p)<\\{pair\_type})$ \1%
+\&{then}\6
+\&{if} $(\\{cur\_type}=\\{picture\_type})\W(\\{type}(\|p)=\\{picture\_type})$ %
+\1\&{then}\6
+\&{begin} \37\&{if} $\|c=\\{minus}$ \1\&{then}\5
+$\\{negate\_edges}(\\{cur\_exp})$;\2\6
+$\\{cur\_edges}\K\\{cur\_exp}$;\5
+$\\{merge\_edges}(\\{value}(\|p))$;\6
+\&{end}\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\|c)$\2\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\6
+\&{if} $\\{type}(\|p)\I\\{pair\_type}$ \1\&{then}\5
+$\\{bad\_binary}(\|p,\39\|c)$\6
+\4\&{else} \&{begin} \37$\|q\K\\{value}(\|p)$;\5
+$\|r\K\\{value}(\\{cur\_exp})$;\5
+$\\{add\_or\_subtract}(\\{x\_part\_loc}(\|q),\39\\{x\_part\_loc}(\|r),\39\|c)$;%
+\5
+$\\{add\_or\_subtract}(\\{y\_part\_loc}(\|q),\39\\{y\_part\_loc}(\|r),\39\|c)$;%
+\6
+\&{end}\2\6
+\4\&{else} \&{if} $\\{type}(\|p)=\\{pair\_type}$ \1\&{then}\5
+$\\{bad\_binary}(\|p,\39\|c)$\6
+\4\&{else} $\\{add\_or\_subtract}(\|p,\39\\{null},\39\|c)$\2\2\2\par
+\U922.\fi
+
+\M930. The first argument to \\{add\_or\_subtract} is the location of a value
+node
+in a capsule or pair node that will soon be recycled. The second argument
+is either a location within a pair or transform node of \\{cur\_exp},
+or it is null (which means that \\{cur\_exp} itself should be the second
+argument). The third argument is either \\{plus} or \\{minus}.
+
+The sum or difference of the numeric quantities will replace the second
+operand. Arithmetic overflow may go undetected; users aren't supposed to
+be monkeying around with really big values.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\hbox{\4}\X935:Declare the procedure called \\{dep\_finish}\X\6
+\4\&{procedure}\1\ \37$\\{add\_or\_subtract}(\|p,\39\|q:\\{pointer};\,\35\|c:%
+\\{quarterword})$;\6
+\4\&{label} \37$\\{done},\39\\{exit}$;\6
+\4\&{var} \37$\|s,\39\|t$: \37\\{small\_number};\C{operand types}\6
+\|r: \37\\{pointer};\C{list traverser}\6
+\|v: \37\\{integer};\C{second operand value}\2\6
+\&{begin} \37\&{if} $\|q=\\{null}$ \1\&{then}\6
+\&{begin} \37$\|t\K\\{cur\_type}$;\6
+\&{if} $\|t<\\{dependent}$ \1\&{then}\5
+$\|v\K\\{cur\_exp}$\ \&{else} $\|v\K\\{dep\_list}(\\{cur\_exp})$;\2\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|t\K\\{type}(\|q)$;\6
+\&{if} $\|t<\\{dependent}$ \1\&{then}\5
+$\|v\K\\{value}(\|q)$\ \&{else} $\|v\K\\{dep\_list}(\|q)$;\2\6
+\&{end};\2\6
+\&{if} $\|t=\\{known}$ \1\&{then}\6
+\&{begin} \37\&{if} $\|c=\\{minus}$ \1\&{then}\5
+$\\{negate}(\|v)$;\2\6
+\&{if} $\\{type}(\|p)=\\{known}$ \1\&{then}\6
+\&{begin} \37$\|v\K\\{slow\_add}(\\{value}(\|p),\39\|v)$;\6
+\&{if} $\|q=\\{null}$ \1\&{then}\5
+$\\{cur\_exp}\K\|v$\ \&{else} $\\{value}(\|q)\K\|v$;\2\6
+\&{return};\6
+\&{end};\2\6
+\X931:Add a known value to the constant term of $\\{dep\_list}(\|p)$\X;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\|c=\\{minus}$ \1\&{then}\5
+$\\{negate\_dep\_list}(\|v)$;\2\6
+\X932:Add operand \|p to the dependency list \|v\X;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M931. \P$\X931:Add a known value to the constant term of $\\{dep\_list}(\|p)$%
+\X\S$\6
+$\|r\K\\{dep\_list}(\|p)$;\6
+\&{while} $\\{info}(\|r)\I\\{null}$ \1\&{do}\5
+$\|r\K\\{link}(\|r)$;\2\6
+$\\{value}(\|r)\K\\{slow\_add}(\\{value}(\|r),\39\|v)$;\6
+\&{if} $\|q=\\{null}$ \1\&{then}\6
+\&{begin} \37$\|q\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{cur\_exp}\K\|q$;\5
+$\\{cur\_type}\K\\{type}(\|p)$;\5
+$\\{name\_type}(\|q)\K\\{capsule}$;\6
+\&{end};\2\6
+$\\{dep\_list}(\|q)\K\\{dep\_list}(\|p)$;\5
+$\\{type}(\|q)\K\\{type}(\|p)$;\5
+$\\{prev\_dep}(\|q)\K\\{prev\_dep}(\|p)$;\5
+$\\{link}(\\{prev\_dep}(\|p))\K\|q$;\5
+$\\{type}(\|p)\K\\{known}$;\C{this will keep the recycler from collecting
+non-garbage}\par
+\U930.\fi
+
+\M932. We prefer \\{dependent} lists to \\{proto\_dependent} ones, because it
+is
+nice to retain the extra accuracy of \\{fraction} coefficients.
+But we have to handle both kinds, and mixtures too.
+
+\Y\P$\4\X932:Add operand \|p to the dependency list \|v\X\S$\6
+\&{if} $\\{type}(\|p)=\\{known}$ \1\&{then}\5
+\X933:Add the known $\\{value}(\|p)$ to the constant term of \|v\X\6
+\4\&{else} \&{begin} \37$\|s\K\\{type}(\|p)$;\5
+$\|r\K\\{dep\_list}(\|p)$;\6
+\&{if} $\|t=\\{dependent}$ \1\&{then}\6
+\&{begin} \37\&{if} $\|s=\\{dependent}$ \1\&{then}\6
+\&{if} $\\{max\_coef}(\|r)+\\{max\_coef}(\|v)<\\{coef\_bound}$ \1\&{then}\6
+\&{begin} \37$\|v\K\\{p\_plus\_q}(\|v,\39\|r,\39\\{dependent})$;\5
+\&{goto} \37\\{done};\6
+\&{end};\C{\\{fix\_needed} will necessarily be false}\2\2\6
+$\|t\K\\{proto\_dependent}$;\5
+$\|v\K\\{p\_over\_v}(\|v,\39\\{unity},\39\\{dependent},\39\\{proto%
+\_dependent})$;\6
+\&{end};\2\6
+\&{if} $\|s=\\{proto\_dependent}$ \1\&{then}\5
+$\|v\K\\{p\_plus\_q}(\|v,\39\|r,\39\\{proto\_dependent})$\6
+\4\&{else} $\|v\K\\{p\_plus\_fq}(\|v,\39\\{unity},\39\|r,\39\\{proto%
+\_dependent},\39\\{dependent})$;\2\6
+\4\\{done}: \37\X934:Output the answer, \|v (which might have become \\{known})%
+\X;\6
+\&{end}\2\par
+\U930.\fi
+
+\M933. \P$\X933:Add the known $\\{value}(\|p)$ to the constant term of \|v\X\S$%
+\6
+\&{begin} \37\&{while} $\\{info}(\|v)\I\\{null}$ \1\&{do}\5
+$\|v\K\\{link}(\|v)$;\2\6
+$\\{value}(\|v)\K\\{slow\_add}(\\{value}(\|p),\39\\{value}(\|v))$;\6
+\&{end}\par
+\U932.\fi
+
+\M934. \P$\X934:Output the answer, \|v (which might have become \\{known})\X\S$%
+\6
+\&{if} $\|q\I\\{null}$ \1\&{then}\5
+$\\{dep\_finish}(\|v,\39\|q,\39\|t)$\6
+\4\&{else} \&{begin} \37$\\{cur\_type}\K\|t$;\5
+$\\{dep\_finish}(\|v,\39\\{null},\39\|t)$;\6
+\&{end}\2\par
+\U932.\fi
+
+\M935. Here's the current situation: The dependency list \|v of type \|t
+should either be put into the current expression (if $\|q=\\{null}$) or
+into location \|q within a pair node (otherwise). The destination (\\{cur\_exp}
+or \|q) formerly held a dependency list with the same
+final pointer as the list \|v.
+
+\Y\P$\4\X935:Declare the procedure called \\{dep\_finish}\X\S$\6
+\4\&{procedure}\1\ \37$\\{dep\_finish}(\|v,\39\|q:\\{pointer};\,\35\|t:%
+\\{small\_number})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the destination}\6
+\\{vv}: \37\\{scaled};\C{the value, if it is \\{known}}\2\6
+\&{begin} \37\&{if} $\|q=\\{null}$ \1\&{then}\5
+$\|p\K\\{cur\_exp}$\ \&{else} $\|p\K\|q$;\2\6
+$\\{dep\_list}(\|p)\K\|v$;\5
+$\\{type}(\|p)\K\|t$;\6
+\&{if} $\\{info}(\|v)=\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{vv}\K\\{value}(\|v)$;\6
+\&{if} $\|q=\\{null}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(\\{vv})$\6
+\4\&{else} \&{begin} \37$\\{recycle\_value}(\|p)$;\5
+$\\{type}(\|q)\K\\{known}$;\5
+$\\{value}(\|q)\K\\{vv}$;\6
+\&{end};\2\6
+\&{end}\6
+\4\&{else} \&{if} $\|q=\\{null}$ \1\&{then}\5
+$\\{cur\_type}\K\|t$;\2\2\6
+\&{if} $\\{fix\_needed}$ \1\&{then}\5
+\\{fix\_dependencies};\2\6
+\&{end};\par
+\U930.\fi
+
+\M936. Let's turn now to the six basic relations of comparison.
+
+\Y\P$\4\X936:Additional cases of binary operators\X\S$\6
+\4$\\{less\_than},\39\\{less\_or\_equal},\39\\{greater\_than},\39\\{greater\_or%
+\_equal},\39\\{equal\_to},\39\\{unequal\_to}$: \37\&{begin} \37\hbox{}\6
+\&{if} $(\\{cur\_type}>\\{pair\_type})\W(\\{type}(\|p)>\\{pair\_type})$ \1%
+\&{then}\5
+$\\{add\_or\_subtract}(\|p,\39\\{null},\39\\{minus})$\C{$\\{cur\_exp}\K(\|p)-%
+\\{cur\_exp}$}\6
+\4\&{else} \&{if} $\\{cur\_type}\I\\{type}(\|p)$ \1\&{then}\6
+\&{begin} \37$\\{bad\_binary}(\|p,\39\|c)$;\5
+\&{goto} \37\\{done};\6
+\&{end}\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{string\_type}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(\\{str\_vs\_str}(\\{value}(\|p),\39\\{cur\_exp}))$\6
+\4\&{else} \&{if} $(\\{cur\_type}=\\{unknown\_string})\V(\\{cur\_type}=%
+\\{unknown\_boolean})$ \1\&{then}\5
+\X938:Check if unknowns have been equated\X\6
+\4\&{else} \&{if} $(\\{cur\_type}=\\{pair\_type})\V(\\{cur\_type}=\\{transform%
+\_type})$ \1\&{then}\5
+\X939:Reduce comparison of big nodes to comparison of scalars\X\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{boolean\_type}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(\\{cur\_exp}-\\{value}(\|p))$\6
+\4\&{else} \&{begin} \37$\\{bad\_binary}(\|p,\39\|c)$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\2\2\2\2\2\6
+\X937:Compare the current expression with zero\X;\6
+\4\\{done}: \37\&{end};\par
+\As940, 941, 948, 951, 952, 975, 983\ETs988.
+\U922.\fi
+
+\M937. \P$\X937:Compare the current expression with zero\X\S$\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{cur\_type}<\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{disp\_err}(\|p,\39\.{""})$;\5
+$\\{help1}(\.{"The\ quantities\ shown\ above\ have\ not\ been\ equated."})$\6
+\&{end}\6
+\4\&{else} $\\{help2}(\.{"Oh\ dear.\ I\ can\'t\ decide\ if\ the\ expression\
+above\ is\ positive,"})$\2\6
+$(\.{"negative,\ or\ zero.\ So\ this\ comparison\ test\ won\'t\ be\ \`true%
+\'."})$;\5
+$\\{exp\_err}(\.{"Unknown\ relation\ will\ be\ considered\ false"})$;\5
+$\\{put\_get\_flush\_error}(\\{false\_code})$;\6
+\&{end}\6
+\4\&{else} \&{case} $\|c$ \1\&{of}\6
+\4\\{less\_than}: \37$\\{boolean\_reset}(\\{cur\_exp}<0)$;\6
+\4\\{less\_or\_equal}: \37$\\{boolean\_reset}(\\{cur\_exp}\L0)$;\6
+\4\\{greater\_than}: \37$\\{boolean\_reset}(\\{cur\_exp}>0)$;\6
+\4\\{greater\_or\_equal}: \37$\\{boolean\_reset}(\\{cur\_exp}\G0)$;\6
+\4\\{equal\_to}: \37$\\{boolean\_reset}(\\{cur\_exp}=0)$;\6
+\4\\{unequal\_to}: \37$\\{boolean\_reset}(\\{cur\_exp}\I0)$;\2\6
+\&{end};\C{there are no other cases}\2\6
+$\\{cur\_type}\K\\{boolean\_type}$\par
+\U936.\fi
+
+\M938. When two unknown strings are in the same ring, we know that they are
+equal. Otherwise, we don't know whether they are equal or not, so we
+make no change.
+
+\Y\P$\4\X938:Check if unknowns have been equated\X\S$\6
+\&{begin} \37$\|q\K\\{value}(\\{cur\_exp})$;\6
+\&{while} $(\|q\I\\{cur\_exp})\W(\|q\I\|p)$ \1\&{do}\5
+$\|q\K\\{value}(\|q)$;\2\6
+\&{if} $\|q=\|p$ \1\&{then}\5
+$\\{flush\_cur\_exp}(0)$;\2\6
+\&{end}\par
+\U936.\fi
+
+\M939. \P$\X939:Reduce comparison of big nodes to comparison of scalars\X\S$\6
+\&{begin} \37$\|q\K\\{value}(\|p)$;\5
+$\|r\K\\{value}(\\{cur\_exp})$;\5
+$\\{rr}\K\|r+\\{big\_node\_size}[\\{cur\_type}]-2$;\6
+\~ \1\&{loop}\ \&{begin} \37$\\{add\_or\_subtract}(\|q,\39\|r,\39\\{minus})$;\6
+\&{if} $\\{type}(\|r)\I\\{known}$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+\&{if} $\\{value}(\|r)\I0$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+\&{if} $\|r=\\{rr}$ \1\&{then}\5
+\&{goto} \37\\{done1};\2\6
+$\|q\K\|q+2$;\5
+$\|r\K\|r+2$;\6
+\&{end};\2\6
+\4\\{done1}: \37$\\{take\_part}(\\{x\_part}+\\{half}(\|r-\\{value}(\\{cur%
+\_exp})))$;\6
+\&{end}\par
+\U936.\fi
+
+\M940. Here we use the sneaky fact that $\\{and\_op}-\\{false\_code}=\\{or%
+\_op}-\\{true\_code}$.
+
+\Y\P$\4\X936:Additional cases of binary operators\X\mathrel{+}\S$\6
+\4$\\{and\_op},\39\\{or\_op}$: \37\&{if} $(\\{type}(\|p)\I\\{boolean\_type})\V(%
+\\{cur\_type}\I\\{boolean\_type})$ \1\&{then}\5
+$\\{bad\_binary}(\|p,\39\|c)$\6
+\4\&{else} \&{if} $\\{value}(\|p)=\|c+\\{false\_code}-\\{and\_op}$ \1\&{then}\5
+$\\{cur\_exp}\K\\{value}(\|p)$;\2\2\par
+\fi
+
+\M941. \P$\X936:Additional cases of binary operators\X\mathrel{+}\S$\6
+\4\\{times}: \37\&{if} $(\\{cur\_type}<\\{pair\_type})\V(\\{type}(\|p)<\\{pair%
+\_type})$ \1\&{then}\5
+$\\{bad\_binary}(\|p,\39\\{times})$\6
+\4\&{else} \&{if} $(\\{cur\_type}=\\{known})\V(\\{type}(\|p)=\\{known})$ \1%
+\&{then}\5
+\X942:Multiply when at least one operand is known\X\6
+\4\&{else} \&{if} $(\\{nice\_pair}(\|p,\39\\{type}(\|p))\W(\\{cur\_type}>%
+\\{pair\_type}))\V(\\{nice\_pair}(\\{cur\_exp},\39\\{cur\_type})\W(\\{type}(%
+\|p)>\\{pair\_type}))$ \1\&{then}\6
+\&{begin} \37$\\{hard\_times}(\|p)$;\5
+\&{return};\6
+\&{end}\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\\{times})$;\2\2\2\par
+\fi
+
+\M942. \P$\X942:Multiply when at least one operand is known\X\S$\6
+\&{begin} \37\&{if} $\\{type}(\|p)=\\{known}$ \1\&{then}\6
+\&{begin} \37$\|v\K\\{value}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|v\K\\{cur\_exp}$;\5
+$\\{unstash\_cur\_exp}(\|p)$;\6
+\&{end};\2\6
+\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\5
+$\\{cur\_exp}\K\\{take\_scaled}(\\{cur\_exp},\39\|v)$\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{value}(\\{cur\_exp})$;\5
+$\\{dep\_mult}(\\{x\_part\_loc}(\|p),\39\|v,\39\\{true})$;\5
+$\\{dep\_mult}(\\{y\_part\_loc}(\|p),\39\|v,\39\\{true})$;\6
+\&{end}\6
+\4\&{else} $\\{dep\_mult}(\\{null},\39\|v,\39\\{true})$;\2\2\6
+\&{return};\6
+\&{end}\par
+\U941.\fi
+
+\M943. \P$\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{dep\_mult}(\|p:\\{pointer};\,\35\|v:\\{integer};\,%
+\35\\{v\_is\_scaled}:\\{boolean})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the dependency list being multiplied by %
+\|v}\6
+$\|s,\39\|t$: \37\\{small\_number};\C{its type, before and after}\2\6
+\&{begin} \37\&{if} $\|p=\\{null}$ \1\&{then}\5
+$\|q\K\\{cur\_exp}$\6
+\4\&{else} \&{if} $\\{type}(\|p)\I\\{known}$ \1\&{then}\5
+$\|q\K\|p$\6
+\4\&{else} \&{begin} \37\&{if} $\\{v\_is\_scaled}$ \1\&{then}\5
+$\\{value}(\|p)\K\\{take\_scaled}(\\{value}(\|p),\39\|v)$\6
+\4\&{else} $\\{value}(\|p)\K\\{take\_fraction}(\\{value}(\|p),\39\|v)$;\2\6
+\&{return};\6
+\&{end};\2\2\6
+$\|t\K\\{type}(\|q)$;\5
+$\|q\K\\{dep\_list}(\|q)$;\5
+$\|s\K\|t$;\6
+\&{if} $\|t=\\{dependent}$ \1\&{then}\6
+\&{if} $\\{v\_is\_scaled}$ \1\&{then}\6
+\&{if} $\\{ab\_vs\_cd}(\\{max\_coef}(\|q),\39\\{abs}(\|v),\39\\{coef\_bound}-1,%
+\39\\{unity})\G0$ \1\&{then}\5
+$\|t\K\\{proto\_dependent}$;\2\2\2\6
+$\|q\K\\{p\_times\_v}(\|q,\39\|v,\39\|s,\39\|t,\39\\{v\_is\_scaled})$;\5
+$\\{dep\_finish}(\|q,\39\|p,\39\|t)$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M944. Here is a routine that is similar to \\{times}; but it is invoked only
+internally, when \|v is a \\{fraction} whose magnitude is at most~1,
+and when $\\{cur\_type}\G\\{pair\_type}$.
+
+\Y\P\4\&{procedure}\1\ \37$\\{frac\_mult}(\|n,\39\|d:\\{scaled})$;%
+\C{multiplies \\{cur\_exp} by $\|n/\|d$}\6
+\4\&{var} \37\|p: \37\\{pointer};\C{a pair node}\6
+\\{old\_exp}: \37\\{pointer};\C{a capsule to recycle}\6
+\|v: \37\\{fraction};\C{$\|n/\|d$}\2\6
+\&{begin} \37\&{if} $\\{internal}[\\{tracing\_commands}]>\\{two}$ \1\&{then}\5
+\X945:Trace the fraction multiplication\X;\2\6
+\&{case} $\\{cur\_type}$ \1\&{of}\6
+\4$\\{transform\_type},\39\\{pair\_type}$: \37$\\{old\_exp}\K\\{tarnished}(%
+\\{cur\_exp})$;\6
+\4\\{independent}: \37$\\{old\_exp}\K\\{void}$;\6
+\4\&{othercases} \37$\\{old\_exp}\K\\{null}$\2\6
+\&{endcases};\6
+\&{if} $\\{old\_exp}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{old\_exp}\K\\{cur\_exp}$;\5
+$\\{make\_exp\_copy}(\\{old\_exp})$;\6
+\&{end};\2\6
+$\|v\K\\{make\_fraction}(\|n,\39\|d)$;\6
+\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\5
+$\\{cur\_exp}\K\\{take\_fraction}(\\{cur\_exp},\39\|v)$\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{value}(\\{cur\_exp})$;\5
+$\\{dep\_mult}(\\{x\_part\_loc}(\|p),\39\|v,\39\\{false})$;\5
+$\\{dep\_mult}(\\{y\_part\_loc}(\|p),\39\|v,\39\\{false})$;\6
+\&{end}\6
+\4\&{else} $\\{dep\_mult}(\\{null},\39\|v,\39\\{false})$;\2\2\6
+\&{if} $\\{old\_exp}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{recycle\_value}(\\{old\_exp})$;\5
+$\\{free\_node}(\\{old\_exp},\39\\{value\_node\_size})$;\6
+\&{end}\2\6
+\&{end};\par
+\fi
+
+\M945. \P$\X945:Trace the fraction multiplication\X\S$\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{("})$;\5
+$\\{print\_scaled}(\|n)$;\5
+$\\{print\_char}(\.{"/"})$;\5
+$\\{print\_scaled}(\|d)$;\5
+$\\{print}(\.{")*("})$;\5
+$\\{print\_exp}(\\{null},\390)$;\5
+$\\{print}(\.{")\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\par
+\U944.\fi
+
+\M946. The \\{hard\_times} routine multiplies a nice pair by a dependency list.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{hard\_times}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{a copy of the dependent variable \|p}\6
+\|r: \37\\{pointer};\C{the big node for the nice pair}\6
+$\|u,\39\|v$: \37\\{scaled};\C{the known values of the nice pair}\2\6
+\&{begin} \37\&{if} $\\{type}(\|p)=\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\|q\K\\{stash\_cur\_exp}$;\5
+$\\{unstash\_cur\_exp}(\|p)$;\5
+$\|p\K\|q$;\6
+\&{end};\C{now $\\{cur\_type}=\\{pair\_type}$}\2\6
+$\|r\K\\{value}(\\{cur\_exp})$;\5
+$\|u\K\\{value}(\\{x\_part\_loc}(\|r))$;\5
+$\|v\K\\{value}(\\{y\_part\_loc}(\|r))$;\5
+\X947:Move the dependent variable \|p into both parts of the pair node \|r\X;\6
+$\\{dep\_mult}(\\{x\_part\_loc}(\|r),\39\|u,\39\\{true})$;\5
+$\\{dep\_mult}(\\{y\_part\_loc}(\|r),\39\|v,\39\\{true})$;\6
+\&{end};\par
+\fi
+
+\M947. \P$\X947:Move the dependent variable \|p into both parts of the pair
+node \|r\X\S$\6
+$\\{type}(\\{y\_part\_loc}(\|r))\K\\{type}(\|p)$;\5
+$\\{new\_dep}(\\{y\_part\_loc}(\|r),\39\\{copy\_dep\_list}(\\{dep\_list}(%
+\|p)))$;\6
+$\\{type}(\\{x\_part\_loc}(\|r))\K\\{type}(\|p)$;\5
+$\\{mem}[\\{value\_loc}(\\{x\_part\_loc}(\|r))]\K\\{mem}[\\{value\_loc}(\|p)]$;%
+\5
+$\\{link}(\\{prev\_dep}(\|p))\K\\{x\_part\_loc}(\|r)$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$\par
+\U946.\fi
+
+\M948. \P$\X936:Additional cases of binary operators\X\mathrel{+}\S$\6
+\4\\{over}: \37\&{if} $(\\{cur\_type}\I\\{known})\V(\\{type}(\|p)<\\{pair%
+\_type})$ \1\&{then}\5
+$\\{bad\_binary}(\|p,\39\\{over})$\6
+\4\&{else} \&{begin} \37$\|v\K\\{cur\_exp}$;\5
+$\\{unstash\_cur\_exp}(\|p)$;\6
+\&{if} $\|v=0$ \1\&{then}\5
+\X950:Squeal about division by zero\X\6
+\4\&{else} \&{begin} \37\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\5
+$\\{cur\_exp}\K\\{make\_scaled}(\\{cur\_exp},\39\|v)$\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{value}(\\{cur\_exp})$;\5
+$\\{dep\_div}(\\{x\_part\_loc}(\|p),\39\|v)$;\5
+$\\{dep\_div}(\\{y\_part\_loc}(\|p),\39\|v)$;\6
+\&{end}\6
+\4\&{else} $\\{dep\_div}(\\{null},\39\|v)$;\2\2\6
+\&{end};\2\6
+\&{return};\6
+\&{end};\2\par
+\fi
+
+\M949. \P$\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{dep\_div}(\|p:\\{pointer};\,\35\|v:\\{scaled})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{the dependency list being divided by \|v}\6
+$\|s,\39\|t$: \37\\{small\_number};\C{its type, before and after}\2\6
+\&{begin} \37\&{if} $\|p=\\{null}$ \1\&{then}\5
+$\|q\K\\{cur\_exp}$\6
+\4\&{else} \&{if} $\\{type}(\|p)\I\\{known}$ \1\&{then}\5
+$\|q\K\|p$\6
+\4\&{else} \&{begin} \37$\\{value}(\|p)\K\\{make\_scaled}(\\{value}(\|p),\39%
+\|v)$;\5
+\&{return};\6
+\&{end};\2\2\6
+$\|t\K\\{type}(\|q)$;\5
+$\|q\K\\{dep\_list}(\|q)$;\5
+$\|s\K\|t$;\6
+\&{if} $\|t=\\{dependent}$ \1\&{then}\6
+\&{if} $\\{ab\_vs\_cd}(\\{max\_coef}(\|q),\39\\{unity},\39\\{coef\_bound}-1,\39%
+\\{abs}(\|v))\G0$ \1\&{then}\5
+$\|t\K\\{proto\_dependent}$;\2\2\6
+$\|q\K\\{p\_over\_v}(\|q,\39\|v,\39\|s,\39\|t)$;\5
+$\\{dep\_finish}(\|q,\39\|p,\39\|t)$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M950. \P$\X950:Squeal about division by zero\X\S$\6
+\&{begin} \37$\\{exp\_err}(\.{"Division\ by\ zero"})$;\5
+$\\{help2}(\.{"You\'re\ trying\ to\ divide\ the\ quantity\ shown\ above\ the\
+error"})$\6
+$(\.{"message\ by\ zero.\ I\'m\ going\ to\ divide\ it\ by\ one\ instead."})$;\5
+\\{put\_get\_error};\6
+\&{end}\par
+\U948.\fi
+
+\M951. \P$\X936:Additional cases of binary operators\X\mathrel{+}\S$\6
+\4$\\{pythag\_add},\39\\{pythag\_sub}$: \37\&{if} $(\\{cur\_type}=\\{known})\W(%
+\\{type}(\|p)=\\{known})$ \1\&{then}\6
+\&{if} $\|c=\\{pythag\_add}$ \1\&{then}\5
+$\\{cur\_exp}\K\\{pyth\_add}(\\{value}(\|p),\39\\{cur\_exp})$\6
+\4\&{else} $\\{cur\_exp}\K\\{pyth\_sub}(\\{value}(\|p),\39\\{cur\_exp})$\2\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\|c)$;\2\par
+\fi
+
+\M952. The next few sections of the program deal with affine transformations
+of coordinate data.
+
+\Y\P$\4\X936:Additional cases of binary operators\X\mathrel{+}\S$\6
+\4$\\{rotated\_by},\39\\{slanted\_by},\39\\{scaled\_by},\39\\{shifted\_by},\39%
+\\{transformed\_by},\39\\{x\_scaled},\39\\{y\_scaled},\39\\{z\_scaled}$: \37%
+\hbox{}\6
+\&{if} $(\\{type}(\|p)=\\{path\_type})\V(\\{type}(\|p)=\\{future\_pen})\V(%
+\\{type}(\|p)=\\{pen\_type})$ \1\&{then}\6
+\&{begin} \37$\\{path\_trans}(\|p,\39\|c)$;\5
+\&{return};\6
+\&{end}\6
+\4\&{else} \&{if} $(\\{type}(\|p)=\\{pair\_type})\V(\\{type}(\|p)=\\{transform%
+\_type})$ \1\&{then}\5
+$\\{big\_trans}(\|p,\39\|c)$\6
+\4\&{else} \&{if} $\\{type}(\|p)=\\{picture\_type}$ \1\&{then}\6
+\&{begin} \37$\\{edges\_trans}(\|p,\39\|c)$;\5
+\&{return};\6
+\&{end}\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\|c)$;\2\2\2\par
+\fi
+
+\M953. Let \|c be one of the eight transform operators. The procedure call
+$\\{set\_up\_trans}(\|c)$ first changes \\{cur\_exp} to a transform that
+corresponds to
+\|c and the original value of \\{cur\_exp}. (In particular, \\{cur\_exp}
+doesn't
+change at all if $\|c=\\{transformed\_by}$.)
+
+Then, if all components of the resulting transform are \\{known}, they are
+moved to the global variables \\{txx}, \\{txy}, \\{tyx}, \\{tyy}, \\{tx}, %
+\\{ty};
+and \\{cur\_exp} is changed to the known value zero.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{set\_up\_trans}(\|c:\\{quarterword})$;\6
+\4\&{label} \37$\\{done},\39\\{exit}$;\6
+\4\&{var} \37$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{list manipulation
+registers}\2\6
+\&{begin} \37\&{if} $(\|c\I\\{transformed\_by})\V(\\{cur\_type}\I\\{transform%
+\_type})$ \1\&{then}\5
+\X955:Put the current transform into \\{cur\_exp}\X;\2\6
+\X956:If the current transform is entirely known, stash it in global variables;
+otherwise \&{return}\X;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M954. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{txx},\39\\{txy},\39\\{tyx},\39\\{tyy},\39\\{tx},\39\\{ty}$: \37%
+\\{scaled};\C{current transform coefficients}\par
+\fi
+
+\M955. \P$\X955:Put the current transform into \\{cur\_exp}\X\S$\6
+\&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+$\\{cur\_exp}\K\\{id\_transform}$;\5
+$\\{cur\_type}\K\\{transform\_type}$;\5
+$\|q\K\\{value}(\\{cur\_exp})$;\6
+\&{case} $\|c$ \1\&{of}\6
+\X957:For each of the eight cases, change the relevant fields of \\{cur\_exp}
+and \&{goto} \\{done}; but do nothing if capsule \|p doesn't have the
+appropriate type\X\2\6
+\&{end};\C{there are no other cases}\6
+$\\{disp\_err}(\|p,\39\.{"Improper\ transformation\ argument"})$;\5
+$\\{help3}(\.{"The\ expression\ shown\ above\ has\ the\ wrong\ type,"})$\6
+$(\.{"so\ I\ can\'t\ transform\ anything\ using\ it."})$\6
+$(\.{"Proceed,\ and\ I\'ll\ omit\ the\ transformation."})$;\5
+\\{put\_get\_error};\6
+\4\\{done}: \37$\\{recycle\_value}(\|p)$;\5
+$\\{free\_node}(\|p,\39\\{value\_node\_size})$;\6
+\&{end}\par
+\U953.\fi
+
+\M956. \P$\X956:If the current transform is entirely known, stash it in global
+variables; otherwise \&{return}\X\S$\6
+$\|q\K\\{value}(\\{cur\_exp})$;\5
+$\|r\K\|q+\\{transform\_node\_size}$;\6
+\1\&{repeat} \37$\|r\K\|r-2$;\6
+\&{if} $\\{type}(\|r)\I\\{known}$ \1\&{then}\5
+\&{return};\2\6
+\4\&{until}\5
+$\|r=\|q$;\2\6
+$\\{txx}\K\\{value}(\\{xx\_part\_loc}(\|q))$;\5
+$\\{txy}\K\\{value}(\\{xy\_part\_loc}(\|q))$;\5
+$\\{tyx}\K\\{value}(\\{yx\_part\_loc}(\|q))$;\5
+$\\{tyy}\K\\{value}(\\{yy\_part\_loc}(\|q))$;\5
+$\\{tx}\K\\{value}(\\{x\_part\_loc}(\|q))$;\5
+$\\{ty}\K\\{value}(\\{y\_part\_loc}(\|q))$;\5
+$\\{flush\_cur\_exp}(0)$\par
+\U953.\fi
+
+\M957. \P$\X957:For each of the eight cases, change the relevant fields of %
+\\{cur\_exp} and \&{goto} \\{done}; but do nothing if capsule \|p doesn't have
+the appropriate type\X\S$\6
+\4\\{rotated\_by}: \37\&{if} $\\{type}(\|p)=\\{known}$ \1\&{then}\5
+\X958:Install sines and cosines, then \&{goto} \\{done}\X;\2\6
+\4\\{slanted\_by}: \37\&{if} $\\{type}(\|p)>\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\\{install}(\\{xy\_part\_loc}(\|q),\39\|p)$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\4\\{scaled\_by}: \37\&{if} $\\{type}(\|p)>\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\\{install}(\\{xx\_part\_loc}(\|q),\39\|p)$;\5
+$\\{install}(\\{yy\_part\_loc}(\|q),\39\|p)$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\4\\{shifted\_by}: \37\&{if} $\\{type}(\|p)=\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\|r\K\\{value}(\|p)$;\5
+$\\{install}(\\{x\_part\_loc}(\|q),\39\\{x\_part\_loc}(\|r))$;\5
+$\\{install}(\\{y\_part\_loc}(\|q),\39\\{y\_part\_loc}(\|r))$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\4\\{x\_scaled}: \37\&{if} $\\{type}(\|p)>\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\\{install}(\\{xx\_part\_loc}(\|q),\39\|p)$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\4\\{y\_scaled}: \37\&{if} $\\{type}(\|p)>\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\\{install}(\\{yy\_part\_loc}(\|q),\39\|p)$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\4\\{z\_scaled}: \37\&{if} $\\{type}(\|p)=\\{pair\_type}$ \1\&{then}\5
+\X959:Install a complex multiplier, then \&{goto} \\{done}\X;\2\6
+\4\\{transformed\_by}: \37\\{do\_nothing};\par
+\U955.\fi
+
+\M958. \P$\X958:Install sines and cosines, then \&{goto} \\{done}\X\S$\6
+\&{begin} \37$\\{n\_sin\_cos}((\\{value}(\|p)\mathbin{\&{mod}}\\{three\_sixty%
+\_units})\ast16)$;\5
+$\\{value}(\\{xx\_part\_loc}(\|q))\K\\{round\_fraction}(\\{n\_cos})$;\5
+$\\{value}(\\{yx\_part\_loc}(\|q))\K\\{round\_fraction}(\\{n\_sin})$;\5
+$\\{value}(\\{xy\_part\_loc}(\|q))\K-\\{value}(\\{yx\_part\_loc}(\|q))$;\5
+$\\{value}(\\{yy\_part\_loc}(\|q))\K\\{value}(\\{xx\_part\_loc}(\|q))$;\5
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U957.\fi
+
+\M959. \P$\X959:Install a complex multiplier, then \&{goto} \\{done}\X\S$\6
+\&{begin} \37$\|r\K\\{value}(\|p)$;\5
+$\\{install}(\\{xx\_part\_loc}(\|q),\39\\{x\_part\_loc}(\|r))$;\5
+$\\{install}(\\{yy\_part\_loc}(\|q),\39\\{x\_part\_loc}(\|r))$;\5
+$\\{install}(\\{yx\_part\_loc}(\|q),\39\\{y\_part\_loc}(\|r))$;\6
+\&{if} $\\{type}(\\{y\_part\_loc}(\|r))=\\{known}$ \1\&{then}\5
+$\\{negate}(\\{value}(\\{y\_part\_loc}(\|r)))$\6
+\4\&{else} $\\{negate\_dep\_list}(\\{dep\_list}(\\{y\_part\_loc}(\|r)))$;\2\6
+$\\{install}(\\{xy\_part\_loc}(\|q),\39\\{y\_part\_loc}(\|r))$;\5
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U957.\fi
+
+\M960. Procedure \\{set\_up\_known\_trans} is like \\{set\_up\_trans}, but it
+insists that the transformation be entirely known.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{set\_up\_known\_trans}(\|c:\\{quarterword})$;\2\6
+\&{begin} \37$\\{set\_up\_trans}(\|c)$;\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Transform\ components\ aren\'t\ all\ known"})$;\5
+$\\{help3}(\.{"I\'m\ unable\ to\ apply\ a\ partially\ specified\
+transformation"})$\6
+$(\.{"except\ to\ a\ fully\ known\ pair\ or\ transform."})$\6
+$(\.{"Proceed,\ and\ I\'ll\ omit\ the\ transformation."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\5
+$\\{txx}\K\\{unity}$;\5
+$\\{txy}\K0$;\5
+$\\{tyx}\K0$;\5
+$\\{tyy}\K\\{unity}$;\5
+$\\{tx}\K0$;\5
+$\\{ty}\K0$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M961. Here's a procedure that applies the transform $\\{txx}\to\\{ty}$ to a
+pair of
+coordinates in locations \|p and~\|q.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{trans}(\|p,\39\|q:\\{pointer})$;\6
+\4\&{var} \37\|v: \37\\{scaled};\C{the new \|x value}\2\6
+\&{begin} \37$\|v\K\\{take\_scaled}(\\{mem}[\|p].\\{sc},\39\\{txx})+\\{take%
+\_scaled}(\\{mem}[\|q].\\{sc},\39\\{txy})+\\{tx}$;\5
+$\\{mem}[\|q].\\{sc}\K\\{take\_scaled}(\\{mem}[\|p].\\{sc},\39\\{tyx})+\\{take%
+\_scaled}(\\{mem}[\|q].\\{sc},\39\\{tyy})+\\{ty}$;\5
+$\\{mem}[\|p].\\{sc}\K\|v$;\6
+\&{end};\par
+\fi
+
+\M962. The simplest transformation procedure applies a transform to all
+coordinates of a path. The \\{null\_pen} remains unchanged if it isn't
+being shifted.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{path\_trans}(\|p:\\{pointer};\,\35\|c:%
+\\{quarterword})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|q: \37\\{pointer};\C{list traverser}\2\6
+\&{begin} \37$\\{set\_up\_known\_trans}(\|c)$;\5
+$\\{unstash\_cur\_exp}(\|p)$;\6
+\&{if} $\\{cur\_type}=\\{pen\_type}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{max\_offset}(\\{cur\_exp})=0$ \1\&{then}\6
+\&{if} $\\{tx}=0$ \1\&{then}\6
+\&{if} $\\{ty}=0$ \1\&{then}\5
+\&{return};\2\2\2\6
+$\\{flush\_cur\_exp}(\\{make\_path}(\\{cur\_exp}))$;\5
+$\\{cur\_type}\K\\{future\_pen}$;\6
+\&{end};\2\6
+$\|q\K\\{cur\_exp}$;\6
+\1\&{repeat} \37\&{if} $\\{left\_type}(\|q)\I\\{endpoint}$ \1\&{then}\5
+$\\{trans}(\|q+3,\39\|q+4)$;\C{that's \\{left\_x} and \\{left\_y}}\2\6
+$\\{trans}(\|q+1,\39\|q+2)$;\C{that's \\{x\_coord} and \\{y\_coord}}\6
+\&{if} $\\{right\_type}(\|q)\I\\{endpoint}$ \1\&{then}\5
+$\\{trans}(\|q+5,\39\|q+6)$;\C{that's \\{right\_x} and \\{right\_y}}\2\6
+$\|q\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\|q=\\{cur\_exp}$;\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M963. The next simplest transformation procedure applies to edges.
+It is simple primarily because \MF\ doesn't allow very general
+transformations to be made, and because the tricky subroutines
+for edge transformation have already been written.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{edges\_trans}(\|p:\\{pointer};\,\35\|c:%
+\\{quarterword})$;\6
+\4\&{label} \37\\{exit};\2\6
+\&{begin} \37$\\{set\_up\_known\_trans}(\|c)$;\5
+$\\{unstash\_cur\_exp}(\|p)$;\5
+$\\{cur\_edges}\K\\{cur\_exp}$;\6
+\&{if} $\\{empty\_edges}(\\{cur\_edges})$ \1\&{then}\5
+\&{return};\C{the empty set is easy to transform}\2\6
+\&{if} $\\{txx}=0$ \1\&{then}\6
+\&{if} $\\{tyy}=0$ \1\&{then}\6
+\&{if} $\\{txy}\mathbin{\&{mod}}\\{unity}=0$ \1\&{then}\6
+\&{if} $\\{tyx}\mathbin{\&{mod}}\\{unity}=0$ \1\&{then}\6
+\&{begin} \37\\{xy\_swap\_edges};\5
+$\\{txx}\K\\{txy}$;\5
+$\\{tyy}\K\\{tyx}$;\5
+$\\{txy}\K0$;\5
+$\\{tyx}\K0$;\6
+\&{if} $\\{empty\_edges}(\\{cur\_edges})$ \1\&{then}\5
+\&{return};\2\6
+\&{end};\2\2\2\2\6
+\&{if} $\\{txy}=0$ \1\&{then}\6
+\&{if} $\\{tyx}=0$ \1\&{then}\6
+\&{if} $\\{txx}\mathbin{\&{mod}}\\{unity}=0$ \1\&{then}\6
+\&{if} $\\{tyy}\mathbin{\&{mod}}\\{unity}=0$ \1\&{then}\5
+\X964:Scale the edges, shift them, and \&{return}\X;\2\2\2\2\6
+$\\{print\_err}(\.{"That\ transformation\ is\ too\ hard"})$;\5
+$\\{help3}(\.{"I\ can\ apply\ complicated\ transformations\ to\ paths,"})$\6
+$(\.{"but\ I\ can\ only\ do\ integer\ operations\ on\ pictures."})$\6
+$(\.{"Proceed,\ and\ I\'ll\ omit\ the\ transformation."})$;\5
+\\{put\_get\_error};\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M964. \P$\X964:Scale the edges, shift them, and \&{return}\X\S$\6
+\&{begin} \37\&{if} $(\\{txx}=0)\V(\\{tyy}=0)$ \1\&{then}\6
+\&{begin} \37$\\{toss\_edges}(\\{cur\_edges})$;\5
+$\\{cur\_exp}\K\\{get\_node}(\\{edge\_header\_size})$;\5
+$\\{init\_edges}(\\{cur\_exp})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{txx}<0$ \1\&{then}\6
+\&{begin} \37\\{x\_reflect\_edges};\5
+$\\{txx}\K-\\{txx}$;\6
+\&{end};\2\6
+\&{if} $\\{tyy}<0$ \1\&{then}\6
+\&{begin} \37\\{y\_reflect\_edges};\5
+$\\{tyy}\K-\\{tyy}$;\6
+\&{end};\2\6
+\&{if} $\\{txx}\I\\{unity}$ \1\&{then}\5
+$\\{x\_scale\_edges}(\\{txx}\mathbin{\&{div}}\\{unity})$;\2\6
+\&{if} $\\{tyy}\I\\{unity}$ \1\&{then}\5
+$\\{y\_scale\_edges}(\\{tyy}\mathbin{\&{div}}\\{unity})$;\2\6
+\X965:Shift the edges by $(\\{tx},\\{ty})$, rounded\X;\6
+\&{end};\2\6
+\&{return};\6
+\&{end}\par
+\U963.\fi
+
+\M965. \P$\X965:Shift the edges by $(\\{tx},\\{ty})$, rounded\X\S$\6
+$\\{tx}\K\\{round\_unscaled}(\\{tx})$;\5
+$\\{ty}\K\\{round\_unscaled}(\\{ty})$;\6
+\&{if} $(\\{m\_min}(\\{cur\_edges})+\\{tx}\L0)\V(\\{m\_max}(\\{cur\_edges})+%
+\\{tx}\G8192)\V\30(\\{n\_min}(\\{cur\_edges})+\\{ty}\L0)\V(\\{n\_max}(\\{cur%
+\_edges})+\\{ty}\G8191)\V\30(\\{abs}(\\{tx})\G4096)\V(\\{abs}(\\{ty})\G4096)$ %
+\1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Too\ far\ to\ shift"})$;\5
+$\\{help3}(\.{"I\ can\'t\ shift\ the\ picture\ as\ requested---it\ would"})$\6
+$(\.{"make\ some\ coordinates\ too\ large\ or\ too\ small."})$\6
+$(\.{"Proceed,\ and\ I\'ll\ omit\ the\ transformation."})$;\5
+\\{put\_get\_error};\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $\\{tx}\I0$ \1\&{then}\6
+\&{begin} \37\&{if} $\R\\{valid\_range}(\\{m\_offset}(\\{cur\_edges})-\\{tx})$ %
+\1\&{then}\5
+\\{fix\_offset};\2\6
+$\\{m\_min}(\\{cur\_edges})\K\\{m\_min}(\\{cur\_edges})+\\{tx}$;\5
+$\\{m\_max}(\\{cur\_edges})\K\\{m\_max}(\\{cur\_edges})+\\{tx}$;\5
+$\\{m\_offset}(\\{cur\_edges})\K\\{m\_offset}(\\{cur\_edges})-\\{tx}$;\5
+$\\{last\_window\_time}(\\{cur\_edges})\K0$;\6
+\&{end};\2\6
+\&{if} $\\{ty}\I0$ \1\&{then}\6
+\&{begin} \37$\\{n\_min}(\\{cur\_edges})\K\\{n\_min}(\\{cur\_edges})+\\{ty}$;\5
+$\\{n\_max}(\\{cur\_edges})\K\\{n\_max}(\\{cur\_edges})+\\{ty}$;\5
+$\\{n\_pos}(\\{cur\_edges})\K\\{n\_pos}(\\{cur\_edges})+\\{ty}$;\5
+$\\{last\_window\_time}(\\{cur\_edges})\K0$;\6
+\&{end};\2\6
+\&{end}\2\par
+\U964.\fi
+
+\M966. The hard cases of transformation occur when big nodes are involved,
+and when some of their components are unknown.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\hbox{\4}\X968:Declare subroutines needed by \\{big\_trans}\X\6
+\4\&{procedure}\1\ \37$\\{big\_trans}(\|p:\\{pointer};\,\35\|c:%
+\\{quarterword})$;\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37$\|q,\39\|r,\39\\{pp},\39\\{qq}$: \37\\{pointer};\C{list
+manipulation registers}\6
+\|s: \37\\{small\_number};\C{size of a big node}\2\6
+\&{begin} \37$\|s\K\\{big\_node\_size}[\\{type}(\|p)]$;\5
+$\|q\K\\{value}(\|p)$;\5
+$\|r\K\|q+\|s$;\6
+\1\&{repeat} \37$\|r\K\|r-2$;\6
+\&{if} $\\{type}(\|r)\I\\{known}$ \1\&{then}\5
+\X967:Transform an unknown big node and \&{return}\X;\2\6
+\4\&{until}\5
+$\|r=\|q$;\2\6
+\X970:Transform a known big node\X;\6
+\4\\{exit}: \37\&{end};\C{node \|p will now be recycled by \\{do\_binary}}\par
+\fi
+
+\M967. \P$\X967:Transform an unknown big node and \&{return}\X\S$\6
+\&{begin} \37$\\{set\_up\_known\_trans}(\|c)$;\5
+$\\{make\_exp\_copy}(\|p)$;\5
+$\|r\K\\{value}(\\{cur\_exp})$;\6
+\&{if} $\\{cur\_type}=\\{transform\_type}$ \1\&{then}\6
+\&{begin} \37$\\{bilin1}(\\{yy\_part\_loc}(\|r),\39\\{tyy},\39\\{xy\_part%
+\_loc}(\|q),\39\\{tyx},\390)$;\5
+$\\{bilin1}(\\{yx\_part\_loc}(\|r),\39\\{tyy},\39\\{xx\_part\_loc}(\|q),\39%
+\\{tyx},\390)$;\5
+$\\{bilin1}(\\{xy\_part\_loc}(\|r),\39\\{txx},\39\\{yy\_part\_loc}(\|q),\39%
+\\{txy},\390)$;\5
+$\\{bilin1}(\\{xx\_part\_loc}(\|r),\39\\{txx},\39\\{yx\_part\_loc}(\|q),\39%
+\\{txy},\390)$;\6
+\&{end};\2\6
+$\\{bilin1}(\\{y\_part\_loc}(\|r),\39\\{tyy},\39\\{x\_part\_loc}(\|q),\39%
+\\{tyx},\39\\{ty})$;\5
+$\\{bilin1}(\\{x\_part\_loc}(\|r),\39\\{txx},\39\\{y\_part\_loc}(\|q),\39%
+\\{txy},\39\\{tx})$;\5
+\&{return};\6
+\&{end}\par
+\U966.\fi
+
+\M968. Let \|p point to a two-word value field inside a big node of \\{cur%
+\_exp},
+and let \|q point to a another value field. The \\{bilin1} procedure
+replaces \|p by $p\cdot t+q\cdot u+\delta$.
+
+\Y\P$\4\X968:Declare subroutines needed by \\{big\_trans}\X\S$\6
+\4\&{procedure}\1\ \37$\\{bilin1}(\|p:\\{pointer};\,\35\|t:\\{scaled};\,\35%
+\|q:\\{pointer};\,\35\|u,\39\\{delta}:\\{scaled})$;\6
+\4\&{var} \37\|r: \37\\{pointer};\C{list traverser}\2\6
+\&{begin} \37\&{if} $\|t\I\\{unity}$ \1\&{then}\5
+$\\{dep\_mult}(\|p,\39\|t,\39\\{true})$;\2\6
+\&{if} $\|u\I0$ \1\&{then}\6
+\&{if} $\\{type}(\|q)=\\{known}$ \1\&{then}\5
+$\\{delta}\K\\{delta}+\\{take\_scaled}(\\{value}(\|q),\39\|u)$\6
+\4\&{else} \&{begin} \37\X969:Ensure that $\\{type}(\|p)=\\{proto\_dependent}$%
+\X;\6
+$\\{dep\_list}(\|p)\K\\{p\_plus\_fq}(\\{dep\_list}(\|p),\39\|u,\39\\{dep%
+\_list}(\|q),\39\\{proto\_dependent},\39\\{type}(\|q))$;\6
+\&{end};\2\2\6
+\&{if} $\\{type}(\|p)=\\{known}$ \1\&{then}\5
+$\\{value}(\|p)\K\\{value}(\|p)+\\{delta}$\6
+\4\&{else} \&{begin} \37$\|r\K\\{dep\_list}(\|p)$;\6
+\&{while} $\\{info}(\|r)\I\\{null}$ \1\&{do}\5
+$\|r\K\\{link}(\|r)$;\2\6
+$\\{delta}\K\\{value}(\|r)+\\{delta}$;\6
+\&{if} $\|r\I\\{dep\_list}(\|p)$ \1\&{then}\5
+$\\{value}(\|r)\K\\{delta}$\6
+\4\&{else} \&{begin} \37$\\{recycle\_value}(\|p)$;\5
+$\\{type}(\|p)\K\\{known}$;\5
+$\\{value}(\|p)\K\\{delta}$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{if} $\\{fix\_needed}$ \1\&{then}\5
+\\{fix\_dependencies};\2\6
+\&{end};\par
+\As971, 972\ETs974.
+\U966.\fi
+
+\M969. \P$\X969:Ensure that $\\{type}(\|p)=\\{proto\_dependent}$\X\S$\6
+\&{if} $\\{type}(\|p)\I\\{proto\_dependent}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{type}(\|p)=\\{known}$ \1\&{then}\5
+$\\{new\_dep}(\|p,\39\\{const\_dependency}(\\{value}(\|p)))$\6
+\4\&{else} $\\{dep\_list}(\|p)\K\\{p\_times\_v}(\\{dep\_list}(\|p),\39%
+\\{unity},\39\\{dependent},\39\\{proto\_dependent},\39\\{true})$;\2\6
+$\\{type}(\|p)\K\\{proto\_dependent}$;\6
+\&{end}\2\par
+\U968.\fi
+
+\M970. \P$\X970:Transform a known big node\X\S$\6
+$\\{set\_up\_trans}(\|c)$;\6
+\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\5
+\X973:Transform known by known\X\6
+\4\&{else} \&{begin} \37$\\{pp}\K\\{stash\_cur\_exp}$;\5
+$\\{qq}\K\\{value}(\\{pp})$;\5
+$\\{make\_exp\_copy}(\|p)$;\5
+$\|r\K\\{value}(\\{cur\_exp})$;\6
+\&{if} $\\{cur\_type}=\\{transform\_type}$ \1\&{then}\6
+\&{begin} \37$\\{bilin2}(\\{yy\_part\_loc}(\|r),\39\\{yy\_part\_loc}(\\{qq}),%
+\39\\{value}(\\{xy\_part\_loc}(\|q)),\39\\{yx\_part\_loc}(\\{qq}),\39%
+\\{null})$;\5
+$\\{bilin2}(\\{yx\_part\_loc}(\|r),\39\\{yy\_part\_loc}(\\{qq}),\39\\{value}(%
+\\{xx\_part\_loc}(\|q)),\39\\{yx\_part\_loc}(\\{qq}),\39\\{null})$;\5
+$\\{bilin2}(\\{xy\_part\_loc}(\|r),\39\\{xx\_part\_loc}(\\{qq}),\39\\{value}(%
+\\{yy\_part\_loc}(\|q)),\39\\{xy\_part\_loc}(\\{qq}),\39\\{null})$;\5
+$\\{bilin2}(\\{xx\_part\_loc}(\|r),\39\\{xx\_part\_loc}(\\{qq}),\39\\{value}(%
+\\{yx\_part\_loc}(\|q)),\39\\{xy\_part\_loc}(\\{qq}),\39\\{null})$;\6
+\&{end};\2\6
+$\\{bilin2}(\\{y\_part\_loc}(\|r),\39\\{yy\_part\_loc}(\\{qq}),\39\\{value}(%
+\\{x\_part\_loc}(\|q)),\39\\{yx\_part\_loc}(\\{qq}),\39\\{y\_part\_loc}(%
+\\{qq}))$;\5
+$\\{bilin2}(\\{x\_part\_loc}(\|r),\39\\{xx\_part\_loc}(\\{qq}),\39\\{value}(%
+\\{y\_part\_loc}(\|q)),\39\\{xy\_part\_loc}(\\{qq}),\39\\{x\_part\_loc}(%
+\\{qq}))$;\5
+$\\{recycle\_value}(\\{pp})$;\5
+$\\{free\_node}(\\{pp},\39\\{value\_node\_size})$;\6
+\&{end};\2\par
+\U966.\fi
+
+\M971. Let \|p be a \\{proto\_dependent} value whose dependency list ends
+at \\{dep\_final}. The following procedure adds \|v times another
+numeric quantity to~\|p.
+
+\Y\P$\4\X968:Declare subroutines needed by \\{big\_trans}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{add\_mult\_dep}(\|p:\\{pointer};\,\35\|v:\\{scaled};%
+\,\35\|r:\\{pointer})$;\2\6
+\&{begin} \37\&{if} $\\{type}(\|r)=\\{known}$ \1\&{then}\5
+$\\{value}(\\{dep\_final})\K\\{value}(\\{dep\_final})+\\{take\_scaled}(%
+\\{value}(\|r),\39\|v)$\6
+\4\&{else} \&{begin} \37$\\{dep\_list}(\|p)\K\\{p\_plus\_fq}(\\{dep\_list}(%
+\|p),\39\|v,\39\\{dep\_list}(\|r),\39\\{proto\_dependent},\39\\{type}(\|r))$;\6
+\&{if} $\\{fix\_needed}$ \1\&{then}\5
+\\{fix\_dependencies};\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M972. The \\{bilin2} procedure is something like \\{bilin1}, but with known
+and unknown quantities reversed. Parameter \|p points to a value field
+within the big node for \\{cur\_exp}; and $\\{type}(\|p)=\\{known}$. Parameters
+\|t and~\|u point to value fields elsewhere; so does parameter~\|q,
+unless it is \\{null} (which stands for zero). Location~\|p will be
+replaced by $p\cdot t+v\cdot u+q$.
+
+\Y\P$\4\X968:Declare subroutines needed by \\{big\_trans}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{bilin2}(\|p,\39\|t:\\{pointer};\,\35\|v:\\{scaled};%
+\,\35\|u,\39\|q:\\{pointer})$;\6
+\4\&{var} \37\\{vv}: \37\\{scaled};\C{temporary storage for $\\{value}(\|p)$}\2%
+\6
+\&{begin} \37$\\{vv}\K\\{value}(\|p)$;\5
+$\\{type}(\|p)\K\\{proto\_dependent}$;\5
+$\\{new\_dep}(\|p,\39\\{const\_dependency}(0))$;\C{this sets \\{dep\_final}}\6
+\&{if} $\\{vv}\I0$ \1\&{then}\5
+$\\{add\_mult\_dep}(\|p,\39\\{vv},\39\|t)$;\C{\\{dep\_final} doesn't change}\2\6
+\&{if} $\|v\I0$ \1\&{then}\5
+$\\{add\_mult\_dep}(\|p,\39\|v,\39\|u)$;\2\6
+\&{if} $\|q\I\\{null}$ \1\&{then}\5
+$\\{add\_mult\_dep}(\|p,\39\\{unity},\39\|q)$;\2\6
+\&{if} $\\{dep\_list}(\|p)=\\{dep\_final}$ \1\&{then}\6
+\&{begin} \37$\\{vv}\K\\{value}(\\{dep\_final})$;\5
+$\\{recycle\_value}(\|p)$;\5
+$\\{type}(\|p)\K\\{known}$;\5
+$\\{value}(\|p)\K\\{vv}$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M973. \P$\X973:Transform known by known\X\S$\6
+\&{begin} \37$\\{make\_exp\_copy}(\|p)$;\5
+$\|r\K\\{value}(\\{cur\_exp})$;\6
+\&{if} $\\{cur\_type}=\\{transform\_type}$ \1\&{then}\6
+\&{begin} \37$\\{bilin3}(\\{yy\_part\_loc}(\|r),\39\\{tyy},\39\\{value}(\\{xy%
+\_part\_loc}(\|q)),\39\\{tyx},\390)$;\5
+$\\{bilin3}(\\{yx\_part\_loc}(\|r),\39\\{tyy},\39\\{value}(\\{xx\_part\_loc}(%
+\|q)),\39\\{tyx},\390)$;\5
+$\\{bilin3}(\\{xy\_part\_loc}(\|r),\39\\{txx},\39\\{value}(\\{yy\_part\_loc}(%
+\|q)),\39\\{txy},\390)$;\5
+$\\{bilin3}(\\{xx\_part\_loc}(\|r),\39\\{txx},\39\\{value}(\\{yx\_part\_loc}(%
+\|q)),\39\\{txy},\390)$;\6
+\&{end};\2\6
+$\\{bilin3}(\\{y\_part\_loc}(\|r),\39\\{tyy},\39\\{value}(\\{x\_part\_loc}(%
+\|q)),\39\\{tyx},\39\\{ty})$;\5
+$\\{bilin3}(\\{x\_part\_loc}(\|r),\39\\{txx},\39\\{value}(\\{y\_part\_loc}(%
+\|q)),\39\\{txy},\39\\{tx})$;\6
+\&{end}\par
+\U970.\fi
+
+\M974. Finally, in \\{bilin3} everything is \\{known}.
+
+\Y\P$\4\X968:Declare subroutines needed by \\{big\_trans}\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{bilin3}(\|p:\\{pointer};\,\35\|t,\39\|v,\39\|u,\39%
+\\{delta}:\\{scaled})$;\2\6
+\&{begin} \37\&{if} $\|t\I\\{unity}$ \1\&{then}\5
+$\\{delta}\K\\{delta}+\\{take\_scaled}(\\{value}(\|p),\39\|t)$\6
+\4\&{else} $\\{delta}\K\\{delta}+\\{value}(\|p)$;\2\6
+\&{if} $\|u\I0$ \1\&{then}\5
+$\\{value}(\|p)\K\\{delta}+\\{take\_scaled}(\|v,\39\|u)$\6
+\4\&{else} $\\{value}(\|p)\K\\{delta}$;\2\6
+\&{end};\par
+\fi
+
+\M975. \P$\X936:Additional cases of binary operators\X\mathrel{+}\S$\6
+\4\\{concatenate}: \37\&{if} $(\\{cur\_type}=\\{string\_type})\W(\\{type}(\|p)=%
+\\{string\_type})$ \1\&{then}\5
+$\\{cat}(\|p)$\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\\{concatenate})$;\2\6
+\4\\{substring\_of}: \37\&{if} $\\{nice\_pair}(\|p,\39\\{type}(\|p))\W(\\{cur%
+\_type}=\\{string\_type})$ \1\&{then}\5
+$\\{chop\_string}(\\{value}(\|p))$\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\\{substring\_of})$;\2\6
+\4\\{subpath\_of}: \37\&{begin} \37\&{if} $\\{cur\_type}=\\{pair\_type}$ \1%
+\&{then}\5
+\\{pair\_to\_path};\2\6
+\&{if} $\\{nice\_pair}(\|p,\39\\{type}(\|p))\W(\\{cur\_type}=\\{path\_type})$ %
+\1\&{then}\5
+$\\{chop\_path}(\\{value}(\|p))$\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\\{subpath\_of})$;\2\6
+\&{end};\par
+\fi
+
+\M976. \P$\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{cat}(\|p:\\{pointer})$;\6
+\4\&{var} \37$\|a,\39\|b$: \37\\{str\_number};\C{the strings being
+concatenated}\6
+\|k: \37\\{pool\_pointer};\C{index into \\{str\_pool}}\2\6
+\&{begin} \37$\|a\K\\{value}(\|p)$;\5
+$\|b\K\\{cur\_exp}$;\5
+$\\{str\_room}(\\{length}(\|a)+\\{length}(\|b))$;\6
+\&{for} $\|k\K\\{str\_start}[\|a]\mathrel{\&{to}}\\{str\_start}[\|a+1]-1$ \1%
+\&{do}\5
+$\\{append\_char}(\\{so}(\\{str\_pool}[\|k]))$;\2\6
+\&{for} $\|k\K\\{str\_start}[\|b]\mathrel{\&{to}}\\{str\_start}[\|b+1]-1$ \1%
+\&{do}\5
+$\\{append\_char}(\\{so}(\\{str\_pool}[\|k]))$;\2\6
+$\\{cur\_exp}\K\\{make\_string}$;\5
+$\\{delete\_str\_ref}(\|b)$;\6
+\&{end};\par
+\fi
+
+\M977. \P$\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{chop\_string}(\|p:\\{pointer})$;\6
+\4\&{var} \37$\|a,\39\|b$: \37\\{integer};\C{start and stop points}\6
+\|l: \37\\{integer};\C{length of the original string}\6
+\|k: \37\\{integer};\C{runs from \|a to \|b}\6
+\|s: \37\\{str\_number};\C{the original string}\6
+\\{reversed}: \37\\{boolean};\C{was $\|a>\|b$?}\2\6
+\&{begin} \37$\|a\K\\{round\_unscaled}(\\{value}(\\{x\_part\_loc}(\|p)))$;\5
+$\|b\K\\{round\_unscaled}(\\{value}(\\{y\_part\_loc}(\|p)))$;\6
+\&{if} $\|a\L\|b$ \1\&{then}\5
+$\\{reversed}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\\{reversed}\K\\{true}$;\5
+$\|k\K\|a$;\5
+$\|a\K\|b$;\5
+$\|b\K\|k$;\6
+\&{end};\2\6
+$\|s\K\\{cur\_exp}$;\5
+$\|l\K\\{length}(\|s)$;\6
+\&{if} $\|a<0$ \1\&{then}\6
+\&{begin} \37$\|a\K0$;\6
+\&{if} $\|b<0$ \1\&{then}\5
+$\|b\K0$;\2\6
+\&{end};\2\6
+\&{if} $\|b>\|l$ \1\&{then}\6
+\&{begin} \37$\|b\K\|l$;\6
+\&{if} $\|a>\|l$ \1\&{then}\5
+$\|a\K\|l$;\2\6
+\&{end};\2\6
+$\\{str\_room}(\|b-\|a)$;\6
+\&{if} $\\{reversed}$ \1\&{then}\6
+\&{for} $\|k\K\\{str\_start}[\|s]+\|b-1\mathrel{\&{downto}}\\{str\_start}[\|s]+%
+\|a$ \1\&{do}\5
+$\\{append\_char}(\\{so}(\\{str\_pool}[\|k]))$\2\6
+\4\&{else} \&{for} $\|k\K\\{str\_start}[\|s]+\|a\mathrel{\&{to}}\\{str\_start}[%
+\|s]+\|b-1$ \1\&{do}\5
+$\\{append\_char}(\\{so}(\\{str\_pool}[\|k]))$;\2\2\6
+$\\{cur\_exp}\K\\{make\_string}$;\5
+$\\{delete\_str\_ref}(\|s)$;\6
+\&{end};\par
+\fi
+
+\M978. \P$\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{chop\_path}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{a knot in the original path}\6
+$\\{pp},\39\\{qq},\39\\{rr},\39\\{ss}$: \37\\{pointer};\C{link variables for
+copies of path nodes}\6
+$\|a,\39\|b,\39\|k,\39\|l$: \37\\{scaled};\C{indices for chopping}\6
+\\{reversed}: \37\\{boolean};\C{was $\|a>\|b$?}\2\6
+\&{begin} \37$\|l\K\\{path\_length}$;\5
+$\|a\K\\{value}(\\{x\_part\_loc}(\|p))$;\5
+$\|b\K\\{value}(\\{y\_part\_loc}(\|p))$;\6
+\&{if} $\|a\L\|b$ \1\&{then}\5
+$\\{reversed}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\\{reversed}\K\\{true}$;\5
+$\|k\K\|a$;\5
+$\|a\K\|b$;\5
+$\|b\K\|k$;\6
+\&{end};\2\6
+\X979:Dispense with the cases $\|a<0$ and/or $\|b>\|l$\X;\6
+$\|q\K\\{cur\_exp}$;\6
+\&{while} $\|a\G\\{unity}$ \1\&{do}\6
+\&{begin} \37$\|q\K\\{link}(\|q)$;\5
+$\|a\K\|a-\\{unity}$;\5
+$\|b\K\|b-\\{unity}$;\6
+\&{end};\2\6
+\&{if} $\|b=\|a$ \1\&{then}\5
+\X981:Construct a path from \\{pp} to \\{qq} of length zero\X\6
+\4\&{else} \X980:Construct a path from \\{pp} to \\{qq} of length $\lceil b%
+\rceil$\X;\2\6
+$\\{left\_type}(\\{pp})\K\\{endpoint}$;\5
+$\\{right\_type}(\\{qq})\K\\{endpoint}$;\5
+$\\{link}(\\{qq})\K\\{pp}$;\5
+$\\{toss\_knot\_list}(\\{cur\_exp})$;\6
+\&{if} $\\{reversed}$ \1\&{then}\6
+\&{begin} \37$\\{cur\_exp}\K\\{link}(\\{htap\_ypoc}(\\{pp}))$;\5
+$\\{toss\_knot\_list}(\\{pp})$;\6
+\&{end}\6
+\4\&{else} $\\{cur\_exp}\K\\{pp}$;\2\6
+\&{end};\par
+\fi
+
+\M979. \P$\X979:Dispense with the cases $\|a<0$ and/or $\|b>\|l$\X\S$\6
+\&{if} $\|a<0$ \1\&{then}\6
+\&{if} $\\{left\_type}(\\{cur\_exp})=\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\|a\K0$;\6
+\&{if} $\|b<0$ \1\&{then}\5
+$\|b\K0$;\2\6
+\&{end}\6
+\4\&{else} \1\&{repeat} \37$\|a\K\|a+\|l$;\5
+$\|b\K\|b+\|l$;\6
+\4\&{until}\5
+$\|a\G0$;\C{a cycle always has length $\|l>0$}\2\2\2\6
+\&{if} $\|b>\|l$ \1\&{then}\6
+\&{if} $\\{left\_type}(\\{cur\_exp})=\\{endpoint}$ \1\&{then}\6
+\&{begin} \37$\|b\K\|l$;\6
+\&{if} $\|a>\|l$ \1\&{then}\5
+$\|a\K\|l$;\2\6
+\&{end}\6
+\4\&{else} \&{while} $\|a\G\|l$ \1\&{do}\6
+\&{begin} \37$\|a\K\|a-\|l$;\5
+$\|b\K\|b-\|l$;\6
+\&{end}\2\2\2\par
+\U978.\fi
+
+\M980. \P$\X980:Construct a path from \\{pp} to \\{qq} of length $\lceil b%
+\rceil$\X\S$\6
+\&{begin} \37$\\{pp}\K\\{copy\_knot}(\|q)$;\5
+$\\{qq}\K\\{pp}$;\6
+\1\&{repeat} \37$\|q\K\\{link}(\|q)$;\5
+$\\{rr}\K\\{qq}$;\5
+$\\{qq}\K\\{copy\_knot}(\|q)$;\5
+$\\{link}(\\{rr})\K\\{qq}$;\5
+$\|b\K\|b-\\{unity}$;\6
+\4\&{until}\5
+$\|b\L0$;\2\6
+\&{if} $\|a>0$ \1\&{then}\6
+\&{begin} \37$\\{ss}\K\\{pp}$;\5
+$\\{pp}\K\\{link}(\\{pp})$;\5
+$\\{split\_cubic}(\\{ss},\39\|a\ast\O{10000},\39\\{x\_coord}(\\{pp}),\39\\{y%
+\_coord}(\\{pp}))$;\5
+$\\{pp}\K\\{link}(\\{ss})$;\5
+$\\{free\_node}(\\{ss},\39\\{knot\_node\_size})$;\6
+\&{if} $\\{rr}=\\{ss}$ \1\&{then}\6
+\&{begin} \37$\|b\K\\{make\_scaled}(\|b,\39\\{unity}-\|a)$;\5
+$\\{rr}\K\\{pp}$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{if} $\|b<0$ \1\&{then}\6
+\&{begin} \37$\\{split\_cubic}(\\{rr},\39(\|b+\\{unity})\ast\O{10000},\39\\{x%
+\_coord}(\\{qq}),\39\\{y\_coord}(\\{qq}))$;\5
+$\\{free\_node}(\\{qq},\39\\{knot\_node\_size})$;\5
+$\\{qq}\K\\{link}(\\{rr})$;\6
+\&{end};\2\6
+\&{end}\par
+\U978.\fi
+
+\M981. \P$\X981:Construct a path from \\{pp} to \\{qq} of length zero\X\S$\6
+\&{begin} \37\&{if} $\|a>0$ \1\&{then}\6
+\&{begin} \37$\\{qq}\K\\{link}(\|q)$;\5
+$\\{split\_cubic}(\|q,\39\|a\ast\O{10000},\39\\{x\_coord}(\\{qq}),\39\\{y%
+\_coord}(\\{qq}))$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+$\\{pp}\K\\{copy\_knot}(\|q)$;\5
+$\\{qq}\K\\{pp}$;\6
+\&{end}\par
+\U978.\fi
+
+\M982. The \\{pair\_value} routine changes the current expression to a
+given ordered pair of values.
+
+\Y\P$\4\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{pair\_value}(\|x,\39\|y:\\{scaled})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{a pair node}\2\6
+\&{begin} \37$\|p\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{flush\_cur\_exp}(\|p)$;\5
+$\\{cur\_type}\K\\{pair\_type}$;\5
+$\\{type}(\|p)\K\\{pair\_type}$;\5
+$\\{name\_type}(\|p)\K\\{capsule}$;\5
+$\\{init\_big\_node}(\|p)$;\5
+$\|p\K\\{value}(\|p)$;\6
+$\\{type}(\\{x\_part\_loc}(\|p))\K\\{known}$;\5
+$\\{value}(\\{x\_part\_loc}(\|p))\K\|x$;\6
+$\\{type}(\\{y\_part\_loc}(\|p))\K\\{known}$;\5
+$\\{value}(\\{y\_part\_loc}(\|p))\K\|y$;\6
+\&{end};\par
+\fi
+
+\M983. \P$\X936:Additional cases of binary operators\X\mathrel{+}\S$\6
+\4$\\{point\_of},\39\\{precontrol\_of},\39\\{postcontrol\_of}$: \37\&{begin} %
+\37\&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\5
+\\{pair\_to\_path};\2\6
+\&{if} $(\\{cur\_type}=\\{path\_type})\W(\\{type}(\|p)=\\{known})$ \1\&{then}\5
+$\\{find\_point}(\\{value}(\|p),\39\|c)$\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\|c)$;\2\6
+\&{end};\6
+\4\\{pen\_offset\_of}: \37\&{begin} \37\&{if} $\\{cur\_type}=\\{future\_pen}$ %
+\1\&{then}\5
+\\{materialize\_pen};\2\6
+\&{if} $(\\{cur\_type}=\\{pen\_type})\W\\{nice\_pair}(\|p,\39\\{type}(\|p))$ \1%
+\&{then}\5
+$\\{set\_up\_offset}(\\{value}(\|p))$\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\\{pen\_offset\_of})$;\2\6
+\&{end};\6
+\4\\{direction\_time\_of}: \37\&{begin} \37\&{if} $\\{cur\_type}=\\{pair%
+\_type}$ \1\&{then}\5
+\\{pair\_to\_path};\2\6
+\&{if} $(\\{cur\_type}=\\{path\_type})\W\\{nice\_pair}(\|p,\39\\{type}(\|p))$ %
+\1\&{then}\5
+$\\{set\_up\_direction\_time}(\\{value}(\|p))$\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\\{direction\_time\_of})$;\2\6
+\&{end};\par
+\fi
+
+\M984. \P$\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{set\_up\_offset}(\|p:\\{pointer})$;\2\6
+\&{begin} \37$\\{find\_offset}(\\{value}(\\{x\_part\_loc}(\|p)),\39\\{value}(%
+\\{y\_part\_loc}(\|p)),\39\\{cur\_exp})$;\5
+$\\{pair\_value}(\\{cur\_x},\39\\{cur\_y})$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37$\\{set\_up\_direction\_time}(\|p:\\{pointer})$;\2\6
+\&{begin} \37$\\{flush\_cur\_exp}(\\{find\_direction\_time}(\\{value}(\\{x%
+\_part\_loc}(\|p)),\39\\{value}(\\{y\_part\_loc}(\|p)),\39\\{cur\_exp}))$;\6
+\&{end};\par
+\fi
+
+\M985. \P$\X923:Declare binary action procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{find\_point}(\|v:\\{scaled};\,\35\|c:%
+\\{quarterword})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{the path}\6
+\|n: \37\\{scaled};\C{its length}\6
+\|q: \37\\{pointer};\C{successor of \|p}\2\6
+\&{begin} \37$\|p\K\\{cur\_exp}$;\6
+\&{if} $\\{left\_type}(\|p)=\\{endpoint}$ \1\&{then}\5
+$\|n\K-\\{unity}$\ \&{else} $\|n\K0$;\2\6
+\1\&{repeat} \37$\|p\K\\{link}(\|p)$;\5
+$\|n\K\|n+\\{unity}$;\6
+\4\&{until}\5
+$\|p=\\{cur\_exp}$;\2\6
+\&{if} $\|n=0$ \1\&{then}\5
+$\|v\K0$\6
+\4\&{else} \&{if} $\|v<0$ \1\&{then}\6
+\&{if} $\\{left\_type}(\|p)=\\{endpoint}$ \1\&{then}\5
+$\|v\K0$\6
+\4\&{else} $\|v\K\|n-1-((-\|v-1)\mathbin{\&{mod}}\|n)$\2\6
+\4\&{else} \&{if} $\|v>\|n$ \1\&{then}\6
+\&{if} $\\{left\_type}(\|p)=\\{endpoint}$ \1\&{then}\5
+$\|v\K\|n$\6
+\4\&{else} $\|v\K\|v\mathbin{\&{mod}}\|n$;\2\2\2\2\6
+$\|p\K\\{cur\_exp}$;\6
+\&{while} $\|v\G\\{unity}$ \1\&{do}\6
+\&{begin} \37$\|p\K\\{link}(\|p)$;\5
+$\|v\K\|v-\\{unity}$;\6
+\&{end};\2\6
+\&{if} $\|v\I0$ \1\&{then}\5
+\X986:Insert a fractional node by splitting the cubic\X;\2\6
+\X987:Set the current expression to the desired path coordinates\X;\6
+\&{end};\par
+\fi
+
+\M986. \P$\X986:Insert a fractional node by splitting the cubic\X\S$\6
+\&{begin} \37$\|q\K\\{link}(\|p)$;\5
+$\\{split\_cubic}(\|p,\39\|v\ast\O{10000},\39\\{x\_coord}(\|q),\39\\{y\_coord}(%
+\|q))$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end}\par
+\U985.\fi
+
+\M987. \P$\X987:Set the current expression to the desired path coordinates\X\S$%
+\6
+\&{case} $\|c$ \1\&{of}\6
+\4\\{point\_of}: \37$\\{pair\_value}(\\{x\_coord}(\|p),\39\\{y\_coord}(\|p))$;\6
+\4\\{precontrol\_of}: \37\&{if} $\\{left\_type}(\|p)=\\{endpoint}$ \1\&{then}\5
+$\\{pair\_value}(\\{x\_coord}(\|p),\39\\{y\_coord}(\|p))$\6
+\4\&{else} $\\{pair\_value}(\\{left\_x}(\|p),\39\\{left\_y}(\|p))$;\2\6
+\4\\{postcontrol\_of}: \37\&{if} $\\{right\_type}(\|p)=\\{endpoint}$ \1\&{then}%
+\5
+$\\{pair\_value}(\\{x\_coord}(\|p),\39\\{y\_coord}(\|p))$\6
+\4\&{else} $\\{pair\_value}(\\{right\_x}(\|p),\39\\{right\_y}(\|p))$;\2\2\6
+\&{end}\C{there are no other cases}\par
+\U985.\fi
+
+\M988. \P$\X936:Additional cases of binary operators\X\mathrel{+}\S$\6
+\4\\{intersect}: \37\&{begin} \37\&{if} $\\{type}(\|p)=\\{pair\_type}$ \1%
+\&{then}\6
+\&{begin} \37$\|q\K\\{stash\_cur\_exp}$;\5
+$\\{unstash\_cur\_exp}(\|p)$;\5
+\\{pair\_to\_path};\5
+$\|p\K\\{stash\_cur\_exp}$;\5
+$\\{unstash\_cur\_exp}(\|q)$;\6
+\&{end};\2\6
+\&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\5
+\\{pair\_to\_path};\2\6
+\&{if} $(\\{cur\_type}=\\{path\_type})\W(\\{type}(\|p)=\\{path\_type})$ \1%
+\&{then}\6
+\&{begin} \37$\\{path\_intersection}(\\{value}(\|p),\39\\{cur\_exp})$;\5
+$\\{pair\_value}(\\{cur\_t},\39\\{cur\_tt})$;\6
+\&{end}\6
+\4\&{else} $\\{bad\_binary}(\|p,\39\\{intersect})$;\2\6
+\&{end};\par
+\fi
+
+\N989. \[43] Statements and commands.
+The chief executive of \MF\ is the \\{do\_statement} routine, which
+contains the master switch that causes all the various pieces of \MF\
+to do their things, in the right order.
+
+In a sense, this is the grand climax of the program: It applies all the
+tools that we have worked so hard to construct. In another sense, this is
+the messiest part of the program: It necessarily refers to other pieces
+of code all over the place, so that a person can't fully understand what is
+going on without paging back and forth to be reminded of conventions that
+are defined elsewhere. We are now at the hub of the web.
+
+The structure of \\{do\_statement} itself is quite simple. The first token
+of the statement is fetched using \\{get\_x\_next}. If it can be the first
+token of an expression, we look for an equation, an assignment, or a
+title. Otherwise we use a \&{case} construction to branch at high speed to
+the appropriate routine for various and sundry other types of commands,
+each of which has an ``action procedure'' that does the necessary work.
+
+The program uses the fact that
+$$\hbox{$\\{min\_primary\_command}=\\{max\_statement\_command}=\\{type%
+\_name}$}$$
+to interpret a statement that starts with, e.g., `\&{string}',
+as a type declaration rather than a boolean expression.
+
+\Y\P\hbox{\4}\X1154:Declare generic font output procedures\X\6
+\hbox{\4}\X995:Declare action procedures for use by \\{do\_statement}\X\6
+\4\&{procedure}\1\ \37\\{do\_statement};\C{governs \MF's activities}\2\6
+\&{begin} \37$\\{cur\_type}\K\\{vacuous}$;\5
+\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}>\\{max\_primary\_command}$ \1\&{then}\5
+\X990:Worry about bad statement\X\6
+\4\&{else} \&{if} $\\{cur\_cmd}>\\{max\_statement\_command}$ \1\&{then}\5
+\X993:Do an equation, assignment, title, or `$\langle\,$expression$\,\rangle\,$%
+\&{endgroup}'\X\6
+\4\&{else} \X992:Do a statement that doesn't begin with an expression\X;\2\2\6
+\&{if} $\\{cur\_cmd}<\\{semicolon}$ \1\&{then}\5
+\X991:Flush unparsable junk that was found after the statement\X;\2\6
+$\\{error\_count}\K0$;\6
+\&{end};\par
+\fi
+
+\M990. The only command codes $>\\{max\_primary\_command}$ that can be present
+at the beginning of a statement are \\{semicolon} and higher; these
+occur when the statement is null.
+
+\Y\P$\4\X990:Worry about bad statement\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_cmd}<\\{semicolon}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"A\ statement\ can\'t\ begin\ with\ \`"})$;\5
+$\\{print\_cmd\_mod}(\\{cur\_cmd},\39\\{cur\_mod})$;\5
+$\\{print\_char}(\.{"\'"})$;\5
+$\\{help5}(\.{"I\ was\ looking\ for\ the\ beginning\ of\ a\ new\ statement."})$%
+\6
+$(\.{"If\ you\ just\ proceed\ without\ changing\ anything,\ I\'ll\ ignore"})$\6
+$(\.{"everything\ up\ to\ the\ next\ \`;\'.\ Please\ insert\ a\ semicolon"})$\6
+$(\.{"now\ in\ front\ of\ anything\ that\ you\ don\'t\ want\ me\ to\
+delete."})$\6
+$(\.{"(See\ Chapter\ 27\ of\ The\ METAFONTbook\ for\ an\ example.)"})$;\6
+\\{back\_error};\5
+\\{get\_x\_next};\6
+\&{end};\2\6
+\&{end}\par
+\U989.\fi
+
+\M991. The help message printed here says that everything is flushed up to
+a semicolon, but actually the commands \\{end\_group} and \\{stop} will
+also terminate a statement.
+
+\Y\P$\4\X991:Flush unparsable junk that was found after the statement\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Extra\ tokens\ will\ be\ flushed"})$;\5
+$\\{help6}(\.{"I\'ve\ just\ read\ as\ much\ of\ that\ statement\ as\ I\ could\
+fathom,"})$\6
+$(\.{"so\ a\ semicolon\ should\ have\ been\ next.\ It\'s\ very\ puzzling..."})$%
+\6
+$(\.{"but\ I\'ll\ try\ to\ get\ myself\ back\ together,\ by\ ignoring"})$\6
+$(\.{"everything\ up\ to\ the\ next\ \`;\'.\ Please\ insert\ a\ semicolon"})$\6
+$(\.{"now\ in\ front\ of\ anything\ that\ you\ don\'t\ want\ me\ to\
+delete."})$\6
+$(\.{"(See\ Chapter\ 27\ of\ The\ METAFONTbook\ for\ an\ example.)"})$;\6
+\\{back\_error};\5
+$\\{scanner\_status}\K\\{flushing}$;\6
+\1\&{repeat} \37\\{get\_next};\5
+\X743:Decrease the string reference count, if the current token is a string\X;\6
+\4\&{until}\5
+\\{end\_of\_statement};\C{$\\{cur\_cmd}=\\{semicolon}$, \\{end\_group}, or %
+\\{stop}}\2\6
+$\\{scanner\_status}\K\\{normal}$;\6
+\&{end}\par
+\U989.\fi
+
+\M992. If \\{do\_statement} ends with $\\{cur\_cmd}=\\{end\_group}$, we should
+have
+$\\{cur\_type}=\\{vacuous}$ unless the statement was simply an expression;
+in the latter case, \\{cur\_type} and \\{cur\_exp} should represent that
+expression.
+
+\Y\P$\4\X992:Do a statement that doesn't begin with an expression\X\S$\6
+\&{begin} \37\&{if} $\\{internal}[\\{tracing\_commands}]>0$ \1\&{then}\5
+\\{show\_cur\_cmd\_mod};\2\6
+\&{case} $\\{cur\_cmd}$ \1\&{of}\6
+\4\\{type\_name}: \37\\{do\_type\_declaration};\6
+\4\\{macro\_def}: \37\&{if} $\\{cur\_mod}>\\{var\_def}$ \1\&{then}\5
+\\{make\_op\_def}\6
+\4\&{else} \&{if} $\\{cur\_mod}>\\{end\_def}$ \1\&{then}\5
+\\{scan\_def};\2\2\6
+\hbox{\4}\X1020:Cases of \\{do\_statement} that invoke particular commands\X\2\6
+\&{end};\C{there are no other cases}\6
+$\\{cur\_type}\K\\{vacuous}$;\6
+\&{end}\par
+\U989.\fi
+
+\M993. The most important statements begin with expressions.
+
+\Y\P$\4\X993:Do an equation, assignment, title, or `$\langle\,$expression$\,%
+\rangle\,$\&{endgroup}'\X\S$\6
+\&{begin} \37$\\{var\_flag}\K\\{assignment}$;\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_cmd}<\\{end\_group}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{cur\_cmd}=\\{equals}$ \1\&{then}\5
+\\{do\_equation}\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{assignment}$ \1\&{then}\5
+\\{do\_assignment}\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{string\_type}$ \1\&{then}\5
+\X994:Do a title\X\6
+\4\&{else} \&{if} $\\{cur\_type}\I\\{vacuous}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Isolated\ expression"})$;\5
+$\\{help3}(\.{"I\ couldn\'t\ find\ an\ \`=\'\ or\ \`:=\'\ after\ the"})$\6
+$(\.{"expression\ that\ is\ shown\ above\ this\ error\ message,"})$\6
+$(\.{"so\ I\ guess\ I\'ll\ just\ ignore\ it\ and\ carry\ on."})$;\5
+\\{put\_get\_error};\6
+\&{end};\2\2\2\2\6
+$\\{flush\_cur\_exp}(0)$;\5
+$\\{cur\_type}\K\\{vacuous}$;\6
+\&{end};\2\6
+\&{end}\par
+\U989.\fi
+
+\M994. \P$\X994:Do a title\X\S$\6
+\&{begin} \37\&{if} $\\{internal}[\\{tracing\_titles}]>0$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{""})$;\5
+$\\{slow\_print}(\\{cur\_exp})$;\5
+\\{update\_terminal};\6
+\&{end};\2\6
+\&{if} $\\{internal}[\\{proofing}]>0$ \1\&{then}\5
+\X1179:Send the current expression as a title to the output file\X;\2\6
+\&{end}\par
+\U993.\fi
+
+\M995. Equations and assignments are performed by the pair of mutually
+recursive
+routines \\{do\_equation} and \\{do\_assignment}. These routines are called
+when
+$\\{cur\_cmd}=\\{equals}$ and when $\\{cur\_cmd}=\\{assignment}$, respectively;
+the left-hand
+side is in \\{cur\_type} and \\{cur\_exp}, while the right-hand side is yet
+to be scanned. After the routines are finished, \\{cur\_type} and \\{cur\_exp}
+will be equal to the right-hand side (which will normally be equal
+to the left-hand side).
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X\S$\6
+\hbox{\4}\X1006:Declare the procedure called \\{try\_eq}\X\6
+\hbox{\4}\X1001:Declare the procedure called \\{make\_eq}\X\6
+\4\&{procedure}\1\ \37\\{do\_assignment};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{do\_equation};\6
+\4\&{var} \37\\{lhs}: \37\\{pointer};\C{capsule for the left-hand side}\6
+\|p: \37\\{pointer};\C{temporary register}\2\6
+\&{begin} \37$\\{lhs}\K\\{stash\_cur\_exp}$;\5
+\\{get\_x\_next};\5
+$\\{var\_flag}\K\\{assignment}$;\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_cmd}=\\{equals}$ \1\&{then}\5
+\\{do\_equation}\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{assignment}$ \1\&{then}\5
+\\{do\_assignment};\2\2\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>\\{two}$ \1\&{then}\5
+\X997:Trace the current equation\X;\2\6
+\&{if} $\\{cur\_type}=\\{unknown\_path}$ \1\&{then}\6
+\&{if} $\\{type}(\\{lhs})=\\{pair\_type}$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{stash\_cur\_exp}$;\5
+$\\{unstash\_cur\_exp}(\\{lhs})$;\5
+$\\{lhs}\K\|p$;\6
+\&{end};\C{in this case \\{make\_eq} will change the pair to a path}\2\2\6
+$\\{make\_eq}(\\{lhs})$;\C{equate \\{lhs} to $(\\{cur\_type},\\{cur\_exp})$}\6
+\&{end};\par
+\As996, 1015, 1021, 1029, 1031, 1034, 1035, 1036, 1040, 1041, 1044, 1045, 1046,
+1049, 1050, 1051, 1054, 1057, 1059, 1070, 1071, 1072, 1073, 1074, 1082, 1103,
+1104, 1106, 1177\ETs1186.
+\U989.\fi
+
+\M996. And \\{do\_assignment} is similar to \\{do\_expression}:
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_assignment};\6
+\4\&{var} \37\\{lhs}: \37\\{pointer};\C{token list for the left-hand side}\6
+\|p: \37\\{pointer};\C{where the left-hand value is stored}\6
+\|q: \37\\{pointer};\C{temporary capsule for the right-hand value}\2\6
+\&{begin} \37\&{if} $\\{cur\_type}\I\\{token\_list}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ \`:=\'\ will\ be\ changed\ to\ \`=%
+\'"})$;\5
+$\\{help2}(\.{"I\ didn\'t\ find\ a\ variable\ name\ at\ the\ left\ of\ the\ %
+\`:=\',"})$\6
+$(\.{"so\ I\'m\ going\ to\ pretend\ that\ you\ said\ \`=\'\ instead."})$;\6
+\\{error};\5
+\\{do\_equation};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{lhs}\K\\{cur\_exp}$;\5
+$\\{cur\_type}\K\\{vacuous}$;\6
+\\{get\_x\_next};\5
+$\\{var\_flag}\K\\{assignment}$;\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_cmd}=\\{equals}$ \1\&{then}\5
+\\{do\_equation}\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{assignment}$ \1\&{then}\5
+\\{do\_assignment};\2\2\6
+\&{if} $\\{internal}[\\{tracing\_commands}]>\\{two}$ \1\&{then}\5
+\X998:Trace the current assignment\X;\2\6
+\&{if} $\\{info}(\\{lhs})>\\{hash\_end}$ \1\&{then}\5
+\X999:Assign the current expression to an internal variable\X\6
+\4\&{else} \X1000:Assign the current expression to the variable \\{lhs}\X;\2\6
+$\\{flush\_node\_list}(\\{lhs})$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M997. \P$\X997:Trace the current equation\X\S$\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{("})$;\5
+$\\{print\_exp}(\\{lhs},\390)$;\5
+$\\{print}(\.{")=("})$;\5
+$\\{print\_exp}(\\{null},\390)$;\5
+$\\{print}(\.{")\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\par
+\U995.\fi
+
+\M998. \P$\X998:Trace the current assignment\X\S$\6
+\&{begin} \37\\{begin\_diagnostic};\5
+$\\{print\_nl}(\.{"\{"})$;\6
+\&{if} $\\{info}(\\{lhs})>\\{hash\_end}$ \1\&{then}\5
+$\\{slow\_print}(\\{int\_name}[\\{info}(\\{lhs})-(\\{hash\_end})])$\6
+\4\&{else} $\\{show\_token\_list}(\\{lhs},\39\\{null},\391000,\390)$;\2\6
+$\\{print}(\.{":="})$;\5
+$\\{print\_exp}(\\{null},\390)$;\5
+$\\{print\_char}(\.{"\}"})$;\5
+$\\{end\_diagnostic}(\\{false})$;\6
+\&{end}\par
+\U996.\fi
+
+\M999. \P$\X999:Assign the current expression to an internal variable\X\S$\6
+\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\5
+$\\{internal}[\\{info}(\\{lhs})-(\\{hash\_end})]\K\\{cur\_exp}$\6
+\4\&{else} \&{begin} \37$\\{exp\_err}(\.{"Internal\ quantity\ \`"})$;\5
+$\\{slow\_print}(\\{int\_name}[\\{info}(\\{lhs})-(\\{hash\_end})])$;\5
+$\\{print}(\.{"\'\ must\ receive\ a\ known\ value"})$;\5
+$\\{help2}(\.{"I\ can\'t\ set\ an\ internal\ quantity\ to\ anything\ but\ a\
+known"})$\6
+$(\.{"numeric\ value,\ so\ I\'ll\ have\ to\ ignore\ this\ assignment."})$;\5
+\\{put\_get\_error};\6
+\&{end}\2\par
+\U996.\fi
+
+\M1000. \P$\X1000:Assign the current expression to the variable \\{lhs}\X\S$\6
+\&{begin} \37$\|p\K\\{find\_variable}(\\{lhs})$;\6
+\&{if} $\|p\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\|q\K\\{stash\_cur\_exp}$;\5
+$\\{cur\_type}\K\\{und\_type}(\|p)$;\5
+$\\{recycle\_value}(\|p)$;\5
+$\\{type}(\|p)\K\\{cur\_type}$;\5
+$\\{value}(\|p)\K\\{null}$;\5
+$\\{make\_exp\_copy}(\|p)$;\5
+$\|p\K\\{stash\_cur\_exp}$;\5
+$\\{unstash\_cur\_exp}(\|q)$;\5
+$\\{make\_eq}(\|p)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{obliterated}(\\{lhs})$;\5
+\\{put\_get\_error};\6
+\&{end};\2\6
+\&{end}\par
+\U996.\fi
+
+\M1001. And now we get to the nitty-gritty. The \\{make\_eq} procedure is given
+a pointer to a capsule that is to be equated to the current expression.
+
+\Y\P$\4\X1001:Declare the procedure called \\{make\_eq}\X\S$\6
+\4\&{procedure}\1\ \37$\\{make\_eq}(\\{lhs}:\\{pointer})$;\6
+\4\&{label} \37$\\{restart},\39\\{done},\39\\{not\_found}$;\6
+\4\&{var} \37\|t: \37\\{small\_number};\C{type of the left-hand side}\6
+\|v: \37\\{integer};\C{value of the left-hand side}\6
+$\|p,\39\|q$: \37\\{pointer};\C{pointers inside of big nodes}\2\6
+\&{begin} \37\\{restart}: \37$\|t\K\\{type}(\\{lhs})$;\6
+\&{if} $\|t\L\\{pair\_type}$ \1\&{then}\5
+$\|v\K\\{value}(\\{lhs})$;\2\6
+\&{case} $\|t$ \1\&{of}\6
+\hbox{\4}\X1003:For each type \|t, make an equation and \&{goto} \\{done}
+unless \\{cur\_type} is incompatible with~\|t\X\2\6
+\&{end};\C{all cases have been listed}\6
+\X1002:Announce that the equation cannot be performed\X;\6
+\4\\{done}: \37\\{check\_arith};\5
+$\\{recycle\_value}(\\{lhs})$;\5
+$\\{free\_node}(\\{lhs},\39\\{value\_node\_size})$;\6
+\&{end};\par
+\U995.\fi
+
+\M1002. \P$\X1002:Announce that the equation cannot be performed\X\S$\6
+$\\{disp\_err}(\\{lhs},\39\.{""})$;\5
+$\\{exp\_err}(\.{"Equation\ cannot\ be\ performed\ ("})$;\6
+\&{if} $\\{type}(\\{lhs})\L\\{pair\_type}$ \1\&{then}\5
+$\\{print\_type}(\\{type}(\\{lhs}))$\ \&{else} $\\{print}(\.{"numeric"})$;\2\6
+$\\{print\_char}(\.{"="})$;\6
+\&{if} $\\{cur\_type}\L\\{pair\_type}$ \1\&{then}\5
+$\\{print\_type}(\\{cur\_type})$\ \&{else} $\\{print}(\.{"numeric"})$;\2\6
+$\\{print\_char}(\.{")"})$;\6
+$\\{help2}(\.{"I\'m\ sorry,\ but\ I\ don\'t\ know\ how\ to\ make\ such\ things\
+equal."})$\6
+$(\.{"(See\ the\ two\ expressions\ just\ above\ the\ error\ message.)"})$;\5
+\\{put\_get\_error}\par
+\U1001.\fi
+
+\M1003. \P$\X1003:For each type \|t, make an equation and \&{goto} \\{done}
+unless \\{cur\_type} is incompatible with~\|t\X\S$\6
+\4$\\{boolean\_type},\39\\{string\_type},\39\\{pen\_type},\39\\{path\_type},\39%
+\\{picture\_type}$: \37\&{if} $\\{cur\_type}=\|t+\\{unknown\_tag}$ \1\&{then}\6
+\&{begin} \37$\\{nonlinear\_eq}(\|v,\39\\{cur\_exp},\39\\{false})$;\5
+\&{goto} \37\\{done};\6
+\&{end}\6
+\4\&{else} \&{if} $\\{cur\_type}=\|t$ \1\&{then}\5
+\X1004:Report redundant or inconsistent equation and \&{goto} \\{done}\X;\2\2\6
+\4\\{unknown\_types}: \37\&{if} $\\{cur\_type}=\|t-\\{unknown\_tag}$ \1\&{then}%
+\6
+\&{begin} \37$\\{nonlinear\_eq}(\\{cur\_exp},\39\\{lhs},\39\\{true})$;\5
+\&{goto} \37\\{done};\6
+\&{end}\6
+\4\&{else} \&{if} $\\{cur\_type}=\|t$ \1\&{then}\6
+\&{begin} \37$\\{ring\_merge}(\\{lhs},\39\\{cur\_exp})$;\5
+\&{goto} \37\\{done};\6
+\&{end}\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\6
+\&{if} $\|t=\\{unknown\_path}$ \1\&{then}\6
+\&{begin} \37\\{pair\_to\_path};\5
+\&{goto} \37\\{restart};\6
+\&{end};\2\2\2\2\6
+\4$\\{transform\_type},\39\\{pair\_type}$: \37\&{if} $\\{cur\_type}=\|t$ \1%
+\&{then}\5
+\X1005:Do multiple equations and \&{goto} \\{done}\X;\2\6
+\4$\\{known},\39\\{dependent},\39\\{proto\_dependent},\39\\{independent}$: \37%
+\&{if} $\\{cur\_type}\G\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{try\_eq}(\\{lhs},\39\\{null})$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\4\\{vacuous}: \37\\{do\_nothing};\par
+\U1001.\fi
+
+\M1004. \P$\X1004:Report redundant or inconsistent equation and \&{goto} %
+\\{done}\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_type}\L\\{string\_type}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{cur\_type}=\\{string\_type}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{str\_vs\_str}(\|v,\39\\{cur\_exp})\I0$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{end}\6
+\4\&{else} \&{if} $\|v\I\\{cur\_exp}$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\2\6
+\X623:Exclaim about a redundant equation\X;\6
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+$\\{print\_err}(\.{"Redundant\ or\ inconsistent\ equation"})$;\5
+$\\{help2}(\.{"An\ equation\ between\ already-known\ quantities\ can\'t\
+help."})$\6
+$(\.{"But\ don\'t\ worry;\ continue\ and\ I\'ll\ just\ ignore\ it."})$;\5
+\\{put\_get\_error};\5
+\&{goto} \37\\{done};\6
+\4\\{not\_found}: \37$\\{print\_err}(\.{"Inconsistent\ equation"})$;\5
+$\\{help2}(\.{"The\ equation\ I\ just\ read\ contradicts\ what\ was\ said\
+before."})$\6
+$(\.{"But\ don\'t\ worry;\ continue\ and\ I\'ll\ just\ ignore\ it."})$;\5
+\\{put\_get\_error};\5
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U1003.\fi
+
+\M1005. \P$\X1005:Do multiple equations and \&{goto} \\{done}\X\S$\6
+\&{begin} \37$\|p\K\|v+\\{big\_node\_size}[\|t]$;\5
+$\|q\K\\{value}(\\{cur\_exp})+\\{big\_node\_size}[\|t]$;\6
+\1\&{repeat} \37$\|p\K\|p-2$;\5
+$\|q\K\|q-2$;\5
+$\\{try\_eq}(\|p,\39\|q)$;\6
+\4\&{until}\5
+$\|p=\|v$;\2\6
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U1003.\fi
+
+\M1006. The first argument to \\{try\_eq} is the location of a value node
+in a capsule that will soon be recycled. The second argument is
+either a location within a pair or transform node pointed to by
+\\{cur\_exp}, or it is \\{null} (which means that \\{cur\_exp} itself
+serves as the second argument). The idea is to leave \\{cur\_exp} unchanged,
+but to equate the two operands.
+
+\Y\P$\4\X1006:Declare the procedure called \\{try\_eq}\X\S$\6
+\4\&{procedure}\1\ \37$\\{try\_eq}(\|l,\39\|r:\\{pointer})$;\6
+\4\&{label} \37$\\{done},\39\\{done1}$;\6
+\4\&{var} \37\|p: \37\\{pointer};\C{dependency list for right operand minus
+left operand}\6
+\|t: \37$\\{known}\to\\{independent}$;\C{the type of list \|p}\6
+\|q: \37\\{pointer};\C{the constant term of \|p is here}\6
+\\{pp}: \37\\{pointer};\C{dependency list for right operand}\6
+\\{tt}: \37$\\{dependent}\to\\{independent}$;\C{the type of list \\{pp}}\6
+\\{copied}: \37\\{boolean};\C{have we copied a list that ought to be recycled?}%
+\2\6
+\&{begin} \37\X1007:Remove the left operand from its container, negate it, and
+put it into dependency list~\|p with constant term~\|q\X;\6
+\X1009:Add the right operand to list \|p\X;\6
+\&{if} $\\{info}(\|p)=\\{null}$ \1\&{then}\5
+\X1008:Deal with redundant or inconsistent equation\X\6
+\4\&{else} \&{begin} \37$\\{linear\_eq}(\|p,\39\|t)$;\6
+\&{if} $\|r=\\{null}$ \1\&{then}\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\6
+\&{if} $\\{type}(\\{cur\_exp})=\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{pp}\K\\{cur\_exp}$;\5
+$\\{cur\_exp}\K\\{value}(\\{cur\_exp})$;\5
+$\\{cur\_type}\K\\{known}$;\5
+$\\{free\_node}(\\{pp},\39\\{value\_node\_size})$;\6
+\&{end};\2\2\2\6
+\&{end};\2\6
+\&{end};\par
+\U995.\fi
+
+\M1007. \P$\X1007:Remove the left operand from its container, negate it, and
+put it into dependency list~\|p with constant term~\|q\X\S$\6
+$\|t\K\\{type}(\|l)$;\6
+\&{if} $\|t=\\{known}$ \1\&{then}\6
+\&{begin} \37$\|t\K\\{dependent}$;\5
+$\|p\K\\{const\_dependency}(-\\{value}(\|l))$;\5
+$\|q\K\|p$;\6
+\&{end}\6
+\4\&{else} \&{if} $\|t=\\{independent}$ \1\&{then}\6
+\&{begin} \37$\|t\K\\{dependent}$;\5
+$\|p\K\\{single\_dependency}(\|l)$;\5
+$\\{negate}(\\{value}(\|p))$;\5
+$\|q\K\\{dep\_final}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|p\K\\{dep\_list}(\|l)$;\5
+$\|q\K\|p$;\6
+\~ \1\&{loop}\ \&{begin} \37$\\{negate}(\\{value}(\|q))$;\6
+\&{if} $\\{info}(\|q)=\\{null}$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+\4\\{done}: \37$\\{link}(\\{prev\_dep}(\|l))\K\\{link}(\|q)$;\5
+$\\{prev\_dep}(\\{link}(\|q))\K\\{prev\_dep}(\|l)$;\5
+$\\{type}(\|l)\K\\{known}$;\6
+\&{end}\2\2\par
+\U1006.\fi
+
+\M1008. \P$\X1008:Deal with redundant or inconsistent equation\X\S$\6
+\&{begin} \37\&{if} $\\{abs}(\\{value}(\|p))>64$ \1\&{then}\C{off by .001 or
+more}\6
+\&{begin} \37$\\{print\_err}(\.{"Inconsistent\ equation"})$;\6
+$\\{print}(\.{"\ (off\ by\ "})$;\5
+$\\{print\_scaled}(\\{value}(\|p))$;\5
+$\\{print\_char}(\.{")"})$;\5
+$\\{help2}(\.{"The\ equation\ I\ just\ read\ contradicts\ what\ was\ said\
+before."})$\6
+$(\.{"But\ don\'t\ worry;\ continue\ and\ I\'ll\ just\ ignore\ it."})$;\5
+\\{put\_get\_error};\6
+\&{end}\6
+\4\&{else} \&{if} $\|r=\\{null}$ \1\&{then}\5
+\X623:Exclaim about a redundant equation\X;\2\2\6
+$\\{free\_node}(\|p,\39\\{dep\_node\_size})$;\6
+\&{end}\par
+\U1006.\fi
+
+\M1009. \P$\X1009:Add the right operand to list \|p\X\S$\6
+\&{if} $\|r=\\{null}$ \1\&{then}\6
+\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{value}(\|q)\K\\{value}(\|q)+\\{cur\_exp}$;\5
+\&{goto} \37\\{done1};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{tt}\K\\{cur\_type}$;\6
+\&{if} $\\{tt}=\\{independent}$ \1\&{then}\5
+$\\{pp}\K\\{single\_dependency}(\\{cur\_exp})$\6
+\4\&{else} $\\{pp}\K\\{dep\_list}(\\{cur\_exp})$;\2\6
+\&{end}\2\6
+\4\&{else} \&{if} $\\{type}(\|r)=\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{value}(\|q)\K\\{value}(\|q)+\\{value}(\|r)$;\5
+\&{goto} \37\\{done1};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{tt}\K\\{type}(\|r)$;\6
+\&{if} $\\{tt}=\\{independent}$ \1\&{then}\5
+$\\{pp}\K\\{single\_dependency}(\|r)$\6
+\4\&{else} $\\{pp}\K\\{dep\_list}(\|r)$;\2\6
+\&{end};\2\2\6
+\&{if} $\\{tt}\I\\{independent}$ \1\&{then}\5
+$\\{copied}\K\\{false}$\6
+\4\&{else} \&{begin} \37$\\{copied}\K\\{true}$;\5
+$\\{tt}\K\\{dependent}$;\6
+\&{end};\2\6
+\X1010:Add dependency list \\{pp} of type \\{tt} to dependency list~\|p of
+type~\|t\X;\6
+\&{if} $\\{copied}$ \1\&{then}\5
+$\\{flush\_node\_list}(\\{pp})$;\2\6
+\4\\{done1}: \37\par
+\U1006.\fi
+
+\M1010. \P$\X1010:Add dependency list \\{pp} of type \\{tt} to dependency list~%
+\|p of type~\|t\X\S$\6
+$\\{watch\_coefs}\K\\{false}$;\6
+\&{if} $\|t=\\{tt}$ \1\&{then}\5
+$\|p\K\\{p\_plus\_q}(\|p,\39\\{pp},\39\|t)$\6
+\4\&{else} \&{if} $\|t=\\{proto\_dependent}$ \1\&{then}\5
+$\|p\K\\{p\_plus\_fq}(\|p,\39\\{unity},\39\\{pp},\39\\{proto\_dependent},\39%
+\\{dependent})$\6
+\4\&{else} \&{begin} \37$\|q\K\|p$;\6
+\&{while} $\\{info}(\|q)\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\\{value}(\|q)\K\\{round\_fraction}(\\{value}(\|q))$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+$\|t\K\\{proto\_dependent}$;\5
+$\|p\K\\{p\_plus\_q}(\|p,\39\\{pp},\39\|t)$;\6
+\&{end};\2\2\6
+$\\{watch\_coefs}\K\\{true}$;\par
+\U1009.\fi
+
+\M1011. Our next goal is to process type declarations. For this purpose it's
+convenient to have a procedure that scans a $\langle\,$declared
+variable$\,\rangle$ and returns the corresponding token list. After the
+following procedure has acted, the token after the declared variable
+will have been scanned, so it will appear in \\{cur\_cmd}, \\{cur\_mod},
+and~\\{cur\_sym}.
+
+\Y\P$\4\X1011:Declare the function called \\{scan\_declared\_variable}\X\S$\6
+\4\&{function}\1\ \37\\{scan\_declared\_variable}: \37\\{pointer};\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|x: \37\\{pointer};\C{hash address of the variable's root}\6
+$\|h,\39\|t$: \37\\{pointer};\C{head and tail of the token list to be returned}%
+\6
+\|l: \37\\{pointer};\C{hash address of left bracket}\2\6
+\&{begin} \37\\{get\_symbol};\5
+$\|x\K\\{cur\_sym}$;\6
+\&{if} $\\{cur\_cmd}\I\\{tag\_token}$ \1\&{then}\5
+$\\{clear\_symbol}(\|x,\39\\{false})$;\2\6
+$\|h\K\\{get\_avail}$;\5
+$\\{info}(\|h)\K\|x$;\5
+$\|t\K\|h$;\6
+\~ \1\&{loop}\ \&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{cur\_sym}=0$ \1\&{then}\5
+\&{goto} \37\\{done};\2\6
+\&{if} $\\{cur\_cmd}\I\\{tag\_token}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}\I\\{internal\_quantity}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}=\\{left\_bracket}$ \1\&{then}\5
+\X1012:Descend past a collective subscript\X\6
+\4\&{else} \&{goto} \37\\{done};\2\2\2\6
+$\\{link}(\|t)\K\\{get\_avail}$;\5
+$\|t\K\\{link}(\|t)$;\5
+$\\{info}(\|t)\K\\{cur\_sym}$;\6
+\&{end};\2\6
+\4\\{done}: \37\&{if} $\\{eq\_type}(\|x)\I\\{tag\_token}$ \1\&{then}\5
+$\\{clear\_symbol}(\|x,\39\\{false})$;\2\6
+\&{if} $\\{equiv}(\|x)=\\{null}$ \1\&{then}\5
+$\\{new\_root}(\|x)$;\2\6
+$\\{scan\_declared\_variable}\K\|h$;\6
+\&{end};\par
+\U697.\fi
+
+\M1012. If the subscript isn't collective, we don't accept it as part of the
+declared variable.
+
+\Y\P$\4\X1012:Descend past a collective subscript\X\S$\6
+\&{begin} \37$\|l\K\\{cur\_sym}$;\5
+\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}\I\\{right\_bracket}$ \1\&{then}\6
+\&{begin} \37\\{back\_input};\5
+$\\{cur\_sym}\K\|l$;\5
+$\\{cur\_cmd}\K\\{left\_bracket}$;\5
+\&{goto} \37\\{done};\6
+\&{end}\6
+\4\&{else} $\\{cur\_sym}\K\\{collective\_subscript}$;\2\6
+\&{end}\par
+\U1011.\fi
+
+\M1013. Type declarations are introduced by the following primitive operations.
+
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"numeric"},\39\\{type\_name},\39\\{numeric\_type})$;\6
+$\\{primitive}(\.{"string"},\39\\{type\_name},\39\\{string\_type})$;\6
+$\\{primitive}(\.{"boolean"},\39\\{type\_name},\39\\{boolean\_type})$;\6
+$\\{primitive}(\.{"path"},\39\\{type\_name},\39\\{path\_type})$;\6
+$\\{primitive}(\.{"pen"},\39\\{type\_name},\39\\{pen\_type})$;\6
+$\\{primitive}(\.{"picture"},\39\\{type\_name},\39\\{picture\_type})$;\6
+$\\{primitive}(\.{"transform"},\39\\{type\_name},\39\\{transform\_type})$;\6
+$\\{primitive}(\.{"pair"},\39\\{type\_name},\39\\{pair\_type})$;\par
+\fi
+
+\M1014. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{type\_name}: \37$\\{print\_type}(\|m)$;\par
+\fi
+
+\M1015. Now we are ready to handle type declarations, assuming that a
+\\{type\_name} has just been scanned.
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_type\_declaration};\6
+\4\&{var} \37\|t: \37\\{small\_number};\C{the type being declared}\6
+\|p: \37\\{pointer};\C{token list for a declared variable}\6
+\|q: \37\\{pointer};\C{value node for the variable}\2\6
+\&{begin} \37\&{if} $\\{cur\_mod}\G\\{transform\_type}$ \1\&{then}\5
+$\|t\K\\{cur\_mod}$\ \&{else} $\|t\K\\{cur\_mod}+\\{unknown\_tag}$;\2\6
+\1\&{repeat} \37$\|p\K\\{scan\_declared\_variable}$;\5
+$\\{flush\_variable}(\\{equiv}(\\{info}(\|p)),\39\\{link}(\|p),\39\\{false})$;\6
+$\|q\K\\{find\_variable}(\|p)$;\6
+\&{if} $\|q\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{type}(\|q)\K\|t$;\5
+$\\{value}(\|q)\K\\{null}$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Declared\ variable\ conflicts\ with%
+\ previous\ vardef"})$;\5
+$\\{help2}(\.{"You\ can\'t\ use,\ e.g.,\ \`numeric\ foo[]\'\ after\ \`vardef\
+foo\'."})$\6
+$(\.{"Proceed,\ and\ I\'ll\ ignore\ the\ illegal\ redeclaration."})$;\5
+\\{put\_get\_error};\6
+\&{end};\2\6
+$\\{flush\_list}(\|p)$;\6
+\&{if} $\\{cur\_cmd}<\\{comma}$ \1\&{then}\5
+\X1016:Flush spurious symbols after the declared variable\X;\2\6
+\4\&{until}\5
+\\{end\_of\_statement};\2\6
+\&{end};\par
+\fi
+
+\M1016. \P$\X1016:Flush spurious symbols after the declared variable\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Illegal\ suffix\ of\ declared\ variable\ will\
+be\ flushed"})$;\5
+$\\{help5}(\.{"Variables\ in\ declarations\ must\ consist\ entirely\ of"})$\6
+$(\.{"names\ and\ collective\ subscripts,\ e.g.,\ \`x[]a\'."})$\6
+$(\.{"Are\ you\ trying\ to\ use\ a\ reserved\ word\ in\ a\ variable\ name?"})$\6
+$(\.{"I\'m\ going\ to\ discard\ the\ junk\ I\ found\ here,"})$\6
+$(\.{"up\ to\ the\ next\ comma\ or\ the\ end\ of\ the\ declaration."})$;\6
+\&{if} $\\{cur\_cmd}=\\{numeric\_token}$ \1\&{then}\5
+$\\{help\_line}[2]\K\.{"Explicit\ subscripts\ like\ \`x15a\'\ aren\'t\
+permitted."}$;\2\6
+\\{put\_get\_error};\5
+$\\{scanner\_status}\K\\{flushing}$;\6
+\1\&{repeat} \37\\{get\_next};\5
+\X743:Decrease the string reference count, if the current token is a string\X;\6
+\4\&{until}\5
+$\\{cur\_cmd}\G\\{comma}$;\C{either \\{end\_of\_statement} or $\\{cur\_cmd}=%
+\\{comma}$}\2\6
+$\\{scanner\_status}\K\\{normal}$;\6
+\&{end}\par
+\U1015.\fi
+
+\M1017. \MF's \\{main\_control} procedure just calls \\{do\_statement}
+repeatedly
+until coming to the end of the user's program.
+Each execution of \\{do\_statement} concludes with
+$\\{cur\_cmd}=\\{semicolon}$, \\{end\_group}, or \\{stop}.
+
+\Y\P\4\&{procedure}\1\ \37\\{main\_control};\2\6
+\&{begin} \37\1\&{repeat} \37\\{do\_statement};\6
+\&{if} $\\{cur\_cmd}=\\{end\_group}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Extra\ \`endgroup\'"})$;\5
+$\\{help2}(\.{"I\'m\ not\ currently\ working\ on\ a\ \`begingroup\',"})$\6
+$(\.{"so\ I\ had\ better\ not\ try\ to\ end\ anything."})$;\5
+$\\{flush\_error}(0)$;\6
+\&{end};\2\6
+\4\&{until}\5
+$\\{cur\_cmd}=\\{stop}$;\2\6
+\&{end};\par
+\fi
+
+\M1018. \P$\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}%
+\S$\6
+$\\{primitive}(\.{"end"},\39\\{stop},\390)$;\6
+$\\{primitive}(\.{"dump"},\39\\{stop},\391)$;\par
+\fi
+
+\M1019. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{stop}: \37\&{if} $\|m=0$ \1\&{then}\5
+$\\{print}(\.{"end"})$\ \&{else} $\\{print}(\.{"dump"})$;\2\par
+\fi
+
+\N1020. \[44] Commands.
+Let's turn now to statements that are classified as ``commands'' because
+of their imperative nature. We'll begin with simple ones, so that it
+will be clear how to hook command processing into the \\{do\_statement}
+routine;
+then we'll tackle the tougher commands.
+
+Here's one of the simplest:
+
+\Y\P$\4\X1020:Cases of \\{do\_statement} that invoke particular commands\X\S$\6
+\4\\{random\_seed}: \37\\{do\_random\_seed};\par
+\As1023, 1026, 1030, 1033, 1039, 1058, 1069, 1076, 1081, 1100\ETs1175.
+\U992.\fi
+
+\M1021. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_random\_seed};\2\6
+\&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}\I\\{assignment}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{":="})$;\5
+$\\{help1}(\.{"Always\ say\ \`randomseed:=<numeric\ expression>\'."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Unknown\ value\ will\ be\ ignored"})$;\5
+$\\{help2}(\.{"Your\ expression\ was\ too\ random\ for\ me\ to\ handle,"})$\6
+$(\.{"so\ I\ won\'t\ change\ the\ random\ seed\ just\ now."})$;\6
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end}\6
+\4\&{else} \X1022:Initialize the random seed to \\{cur\_exp}\X;\2\6
+\&{end};\par
+\fi
+
+\M1022. \P$\X1022:Initialize the random seed to \\{cur\_exp}\X\S$\6
+\&{begin} \37$\\{init\_randoms}(\\{cur\_exp})$;\6
+\&{if} $\\{selector}\G\\{log\_only}$ \1\&{then}\6
+\&{begin} \37$\\{old\_setting}\K\\{selector}$;\5
+$\\{selector}\K\\{log\_only}$;\5
+$\\{print\_nl}(\.{"\{randomseed:="})$;\5
+$\\{print\_scaled}(\\{cur\_exp})$;\5
+$\\{print\_char}(\.{"\}"})$;\5
+$\\{print\_nl}(\.{""})$;\5
+$\\{selector}\K\\{old\_setting}$;\6
+\&{end};\2\6
+\&{end}\par
+\U1021.\fi
+
+\M1023. And here's another simple one (somewhat different in flavor):
+
+\Y\P$\4\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{mode\_command}: \37\&{begin} \37\\{print\_ln};\5
+$\\{interaction}\K\\{cur\_mod}$;\5
+\X70:Initialize the print \\{selector} based on \\{interaction}\X;\6
+\&{if} $\\{log\_opened}$ \1\&{then}\5
+$\\{selector}\K\\{selector}+2$;\2\6
+\\{get\_x\_next};\6
+\&{end};\par
+\fi
+
+\M1024. \P$\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}%
+\S$\6
+$\\{primitive}(\.{"batchmode"},\39\\{mode\_command},\39\\{batch\_mode})$;\5
+$\\{primitive}(\.{"nonstopmode"},\39\\{mode\_command},\39\\{nonstop\_mode})$;\5
+$\\{primitive}(\.{"scrollmode"},\39\\{mode\_command},\39\\{scroll\_mode})$;\5
+$\\{primitive}(\.{"errorstopmode"},\39\\{mode\_command},\39\\{error\_stop%
+\_mode})$;\par
+\fi
+
+\M1025. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{mode\_command}: \37\&{case} $\|m$ \1\&{of}\6
+\4\\{batch\_mode}: \37$\\{print}(\.{"batchmode"})$;\6
+\4\\{nonstop\_mode}: \37$\\{print}(\.{"nonstopmode"})$;\6
+\4\\{scroll\_mode}: \37$\\{print}(\.{"scrollmode"})$;\6
+\4\&{othercases} \37$\\{print}(\.{"errorstopmode"})$\2\6
+\&{endcases};\par
+\fi
+
+\M1026. The `\&{inner}' and `\&{outer}' commands are only slightly harder.
+
+\Y\P$\4\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{protection\_command}: \37\\{do\_protection};\par
+\fi
+
+\M1027. \P$\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}%
+\S$\6
+$\\{primitive}(\.{"inner"},\39\\{protection\_command},\390)$;\6
+$\\{primitive}(\.{"outer"},\39\\{protection\_command},\391)$;\par
+\fi
+
+\M1028. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{protection\_command}: \37\&{if} $\|m=0$ \1\&{then}\5
+$\\{print}(\.{"inner"})$\ \&{else} $\\{print}(\.{"outer"})$;\2\par
+\fi
+
+\M1029. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_protection};\6
+\4\&{var} \37\|m: \37$0\to1$;\C{0 to unprotect, 1 to protect}\6
+\|t: \37\\{halfword};\C{the \\{eq\_type} before we change it}\2\6
+\&{begin} \37$\|m\K\\{cur\_mod}$;\6
+\1\&{repeat} \37\\{get\_symbol};\5
+$\|t\K\\{eq\_type}(\\{cur\_sym})$;\6
+\&{if} $\|m=0$ \1\&{then}\6
+\&{begin} \37\&{if} $\|t\G\\{outer\_tag}$ \1\&{then}\5
+$\\{eq\_type}(\\{cur\_sym})\K\|t-\\{outer\_tag}$;\2\6
+\&{end}\6
+\4\&{else} \&{if} $\|t<\\{outer\_tag}$ \1\&{then}\5
+$\\{eq\_type}(\\{cur\_sym})\K\|t+\\{outer\_tag}$;\2\2\6
+\\{get\_x\_next};\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$;\2\6
+\&{end};\par
+\fi
+
+\M1030. \MF\ never defines the tokens `\.(' and `\.)' to be primitives, but
+plain \MF\ begins with the declaration `\&{delimiters} \.{()}'. Such a
+declaration assigns the command code \\{left\_delimiter} to `\.{(}' and
+\\{right\_delimiter} to `\.{)}'; the \\{equiv} of each delimiter is the
+hash address of its mate.
+
+\Y\P$\4\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{delimiters}: \37\\{def\_delims};\par
+\fi
+
+\M1031. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{def\_delims};\6
+\4\&{var} \37$\\{l\_delim},\39\\{r\_delim}$: \37\\{pointer};\C{the new
+delimiter pair}\2\6
+\&{begin} \37\\{get\_clear\_symbol};\5
+$\\{l\_delim}\K\\{cur\_sym}$;\6
+\\{get\_clear\_symbol};\5
+$\\{r\_delim}\K\\{cur\_sym}$;\6
+$\\{eq\_type}(\\{l\_delim})\K\\{left\_delimiter}$;\5
+$\\{equiv}(\\{l\_delim})\K\\{r\_delim}$;\6
+$\\{eq\_type}(\\{r\_delim})\K\\{right\_delimiter}$;\5
+$\\{equiv}(\\{r\_delim})\K\\{l\_delim}$;\6
+\\{get\_x\_next};\6
+\&{end};\par
+\fi
+
+\M1032. Here is a procedure that is called when \MF\ has reached a point
+where some right delimiter is mandatory.
+
+\Y\P$\4\X1032:Declare the procedure called \\{check\_delimiter}\X\S$\6
+\4\&{procedure}\1\ \37$\\{check\_delimiter}(\\{l\_delim},\39\\{r\_delim}:%
+\\{pointer})$;\6
+\4\&{label} \37\\{exit};\2\6
+\&{begin} \37\&{if} $\\{cur\_cmd}=\\{right\_delimiter}$ \1\&{then}\6
+\&{if} $\\{cur\_mod}=\\{l\_delim}$ \1\&{then}\5
+\&{return};\2\2\6
+\&{if} $\\{cur\_sym}\I\\{r\_delim}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\\{text}(\\{r\_delim}))$;\6
+$\\{help2}(\.{"I\ found\ no\ right\ delimiter\ to\ match\ a\ left\ one.\ So\ I%
+\'ve"})$\6
+$(\.{"put\ one\ in,\ behind\ the\ scenes;\ this\ may\ fix\ the\ problem."})$;\5
+\\{back\_error};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"The\ token\ \`"})$;\5
+$\\{slow\_print}(\\{text}(\\{r\_delim}))$;\5
+$\\{print}(\.{"\'\ is\ no\ longer\ a\ right\ delimiter"})$;\5
+$\\{help3}(\.{"Strange:\ This\ token\ has\ lost\ its\ former\ meaning!"})$\6
+$(\.{"I\'ll\ read\ it\ as\ a\ right\ delimiter\ this\ time;"})$\6
+$(\.{"but\ watch\ out,\ I\'ll\ probably\ miss\ it\ later."})$;\5
+\\{error};\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\U697.\fi
+
+\M1033. The next four commands save or change the values associated with
+tokens.
+
+\Y\P$\4\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{save\_command}: \37\1\&{repeat} \37\\{get\_symbol};\5
+$\\{save\_variable}(\\{cur\_sym})$;\5
+\\{get\_x\_next};\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$;\2\6
+\4\\{interim\_command}: \37\\{do\_interim};\6
+\4\\{let\_command}: \37\\{do\_let};\6
+\4\\{new\_internal}: \37\\{do\_new\_internal};\par
+\fi
+
+\M1034. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_statement};\5
+\\{forward};\5
+\hbox{\2}\6
+\4\&{procedure}\1\ \37\\{do\_interim};\2\6
+\&{begin} \37\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}\I\\{internal\_quantity}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"The\ token\ \`"})$;\6
+\&{if} $\\{cur\_sym}=0$ \1\&{then}\5
+$\\{print}(\.{"(\%CAPSULE)"})$\6
+\4\&{else} $\\{slow\_print}(\\{text}(\\{cur\_sym}))$;\2\6
+$\\{print}(\.{"\'\ isn\'t\ an\ internal\ quantity"})$;\5
+$\\{help1}(\.{"Something\ like\ \`tracingonline\'\ should\ follow\ \`interim%
+\'."})$;\5
+\\{back\_error};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{save\_internal}(\\{cur\_mod})$;\5
+\\{back\_input};\6
+\&{end};\2\6
+\\{do\_statement};\6
+\&{end};\par
+\fi
+
+\M1035. The following procedure is careful not to undefine the left-hand symbol
+too soon, lest commands like `{\tt let x=x}' have a surprising effect.
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_let};\6
+\4\&{var} \37\|l: \37\\{pointer};\C{hash location of the left-hand symbol}\2\6
+\&{begin} \37\\{get\_symbol};\5
+$\|l\K\\{cur\_sym}$;\5
+\\{get\_x\_next};\6
+\&{if} $\\{cur\_cmd}\I\\{equals}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}\I\\{assignment}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{"="})$;\5
+$\\{help3}(\.{"You\ should\ have\ said\ \`let\ symbol\ =\ something\'."})$\6
+$(\.{"But\ don\'t\ worry;\ I\'ll\ pretend\ that\ an\ equals\ sign"})$\6
+$(\.{"was\ present.\ The\ next\ token\ I\ read\ will\ be\ \`something\'."})$;\5
+\\{back\_error};\6
+\&{end};\2\2\6
+\\{get\_symbol};\6
+\&{case} $\\{cur\_cmd}$ \1\&{of}\6
+\4$\\{defined\_macro},\39\\{secondary\_primary\_macro},\39\\{tertiary%
+\_secondary\_macro},\39\\{expression\_tertiary\_macro}$: \37$\\{add\_mac\_ref}(%
+\\{cur\_mod})$;\6
+\4\&{othercases} \37\\{do\_nothing}\2\6
+\&{endcases};\6
+$\\{clear\_symbol}(\|l,\39\\{false})$;\5
+$\\{eq\_type}(\|l)\K\\{cur\_cmd}$;\6
+\&{if} $\\{cur\_cmd}=\\{tag\_token}$ \1\&{then}\5
+$\\{equiv}(\|l)\K\\{null}$\6
+\4\&{else} $\\{equiv}(\|l)\K\\{cur\_mod}$;\2\6
+\\{get\_x\_next};\6
+\&{end};\par
+\fi
+
+\M1036. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_new\_internal};\2\6
+\&{begin} \37\1\&{repeat} \37\&{if} $\\{int\_ptr}=\\{max\_internal}$ \1\&{then}%
+\5
+$\\{overflow}(\.{"number\ of\ internals"},\39\\{max\_internal})$;\2\6
+\\{get\_clear\_symbol};\5
+$\\{incr}(\\{int\_ptr})$;\5
+$\\{eq\_type}(\\{cur\_sym})\K\\{internal\_quantity}$;\5
+$\\{equiv}(\\{cur\_sym})\K\\{int\_ptr}$;\5
+$\\{int\_name}[\\{int\_ptr}]\K\\{text}(\\{cur\_sym})$;\5
+$\\{internal}[\\{int\_ptr}]\K0$;\5
+\\{get\_x\_next};\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$;\2\6
+\&{end};\par
+\fi
+
+\M1037. The various `\&{show}' commands are distinguished by modifier fields
+in the usual way.
+
+\Y\P\D \37$\\{show\_token\_code}=0$\C{show the meaning of a single token}\par
+\P\D \37$\\{show\_stats\_code}=1$\C{show current memory and string usage}\par
+\P\D \37$\\{show\_code}=2$\C{show a list of expressions}\par
+\P\D \37$\\{show\_var\_code}=3$\C{show a variable and its descendents}\par
+\P\D \37$\\{show\_dependencies\_code}=4$\C{show dependent variables in terms of
+independents}\par
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"showtoken"},\39\\{show\_command},\39\\{show\_token\_code})$;%
+\6
+$\\{primitive}(\.{"showstats"},\39\\{show\_command},\39\\{show\_stats\_code})$;%
+\6
+$\\{primitive}(\.{"show"},\39\\{show\_command},\39\\{show\_code})$;\6
+$\\{primitive}(\.{"showvariable"},\39\\{show\_command},\39\\{show\_var%
+\_code})$;\6
+$\\{primitive}(\.{"showdependencies"},\39\\{show\_command},\39\\{show%
+\_dependencies\_code})$;\par
+\fi
+
+\M1038. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{show\_command}: \37\&{case} $\|m$ \1\&{of}\6
+\4\\{show\_token\_code}: \37$\\{print}(\.{"showtoken"})$;\6
+\4\\{show\_stats\_code}: \37$\\{print}(\.{"showstats"})$;\6
+\4\\{show\_code}: \37$\\{print}(\.{"show"})$;\6
+\4\\{show\_var\_code}: \37$\\{print}(\.{"showvariable"})$;\6
+\4\&{othercases} \37$\\{print}(\.{"showdependencies"})$\2\6
+\&{endcases};\par
+\fi
+
+\M1039. \P$\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{show\_command}: \37\\{do\_show\_whatever};\par
+\fi
+
+\M1040. The value of \\{cur\_mod} controls the \\{verbosity} in the \\{print%
+\_exp} routine:
+If it's \\{show\_code}, complicated structures are abbreviated, otherwise
+they aren't.
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_show};\2\6
+\&{begin} \37\1\&{repeat} \37\\{get\_x\_next};\5
+\\{scan\_expression};\5
+$\\{print\_nl}(\.{">>\ "})$;\5
+$\\{print\_exp}(\\{null},\392)$;\5
+$\\{flush\_cur\_exp}(0)$;\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$;\2\6
+\&{end};\par
+\fi
+
+\M1041. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{disp\_token};\2\6
+\&{begin} \37$\\{print\_nl}(\.{">\ "})$;\6
+\&{if} $\\{cur\_sym}=0$ \1\&{then}\5
+\X1042:Show a numeric or string or capsule token\X\6
+\4\&{else} \&{begin} \37$\\{slow\_print}(\\{text}(\\{cur\_sym}))$;\5
+$\\{print\_char}(\.{"="})$;\6
+\&{if} $\\{eq\_type}(\\{cur\_sym})\G\\{outer\_tag}$ \1\&{then}\5
+$\\{print}(\.{"(outer)\ "})$;\2\6
+$\\{print\_cmd\_mod}(\\{cur\_cmd},\39\\{cur\_mod})$;\6
+\&{if} $\\{cur\_cmd}=\\{defined\_macro}$ \1\&{then}\6
+\&{begin} \37\\{print\_ln};\5
+$\\{show\_macro}(\\{cur\_mod},\39\\{null},\39100000)$;\6
+\&{end};\C{this avoids recursion between \\{show\_macro} and \\{print\_cmd%
+\_mod}}\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M1042. \P$\X1042:Show a numeric or string or capsule token\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_cmd}=\\{numeric\_token}$ \1\&{then}\5
+$\\{print\_scaled}(\\{cur\_mod})$\6
+\4\&{else} \&{if} $\\{cur\_cmd}=\\{capsule\_token}$ \1\&{then}\6
+\&{begin} \37$\\{g\_pointer}\K\\{cur\_mod}$;\5
+\\{print\_capsule};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{print\_char}(\.{""}\.{""})$;\5
+$\\{slow\_print}(\\{cur\_mod})$;\5
+$\\{print\_char}(\.{""}\.{""})$;\5
+$\\{delete\_str\_ref}(\\{cur\_mod})$;\6
+\&{end};\2\2\6
+\&{end}\par
+\U1041.\fi
+
+\M1043. The following cases of \\{print\_cmd\_mod} might arise in connection
+with \\{disp\_token}, although they don't correspond to any
+primitive tokens.
+
+\Y\P$\4\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of primitives\X%
+\mathrel{+}\S$\6
+\4$\\{left\_delimiter},\39\\{right\_delimiter}$: \37\&{begin} \37\&{if} $\|c=%
+\\{left\_delimiter}$ \1\&{then}\5
+$\\{print}(\.{"lef"})$\6
+\4\&{else} $\\{print}(\.{"righ"})$;\2\6
+$\\{print}(\.{"t\ delimiter\ that\ matches\ "})$;\5
+$\\{slow\_print}(\\{text}(\|m))$;\6
+\&{end};\6
+\4\\{tag\_token}: \37\&{if} $\|m=\\{null}$ \1\&{then}\5
+$\\{print}(\.{"tag"})$\ \&{else} $\\{print}(\.{"variable"})$;\2\6
+\4\\{defined\_macro}: \37$\\{print}(\.{"macro:"})$;\6
+\4$\\{secondary\_primary\_macro},\39\\{tertiary\_secondary\_macro},\39%
+\\{expression\_tertiary\_macro}$: \37\&{begin} \37$\\{print\_cmd\_mod}(\\{macro%
+\_def},\39\|c)$;\5
+$\\{print}(\.{"\'d\ macro:"})$;\5
+\\{print\_ln};\5
+$\\{show\_token\_list}(\\{link}(\\{link}(\|m)),\39\\{null},\391000,\390)$;\6
+\&{end};\6
+\4\\{repeat\_loop}: \37$\\{print}(\.{"[repeat\ the\ loop]"})$;\6
+\4\\{internal\_quantity}: \37$\\{slow\_print}(\\{int\_name}[\|m])$;\par
+\fi
+
+\M1044. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_show\_token};\2\6
+\&{begin} \37\1\&{repeat} \37\\{get\_next};\5
+\\{disp\_token};\5
+\\{get\_x\_next};\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$;\2\6
+\&{end};\par
+\fi
+
+\M1045. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_show\_stats};\2\6
+\&{begin} \37$\\{print\_nl}(\.{"Memory\ usage\ "})$;\6
+\&{stat} \37$\\{print\_int}(\\{var\_used})$;\5
+$\\{print\_char}(\.{"\&"})$;\5
+$\\{print\_int}(\\{dyn\_used})$;\6
+\&{if} $\\{false}$ \1\&{then}\ \2\6
+\&{tats}\hbox{}\6
+$\\{print}(\.{"unknown"})$;\5
+$\\{print}(\.{"\ ("})$;\5
+$\\{print\_int}(\\{hi\_mem\_min}-\\{lo\_mem\_max}-1)$;\5
+$\\{print}(\.{"\ still\ untouched)"})$;\5
+\\{print\_ln};\5
+$\\{print\_nl}(\.{"String\ usage\ "})$;\5
+$\\{print\_int}(\\{str\_ptr}-\\{init\_str\_ptr})$;\5
+$\\{print\_char}(\.{"\&"})$;\5
+$\\{print\_int}(\\{pool\_ptr}-\\{init\_pool\_ptr})$;\5
+$\\{print}(\.{"\ ("})$;\5
+$\\{print\_int}(\\{max\_strings}-\\{max\_str\_ptr})$;\5
+$\\{print\_char}(\.{"\&"})$;\5
+$\\{print\_int}(\\{pool\_size}-\\{max\_pool\_ptr})$;\5
+$\\{print}(\.{"\ still\ untouched)"})$;\5
+\\{print\_ln};\5
+\\{get\_x\_next};\6
+\&{end};\par
+\fi
+
+\M1046. Here's a recursive procedure that gives an abbreviated account
+of a variable, for use by \\{do\_show\_var}.
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{disp\_var}(\|p:\\{pointer})$;\6
+\4\&{var} \37\|q: \37\\{pointer};\C{traverses attributes and subscripts}\6
+\|n: \37$0\to\\{max\_print\_line}$;\C{amount of macro text to show}\2\6
+\&{begin} \37\&{if} $\\{type}(\|p)=\\{structured}$ \1\&{then}\5
+\X1047:Descend the structure\X\6
+\4\&{else} \&{if} $\\{type}(\|p)\G\\{unsuffixed\_macro}$ \1\&{then}\5
+\X1048:Display a variable macro\X\6
+\4\&{else} \&{if} $\\{type}(\|p)\I\\{undefined}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{""})$;\5
+$\\{print\_variable\_name}(\|p)$;\5
+$\\{print\_char}(\.{"="})$;\5
+$\\{print\_exp}(\|p,\390)$;\6
+\&{end};\2\2\2\6
+\&{end};\par
+\fi
+
+\M1047. \P$\X1047:Descend the structure\X\S$\6
+\&{begin} \37$\|q\K\\{attr\_head}(\|p)$;\6
+\1\&{repeat} \37$\\{disp\_var}(\|q)$;\5
+$\|q\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\|q=\\{end\_attr}$;\2\6
+$\|q\K\\{subscr\_head}(\|p)$;\6
+\&{while} $\\{name\_type}(\|q)=\\{subscr}$ \1\&{do}\6
+\&{begin} \37$\\{disp\_var}(\|q)$;\5
+$\|q\K\\{link}(\|q)$;\6
+\&{end};\2\6
+\&{end}\par
+\U1046.\fi
+
+\M1048. \P$\X1048:Display a variable macro\X\S$\6
+\&{begin} \37$\\{print\_nl}(\.{""})$;\5
+$\\{print\_variable\_name}(\|p)$;\6
+\&{if} $\\{type}(\|p)>\\{unsuffixed\_macro}$ \1\&{then}\5
+$\\{print}(\.{"@\#"})$;\C{\\{suffixed\_macro}}\2\6
+$\\{print}(\.{"=macro:"})$;\6
+\&{if} $\\{file\_offset}\G\\{max\_print\_line}-20$ \1\&{then}\5
+$\|n\K5$\6
+\4\&{else} $\|n\K\\{max\_print\_line}-\\{file\_offset}-15$;\2\6
+$\\{show\_macro}(\\{value}(\|p),\39\\{null},\39\|n)$;\6
+\&{end}\par
+\U1046.\fi
+
+\M1049. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_show\_var};\6
+\4\&{label} \37\\{done};\2\6
+\&{begin} \37\1\&{repeat} \37\\{get\_next};\6
+\&{if} $\\{cur\_sym}>0$ \1\&{then}\6
+\&{if} $\\{cur\_sym}\L\\{hash\_end}$ \1\&{then}\6
+\&{if} $\\{cur\_cmd}=\\{tag\_token}$ \1\&{then}\6
+\&{if} $\\{cur\_mod}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{disp\_var}(\\{cur\_mod})$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\2\2\2\6
+\\{disp\_token};\6
+\4\\{done}: \37\\{get\_x\_next};\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$;\2\6
+\&{end};\par
+\fi
+
+\M1050. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_show\_dependencies};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{link that runs through all dependencies}\2\6
+\&{begin} \37$\|p\K\\{link}(\\{dep\_head})$;\6
+\&{while} $\|p\I\\{dep\_head}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{interesting}(\|p)$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{""})$;\5
+$\\{print\_variable\_name}(\|p)$;\6
+\&{if} $\\{type}(\|p)=\\{dependent}$ \1\&{then}\5
+$\\{print\_char}(\.{"="})$\6
+\4\&{else} $\\{print}(\.{"\ =\ "})$;\C{extra spaces imply proto-dependency}\2\6
+$\\{print\_dependency}(\\{dep\_list}(\|p),\39\\{type}(\|p))$;\6
+\&{end};\2\6
+$\|p\K\\{dep\_list}(\|p)$;\6
+\&{while} $\\{info}(\|p)\I\\{null}$ \1\&{do}\5
+$\|p\K\\{link}(\|p)$;\2\6
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\\{get\_x\_next};\6
+\&{end};\par
+\fi
+
+\M1051. Finally we are ready for the procedure that governs all of the
+show commands.
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_show\_whatever};\2\6
+\&{begin} \37\&{if} $\\{interaction}=\\{error\_stop\_mode}$ \1\&{then}\5
+\\{wake\_up\_terminal};\2\6
+\&{case} $\\{cur\_mod}$ \1\&{of}\6
+\4\\{show\_token\_code}: \37\\{do\_show\_token};\6
+\4\\{show\_stats\_code}: \37\\{do\_show\_stats};\6
+\4\\{show\_code}: \37\\{do\_show};\6
+\4\\{show\_var\_code}: \37\\{do\_show\_var};\6
+\4\\{show\_dependencies\_code}: \37\\{do\_show\_dependencies};\2\6
+\&{end};\C{there are no other cases}\6
+\&{if} $\\{internal}[\\{showstopping}]>0$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"OK"})$;\6
+\&{if} $\\{interaction}<\\{error\_stop\_mode}$ \1\&{then}\6
+\&{begin} \37\\{help0};\5
+$\\{decr}(\\{error\_count})$;\6
+\&{end}\6
+\4\&{else} $\\{help1}(\.{"This\ isn\'t\ an\ error\ message;\ I\'m\ just\
+showing\ something."})$;\2\6
+\&{if} $\\{cur\_cmd}=\\{semicolon}$ \1\&{then}\5
+\\{error}\ \&{else} \\{put\_get\_error};\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M1052. The `\&{addto}' command needs the following additional primitives:
+
+\Y\P\D \37$\\{drop\_code}=0$\C{command modifier for `\&{dropping}'}\par
+\P\D \37$\\{keep\_code}=1$\C{command modifier for `\&{keeping}'}\par
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"contour"},\39\\{thing\_to\_add},\39\\{contour\_code})$;\6
+$\\{primitive}(\.{"doublepath"},\39\\{thing\_to\_add},\39\\{double\_path%
+\_code})$;\6
+$\\{primitive}(\.{"also"},\39\\{thing\_to\_add},\39\\{also\_code})$;\6
+$\\{primitive}(\.{"withpen"},\39\\{with\_option},\39\\{pen\_type})$;\6
+$\\{primitive}(\.{"withweight"},\39\\{with\_option},\39\\{known})$;\6
+$\\{primitive}(\.{"dropping"},\39\\{cull\_op},\39\\{drop\_code})$;\6
+$\\{primitive}(\.{"keeping"},\39\\{cull\_op},\39\\{keep\_code})$;\par
+\fi
+
+\M1053. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{thing\_to\_add}: \37\&{if} $\|m=\\{contour\_code}$ \1\&{then}\5
+$\\{print}(\.{"contour"})$\6
+\4\&{else} \&{if} $\|m=\\{double\_path\_code}$ \1\&{then}\5
+$\\{print}(\.{"doublepath"})$\6
+\4\&{else} $\\{print}(\.{"also"})$;\2\2\6
+\4\\{with\_option}: \37\&{if} $\|m=\\{pen\_type}$ \1\&{then}\5
+$\\{print}(\.{"withpen"})$\6
+\4\&{else} $\\{print}(\.{"withweight"})$;\2\6
+\4\\{cull\_op}: \37\&{if} $\|m=\\{drop\_code}$ \1\&{then}\5
+$\\{print}(\.{"dropping"})$\6
+\4\&{else} $\\{print}(\.{"keeping"})$;\2\par
+\fi
+
+\M1054. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{function}\1\ \37\\{scan\_with}: \37\\{boolean};\6
+\4\&{var} \37\|t: \37\\{small\_number};\C{\\{known} or \\{pen\_type}}\6
+\\{result}: \37\\{boolean};\C{the value to return}\2\6
+\&{begin} \37$\|t\K\\{cur\_mod}$;\5
+$\\{cur\_type}\K\\{vacuous}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\5
+$\\{result}\K\\{false}$;\6
+\&{if} $\\{cur\_type}\I\|t$ \1\&{then}\5
+\X1055:Complain about improper type\X\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{pen\_type}$ \1\&{then}\5
+$\\{result}\K\\{true}$\6
+\4\&{else} \X1056:Check the tentative weight\X;\2\2\6
+$\\{scan\_with}\K\\{result}$;\6
+\&{end};\par
+\fi
+
+\M1055. \P$\X1055:Complain about improper type\X\S$\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ type"})$;\5
+$\\{help2}(\.{"Next\ time\ say\ \`withweight\ <known\ numeric\ expression>%
+\';"})$\6
+$(\.{"I\'ll\ ignore\ the\ bad\ \`with\'\ clause\ and\ look\ for\ another."})$;\6
+\&{if} $\|t=\\{pen\_type}$ \1\&{then}\5
+$\\{help\_line}[1]\K\.{"Next\ time\ say\ \`withpen\ <known\ pen\ expression>%
+\';"}$;\2\6
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end}\par
+\U1054.\fi
+
+\M1056. \P$\X1056:Check the tentative weight\X\S$\6
+\&{begin} \37$\\{cur\_exp}\K\\{round\_unscaled}(\\{cur\_exp})$;\6
+\&{if} $(\\{abs}(\\{cur\_exp})<4)\W(\\{cur\_exp}\I0)$ \1\&{then}\5
+$\\{result}\K\\{true}$\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Weight\ must\ be\ -3,\ -2,\ -1,\
++1,\ +2,\ or\ +3"})$;\5
+$\\{help1}(\.{"I\'ll\ ignore\ the\ bad\ \`with\'\ clause\ and\ look\ for\
+another."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end};\2\6
+\&{end}\par
+\U1054.\fi
+
+\M1057. One of the things we need to do when we've parsed an \&{addto} or
+similar command is set \\{cur\_edges} to the header of a supposed \&{picture}
+variable, given a token list for that variable.
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{find\_edges\_var}(\|t:\\{pointer})$;\6
+\4\&{var} \37\|p: \37\\{pointer};\2\6
+\&{begin} \37$\|p\K\\{find\_variable}(\|t)$;\5
+$\\{cur\_edges}\K\\{null}$;\6
+\&{if} $\|p=\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{obliterated}(\|t)$;\5
+\\{put\_get\_error};\6
+\&{end}\6
+\4\&{else} \&{if} $\\{type}(\|p)\I\\{picture\_type}$ \1\&{then}\6
+\&{begin} \37$\\{print\_err}(\.{"Variable\ "})$;\5
+$\\{show\_token\_list}(\|t,\39\\{null},\391000,\390)$;\5
+$\\{print}(\.{"\ is\ the\ wrong\ type\ ("})$;\5
+$\\{print\_type}(\\{type}(\|p))$;\5
+$\\{print\_char}(\.{")"})$;\5
+$\\{help2}(\.{"I\ was\ looking\ for\ a\ "}\.{"known"}\.{"\ picture\
+variable."})$\6
+$(\.{"So\ I\'ll\ not\ change\ anything\ just\ now."})$;\5
+\\{put\_get\_error};\6
+\&{end}\6
+\4\&{else} $\\{cur\_edges}\K\\{value}(\|p)$;\2\2\6
+$\\{flush\_node\_list}(\|t)$;\6
+\&{end};\par
+\fi
+
+\M1058. \P$\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{add\_to\_command}: \37\\{do\_add\_to};\par
+\fi
+
+\M1059. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_add\_to};\6
+\4\&{label} \37$\\{done},\39\\{not\_found}$;\6
+\4\&{var} \37$\\{lhs},\39\\{rhs}$: \37\\{pointer};\C{variable on left, path on
+right}\6
+\|w: \37\\{integer};\C{tentative weight}\6
+\|p: \37\\{pointer};\C{list manipulation register}\6
+\|q: \37\\{pointer};\C{beginning of second half of doubled path}\6
+\\{add\_to\_type}: \37$\\{double\_path\_code}\to\\{also\_code}$;\C{modifier of %
+\&{addto}}\2\6
+\&{begin} \37\\{get\_x\_next};\5
+$\\{var\_flag}\K\\{thing\_to\_add}$;\5
+\\{scan\_primary};\6
+\&{if} $\\{cur\_type}\I\\{token\_list}$ \1\&{then}\5
+\X1060:Abandon edges command because there's no variable\X\6
+\4\&{else} \&{begin} \37$\\{lhs}\K\\{cur\_exp}$;\5
+$\\{add\_to\_type}\K\\{cur\_mod}$;\6
+$\\{cur\_type}\K\\{vacuous}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{add\_to\_type}=\\{also\_code}$ \1\&{then}\5
+\X1061:Augment some edges by others\X\6
+\4\&{else} \X1062:Get ready to fill a contour, and fill it\X;\2\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M1060. \P$\X1060:Abandon edges command because there's no variable\X\S$\6
+\&{begin} \37$\\{exp\_err}(\.{"Not\ a\ suitable\ variable"})$;\5
+$\\{help4}(\.{"At\ this\ point\ I\ needed\ to\ see\ the\ name\ of\ a\ picture\
+variable."})$\6
+$(\.{"(Or\ perhaps\ you\ have\ indeed\ presented\ me\ with\ one;\ I\ might"})$\6
+$(\.{"have\ missed\ it,\ if\ it\ wasn\'t\ followed\ by\ the\ proper\
+token.)"})$\6
+$(\.{"So\ I\'ll\ not\ change\ anything\ just\ now."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end}\par
+\Us1059, 1070, 1071\ETs1074.\fi
+
+\M1061. \P$\X1061:Augment some edges by others\X\S$\6
+\&{begin} \37$\\{find\_edges\_var}(\\{lhs})$;\6
+\&{if} $\\{cur\_edges}=\\{null}$ \1\&{then}\5
+$\\{flush\_cur\_exp}(0)$\6
+\4\&{else} \&{if} $\\{cur\_type}\I\\{picture\_type}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ \`addto\'"})$;\5
+$\\{help2}(\.{"This\ expression\ should\ have\ specified\ a\ known\
+picture."})$\6
+$(\.{"So\ I\'ll\ not\ change\ anything\ just\ now."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{merge\_edges}(\\{cur\_exp})$;\5
+$\\{flush\_cur\_exp}(0)$;\6
+\&{end};\2\2\6
+\&{end}\par
+\U1059.\fi
+
+\M1062. \P$\X1062:Get ready to fill a contour, and fill it\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_type}=\\{pair\_type}$ \1\&{then}\5
+\\{pair\_to\_path};\2\6
+\&{if} $\\{cur\_type}\I\\{path\_type}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ \`addto\'"})$;\5
+$\\{help2}(\.{"This\ expression\ should\ have\ been\ a\ known\ path."})$\6
+$(\.{"So\ I\'ll\ not\ change\ anything\ just\ now."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\5
+$\\{flush\_token\_list}(\\{lhs})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{rhs}\K\\{cur\_exp}$;\5
+$\|w\K1$;\5
+$\\{cur\_pen}\K\\{null\_pen}$;\6
+\&{while} $\\{cur\_cmd}=\\{with\_option}$ \1\&{do}\6
+\&{if} $\\{scan\_with}$ \1\&{then}\6
+\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\5
+$\|w\K\\{cur\_exp}$\6
+\4\&{else} \X1063:Change the tentative pen\X;\2\2\2\6
+\X1064:Complete the contour filling operation\X;\6
+$\\{delete\_pen\_ref}(\\{cur\_pen})$;\6
+\&{end};\2\6
+\&{end}\par
+\U1059.\fi
+
+\M1063. We could say `$\\{add\_pen\_ref}(\\{cur\_pen})$; $\\{flush\_cur%
+\_exp}(0)$' after changing
+\\{cur\_pen} here. But that would have no effect, because the current
+expression
+will not be flushed. Thus we save a bit of code (at the risk of being too
+tricky).
+
+\Y\P$\4\X1063:Change the tentative pen\X\S$\6
+\&{begin} \37$\\{delete\_pen\_ref}(\\{cur\_pen})$;\5
+$\\{cur\_pen}\K\\{cur\_exp}$;\6
+\&{end}\par
+\U1062.\fi
+
+\M1064. \P$\X1064:Complete the contour filling operation\X\S$\6
+$\\{find\_edges\_var}(\\{lhs})$;\6
+\&{if} $\\{cur\_edges}=\\{null}$ \1\&{then}\5
+$\\{toss\_knot\_list}(\\{rhs})$\6
+\4\&{else} \&{begin} \37$\\{lhs}\K\\{null}$;\5
+$\\{cur\_path\_type}\K\\{add\_to\_type}$;\6
+\&{if} $\\{left\_type}(\\{rhs})=\\{endpoint}$ \1\&{then}\6
+\&{if} $\\{cur\_path\_type}=\\{double\_path\_code}$ \1\&{then}\5
+\X1065:Double the path\X\6
+\4\&{else} \X1067:Complain about non-cycle and \&{goto} \\{not\_found}\X\2\6
+\4\&{else} \&{if} $\\{cur\_path\_type}=\\{double\_path\_code}$ \1\&{then}\5
+$\\{lhs}\K\\{htap\_ypoc}(\\{rhs})$;\2\2\6
+$\\{cur\_wt}\K\|w$;\5
+$\\{rhs}\K\\{make\_spec}(\\{rhs},\39\\{max\_offset}(\\{cur\_pen}),\39%
+\\{internal}[\\{tracing\_specs}])$;\5
+\X1068:Check the turning number\X;\6
+\&{if} $\\{max\_offset}(\\{cur\_pen})=0$ \1\&{then}\5
+$\\{fill\_spec}(\\{rhs})$\6
+\4\&{else} $\\{fill\_envelope}(\\{rhs})$;\2\6
+\&{if} $\\{lhs}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\\{rev\_turns}\K\\{true}$;\5
+$\\{lhs}\K\\{make\_spec}(\\{lhs},\39\\{max\_offset}(\\{cur\_pen}),\39%
+\\{internal}[\\{tracing\_specs}])$;\5
+$\\{rev\_turns}\K\\{false}$;\6
+\&{if} $\\{max\_offset}(\\{cur\_pen})=0$ \1\&{then}\5
+$\\{fill\_spec}(\\{lhs})$\6
+\4\&{else} $\\{fill\_envelope}(\\{lhs})$;\2\6
+\&{end};\2\6
+\4\\{not\_found}: \37\&{end}\2\par
+\U1062.\fi
+
+\M1065. \P$\X1065:Double the path\X\S$\6
+\&{if} $\\{link}(\\{rhs})=\\{rhs}$ \1\&{then}\5
+\X1066:Make a trivial one-point path cycle\X\6
+\4\&{else} \&{begin} \37$\|p\K\\{htap\_ypoc}(\\{rhs})$;\5
+$\|q\K\\{link}(\|p)$;\6
+$\\{right\_x}(\\{path\_tail})\K\\{right\_x}(\|q)$;\5
+$\\{right\_y}(\\{path\_tail})\K\\{right\_y}(\|q)$;\5
+$\\{right\_type}(\\{path\_tail})\K\\{right\_type}(\|q)$;\5
+$\\{link}(\\{path\_tail})\K\\{link}(\|q)$;\5
+$\\{free\_node}(\|q,\39\\{knot\_node\_size})$;\6
+$\\{right\_x}(\|p)\K\\{right\_x}(\\{rhs})$;\5
+$\\{right\_y}(\|p)\K\\{right\_y}(\\{rhs})$;\5
+$\\{right\_type}(\|p)\K\\{right\_type}(\\{rhs})$;\5
+$\\{link}(\|p)\K\\{link}(\\{rhs})$;\5
+$\\{free\_node}(\\{rhs},\39\\{knot\_node\_size})$;\6
+$\\{rhs}\K\|p$;\6
+\&{end}\2\par
+\U1064.\fi
+
+\M1066. \P$\X1066:Make a trivial one-point path cycle\X\S$\6
+\&{begin} \37$\\{right\_x}(\\{rhs})\K\\{x\_coord}(\\{rhs})$;\5
+$\\{right\_y}(\\{rhs})\K\\{y\_coord}(\\{rhs})$;\5
+$\\{left\_x}(\\{rhs})\K\\{x\_coord}(\\{rhs})$;\5
+$\\{left\_y}(\\{rhs})\K\\{y\_coord}(\\{rhs})$;\5
+$\\{left\_type}(\\{rhs})\K\\{explicit}$;\5
+$\\{right\_type}(\\{rhs})\K\\{explicit}$;\6
+\&{end}\par
+\U1065.\fi
+
+\M1067. \P$\X1067:Complain about non-cycle and \&{goto} \\{not\_found}\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Not\ a\ cycle"})$;\5
+$\\{help2}(\.{"That\ contour\ should\ have\ ended\ with\ \`..cycle\'\ or\ \`%
+\&cycle\'."})$\6
+$(\.{"So\ I\'ll\ not\ change\ anything\ just\ now."})$;\5
+\\{put\_get\_error};\5
+$\\{toss\_knot\_list}(\\{rhs})$;\5
+\&{goto} \37\\{not\_found};\6
+\&{end}\par
+\U1064.\fi
+
+\M1068. \P$\X1068:Check the turning number\X\S$\6
+\&{if} $\\{turning\_number}\L0$ \1\&{then}\6
+\&{if} $\\{cur\_path\_type}\I\\{double\_path\_code}$ \1\&{then}\6
+\&{if} $\\{internal}[\\{turning\_check}]>0$ \1\&{then}\6
+\&{if} $(\\{turning\_number}<0)\W(\\{link}(\\{cur\_pen})=\\{null})$ \1\&{then}\5
+$\\{negate}(\\{cur\_wt})$\6
+\4\&{else} \&{begin} \37\&{if} $\\{turning\_number}=0$ \1\&{then}\6
+\&{if} $(\\{internal}[\\{turning\_check}]\L\\{unity})\W(\\{link}(\\{cur\_pen})=%
+\\{null})$ \1\&{then}\5
+\&{goto} \37\\{done}\6
+\4\&{else} $\\{print\_strange}(\.{"Strange\ path\ (turning\ number\ is\
+zero)"})$\2\6
+\4\&{else} $\\{print\_strange}(\.{"Backwards\ path\ (turning\ number\ is\
+negative)"})$;\2\6
+$\\{help3}(\.{"The\ path\ doesn\'t\ have\ a\ counterclockwise\ orientation,"})$%
+\6
+$(\.{"so\ I\'ll\ probably\ have\ trouble\ drawing\ it."})$\6
+$(\.{"(See\ Chapter\ 27\ of\ The\ METAFONTbook\ for\ more\ help.)"})$;\5
+\\{put\_get\_error};\6
+\&{end};\2\2\2\2\6
+\4\\{done}: \37\par
+\U1064.\fi
+
+\M1069. \P$\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{ship\_out\_command}: \37\\{do\_ship\_out};\6
+\4\\{display\_command}: \37\\{do\_display};\6
+\4\\{open\_window}: \37\\{do\_open\_window};\6
+\4\\{cull\_command}: \37\\{do\_cull};\par
+\fi
+
+\M1070. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\hbox{\4}\X1098:Declare the function called \\{tfm\_check}\X\6
+\4\&{procedure}\1\ \37\\{do\_ship\_out};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|c: \37\\{integer};\C{the character code}\2\6
+\&{begin} \37\\{get\_x\_next};\5
+$\\{var\_flag}\K\\{semicolon}$;\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{token\_list}$ \1\&{then}\6
+\&{if} $\\{cur\_type}=\\{picture\_type}$ \1\&{then}\5
+$\\{cur\_edges}\K\\{cur\_exp}$\6
+\4\&{else} \&{begin} \37\X1060:Abandon edges command because there's no
+variable\X;\6
+\&{return};\6
+\&{end}\2\6
+\4\&{else} \&{begin} \37$\\{find\_edges\_var}(\\{cur\_exp})$;\5
+$\\{cur\_type}\K\\{vacuous}$;\6
+\&{end};\2\6
+\&{if} $\\{cur\_edges}\I\\{null}$ \1\&{then}\6
+\&{begin} \37$\|c\K\\{round\_unscaled}(\\{internal}[\\{char\_code}])\mathbin{%
+\&{mod}}256$;\6
+\&{if} $\|c<0$ \1\&{then}\5
+$\|c\K\|c+256$;\2\6
+\X1099:Store the width information for character code~\|c\X;\6
+\&{if} $\\{internal}[\\{proofing}]\G0$ \1\&{then}\5
+$\\{ship\_out}(\|c)$;\2\6
+\&{end};\2\6
+$\\{flush\_cur\_exp}(0)$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M1071. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_display};\6
+\4\&{label} \37$\\{not\_found},\39\\{common\_ending},\39\\{exit}$;\6
+\4\&{var} \37\|e: \37\\{pointer};\C{token list for a picture variable}\2\6
+\&{begin} \37\\{get\_x\_next};\5
+$\\{var\_flag}\K\\{in\_window}$;\5
+\\{scan\_primary};\6
+\&{if} $\\{cur\_type}\I\\{token\_list}$ \1\&{then}\5
+\X1060:Abandon edges command because there's no variable\X\6
+\4\&{else} \&{begin} \37$\|e\K\\{cur\_exp}$;\5
+$\\{cur\_type}\K\\{vacuous}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+\&{goto} \37\\{common\_ending};\2\6
+$\\{cur\_exp}\K\\{round\_unscaled}(\\{cur\_exp})$;\6
+\&{if} $\\{cur\_exp}<0$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{if} $\\{cur\_exp}>15$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{if} $\R\\{window\_open}[\\{cur\_exp}]$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\\{find\_edges\_var}(\|e)$;\6
+\&{if} $\\{cur\_edges}\I\\{null}$ \1\&{then}\5
+$\\{disp\_edges}(\\{cur\_exp})$;\2\6
+\&{return};\6
+\4\\{not\_found}: \37$\\{cur\_exp}\K\\{cur\_exp}\ast\\{unity}$;\6
+\4\\{common\_ending}: \37$\\{exp\_err}(\.{"Bad\ window\ number"})$;\5
+$\\{help1}(\.{"It\ should\ be\ the\ number\ of\ an\ open\ window."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\5
+$\\{flush\_token\_list}(\|e)$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M1072. The only thing difficult about `\&{openwindow}' is that the syntax
+allows the user to go astray in many ways. The following subroutine
+helps keep the necessary program reasonably short and sweet.
+
+\Y\P$\4\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{function}\1\ \37$\\{get\_pair}(\|c:\\{command\_code})$: \37\\{boolean};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{a pair of values that are known (we hope)}\6
+\|b: \37\\{boolean};\C{did we find such a pair?}\2\6
+\&{begin} \37\&{if} $\\{cur\_cmd}\I\|c$ \1\&{then}\5
+$\\{get\_pair}\K\\{false}$\6
+\4\&{else} \&{begin} \37\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{nice\_pair}(\\{cur\_exp},\39\\{cur\_type})$ \1\&{then}\6
+\&{begin} \37$\|p\K\\{value}(\\{cur\_exp})$;\5
+$\\{cur\_x}\K\\{value}(\\{x\_part\_loc}(\|p))$;\5
+$\\{cur\_y}\K\\{value}(\\{y\_part\_loc}(\|p))$;\5
+$\|b\K\\{true}$;\6
+\&{end}\6
+\4\&{else} $\|b\K\\{false}$;\2\6
+$\\{flush\_cur\_exp}(0)$;\5
+$\\{get\_pair}\K\|b$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M1073. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_open\_window};\6
+\4\&{label} \37$\\{not\_found},\39\\{exit}$;\6
+\4\&{var} \37\|k: \37\\{integer};\C{the window number in question}\6
+$\\{r0},\39\\{c0},\39\\{r1},\39\\{c1}$: \37\\{scaled};\C{window coordinates}\2\6
+\&{begin} \37\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\|k\K\\{round\_unscaled}(\\{cur\_exp})$;\6
+\&{if} $\|k<0$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{if} $\|k>15$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{if} $\R\\{get\_pair}(\\{from\_token})$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\\{r0}\K\\{cur\_x}$;\5
+$\\{c0}\K\\{cur\_y}$;\6
+\&{if} $\R\\{get\_pair}(\\{to\_token})$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\\{r1}\K\\{cur\_x}$;\5
+$\\{c1}\K\\{cur\_y}$;\6
+\&{if} $\R\\{get\_pair}(\\{at\_token})$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\\{open\_a\_window}(\|k,\39\\{r0},\39\\{c0},\39\\{r1},\39\\{c1},\39\\{cur\_x},%
+\39\\{cur\_y})$;\5
+\&{return};\6
+\4\\{not\_found}: \37$\\{print\_err}(\.{"Improper\ \`openwindow\'"})$;\5
+$\\{help2}(\.{"Say\ \`openwindow\ k\ from\ (r0,c0)\ to\ (r1,c1)\ at\ (x,y)%
+\',"})$\6
+$(\.{"where\ all\ quantities\ are\ known\ and\ k\ is\ between\ 0\ and\ 15."})$;%
+\5
+\\{put\_get\_error};\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M1074. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_cull};\6
+\4\&{label} \37$\\{not\_found},\39\\{exit}$;\6
+\4\&{var} \37\|e: \37\\{pointer};\C{token list for a picture variable}\6
+\\{keeping}: \37$\\{drop\_code}\to\\{keep\_code}$;\C{modifier of \\{cull\_op}}\6
+$\|w,\39\\{w\_in},\39\\{w\_out}$: \37\\{integer};\C{culling weights}\2\6
+\&{begin} \37$\|w\K1$;\5
+\\{get\_x\_next};\5
+$\\{var\_flag}\K\\{cull\_op}$;\5
+\\{scan\_primary};\6
+\&{if} $\\{cur\_type}\I\\{token\_list}$ \1\&{then}\5
+\X1060:Abandon edges command because there's no variable\X\6
+\4\&{else} \&{begin} \37$\|e\K\\{cur\_exp}$;\5
+$\\{cur\_type}\K\\{vacuous}$;\5
+$\\{keeping}\K\\{cur\_mod}$;\6
+\&{if} $\R\\{get\_pair}(\\{cull\_op})$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{while} $(\\{cur\_cmd}=\\{with\_option})\W(\\{cur\_mod}=\\{known})$ \1\&{do}\6
+\&{if} $\\{scan\_with}$ \1\&{then}\5
+$\|w\K\\{cur\_exp}$;\2\2\6
+\X1075:Set up the culling weights, or \&{goto} \\{not\_found} if the thresholds
+are bad\X;\6
+$\\{find\_edges\_var}(\|e)$;\6
+\&{if} $\\{cur\_edges}\I\\{null}$ \1\&{then}\5
+$\\{cull\_edges}(\\{floor\_unscaled}(\\{cur\_x}+\\{unity}-1),\39\\{floor%
+\_unscaled}(\\{cur\_y}),\39\\{w\_out},\39\\{w\_in})$;\2\6
+\&{return};\6
+\4\\{not\_found}: \37$\\{print\_err}(\.{"Bad\ culling\ amounts"})$;\5
+$\\{help1}(\.{"Always\ cull\ by\ known\ amounts\ that\ exclude\ 0."})$;\5
+\\{put\_get\_error};\5
+$\\{flush\_token\_list}(\|e)$;\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M1075. \P$\X1075:Set up the culling weights, or \&{goto} \\{not\_found} if the
+thresholds are bad\X\S$\6
+\&{if} $\\{cur\_x}>\\{cur\_y}$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+\&{if} $\\{keeping}=\\{drop\_code}$ \1\&{then}\6
+\&{begin} \37\&{if} $(\\{cur\_x}>0)\V(\\{cur\_y}<0)$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\\{w\_out}\K\|w$;\5
+$\\{w\_in}\K0$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\&{if} $(\\{cur\_x}\L0)\W(\\{cur\_y}\G0)$ \1\&{then}\5
+\&{goto} \37\\{not\_found};\2\6
+$\\{w\_out}\K0$;\5
+$\\{w\_in}\K\|w$;\6
+\&{end}\2\par
+\U1074.\fi
+
+\M1076. The \&{everyjob} command simply assigns a nonzero value to the global
+variable
+\\{start\_sym}.
+
+\Y\P$\4\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{every\_job\_command}: \37\&{begin} \37\\{get\_symbol};\5
+$\\{start\_sym}\K\\{cur\_sym}$;\5
+\\{get\_x\_next};\6
+\&{end};\par
+\fi
+
+\M1077. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{start\_sym}: \37\\{halfword};\C{a symbolic token to insert at beginning of
+job}\par
+\fi
+
+\M1078. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{start\_sym}\K0$;\par
+\fi
+
+\M1079. Finally, we have only the ``message'' commands remaining.
+
+\Y\P\D \37$\\{message\_code}=0$\par
+\P\D \37$\\{err\_message\_code}=1$\par
+\P\D \37$\\{err\_help\_code}=2$\par
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"message"},\39\\{message\_command},\39\\{message\_code})$;\6
+$\\{primitive}(\.{"errmessage"},\39\\{message\_command},\39\\{err\_message%
+\_code})$;\6
+$\\{primitive}(\.{"errhelp"},\39\\{message\_command},\39\\{err\_help\_code})$;%
+\par
+\fi
+
+\M1080. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{message\_command}: \37\&{if} $\|m<\\{err\_message\_code}$ \1\&{then}\5
+$\\{print}(\.{"message"})$\6
+\4\&{else} \&{if} $\|m=\\{err\_message\_code}$ \1\&{then}\5
+$\\{print}(\.{"errmessage"})$\6
+\4\&{else} $\\{print}(\.{"errhelp"})$;\2\2\par
+\fi
+
+\M1081. \P$\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{message\_command}: \37\\{do\_message};\par
+\fi
+
+\M1082. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_message};\6
+\4\&{var} \37\|m: \37$\\{message\_code}\to\\{err\_help\_code}$;\C{the type of
+message}\2\6
+\&{begin} \37$\|m\K\\{cur\_mod}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{string\_type}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Not\ a\ string"})$;\5
+$\\{help1}(\.{"A\ message\ should\ be\ a\ known\ string\ expression."})$;\5
+\\{put\_get\_error};\6
+\&{end}\6
+\4\&{else} \&{case} $\|m$ \1\&{of}\6
+\4\\{message\_code}: \37\&{begin} \37$\\{print\_nl}(\.{""})$;\5
+$\\{slow\_print}(\\{cur\_exp})$;\6
+\&{end};\6
+\4\\{err\_message\_code}: \37\X1086:Print string \\{cur\_exp} as an error
+message\X;\6
+\4\\{err\_help\_code}: \37\X1083:Save string \\{cur\_exp} as the \\{err\_help}%
+\X;\2\6
+\&{end};\C{there are no other cases}\2\6
+$\\{flush\_cur\_exp}(0)$;\6
+\&{end};\par
+\fi
+
+\M1083. The global variable \\{err\_help} is zero when the user has most
+recently
+given an empty help string, or if none has ever been given.
+
+\Y\P$\4\X1083:Save string \\{cur\_exp} as the \\{err\_help}\X\S$\6
+\&{begin} \37\&{if} $\\{err\_help}\I0$ \1\&{then}\5
+$\\{delete\_str\_ref}(\\{err\_help})$;\2\6
+\&{if} $\\{length}(\\{cur\_exp})=0$ \1\&{then}\5
+$\\{err\_help}\K0$\6
+\4\&{else} \&{begin} \37$\\{err\_help}\K\\{cur\_exp}$;\5
+$\\{add\_str\_ref}(\\{err\_help})$;\6
+\&{end};\2\6
+\&{end}\par
+\U1082.\fi
+
+\M1084. If \&{errmessage} occurs often in \\{scroll\_mode}, without
+user-defined
+\&{errhelp}, we don't want to give a long help message each time. So we
+give a verbose explanation only once.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{long\_help\_seen}: \37\\{boolean};\C{has the long \&{errmessage} help been
+used?}\par
+\fi
+
+\M1085. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{long\_help\_seen}\K\\{false}$;\par
+\fi
+
+\M1086. \P$\X1086:Print string \\{cur\_exp} as an error message\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{""})$;\5
+$\\{slow\_print}(\\{cur\_exp})$;\6
+\&{if} $\\{err\_help}\I0$ \1\&{then}\5
+$\\{use\_err\_help}\K\\{true}$\6
+\4\&{else} \&{if} $\\{long\_help\_seen}$ \1\&{then}\5
+$\\{help1}(\.{"(That\ was\ another\ \`errmessage\'.)"})$\6
+\4\&{else} \&{begin} \37\&{if} $\\{interaction}<\\{error\_stop\_mode}$ \1%
+\&{then}\5
+$\\{long\_help\_seen}\K\\{true}$;\2\6
+$\\{help4}(\.{"This\ error\ message\ was\ generated\ by\ an\ \`errmessage\'"})$%
+\6
+$(\.{"command,\ so\ I\ can\'t\ give\ any\ explicit\ help."})$\6
+$(\.{"Pretend\ that\ you\'re\ Miss\ Marple:\ Examine\ all\ clues,"})$\6
+$(\.{"and\ deduce\ the\ truth\ by\ inspired\ guesses."})$;\6
+\&{end};\2\2\6
+\\{put\_get\_error};\5
+$\\{use\_err\_help}\K\\{false}$;\6
+\&{end}\par
+\U1082.\fi
+
+\N1087. \[45] Font metric data.
+\TeX\ gets its knowledge about fonts from font metric files, also called
+\.{TFM} files; the `\.T' in `\.{TFM}' stands for \TeX,
+but other programs know about them too. One of \MF's duties is to
+write \.{TFM} files so that the user's fonts can readily be
+applied to typesetting.
+
+The information in a \.{TFM} file appears in a sequence of 8-bit bytes.
+Since the number of bytes is always a multiple of~4, we could
+also regard the file as a sequence of 32-bit words, but \MF\ uses the
+byte interpretation. The format of \.{TFM} files was designed by
+Lyle Ramshaw in 1980. The intent is to convey a lot of different kinds
+of information in a compact but useful form.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{tfm\_file}: \37\\{byte\_file};\C{the font metric output goes here}\6
+\4\\{metric\_file\_name}: \37\\{str\_number};\C{full name of the font metric
+file}\par
+\fi
+
+\M1088. The first 24 bytes (6 words) of a \.{TFM} file contain twelve 16-bit
+integers that give the lengths of the various subsequent portions
+of the file. These twelve integers are, in order:
+$$\vbox{\halign{\hfil#&$\null=\null$#\hfil\cr
+\\{lf}&length of the entire file, in words;\cr
+\\{lh}&length of the header data, in words;\cr
+\\{bc}&smallest character code in the font;\cr
+\\{ec}&largest character code in the font;\cr
+\\{nw}&number of words in the width table;\cr
+\\{nh}&number of words in the height table;\cr
+\\{nd}&number of words in the depth table;\cr
+\\{ni}&number of words in the italic correction table;\cr
+\\{nl}&number of words in the lig/kern table;\cr
+\\{nk}&number of words in the kern table;\cr
+\\{ne}&number of words in the extensible character table;\cr
+\\{np}&number of font parameter words.\cr}}$$
+They are all nonnegative and less than $2^{15}$. We must have $\\{bc}-1\L\\{ec}%
+\L255$,
+$\\{ne}\L256$, and
+$$\hbox{$\\{lf}=6+\\{lh}+(\\{ec}-\\{bc}+1)+\\{nw}+\\{nh}+\\{nd}+\\{ni}+\\{nl}+%
+\\{nk}+\\{ne}+\\{np}$.}$$
+Note that a font may contain as many as 256 characters (if $\\{bc}=0$ and $%
+\\{ec}=255$),
+and as few as 0 characters (if $\\{bc}=\\{ec}+1$).
+
+Incidentally, when two or more 8-bit bytes are combined to form an integer of
+16 or more bits, the most significant bytes appear first in the file.
+This is called BigEndian order.
+
+\fi
+
+\M1089. The rest of the \.{TFM} file may be regarded as a sequence of ten data
+arrays having the informal specification
+$$\def\arr$[#1]#2${\&{array} $[#1]$ \&{of} #2}
+\tabskip\centering
+\halign to\displaywidth{\hfil\\{#}\tabskip=0pt&$\,:\,$\arr#\hfil
+\tabskip\centering\cr
+header&$[0\to\\{lh}-1]\hbox{\\{stuff}}$\cr
+char\_info&$[\\{bc}\to\\{ec}]\\{char\_info\_word}$\cr
+width&$[0\to\\{nw}-1]\\{fix\_word}$\cr
+height&$[0\to\\{nh}-1]\\{fix\_word}$\cr
+depth&$[0\to\\{nd}-1]\\{fix\_word}$\cr
+italic&$[0\to\\{ni}-1]\\{fix\_word}$\cr
+lig\_kern&$[0\to\\{nl}-1]\\{lig\_kern\_command}$\cr
+kern&$[0\to\\{nk}-1]\\{fix\_word}$\cr
+exten&$[0\to\\{ne}-1]\\{extensible\_recipe}$\cr
+param&$[1\to\\{np}]\\{fix\_word}$\cr}$$
+The most important data type used here is a \\{fix\_word}, which is
+a 32-bit representation of a binary fraction. A \\{fix\_word} is a signed
+quantity, with the two's complement of the entire word used to represent
+negation. Of the 32 bits in a \\{fix\_word}, exactly 12 are to the left of the
+binary point; thus, the largest \\{fix\_word} value is $2048-2^{-20}$, and
+the smallest is $-2048$. We will see below, however, that all but two of
+the \\{fix\_word} values must lie between $-16$ and $+16$.
+
+\fi
+
+\M1090. The first data array is a block of header information, which contains
+general facts about the font. The header must contain at least two words,
+$\\{header}[0]$ and $\\{header}[1]$, whose meaning is explained below.
+Additional
+header information of use to other software routines might also be
+included, and \MF\ will generate it if the \.{headerbyte} command occurs.
+For example, 16 more words of header information are in use at the Xerox
+Palo Alto Research Center; the first ten specify the character coding
+scheme used (e.g., `\.{XEROX TEXT}' or `\.{TEX MATHSY}'), the next five
+give the font family name (e.g., `\.{HELVETICA}' or `\.{CMSY}'), and the
+last gives the ``face byte.''
+
+\yskip\hang$\\{header}[0]$ is a 32-bit check sum that \MF\ will copy into
+the \.{GF} output file. This helps ensure consistency between files,
+since \TeX\ records the check sums from the \.{TFM}'s it reads, and these
+should match the check sums on actual fonts that are used. The actual
+relation between this check sum and the rest of the \.{TFM} file is not
+important; the check sum is simply an identification number with the
+property that incompatible fonts almost always have distinct check sums.
+
+\yskip\hang$\\{header}[1]$ is a \\{fix\_word} containing the design size of the
+font, in units of \TeX\ points. This number must be at least 1.0; it is
+fairly arbitrary, but usually the design size is 10.0 for a ``10 point''
+font, i.e., a font that was designed to look best at a 10-point size,
+whatever that really means. When a \TeX\ user asks for a font `\.{at}
+$\delta$ \.{pt}', the effect is to override the design size and replace it
+by $\delta$, and to multiply the $x$ and~$y$ coordinates of the points in
+the font image by a factor of $\delta$ divided by the design size. {\sl
+All other dimensions in the\/ \.{TFM} file are \\{fix\_word}\kern-1pt\
+numbers in design-size units.} Thus, for example, the value of $\\{param}[6]$,
+which defines the \.{em} unit, is often the \\{fix\_word} value $2^{20}=1.0$,
+since many fonts have a design size equal to one em. The other dimensions
+must be less than 16 design-size units in absolute value; thus,
+$\\{header}[1]$ and $\\{param}[1]$ are the only \\{fix\_word} entries in the
+whole
+\.{TFM} file whose first byte might be something besides 0 or 255.
+
+\fi
+
+\M1091. Next comes the \\{char\_info} array, which contains one \\{char\_info%
+\_word}
+per character. Each word in this part of the file contains six fields
+packed into four bytes as follows.
+
+\yskip\hang first byte: \\{width\_index} (8 bits)\par
+\hang second byte: \\{height\_index} (4 bits) times 16, plus \\{depth\_index}
+(4~bits)\par
+\hang third byte: \\{italic\_index} (6 bits) times 4, plus \\{tag}
+(2~bits)\par
+\hang fourth byte: \\{remainder} (8 bits)\par
+\yskip\noindent
+The actual width of a character is \\{width}$[\\{width\_index}]$, in
+design-size
+units; this is a device for compressing information, since many characters
+have the same width. Since it is quite common for many characters
+to have the same height, depth, or italic correction, the \.{TFM} format
+imposes a limit of 16 different heights, 16 different depths, and
+64 different italic corrections.
+
+Incidentally, the relation $\\{width}[0]=\\{height}[0]=\\{depth}[0]=
+\\{italic}[0]=0$ should always hold, so that an index of zero implies a
+value of zero. The \\{width\_index} should never be zero unless the
+character does not exist in the font, since a character is valid if and
+only if it lies between \\{bc} and \\{ec} and has a nonzero \\{width\_index}.
+
+\fi
+
+\M1092. The \\{tag} field in a \\{char\_info\_word} has four values that
+explain how to
+interpret the \\{remainder} field.
+
+\def\hangg#1 {\hang\hbox{#1 }}
+\yskip\hangg$\\{tag}=0$ (\\{no\_tag}) means that \\{remainder} is unused.\par
+\hangg$\\{tag}=1$ (\\{lig\_tag}) means that this character has a
+ligature/kerning
+program starting at location \\{remainder} in the \\{lig\_kern} array.\par
+\hangg$\\{tag}=2$ (\\{list\_tag}) means that this character is part of a chain
+of
+characters of ascending sizes, and not the largest in the chain. The
+\\{remainder} field gives the character code of the next larger character.\par
+\hangg$\\{tag}=3$ (\\{ext\_tag}) means that this character code represents an
+extensible character, i.e., a character that is built up of smaller pieces
+so that it can be made arbitrarily large. The pieces are specified in
+$\\{exten}[\\{remainder}]$.\par
+\yskip\noindent
+Characters with $\\{tag}=2$ and $\\{tag}=3$ are treated as characters with $%
+\\{tag}=0$
+unless they are used in special circumstances in math formulas. For example,
+\TeX's \.{\\sum} operation looks for a \\{list\_tag}, and the \.{\\left}
+operation looks for both \\{list\_tag} and \\{ext\_tag}.
+
+\Y\P\D \37$\\{no\_tag}=0$\C{vanilla character}\par
+\P\D \37$\\{lig\_tag}=1$\C{character has a ligature/kerning program}\par
+\P\D \37$\\{list\_tag}=2$\C{character has a successor in a charlist}\par
+\P\D \37$\\{ext\_tag}=3$\C{character is extensible}\par
+\fi
+
+\M1093. The \\{lig\_kern} array contains instructions in a simple programming
+language
+that explains what to do for special letter pairs. Each word in this array is a
+\\{lig\_kern\_command} of four bytes.
+
+\yskip\hang first byte: \\{skip\_byte}, indicates that this is the final
+program
+step if the byte is 128 or more, otherwise the next step is obtained by
+skipping this number of intervening steps.\par
+\hang second byte: \\{next\_char}, ``if \\{next\_char} follows the current
+character,
+then perform the operation and stop, otherwise continue.''\par
+\hang third byte: \\{op\_byte}, indicates a ligature step if less than~128,
+a kern step otherwise.\par
+\hang fourth byte: \\{remainder}.\par
+\yskip\noindent
+In a kern step, an
+additional space equal to $\\{kern}[256\ast(\\{op\_byte}-128)+\\{remainder}]$
+is inserted
+between the current character and \\{next\_char}. This amount is
+often negative, so that the characters are brought closer together
+by kerning; but it might be positive.
+
+There are eight kinds of ligature steps, having \\{op\_byte} codes $4a+2b+c$
+where
+$0\le a\le b+c$ and $0\le b,c\le1$. The character whose code is
+\\{remainder} is inserted between the current character and \\{next\_char};
+then the current character is deleted if $b=0$, and \\{next\_char} is
+deleted if $c=0$; then we pass over $a$~characters to reach the next
+current character (which may have a ligature/kerning program of its own).
+
+If the very first instruction of the \\{lig\_kern} array has $\\{skip%
+\_byte}=255$,
+the \\{next\_char} byte is the so-called right boundary character of this font;
+the value of \\{next\_char} need not lie between \\{bc} and~\\{ec}.
+If the very last instruction of the \\{lig\_kern} array has $\\{skip%
+\_byte}=255$,
+there is a special ligature/kerning program for a left boundary character,
+beginning at location $256\ast\\{op\_byte}+\\{remainder}$.
+The interpretation is that \TeX\ puts implicit boundary characters
+before and after each consecutive string of characters from the same font.
+These implicit characters do not appear in the output, but they can affect
+ligatures and kerning.
+
+If the very first instruction of a character's \\{lig\_kern} program has
+$\\{skip\_byte}>128$, the program actually begins in location
+$256\ast\\{op\_byte}+\\{remainder}$. This feature allows access to large \\{lig%
+\_kern}
+arrays, because the first instruction must otherwise
+appear in a location $\L255$.
+
+Any instruction with $\\{skip\_byte}>128$ in the \\{lig\_kern} array must
+satisfy
+the condition
+$$\hbox{$256\ast\\{op\_byte}+\\{remainder}<\\{nl}$.}$$
+If such an instruction is encountered during
+normal program execution, it denotes an unconditional halt; no ligature
+command is performed.
+
+\Y\P\D \37$\\{stop\_flag}=128+\\{min\_quarterword}$\C{value indicating `%
+\.{STOP}' in a lig/kern program}\par
+\P\D \37$\\{kern\_flag}=128+\\{min\_quarterword}$\C{op code for a kern step}\par
+\P\D \37$\\{skip\_byte}(\#)\S\\{lig\_kern}[\#].\\{b0}$\par
+\P\D \37$\\{next\_char}(\#)\S\\{lig\_kern}[\#].\\{b1}$\par
+\P\D \37$\\{op\_byte}(\#)\S\\{lig\_kern}[\#].\\{b2}$\par
+\P\D \37$\\{rem\_byte}(\#)\S\\{lig\_kern}[\#].\\{b3}$\par
+\fi
+
+\M1094. Extensible characters are specified by an \\{extensible\_recipe}, which
+consists of four bytes called \\{top}, \\{mid}, \\{bot}, and \\{rep} (in this
+order). These bytes are the character codes of individual pieces used to
+build up a large symbol. If \\{top}, \\{mid}, or \\{bot} are zero, they are
+not
+present in the built-up result. For example, an extensible vertical line is
+like an extensible bracket, except that the top and bottom pieces are missing.
+
+Let $T$, $M$, $B$, and $R$ denote the respective pieces, or an empty box
+if the piece isn't present. Then the extensible characters have the form
+$TR^kMR^kB$ from top to bottom, for some $\|k\G0$, unless $M$ is absent;
+in the latter case we can have $TR^kB$ for both even and odd values of~\|k.
+The width of the extensible character is the width of $R$; and the
+height-plus-depth is the sum of the individual height-plus-depths of the
+components used, since the pieces are butted together in a vertical list.
+
+\Y\P\D \37$\\{ext\_top}(\#)\S\\{exten}[\#].\\{b0}$\C{\\{top} piece in a recipe}%
+\par
+\P\D \37$\\{ext\_mid}(\#)\S\\{exten}[\#].\\{b1}$\C{\\{mid} piece in a recipe}%
+\par
+\P\D \37$\\{ext\_bot}(\#)\S\\{exten}[\#].\\{b2}$\C{\\{bot} piece in a recipe}%
+\par
+\P\D \37$\\{ext\_rep}(\#)\S\\{exten}[\#].\\{b3}$\C{\\{rep} piece in a recipe}%
+\par
+\fi
+
+\M1095. The final portion of a \.{TFM} file is the \\{param} array, which is
+another
+sequence of \\{fix\_word} values.
+
+\yskip\hang$\\{param}[1]=\\{slant}$ is the amount of italic slant, which is
+used
+to help position accents. For example, $\\{slant}=.25$ means that when you go
+up one unit, you also go .25 units to the right. The \\{slant} is a pure
+number; it is the only \\{fix\_word} other than the design size itself that is
+not scaled by the design size.
+
+\hang$\\{param}[2]=\\{space}$ is the normal spacing between words in text.
+Note that character \O{40} in the font need not have anything to do with
+blank spaces.
+
+\hang$\\{param}[3]=\\{space\_stretch}$ is the amount of glue stretching between
+words.
+
+\hang$\\{param}[4]=\\{space\_shrink}$ is the amount of glue shrinking between
+words.
+
+\hang$\\{param}[5]=\\{x\_height}$ is the size of one ex in the font; it is also
+the height of letters for which accents don't have to be raised or lowered.
+
+\hang$\\{param}[6]=\\{quad}$ is the size of one em in the font.
+
+\hang$\\{param}[7]=\\{extra\_space}$ is the amount added to $\\{param}[2]$ at
+the
+ends of sentences.
+
+\yskip\noindent
+If fewer than seven parameters are present, \TeX\ sets the missing parameters
+to zero.
+
+\Y\P\D \37$\\{slant\_code}=1$\par
+\P\D \37$\\{space\_code}=2$\par
+\P\D \37$\\{space\_stretch\_code}=3$\par
+\P\D \37$\\{space\_shrink\_code}=4$\par
+\P\D \37$\\{x\_height\_code}=5$\par
+\P\D \37$\\{quad\_code}=6$\par
+\P\D \37$\\{extra\_space\_code}=7$\par
+\fi
+
+\M1096. So that is what \.{TFM} files hold. One of \MF's duties is to output
+such
+information, and it does this all at once at the end of a job.
+In order to prepare for such frenetic activity, it squirrels away the
+necessary facts in various arrays as information becomes available.
+
+Character dimensions (\&{charwd}, \&{charht}, \&{chardp}, and \&{charic})
+are stored respectively in \\{tfm\_width}, \\{tfm\_height}, \\{tfm\_depth}, and
+\\{tfm\_ital\_corr}. Other information about a character (e.g., about
+its ligatures or successors) is accessible via the \\{char\_tag} and
+\\{char\_remainder} arrays. Other information about the font as a whole
+is kept in additional arrays called \\{header\_byte}, \\{lig\_kern},
+\\{kern}, \\{exten}, and \\{param}.
+
+\Y\P\D \37$\\{undefined\_label}\S\\{lig\_table\_size}$\C{an undefined local
+label}\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{bc},\39\\{ec}$: \37\\{eight\_bits};\C{smallest and largest character
+codes shipped out}\6
+\4\\{tfm\_width}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+\\{scaled};\C{\&{charwd} values}\2\6
+\4\\{tfm\_height}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+\\{scaled};\C{\&{charht} values}\2\6
+\4\\{tfm\_depth}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+\\{scaled};\C{\&{chardp} values}\2\6
+\4\\{tfm\_ital\_corr}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+\\{scaled};\C{\&{charic} values}\2\6
+\4\\{char\_exists}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+\\{boolean};\C{has this code been shipped out?}\2\6
+\4\\{char\_tag}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+$\\{no\_tag}\to\\{ext\_tag}$;\C{\\{remainder} category}\2\6
+\4\\{char\_remainder}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+$0\to\\{lig\_table\_size}$;\C{the \\{remainder} byte}\2\6
+\4\\{header\_byte}: \37\&{array} $[1\to\\{header\_size}]$ \1\&{of}\5
+$-1\to255$;\C{bytes of the \.{TFM} header, or $-1$ if unset}\2\6
+\4\\{lig\_kern}: \37\&{array} $[0\to\\{lig\_table\_size}]$ \1\&{of}\5
+\\{four\_quarters};\C{the ligature/kern table}\2\6
+\4\\{nl}: \37$0\to32767-256$;\C{the number of ligature/kern steps so far}\6
+\4\\{kern}: \37\&{array} $[0\to\\{max\_kerns}]$ \1\&{of}\5
+\\{scaled};\C{distinct kerning amounts}\2\6
+\4\\{nk}: \37$0\to\\{max\_kerns}$;\C{the number of distinct kerns so far}\6
+\4\\{exten}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+\\{four\_quarters};\C{extensible character recipes}\2\6
+\4\\{ne}: \37$0\to256$;\C{the number of extensible characters so far}\6
+\4\\{param}: \37\&{array} $[1\to\\{max\_font\_dimen}]$ \1\&{of}\5
+\\{scaled};\C{\&{fontinfo} parameters}\2\6
+\4\\{np}: \37$0\to\\{max\_font\_dimen}$;\C{the largest \&{fontinfo} parameter
+specified so far}\6
+\4$\\{nw},\39\\{nh},\39\\{nd},\39\\{ni}$: \37$0\to256$;\C{sizes of \.{TFM}
+subtables}\6
+\4\\{skip\_table}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+$0\to\\{lig\_table\_size}$;\C{local label status}\2\6
+\4\\{lk\_started}: \37\\{boolean};\C{has there been a lig/kern step in this
+command yet?}\6
+\4\\{bchar}: \37\\{integer};\C{right boundary character}\6
+\4\\{bch\_label}: \37$0\to\\{lig\_table\_size}$;\C{left boundary starting
+location}\6
+\4$\\{ll},\39\\{lll}$: \37$0\to\\{lig\_table\_size}$;\C{registers used for
+lig/kern processing}\6
+\4\\{label\_loc}: \37\&{array} $[0\to256]$ \1\&{of}\5
+$-1\to\\{lig\_table\_size}$;\C{lig/kern starting addresses}\2\6
+\4\\{label\_char}: \37\&{array} $[1\to256]$ \1\&{of}\5
+\\{eight\_bits};\C{characters for \\{label\_loc}}\2\6
+\4\\{label\_ptr}: \37$0\to256$;\C{highest position occupied in \\{label\_loc}}%
+\par
+\fi
+
+\M1097. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+\&{for} $\|k\K0\mathrel{\&{to}}255$ \1\&{do}\6
+\&{begin} \37$\\{tfm\_width}[\|k]\K0$;\5
+$\\{tfm\_height}[\|k]\K0$;\5
+$\\{tfm\_depth}[\|k]\K0$;\5
+$\\{tfm\_ital\_corr}[\|k]\K0$;\5
+$\\{char\_exists}[\|k]\K\\{false}$;\5
+$\\{char\_tag}[\|k]\K\\{no\_tag}$;\5
+$\\{char\_remainder}[\|k]\K0$;\5
+$\\{skip\_table}[\|k]\K\\{undefined\_label}$;\6
+\&{end};\2\6
+\&{for} $\|k\K1\mathrel{\&{to}}\\{header\_size}$ \1\&{do}\5
+$\\{header\_byte}[\|k]\K-1$;\2\6
+$\\{bc}\K255$;\5
+$\\{ec}\K0$;\5
+$\\{nl}\K0$;\5
+$\\{nk}\K0$;\5
+$\\{ne}\K0$;\5
+$\\{np}\K0$;\6
+$\\{internal}[\\{boundary\_char}]\K-\\{unity}$;\5
+$\\{bch\_label}\K\\{undefined\_label}$;\6
+$\\{label\_loc}[0]\K-1$;\5
+$\\{label\_ptr}\K0$;\par
+\fi
+
+\M1098. \P$\X1098:Declare the function called \\{tfm\_check}\X\S$\6
+\4\&{function}\1\ \37$\\{tfm\_check}(\|m:\\{small\_number})$: \37\\{scaled};\2%
+\6
+\&{begin} \37\&{if} $\\{abs}(\\{internal}[\|m])\G\\{fraction\_half}$ \1\&{then}%
+\6
+\&{begin} \37$\\{print\_err}(\.{"Enormous\ "})$;\5
+$\\{print}(\\{int\_name}[\|m])$;\5
+$\\{print}(\.{"\ has\ been\ reduced"})$;\5
+$\\{help1}(\.{"Font\ metric\ dimensions\ must\ be\ less\ than\ 2048pt."})$;\5
+\\{put\_get\_error};\6
+\&{if} $\\{internal}[\|m]>0$ \1\&{then}\5
+$\\{tfm\_check}\K\\{fraction\_half}-1$\6
+\4\&{else} $\\{tfm\_check}\K1-\\{fraction\_half}$;\2\6
+\&{end}\6
+\4\&{else} $\\{tfm\_check}\K\\{internal}[\|m]$;\2\6
+\&{end};\par
+\U1070.\fi
+
+\M1099. \P$\X1099:Store the width information for character code~\|c\X\S$\6
+\&{if} $\|c<\\{bc}$ \1\&{then}\5
+$\\{bc}\K\|c$;\2\6
+\&{if} $\|c>\\{ec}$ \1\&{then}\5
+$\\{ec}\K\|c$;\2\6
+$\\{char\_exists}[\|c]\K\\{true}$;\5
+$\\{gf\_dx}[\|c]\K\\{internal}[\\{char\_dx}]$;\5
+$\\{gf\_dy}[\|c]\K\\{internal}[\\{char\_dy}]$;\5
+$\\{tfm\_width}[\|c]\K\\{tfm\_check}(\\{char\_wd})$;\5
+$\\{tfm\_height}[\|c]\K\\{tfm\_check}(\\{char\_ht})$;\5
+$\\{tfm\_depth}[\|c]\K\\{tfm\_check}(\\{char\_dp})$;\5
+$\\{tfm\_ital\_corr}[\|c]\K\\{tfm\_check}(\\{char\_ic})$\par
+\U1070.\fi
+
+\M1100. Now let's consider \MF's special \.{TFM}-oriented commands.
+
+\Y\P$\4\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{tfm\_command}: \37\\{do\_tfm\_command};\par
+\fi
+
+\M1101. \P\D \37$\\{char\_list\_code}=0$\par
+\P\D \37$\\{lig\_table\_code}=1$\par
+\P\D \37$\\{extensible\_code}=2$\par
+\P\D \37$\\{header\_byte\_code}=3$\par
+\P\D \37$\\{font\_dimen\_code}=4$\par
+\Y\P$\4\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}\S$\6
+$\\{primitive}(\.{"charlist"},\39\\{tfm\_command},\39\\{char\_list\_code})$;\6
+$\\{primitive}(\.{"ligtable"},\39\\{tfm\_command},\39\\{lig\_table\_code})$;\6
+$\\{primitive}(\.{"extensible"},\39\\{tfm\_command},\39\\{extensible\_code})$;\6
+$\\{primitive}(\.{"headerbyte"},\39\\{tfm\_command},\39\\{header\_byte%
+\_code})$;\6
+$\\{primitive}(\.{"fontdimen"},\39\\{tfm\_command},\39\\{font\_dimen\_code})$;%
+\par
+\fi
+
+\M1102. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{tfm\_command}: \37\&{case} $\|m$ \1\&{of}\6
+\4\\{char\_list\_code}: \37$\\{print}(\.{"charlist"})$;\6
+\4\\{lig\_table\_code}: \37$\\{print}(\.{"ligtable"})$;\6
+\4\\{extensible\_code}: \37$\\{print}(\.{"extensible"})$;\6
+\4\\{header\_byte\_code}: \37$\\{print}(\.{"headerbyte"})$;\6
+\4\&{othercases} \37$\\{print}(\.{"fontdimen"})$\2\6
+\&{endcases};\par
+\fi
+
+\M1103. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{function}\1\ \37\\{get\_code}: \37\\{eight\_bits};\C{scans a character
+code value}\6
+\4\&{label} \37\\{found};\6
+\4\&{var} \37\|c: \37\\{integer};\C{the code value found}\2\6
+\&{begin} \37\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}=\\{known}$ \1\&{then}\6
+\&{begin} \37$\|c\K\\{round\_unscaled}(\\{cur\_exp})$;\6
+\&{if} $\|c\G0$ \1\&{then}\6
+\&{if} $\|c<256$ \1\&{then}\5
+\&{goto} \37\\{found};\2\2\6
+\&{end}\6
+\4\&{else} \&{if} $\\{cur\_type}=\\{string\_type}$ \1\&{then}\6
+\&{if} $\\{length}(\\{cur\_exp})=1$ \1\&{then}\6
+\&{begin} \37$\|c\K\\{so}(\\{str\_pool}[\\{str\_start}[\\{cur\_exp}]])$;\5
+\&{goto} \37\\{found};\6
+\&{end};\2\2\2\6
+$\\{exp\_err}(\.{"Invalid\ code\ has\ been\ replaced\ by\ 0"})$;\5
+$\\{help2}(\.{"I\ was\ looking\ for\ a\ number\ between\ 0\ and\ 255,\ or\ for\
+a"})$\6
+$(\.{"string\ of\ length\ 1.\ Didn\'t\ find\ it;\ will\ use\ 0\ instead."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\5
+$\|c\K0$;\6
+\4\\{found}: \37$\\{get\_code}\K\|c$;\6
+\&{end};\par
+\fi
+
+\M1104. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{set\_tag}(\|c:\\{halfword};\,\35\|t:\\{small%
+\_number};\,\35\|r:\\{halfword})$;\2\6
+\&{begin} \37\&{if} $\\{char\_tag}[\|c]=\\{no\_tag}$ \1\&{then}\6
+\&{begin} \37$\\{char\_tag}[\|c]\K\|t$;\5
+$\\{char\_remainder}[\|c]\K\|r$;\6
+\&{if} $\|t=\\{lig\_tag}$ \1\&{then}\6
+\&{begin} \37$\\{incr}(\\{label\_ptr})$;\5
+$\\{label\_loc}[\\{label\_ptr}]\K\|r$;\5
+$\\{label\_char}[\\{label\_ptr}]\K\|c$;\6
+\&{end};\2\6
+\&{end}\6
+\4\&{else} \X1105:Complain about a character tag conflict\X;\2\6
+\&{end};\par
+\fi
+
+\M1105. \P$\X1105:Complain about a character tag conflict\X\S$\6
+\&{begin} \37$\\{print\_err}(\.{"Character\ "})$;\6
+\&{if} $(\|c>\.{"\ "})\W(\|c<127)$ \1\&{then}\5
+$\\{print}(\|c)$\6
+\4\&{else} \&{if} $\|c=256$ \1\&{then}\5
+$\\{print}(\.{"||"})$\6
+\4\&{else} \&{begin} \37$\\{print}(\.{"code\ "})$;\5
+$\\{print\_int}(\|c)$;\6
+\&{end};\2\2\6
+$\\{print}(\.{"\ is\ already\ "})$;\6
+\&{case} $\\{char\_tag}[\|c]$ \1\&{of}\6
+\4\\{lig\_tag}: \37$\\{print}(\.{"in\ a\ ligtable"})$;\6
+\4\\{list\_tag}: \37$\\{print}(\.{"in\ a\ charlist"})$;\6
+\4\\{ext\_tag}: \37$\\{print}(\.{"extensible"})$;\2\6
+\&{end};\C{there are no other cases}\6
+$\\{help2}(\.{"It\'s\ not\ legal\ to\ label\ a\ character\ more\ than\
+once."})$\6
+$(\.{"So\ I\'ll\ not\ change\ anything\ just\ now."})$;\5
+\\{put\_get\_error};\6
+\&{end}\par
+\U1104.\fi
+
+\M1106. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_tfm\_command};\6
+\4\&{label} \37$\\{continue},\39\\{done}$;\6
+\4\&{var} \37$\|c,\39\\{cc}$: \37$0\to256$;\C{character codes}\6
+\|k: \37$0\to\\{max\_kerns}$;\C{index into the \\{kern} array}\6
+\|j: \37\\{integer};\C{index into \\{header\_byte} or \\{param}}\2\6
+\&{begin} \37\&{case} $\\{cur\_mod}$ \1\&{of}\6
+\4\\{char\_list\_code}: \37\&{begin} \37$\|c\K\\{get\_code}$;\C{we will store a
+list of character successors}\6
+\&{while} $\\{cur\_cmd}=\\{colon}$ \1\&{do}\6
+\&{begin} \37$\\{cc}\K\\{get\_code}$;\5
+$\\{set\_tag}(\|c,\39\\{list\_tag},\39\\{cc})$;\5
+$\|c\K\\{cc}$;\6
+\&{end};\2\6
+\&{end};\6
+\4\\{lig\_table\_code}: \37\X1107:Store a list of ligature/kern steps\X;\6
+\4\\{extensible\_code}: \37\X1113:Define an extensible recipe\X;\6
+\4$\\{header\_byte\_code},\39\\{font\_dimen\_code}$: \37\&{begin} \37$\|c\K%
+\\{cur\_mod}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $(\\{cur\_type}\I\\{known})\V(\\{cur\_exp}<\\{half\_unit})$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ location"})$;\5
+$\\{help2}(\.{"I\ was\ looking\ for\ a\ known,\ positive\ number."})$\6
+$(\.{"For\ safety\'s\ sake\ I\'ll\ ignore\ the\ present\ command."})$;\5
+\\{put\_get\_error};\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\|j\K\\{round\_unscaled}(\\{cur\_exp})$;\6
+\&{if} $\\{cur\_cmd}\I\\{colon}$ \1\&{then}\6
+\&{begin} \37$\\{missing\_err}(\.{":"})$;\5
+$\\{help1}(\.{"A\ colon\ should\ follow\ a\ headerbyte\ or\ fontinfo\
+location."})$;\5
+\\{back\_error};\6
+\&{end};\2\6
+\&{if} $\|c=\\{header\_byte\_code}$ \1\&{then}\5
+\X1114:Store a list of header bytes\X\6
+\4\&{else} \X1115:Store a list of font dimensions\X;\2\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\C{there are no other cases}\6
+\&{end};\par
+\fi
+
+\M1107. \P$\X1107:Store a list of ligature/kern steps\X\S$\6
+\&{begin} \37$\\{lk\_started}\K\\{false}$;\6
+\4\\{continue}: \37\\{get\_x\_next};\6
+\&{if} $(\\{cur\_cmd}=\\{skip\_to})\W\\{lk\_started}$ \1\&{then}\5
+\X1110:Process a \\{skip\_to} command and \&{goto} \\{done}\X;\2\6
+\&{if} $\\{cur\_cmd}=\\{bchar\_label}$ \1\&{then}\6
+\&{begin} \37$\|c\K256$;\5
+$\\{cur\_cmd}\K\\{colon}$;\ \&{end}\6
+\4\&{else} \&{begin} \37\\{back\_input};\5
+$\|c\K\\{get\_code}$;\ \&{end};\2\6
+\&{if} $(\\{cur\_cmd}=\\{colon})\V(\\{cur\_cmd}=\\{double\_colon})$ \1\&{then}\5
+\X1111:Record a label in a lig/kern subprogram and \&{goto} \\{continue}\X;\2\6
+\&{if} $\\{cur\_cmd}=\\{lig\_kern\_token}$ \1\&{then}\5
+\X1112:Compile a ligature/kern command\X\6
+\4\&{else} \&{begin} \37$\\{print\_err}(\.{"Illegal\ ligtable\ step"})$;\5
+$\\{help1}(\.{"I\ was\ looking\ for\ \`=:\'\ or\ \`kern\'\ here."})$;\5
+\\{back\_error};\5
+$\\{next\_char}(\\{nl})\K\\{qi}(0)$;\5
+$\\{op\_byte}(\\{nl})\K\\{qi}(0)$;\5
+$\\{rem\_byte}(\\{nl})\K\\{qi}(0)$;\6
+$\\{skip\_byte}(\\{nl})\K\\{stop\_flag}+1$;\C{this specifies an unconditional
+stop}\6
+\&{end};\2\6
+\&{if} $\\{nl}=\\{lig\_table\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"ligtable\ size"},\39\\{lig\_table\_size})$;\2\6
+$\\{incr}(\\{nl})$;\6
+\&{if} $\\{cur\_cmd}=\\{comma}$ \1\&{then}\5
+\&{goto} \37\\{continue};\2\6
+\&{if} $\\{skip\_byte}(\\{nl}-1)<\\{stop\_flag}$ \1\&{then}\5
+$\\{skip\_byte}(\\{nl}-1)\K\\{stop\_flag}$;\2\6
+\4\\{done}: \37\&{end}\par
+\U1106.\fi
+
+\M1108. \P$\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}%
+\S$\6
+$\\{primitive}(\.{"=:"},\39\\{lig\_kern\_token},\390)$;\5
+$\\{primitive}(\.{"=:|"},\39\\{lig\_kern\_token},\391)$;\5
+$\\{primitive}(\.{"=:|>"},\39\\{lig\_kern\_token},\395)$;\5
+$\\{primitive}(\.{"|=:"},\39\\{lig\_kern\_token},\392)$;\5
+$\\{primitive}(\.{"|=:>"},\39\\{lig\_kern\_token},\396)$;\5
+$\\{primitive}(\.{"|=:|"},\39\\{lig\_kern\_token},\393)$;\5
+$\\{primitive}(\.{"|=:|>"},\39\\{lig\_kern\_token},\397)$;\5
+$\\{primitive}(\.{"|=:|>>"},\39\\{lig\_kern\_token},\3911)$;\5
+$\\{primitive}(\.{"kern"},\39\\{lig\_kern\_token},\39128)$;\par
+\fi
+
+\M1109. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{lig\_kern\_token}: \37\&{case} $\|m$ \1\&{of}\6
+\40: \37$\\{print}(\.{"=:"})$;\6
+\41: \37$\\{print}(\.{"=:|"})$;\6
+\42: \37$\\{print}(\.{"|=:"})$;\6
+\43: \37$\\{print}(\.{"|=:|"})$;\6
+\45: \37$\\{print}(\.{"=:|>"})$;\6
+\46: \37$\\{print}(\.{"|=:>"})$;\6
+\47: \37$\\{print}(\.{"|=:|>"})$;\6
+\411: \37$\\{print}(\.{"|=:|>>"})$;\6
+\4\&{othercases} \37$\\{print}(\.{"kern"})$\2\6
+\&{endcases};\par
+\fi
+
+\M1110. Local labels are implemented by maintaining the \\{skip\_table} array,
+where $\\{skip\_table}[\|c]$ is either \\{undefined\_label} or the address of
+the
+most recent lig/kern instruction that skips to local label~\|c. In the
+latter case, the \\{skip\_byte} in that instruction will (temporarily)
+be zero if there were no prior skips to this label, or it will be the
+distance to the prior skip.
+
+We may need to cancel skips that span more than 127 lig/kern steps.
+
+\Y\P\D \37$\\{cancel\_skips}(\#)\S\\{ll}\K\#$;\6
+\1\&{repeat} \37$\\{lll}\K\\{qo}(\\{skip\_byte}(\\{ll}))$;\5
+$\\{skip\_byte}(\\{ll})\K\\{stop\_flag}$;\5
+$\\{ll}\K\\{ll}-\\{lll}$;\6
+\4\&{until}\5
+$\\{lll}=0$\2\par
+\P\D \37$\\{skip\_error}(\#)\S$\1\6
+\&{begin} \37$\\{print\_err}(\.{"Too\ far\ to\ skip"})$;\5
+$\\{help1}(\.{"At\ most\ 127\ lig/kern\ steps\ can\ separate\ skipto1\ from\
+1::."})$;\5
+\\{error};\5
+$\\{cancel\_skips}(\#)$;\6
+\&{end}\2\par
+\Y\P$\4\X1110:Process a \\{skip\_to} command and \&{goto} \\{done}\X\S$\6
+\&{begin} \37$\|c\K\\{get\_code}$;\6
+\&{if} $\\{nl}-\\{skip\_table}[\|c]>128$ \1\&{then}\C{$\\{skip\_table}[\|c]<<%
+\\{nl}\L\\{undefined\_label}$}\6
+\&{begin} \37$\\{skip\_error}(\\{skip\_table}[\|c])$;\5
+$\\{skip\_table}[\|c]\K\\{undefined\_label}$;\6
+\&{end};\2\6
+\&{if} $\\{skip\_table}[\|c]=\\{undefined\_label}$ \1\&{then}\5
+$\\{skip\_byte}(\\{nl}-1)\K\\{qi}(0)$\6
+\4\&{else} $\\{skip\_byte}(\\{nl}-1)\K\\{qi}(\\{nl}-\\{skip\_table}[\|c]-1)$;\2%
+\6
+$\\{skip\_table}[\|c]\K\\{nl}-1$;\5
+\&{goto} \37\\{done};\6
+\&{end}\par
+\U1107.\fi
+
+\M1111. \P$\X1111:Record a label in a lig/kern subprogram and \&{goto} %
+\\{continue}\X\S$\6
+\&{begin} \37\&{if} $\\{cur\_cmd}=\\{colon}$ \1\&{then}\6
+\&{if} $\|c=256$ \1\&{then}\5
+$\\{bch\_label}\K\\{nl}$\6
+\4\&{else} $\\{set\_tag}(\|c,\39\\{lig\_tag},\39\\{nl})$\2\6
+\4\&{else} \&{if} $\\{skip\_table}[\|c]<\\{undefined\_label}$ \1\&{then}\6
+\&{begin} \37$\\{ll}\K\\{skip\_table}[\|c]$;\5
+$\\{skip\_table}[\|c]\K\\{undefined\_label}$;\6
+\1\&{repeat} \37$\\{lll}\K\\{qo}(\\{skip\_byte}(\\{ll}))$;\6
+\&{if} $\\{nl}-\\{ll}>128$ \1\&{then}\6
+\&{begin} \37$\\{skip\_error}(\\{ll})$;\5
+\&{goto} \37\\{continue};\6
+\&{end};\2\6
+$\\{skip\_byte}(\\{ll})\K\\{qi}(\\{nl}-\\{ll}-1)$;\5
+$\\{ll}\K\\{ll}-\\{lll}$;\6
+\4\&{until}\5
+$\\{lll}=0$;\2\6
+\&{end};\2\2\6
+\&{goto} \37\\{continue};\6
+\&{end}\par
+\U1107.\fi
+
+\M1112. \P$\X1112:Compile a ligature/kern command\X\S$\6
+\&{begin} \37$\\{next\_char}(\\{nl})\K\\{qi}(\|c)$;\5
+$\\{skip\_byte}(\\{nl})\K\\{qi}(0)$;\6
+\&{if} $\\{cur\_mod}<128$ \1\&{then}\C{ligature op}\6
+\&{begin} \37$\\{op\_byte}(\\{nl})\K\\{qi}(\\{cur\_mod})$;\5
+$\\{rem\_byte}(\\{nl})\K\\{qi}(\\{get\_code})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ kern"})$;\5
+$\\{help2}(\.{"The\ amount\ of\ kern\ should\ be\ a\ known\ numeric\ value."})$%
+\6
+$(\.{"I\'m\ zeroing\ this\ one.\ Proceed,\ with\ fingers\ crossed."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end};\2\6
+$\\{kern}[\\{nk}]\K\\{cur\_exp}$;\5
+$\|k\K0$;\ \&{while} $\\{kern}[\|k]\I\\{cur\_exp}$ \1\&{do}\5
+$\\{incr}(\|k)$;\2\6
+\&{if} $\|k=\\{nk}$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{nk}=\\{max\_kerns}$ \1\&{then}\5
+$\\{overflow}(\.{"kern"},\39\\{max\_kerns})$;\2\6
+$\\{incr}(\\{nk})$;\6
+\&{end};\2\6
+$\\{op\_byte}(\\{nl})\K\\{kern\_flag}+(\|k\mathbin{\&{div}}256)$;\5
+$\\{rem\_byte}(\\{nl})\K\\{qi}((\|k\mathbin{\&{mod}}256))$;\6
+\&{end};\2\6
+$\\{lk\_started}\K\\{true}$;\6
+\&{end}\par
+\U1107.\fi
+
+\M1113. \P\D \37$\\{missing\_extensible\_punctuation}(\#)\S$\1\6
+\&{begin} \37$\\{missing\_err}(\#)$;\5
+$\\{help1}(\.{"I\'m\ processing\ \`extensible\ c:\ t,m,b,r\'."})$;\5
+\\{back\_error};\6
+\&{end}\2\par
+\Y\P$\4\X1113:Define an extensible recipe\X\S$\6
+\&{begin} \37\&{if} $\\{ne}=256$ \1\&{then}\5
+$\\{overflow}(\.{"extensible"},\39256)$;\2\6
+$\|c\K\\{get\_code}$;\5
+$\\{set\_tag}(\|c,\39\\{ext\_tag},\39\\{ne})$;\6
+\&{if} $\\{cur\_cmd}\I\\{colon}$ \1\&{then}\5
+$\\{missing\_extensible\_punctuation}(\.{":"})$;\2\6
+$\\{ext\_top}(\\{ne})\K\\{qi}(\\{get\_code})$;\6
+\&{if} $\\{cur\_cmd}\I\\{comma}$ \1\&{then}\5
+$\\{missing\_extensible\_punctuation}(\.{","})$;\2\6
+$\\{ext\_mid}(\\{ne})\K\\{qi}(\\{get\_code})$;\6
+\&{if} $\\{cur\_cmd}\I\\{comma}$ \1\&{then}\5
+$\\{missing\_extensible\_punctuation}(\.{","})$;\2\6
+$\\{ext\_bot}(\\{ne})\K\\{qi}(\\{get\_code})$;\6
+\&{if} $\\{cur\_cmd}\I\\{comma}$ \1\&{then}\5
+$\\{missing\_extensible\_punctuation}(\.{","})$;\2\6
+$\\{ext\_rep}(\\{ne})\K\\{qi}(\\{get\_code})$;\5
+$\\{incr}(\\{ne})$;\6
+\&{end}\par
+\U1106.\fi
+
+\M1114. \P$\X1114:Store a list of header bytes\X\S$\6
+\1\&{repeat} \37\&{if} $\|j>\\{header\_size}$ \1\&{then}\5
+$\\{overflow}(\.{"headerbyte"},\39\\{header\_size})$;\2\6
+$\\{header\_byte}[\|j]\K\\{get\_code}$;\5
+$\\{incr}(\|j)$;\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$\2\par
+\U1106.\fi
+
+\M1115. \P$\X1115:Store a list of font dimensions\X\S$\6
+\1\&{repeat} \37\&{if} $\|j>\\{max\_font\_dimen}$ \1\&{then}\5
+$\\{overflow}(\.{"fontdimen"},\39\\{max\_font\_dimen})$;\2\6
+\&{while} $\|j>\\{np}$ \1\&{do}\6
+\&{begin} \37$\\{incr}(\\{np})$;\5
+$\\{param}[\\{np}]\K0$;\6
+\&{end};\2\6
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{cur\_type}\I\\{known}$ \1\&{then}\6
+\&{begin} \37$\\{exp\_err}(\.{"Improper\ font\ parameter"})$;\5
+$\\{help1}(\.{"I\'m\ zeroing\ this\ one.\ Proceed,\ with\ fingers\
+crossed."})$;\5
+$\\{put\_get\_flush\_error}(0)$;\6
+\&{end};\2\6
+$\\{param}[\|j]\K\\{cur\_exp}$;\5
+$\\{incr}(\|j)$;\6
+\4\&{until}\5
+$\\{cur\_cmd}\I\\{comma}$\2\par
+\U1106.\fi
+
+\M1116. OK: We've stored all the data that is needed for the \.{TFM} file.
+All that remains is to output it in the correct format.
+
+An interesting problem needs to be solved in this connection, because
+the \.{TFM} format allows at most 256~widths, 16~heights, 16~depths,
+and 64~italic corrections. If the data has more distinct values than
+this, we want to meet the necessary restrictions by perturbing the
+given values as little as possible.
+
+\MF\ solves this problem in two steps. First the values of a given
+kind (widths, heights, depths, or italic corrections) are sorted;
+then the list of sorted values is perturbed, if necessary.
+
+The sorting operation is facilitated by having a special node of
+essentially infinite \\{value} at the end of the current list.
+
+\Y\P$\4\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}\S$\6
+$\\{value}(\\{inf\_val})\K\\{fraction\_four}$;\par
+\fi
+
+\M1117. Straight linear insertion is good enough for sorting, since the lists
+are usually not terribly long. As we work on the data, the current list
+will start at $\\{link}(\\{temp\_head})$ and end at \\{inf\_val}; the nodes in
+this
+list will be in increasing order of their \\{value} fields.
+
+Given such a list, the \\{sort\_in} function takes a value and returns a
+pointer
+to where that value can be found in the list. The value is inserted in
+the proper place, if necessary.
+
+At the time we need to do these operations, most of \MF's work has been
+completed, so we will have plenty of memory to play with. The value nodes
+that are allocated for sorting will never be returned to free storage.
+
+\Y\P\D \37$\\{clear\_the\_list}\S\\{link}(\\{temp\_head})\K\\{inf\_val}$\par
+\Y\P\4\&{function}\1\ \37$\\{sort\_in}(\|v:\\{scaled})$: \37\\{pointer};\6
+\4\&{label} \37\\{found};\6
+\4\&{var} \37$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{list manipulation
+registers}\2\6
+\&{begin} \37$\|p\K\\{temp\_head}$;\6
+\~ \1\&{loop}\ \&{begin} \37$\|q\K\\{link}(\|p)$;\6
+\&{if} $\|v\L\\{value}(\|q)$ \1\&{then}\5
+\&{goto} \37\\{found};\2\6
+$\|p\K\|q$;\6
+\&{end};\2\6
+\4\\{found}: \37\&{if} $\|v<\\{value}(\|q)$ \1\&{then}\6
+\&{begin} \37$\|r\K\\{get\_node}(\\{value\_node\_size})$;\5
+$\\{value}(\|r)\K\|v$;\5
+$\\{link}(\|r)\K\|q$;\5
+$\\{link}(\|p)\K\|r$;\6
+\&{end};\2\6
+$\\{sort\_in}\K\\{link}(\|p)$;\6
+\&{end};\par
+\fi
+
+\M1118. Now we come to the interesting part, where we reduce the list if
+necessary
+until it has the required size. The \\{min\_cover} routine is basic to this
+process; it computes the minimum number~\|m such that the values of the
+current sorted list can be covered by \|m~intervals of width~\|d. It
+also sets the global value \\{perturbation} to the smallest value $d'>d$
+such that the covering found by this algorithm would be different.
+
+In particular, $\\{min\_cover}(0)$ returns the number of distinct values in the
+current list and sets \\{perturbation} to the minimum distance between
+adjacent values.
+
+\Y\P\4\&{function}\1\ \37$\\{min\_cover}(\|d:\\{scaled})$: \37\\{integer};\6
+\4\&{var} \37\|p: \37\\{pointer};\C{runs through the current list}\6
+\|l: \37\\{scaled};\C{the least element covered by the current interval}\6
+\|m: \37\\{integer};\C{lower bound on the size of the minimum cover}\2\6
+\&{begin} \37$\|m\K0$;\5
+$\|p\K\\{link}(\\{temp\_head})$;\5
+$\\{perturbation}\K\\{el\_gordo}$;\6
+\&{while} $\|p\I\\{inf\_val}$ \1\&{do}\6
+\&{begin} \37$\\{incr}(\|m)$;\5
+$\|l\K\\{value}(\|p)$;\6
+\1\&{repeat} \37$\|p\K\\{link}(\|p)$;\6
+\4\&{until}\5
+$\\{value}(\|p)>\|l+\|d$;\2\6
+\&{if} $\\{value}(\|p)-\|l<\\{perturbation}$ \1\&{then}\5
+$\\{perturbation}\K\\{value}(\|p)-\|l$;\2\6
+\&{end};\2\6
+$\\{min\_cover}\K\|m$;\6
+\&{end};\par
+\fi
+
+\M1119. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{perturbation}: \37\\{scaled};\C{quantity related to \.{TFM} rounding}\6
+\4\\{excess}: \37\\{integer};\C{the list is this much too long}\par
+\fi
+
+\M1120. The smallest \|d such that a given list can be covered with \|m
+intervals
+is determined by the \\{threshold} routine, which is sort of an inverse
+to \\{min\_cover}. The idea is to increase the interval size rapidly until
+finding the range, then to go sequentially until the exact borderline has
+been discovered.
+
+\Y\P\4\&{function}\1\ \37$\\{threshold}(\|m:\\{integer})$: \37\\{scaled};\6
+\4\&{var} \37\|d: \37\\{scaled};\C{lower bound on the smallest interval size}\2%
+\6
+\&{begin} \37$\\{excess}\K\\{min\_cover}(0)-\|m$;\6
+\&{if} $\\{excess}\L0$ \1\&{then}\5
+$\\{threshold}\K0$\6
+\4\&{else} \&{begin} \37\1\&{repeat} \37$\|d\K\\{perturbation}$;\6
+\4\&{until}\5
+$\\{min\_cover}(\|d+\|d)\L\|m$;\2\6
+\&{while} $\\{min\_cover}(\|d)>\|m$ \1\&{do}\5
+$\|d\K\\{perturbation}$;\2\6
+$\\{threshold}\K\|d$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M1121. The \\{skimp} procedure reduces the current list to at most \|m
+entries,
+by changing values if necessary. It also sets $\\{info}(\|p)\K\|k$ if $%
+\\{value}(\|p)$
+is the \|kth distinct value on the resulting list, and it sets
+\\{perturbation} to the maximum amount by which a \\{value} field has
+been changed. The size of the resulting list is returned as the
+value of \\{skimp}.
+
+\Y\P\4\&{function}\1\ \37$\\{skimp}(\|m:\\{integer})$: \37\\{integer};\6
+\4\&{var} \37\|d: \37\\{scaled};\C{the size of intervals being coalesced}\6
+$\|p,\39\|q,\39\|r$: \37\\{pointer};\C{list manipulation registers}\6
+\|l: \37\\{scaled};\C{the least value in the current interval}\6
+\|v: \37\\{scaled};\C{a compromise value}\2\6
+\&{begin} \37$\|d\K\\{threshold}(\|m)$;\5
+$\\{perturbation}\K0$;\5
+$\|q\K\\{temp\_head}$;\5
+$\|m\K0$;\5
+$\|p\K\\{link}(\\{temp\_head})$;\6
+\&{while} $\|p\I\\{inf\_val}$ \1\&{do}\6
+\&{begin} \37$\\{incr}(\|m)$;\5
+$\|l\K\\{value}(\|p)$;\5
+$\\{info}(\|p)\K\|m$;\6
+\&{if} $\\{value}(\\{link}(\|p))\L\|l+\|d$ \1\&{then}\5
+\X1122:Replace an interval of values by its midpoint\X;\2\6
+$\|q\K\|p$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\\{skimp}\K\|m$;\6
+\&{end};\par
+\fi
+
+\M1122. \P$\X1122:Replace an interval of values by its midpoint\X\S$\6
+\&{begin} \37\1\&{repeat} \37$\|p\K\\{link}(\|p)$;\5
+$\\{info}(\|p)\K\|m$;\5
+$\\{decr}(\\{excess})$;\ \&{if} $\\{excess}=0$ \1\&{then}\5
+$\|d\K0$;\2\6
+\4\&{until}\5
+$\\{value}(\\{link}(\|p))>\|l+\|d$;\2\6
+$\|v\K\|l+\\{half}(\\{value}(\|p)-\|l)$;\6
+\&{if} $\\{value}(\|p)-\|v>\\{perturbation}$ \1\&{then}\5
+$\\{perturbation}\K\\{value}(\|p)-\|v$;\2\6
+$\|r\K\|q$;\6
+\1\&{repeat} \37$\|r\K\\{link}(\|r)$;\5
+$\\{value}(\|r)\K\|v$;\6
+\4\&{until}\5
+$\|r=\|p$;\2\6
+$\\{link}(\|q)\K\|p$;\C{remove duplicate values from the current list}\6
+\&{end}\par
+\U1121.\fi
+
+\M1123. A warning message is issued whenever something is perturbed by
+more than 1/16\thinspace pt.
+
+\Y\P\4\&{procedure}\1\ \37$\\{tfm\_warning}(\|m:\\{small\_number})$;\2\6
+\&{begin} \37$\\{print\_nl}(\.{"(some\ "})$;\5
+$\\{print}(\\{int\_name}[\|m])$;\5
+$\\{print}(\.{"\ values\ had\ to\ be\ adjusted\ by\ as\ much\ as\ "})$;\5
+$\\{print\_scaled}(\\{perturbation})$;\5
+$\\{print}(\.{"pt)"})$;\6
+\&{end};\par
+\fi
+
+\M1124. Here's an example of how we use these routines.
+The width data needs to be perturbed only if there are 256 distinct
+widths, but \MF\ must check for this case even though it is
+highly unusual.
+
+An integer variable \|k will be defined when we use this code.
+The \\{dimen\_head} array will contain pointers to the sorted
+lists of dimensions.
+
+\Y\P$\4\X1124:Massage the \.{TFM} widths\X\S$\6
+\\{clear\_the\_list};\6
+\&{for} $\|k\K\\{bc}\mathrel{\&{to}}\\{ec}$ \1\&{do}\6
+\&{if} $\\{char\_exists}[\|k]$ \1\&{then}\5
+$\\{tfm\_width}[\|k]\K\\{sort\_in}(\\{tfm\_width}[\|k])$;\2\2\6
+$\\{nw}\K\\{skimp}(255)+1$;\5
+$\\{dimen\_head}[1]\K\\{link}(\\{temp\_head})$;\6
+\&{if} $\\{perturbation}\G\O{10000}$ \1\&{then}\5
+$\\{tfm\_warning}(\\{char\_wd})$\2\par
+\U1206.\fi
+
+\M1125. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{dimen\_head}: \37\&{array} $[1\to4]$ \1\&{of}\5
+\\{pointer};\C{lists of \.{TFM} dimensions}\2\par
+\fi
+
+\M1126. Heights, depths, and italic corrections are different from widths
+not only because their list length is more severely restricted, but
+also because zero values do not need to be put into the lists.
+
+\Y\P$\4\X1126:Massage the \.{TFM} heights, depths, and italic corrections\X\S$\6
+\\{clear\_the\_list};\6
+\&{for} $\|k\K\\{bc}\mathrel{\&{to}}\\{ec}$ \1\&{do}\6
+\&{if} $\\{char\_exists}[\|k]$ \1\&{then}\6
+\&{if} $\\{tfm\_height}[\|k]=0$ \1\&{then}\5
+$\\{tfm\_height}[\|k]\K\\{zero\_val}$\6
+\4\&{else} $\\{tfm\_height}[\|k]\K\\{sort\_in}(\\{tfm\_height}[\|k])$;\2\2\2\6
+$\\{nh}\K\\{skimp}(15)+1$;\5
+$\\{dimen\_head}[2]\K\\{link}(\\{temp\_head})$;\6
+\&{if} $\\{perturbation}\G\O{10000}$ \1\&{then}\5
+$\\{tfm\_warning}(\\{char\_ht})$;\2\6
+\\{clear\_the\_list};\6
+\&{for} $\|k\K\\{bc}\mathrel{\&{to}}\\{ec}$ \1\&{do}\6
+\&{if} $\\{char\_exists}[\|k]$ \1\&{then}\6
+\&{if} $\\{tfm\_depth}[\|k]=0$ \1\&{then}\5
+$\\{tfm\_depth}[\|k]\K\\{zero\_val}$\6
+\4\&{else} $\\{tfm\_depth}[\|k]\K\\{sort\_in}(\\{tfm\_depth}[\|k])$;\2\2\2\6
+$\\{nd}\K\\{skimp}(15)+1$;\5
+$\\{dimen\_head}[3]\K\\{link}(\\{temp\_head})$;\6
+\&{if} $\\{perturbation}\G\O{10000}$ \1\&{then}\5
+$\\{tfm\_warning}(\\{char\_dp})$;\2\6
+\\{clear\_the\_list};\6
+\&{for} $\|k\K\\{bc}\mathrel{\&{to}}\\{ec}$ \1\&{do}\6
+\&{if} $\\{char\_exists}[\|k]$ \1\&{then}\6
+\&{if} $\\{tfm\_ital\_corr}[\|k]=0$ \1\&{then}\5
+$\\{tfm\_ital\_corr}[\|k]\K\\{zero\_val}$\6
+\4\&{else} $\\{tfm\_ital\_corr}[\|k]\K\\{sort\_in}(\\{tfm\_ital\_corr}[\|k])$;%
+\2\2\2\6
+$\\{ni}\K\\{skimp}(63)+1$;\5
+$\\{dimen\_head}[4]\K\\{link}(\\{temp\_head})$;\6
+\&{if} $\\{perturbation}\G\O{10000}$ \1\&{then}\5
+$\\{tfm\_warning}(\\{char\_ic})$\2\par
+\U1206.\fi
+
+\M1127. \P$\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}%
+\S$\6
+$\\{value}(\\{zero\_val})\K0$;\5
+$\\{info}(\\{zero\_val})\K0$;\par
+\fi
+
+\M1128. Bytes 5--8 of the header are set to the design size, unless the user
+has
+some crazy reason for specifying them differently.
+
+Error messages are not allowed at the time this procedure is called,
+so a warning is printed instead.
+
+The value of \\{max\_tfm\_dimen} is calculated so that
+$$\hbox{$\\{make\_scaled}(16\ast\\{max\_tfm\_dimen},\\{internal}[\\{design%
+\_size}])$}
+< \\{three\_bytes}.$$
+
+\Y\P\D \37$\\{three\_bytes}\S\O{100000000}$\C{$2^{24}$}\par
+\Y\P\4\&{procedure}\1\ \37\\{fix\_design\_size};\6
+\4\&{var} \37\|d: \37\\{scaled};\C{the design size}\2\6
+\&{begin} \37$\|d\K\\{internal}[\\{design\_size}]$;\6
+\&{if} $(\|d<\\{unity})\V(\|d\G\\{fraction\_half})$ \1\&{then}\6
+\&{begin} \37\&{if} $\|d\I0$ \1\&{then}\5
+$\\{print\_nl}(\.{"(illegal\ design\ size\ has\ been\ changed\ to\ 128pt)"})$;%
+\2\6
+$\|d\K\O{40000000}$;\5
+$\\{internal}[\\{design\_size}]\K\|d$;\6
+\&{end};\2\6
+\&{if} $\\{header\_byte}[5]<0$ \1\&{then}\6
+\&{if} $\\{header\_byte}[6]<0$ \1\&{then}\6
+\&{if} $\\{header\_byte}[7]<0$ \1\&{then}\6
+\&{if} $\\{header\_byte}[8]<0$ \1\&{then}\6
+\&{begin} \37$\\{header\_byte}[5]\K\|d\mathbin{\&{div}}\O{4000000}$;\5
+$\\{header\_byte}[6]\K(\|d\mathbin{\&{div}}4096)\mathbin{\&{mod}}256$;\5
+$\\{header\_byte}[7]\K(\|d\mathbin{\&{div}}16)\mathbin{\&{mod}}256$;\5
+$\\{header\_byte}[8]\K(\|d\mathbin{\&{mod}}16)\ast16$;\6
+\&{end};\2\2\2\2\6
+$\\{max\_tfm\_dimen}\K16\ast\\{internal}[\\{design\_size}]-\\{internal}[%
+\\{design\_size}]\mathbin{\&{div}}\O{10000000}$;\6
+\&{if} $\\{max\_tfm\_dimen}\G\\{fraction\_half}$ \1\&{then}\5
+$\\{max\_tfm\_dimen}\K\\{fraction\_half}-1$;\2\6
+\&{end};\par
+\fi
+
+\M1129. The \\{dimen\_out} procedure computes a \\{fix\_word} relative to the
+design size. If the data was out of range, it is corrected and the
+global variable \\{tfm\_changed} is increased by~one.
+
+\Y\P\4\&{function}\1\ \37$\\{dimen\_out}(\|x:\\{scaled})$: \37\\{integer};\2\6
+\&{begin} \37\&{if} $\\{abs}(\|x)>\\{max\_tfm\_dimen}$ \1\&{then}\6
+\&{begin} \37$\\{incr}(\\{tfm\_changed})$;\6
+\&{if} $\|x>0$ \1\&{then}\5
+$\|x\K\\{three\_bytes}-1$\ \&{else} $\|x\K1-\\{three\_bytes}$;\2\6
+\&{end}\6
+\4\&{else} $\|x\K\\{make\_scaled}(\|x\ast16,\39\\{internal}[\\{design%
+\_size}])$;\2\6
+$\\{dimen\_out}\K\|x$;\6
+\&{end};\par
+\fi
+
+\M1130. \P$\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{max\_tfm\_dimen}: \37\\{scaled};\C{bound on widths, heights, kerns, etc.}\6
+\4\\{tfm\_changed}: \37\\{integer};\C{the number of data entries that were out
+of bounds}\par
+\fi
+
+\M1131. If the user has not specified any of the first four header bytes,
+the \\{fix\_check\_sum} procedure replaces them by a ``check sum'' computed
+from the \\{tfm\_width} data relative to the design size.
+
+\Y\P\4\&{procedure}\1\ \37\\{fix\_check\_sum};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|k: \37\\{eight\_bits};\C{runs through character codes}\6
+$\\{b1},\39\\{b2},\39\\{b3},\39\\{b4}$: \37\\{eight\_bits};\C{bytes of the
+check sum}\6
+\|x: \37\\{integer};\C{hash value used in check sum computation}\2\6
+\&{begin} \37\&{if} $\\{header\_byte}[1]<0$ \1\&{then}\6
+\&{if} $\\{header\_byte}[2]<0$ \1\&{then}\6
+\&{if} $\\{header\_byte}[3]<0$ \1\&{then}\6
+\&{if} $\\{header\_byte}[4]<0$ \1\&{then}\6
+\&{begin} \37\X1132:Compute a check sum in $(\\{b1},\\{b2},\\{b3},\\{b4})$\X;\6
+$\\{header\_byte}[1]\K\\{b1}$;\5
+$\\{header\_byte}[2]\K\\{b2}$;\5
+$\\{header\_byte}[3]\K\\{b3}$;\5
+$\\{header\_byte}[4]\K\\{b4}$;\5
+\&{return};\6
+\&{end};\2\2\2\2\6
+\&{for} $\|k\K1\mathrel{\&{to}}4$ \1\&{do}\6
+\&{if} $\\{header\_byte}[\|k]<0$ \1\&{then}\5
+$\\{header\_byte}[\|k]\K0$;\2\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M1132. \P$\X1132:Compute a check sum in $(\\{b1},\\{b2},\\{b3},\\{b4})$\X\S$\6
+$\\{b1}\K\\{bc}$;\5
+$\\{b2}\K\\{ec}$;\5
+$\\{b3}\K\\{bc}$;\5
+$\\{b4}\K\\{ec}$;\5
+$\\{tfm\_changed}\K0$;\6
+\&{for} $\|k\K\\{bc}\mathrel{\&{to}}\\{ec}$ \1\&{do}\6
+\&{if} $\\{char\_exists}[\|k]$ \1\&{then}\6
+\&{begin} \37$\|x\K\\{dimen\_out}(\\{value}(\\{tfm\_width}[\|k]))+(\|k+4)\ast%
+\O{20000000}$;\C{this is positive}\6
+$\\{b1}\K(\\{b1}+\\{b1}+\|x)\mathbin{\&{mod}}255$;\5
+$\\{b2}\K(\\{b2}+\\{b2}+\|x)\mathbin{\&{mod}}253$;\5
+$\\{b3}\K(\\{b3}+\\{b3}+\|x)\mathbin{\&{mod}}251$;\5
+$\\{b4}\K(\\{b4}+\\{b4}+\|x)\mathbin{\&{mod}}247$;\6
+\&{end}\2\2\par
+\U1131.\fi
+
+\M1133. Finally we're ready to actually write the \.{TFM} information.
+Here are some utility routines for this purpose.
+
+\Y\P\D \37$\\{tfm\_out}(\#)\S\\{write}(\\{tfm\_file},\39\#)$\C{output one byte
+to \\{tfm\_file}}\par
+\Y\P\4\&{procedure}\1\ \37$\\{tfm\_two}(\|x:\\{integer})$;\C{output two bytes
+to \\{tfm\_file}}\2\6
+\&{begin} \37$\\{tfm\_out}(\|x\mathbin{\&{div}}256)$;\5
+$\\{tfm\_out}(\|x\mathbin{\&{mod}}256)$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37$\\{tfm\_four}(\|x:\\{integer})$;\C{output four bytes to
+\\{tfm\_file}}\2\6
+\&{begin} \37\&{if} $\|x\G0$ \1\&{then}\5
+$\\{tfm\_out}(\|x\mathbin{\&{div}}\\{three\_bytes})$\6
+\4\&{else} \&{begin} \37$\|x\K\|x+\O{10000000000}$;\C{use two's complement for
+negative values}\6
+$\|x\K\|x+\O{10000000000}$;\5
+$\\{tfm\_out}((\|x\mathbin{\&{div}}\\{three\_bytes})+128)$;\6
+\&{end};\2\6
+$\|x\K\|x\mathbin{\&{mod}}\\{three\_bytes}$;\5
+$\\{tfm\_out}(\|x\mathbin{\&{div}}\\{unity})$;\5
+$\|x\K\|x\mathbin{\&{mod}}\\{unity}$;\5
+$\\{tfm\_out}(\|x\mathbin{\&{div}}\O{400})$;\5
+$\\{tfm\_out}(\|x\mathbin{\&{mod}}\O{400})$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37$\\{tfm\_qqqq}(\|x:\\{four\_quarters})$;\C{output four
+quarterwords to \\{tfm\_file}}\2\6
+\&{begin} \37$\\{tfm\_out}(\\{qo}(\|x.\\{b0}))$;\5
+$\\{tfm\_out}(\\{qo}(\|x.\\{b1}))$;\5
+$\\{tfm\_out}(\\{qo}(\|x.\\{b2}))$;\5
+$\\{tfm\_out}(\\{qo}(\|x.\\{b3}))$;\6
+\&{end};\par
+\fi
+
+\M1134. \P$\X1134:Finish the \.{TFM} file\X\S$\6
+\&{if} $\\{job\_name}=0$ \1\&{then}\5
+\\{open\_log\_file};\2\6
+$\\{pack\_job\_name}(\.{".tfm"})$;\6
+\&{while} $\R\\{b\_open\_out}(\\{tfm\_file})$ \1\&{do}\5
+$\\{prompt\_file\_name}(\.{"file\ name\ for\ font\ metrics"},\39\.{".tfm"})$;\2%
+\6
+$\\{metric\_file\_name}\K\\{b\_make\_name\_string}(\\{tfm\_file})$;\5
+\X1135:Output the subfile sizes and header bytes\X;\6
+\X1136:Output the character information bytes, then output the dimensions
+themselves\X;\6
+\X1139:Output the ligature/kern program\X;\6
+\X1140:Output the extensible character recipes and the font metric parameters%
+\X;\6
+\&{stat} \37\&{if} $\\{internal}[\\{tracing\_stats}]>0$ \1\&{then}\5
+\X1141:Log the subfile sizes of the \.{TFM} file\X;\2\ \&{tats}\6
+$\\{print\_nl}(\.{"Font\ metrics\ written\ on\ "})$;\5
+$\\{slow\_print}(\\{metric\_file\_name})$;\5
+$\\{print\_char}(\.{"."})$;\5
+$\\{b\_close}(\\{tfm\_file})$\par
+\U1206.\fi
+
+\M1135. Integer variables \\{lh}, \|k, and \\{lk\_offset} will be defined when
+we use
+this code.
+
+\Y\P$\4\X1135:Output the subfile sizes and header bytes\X\S$\6
+$\|k\K\\{header\_size}$;\6
+\&{while} $\\{header\_byte}[\|k]<0$ \1\&{do}\5
+$\\{decr}(\|k)$;\2\6
+$\\{lh}\K(\|k+3)\mathbin{\&{div}}4$;\C{this is the number of header words}\6
+\&{if} $\\{bc}>\\{ec}$ \1\&{then}\5
+$\\{bc}\K1$;\C{if there are no characters, $\\{ec}=0$ and $\\{bc}=1$}\2\6
+\X1137:Compute the ligature/kern program offset and implant the left boundary
+label\X;\6
+$\\{tfm\_two}(6+\\{lh}+(\\{ec}-\\{bc}+1)+\\{nw}+\\{nh}+\\{nd}+\\{ni}+\\{nl}+%
+\\{lk\_offset}+\\{nk}+\\{ne}+\\{np})$;\C{this is the total number of file words
+that will be output}\6
+$\\{tfm\_two}(\\{lh})$;\5
+$\\{tfm\_two}(\\{bc})$;\5
+$\\{tfm\_two}(\\{ec})$;\5
+$\\{tfm\_two}(\\{nw})$;\5
+$\\{tfm\_two}(\\{nh})$;\5
+$\\{tfm\_two}(\\{nd})$;\5
+$\\{tfm\_two}(\\{ni})$;\5
+$\\{tfm\_two}(\\{nl}+\\{lk\_offset})$;\5
+$\\{tfm\_two}(\\{nk})$;\5
+$\\{tfm\_two}(\\{ne})$;\5
+$\\{tfm\_two}(\\{np})$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}4\ast\\{lh}$ \1\&{do}\6
+\&{begin} \37\&{if} $\\{header\_byte}[\|k]<0$ \1\&{then}\5
+$\\{header\_byte}[\|k]\K0$;\2\6
+$\\{tfm\_out}(\\{header\_byte}[\|k])$;\6
+\&{end}\2\par
+\U1134.\fi
+
+\M1136. \P$\X1136:Output the character information bytes, then output the
+dimensions themselves\X\S$\6
+\&{for} $\|k\K\\{bc}\mathrel{\&{to}}\\{ec}$ \1\&{do}\6
+\&{if} $\R\\{char\_exists}[\|k]$ \1\&{then}\5
+$\\{tfm\_four}(0)$\6
+\4\&{else} \&{begin} \37$\\{tfm\_out}(\\{info}(\\{tfm\_width}[\|k]))$;\C{the
+width index}\6
+$\\{tfm\_out}((\\{info}(\\{tfm\_height}[\|k]))\ast16+\\{info}(\\{tfm\_depth}[%
+\|k]))$;\5
+$\\{tfm\_out}((\\{info}(\\{tfm\_ital\_corr}[\|k]))\ast4+\\{char\_tag}[\|k])$;\5
+$\\{tfm\_out}(\\{char\_remainder}[\|k])$;\6
+\&{end};\2\2\6
+$\\{tfm\_changed}\K0$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}4$ \1\&{do}\6
+\&{begin} \37$\\{tfm\_four}(0)$;\5
+$\|p\K\\{dimen\_head}[\|k]$;\6
+\&{while} $\|p\I\\{inf\_val}$ \1\&{do}\6
+\&{begin} \37$\\{tfm\_four}(\\{dimen\_out}(\\{value}(\|p)))$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+\&{end}\2\par
+\U1134.\fi
+
+\M1137. We need to output special instructions at the beginning of the
+\\{lig\_kern} array in order to specify the right boundary character
+and/or to handle starting addresses that exceed 255. The \\{label\_loc}
+and \\{label\_char} arrays have been set up to record all the
+starting addresses; we have $-1=\\{label\_loc}[0]<\\{label\_loc}[1]\le\cdots
+\le\\{label\_loc}[\\{label\_ptr} ] $.
+
+\Y\P$\4\X1137:Compute the ligature/kern program offset and implant the left
+boundary label\X\S$\6
+$\\{bchar}\K\\{round\_unscaled}(\\{internal}[\\{boundary\_char}])$;\6
+\&{if} $(\\{bchar}<0)\V(\\{bchar}>255)$ \1\&{then}\6
+\&{begin} \37$\\{bchar}\K-1$;\5
+$\\{lk\_started}\K\\{false}$;\5
+$\\{lk\_offset}\K0$;\ \&{end}\6
+\4\&{else} \&{begin} \37$\\{lk\_started}\K\\{true}$;\5
+$\\{lk\_offset}\K1$;\ \&{end};\2\6
+\X1138:Find the minimum \\{lk\_offset} and adjust all remainders\X;\6
+\&{if} $\\{bch\_label}<\\{undefined\_label}$ \1\&{then}\6
+\&{begin} \37$\\{skip\_byte}(\\{nl})\K\\{qi}(255)$;\5
+$\\{next\_char}(\\{nl})\K\\{qi}(0)$;\5
+$\\{op\_byte}(\\{nl})\K\\{qi}(((\\{bch\_label}+\\{lk\_offset})\mathbin{%
+\&{div}}256))$;\5
+$\\{rem\_byte}(\\{nl})\K\\{qi}(((\\{bch\_label}+\\{lk\_offset})\mathbin{%
+\&{mod}}256))$;\5
+$\\{incr}(\\{nl})$;\C{possibly $\\{nl}=\\{lig\_table\_size}+1$}\6
+\&{end}\2\par
+\U1135.\fi
+
+\M1138. \P$\X1138:Find the minimum \\{lk\_offset} and adjust all remainders\X%
+\S$\6
+$\|k\K\\{label\_ptr}$;\C{pointer to the largest unallocated label}\6
+\&{if} $\\{label\_loc}[\|k]+\\{lk\_offset}>255$ \1\&{then}\6
+\&{begin} \37$\\{lk\_offset}\K0$;\5
+$\\{lk\_started}\K\\{false}$;\C{location 0 can do double duty}\6
+\1\&{repeat} \37$\\{char\_remainder}[\\{label\_char}[\|k]]\K\\{lk\_offset}$;\6
+\&{while} $\\{label\_loc}[\|k-1]=\\{label\_loc}[\|k]$ \1\&{do}\6
+\&{begin} \37$\\{decr}(\|k)$;\5
+$\\{char\_remainder}[\\{label\_char}[\|k]]\K\\{lk\_offset}$;\6
+\&{end};\2\6
+$\\{incr}(\\{lk\_offset})$;\5
+$\\{decr}(\|k)$;\6
+\4\&{until}\5
+$\\{lk\_offset}+\\{label\_loc}[\|k]<256$;\C{N.B.: $\\{lk\_offset}=256$
+satisfies this when $\|k=0$}\2\6
+\&{end};\2\6
+\&{if} $\\{lk\_offset}>0$ \1\&{then}\6
+\&{while} $\|k>0$ \1\&{do}\6
+\&{begin} \37$\\{char\_remainder}[\\{label\_char}[\|k]]\K\\{char\_remainder}[%
+\\{label\_char}[\|k]]+\\{lk\_offset}$;\5
+$\\{decr}(\|k)$;\6
+\&{end}\2\2\par
+\U1137.\fi
+
+\M1139. \P$\X1139:Output the ligature/kern program\X\S$\6
+\&{for} $\|k\K0\mathrel{\&{to}}255$ \1\&{do}\6
+\&{if} $\\{skip\_table}[\|k]<\\{undefined\_label}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"(local\ label\ "})$;\5
+$\\{print\_int}(\|k)$;\5
+$\\{print}(\.{"::\ was\ missing)"})$;\5
+$\\{cancel\_skips}(\\{skip\_table}[\|k])$;\6
+\&{end};\2\2\6
+\&{if} $\\{lk\_started}$ \1\&{then}\C{$\\{lk\_offset}=1$ for the special %
+\\{bchar}}\6
+\&{begin} \37$\\{tfm\_out}(255)$;\5
+$\\{tfm\_out}(\\{bchar})$;\5
+$\\{tfm\_two}(0)$;\6
+\&{end}\6
+\4\&{else} \&{for} $\|k\K1\mathrel{\&{to}}\\{lk\_offset}$ \1\&{do}\C{output the
+redirection specs}\6
+\&{begin} \37$\\{ll}\K\\{label\_loc}[\\{label\_ptr}]$;\6
+\&{if} $\\{bchar}<0$ \1\&{then}\6
+\&{begin} \37$\\{tfm\_out}(254)$;\5
+$\\{tfm\_out}(0)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{tfm\_out}(255)$;\5
+$\\{tfm\_out}(\\{bchar})$;\6
+\&{end};\2\6
+$\\{tfm\_two}(\\{ll}+\\{lk\_offset})$;\6
+\1\&{repeat} \37$\\{decr}(\\{label\_ptr})$;\6
+\4\&{until}\5
+$\\{label\_loc}[\\{label\_ptr}]<\\{ll}$;\2\6
+\&{end};\2\2\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{nl}-1$ \1\&{do}\5
+$\\{tfm\_qqqq}(\\{lig\_kern}[\|k])$;\2\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{nk}-1$ \1\&{do}\5
+$\\{tfm\_four}(\\{dimen\_out}(\\{kern}[\|k]))$\2\par
+\U1134.\fi
+
+\M1140. \P$\X1140:Output the extensible character recipes and the font metric
+parameters\X\S$\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{ne}-1$ \1\&{do}\5
+$\\{tfm\_qqqq}(\\{exten}[\|k])$;\2\6
+\&{for} $\|k\K1\mathrel{\&{to}}\\{np}$ \1\&{do}\6
+\&{if} $\|k=1$ \1\&{then}\6
+\&{if} $\\{abs}(\\{param}[1])<\\{fraction\_half}$ \1\&{then}\5
+$\\{tfm\_four}(\\{param}[1]\ast16)$\6
+\4\&{else} \&{begin} \37$\\{incr}(\\{tfm\_changed})$;\6
+\&{if} $\\{param}[1]>0$ \1\&{then}\5
+$\\{tfm\_four}(\\{el\_gordo})$\6
+\4\&{else} $\\{tfm\_four}(-\\{el\_gordo})$;\2\6
+\&{end}\2\6
+\4\&{else} $\\{tfm\_four}(\\{dimen\_out}(\\{param}[\|k]))$;\2\2\6
+\&{if} $\\{tfm\_changed}>0$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{tfm\_changed}=1$ \1\&{then}\5
+$\\{print\_nl}(\.{"(a\ font\ metric\ dimension"})$\6
+\4\&{else} \&{begin} \37$\\{print\_nl}(\.{"("})$;\5
+$\\{print\_int}(\\{tfm\_changed})$;\5
+$\\{print}(\.{"\ font\ metric\ dimensions"})$;\6
+\&{end};\2\6
+$\\{print}(\.{"\ had\ to\ be\ decreased)"})$;\6
+\&{end}\2\par
+\U1134.\fi
+
+\M1141. \P$\X1141:Log the subfile sizes of the \.{TFM} file\X\S$\6
+\&{begin} \37$\\{wlog\_ln}(\.{\'\ \'})$;\6
+\&{if} $\\{bch\_label}<\\{undefined\_label}$ \1\&{then}\5
+$\\{decr}(\\{nl})$;\2\6
+$\\{wlog\_ln}(\.{\'(You\ used\ \'},\39\\{nw}:1,\39\.{\'w,\'},\39\30\\{nh}:1,\39%
+\.{\'h,\'},\39\30\\{nd}:1,\39\.{\'d,\'},\39\30\\{ni}:1,\39\.{\'i,\'},\39\30%
+\\{nl}:1,\39\.{\'l,\'},\39\30\\{nk}:1,\39\.{\'k,\'},\39\30\\{ne}:1,\39\.{\'e,%
+\'},\39\30\\{np}:1,\39\.{\'p\ metric\ file\ positions\'})$;\5
+$\\{wlog\_ln}(\.{\'\ \ out\ of\ \'},\39\30\.{\'256w,16h,16d,64i,\'},\39\30%
+\\{lig\_table\_size}:1,\39\.{\'l,\'},\39\\{max\_kerns}:1,\39\.{\'k,256e,\'},\39%
+\30\\{max\_font\_dimen}:1,\39\.{\'p)\'})$;\6
+\&{end}\par
+\U1134.\fi
+
+\N1142. \[46] Generic font file format.
+The most important output produced by a typical run of \MF\ is the
+``generic font'' (\.{GF}) file that specifies the bit patterns of the
+characters that have been drawn. The term {\sl generic\/} indicates that
+this file format doesn't match the conventions of any name-brand manufacturer;
+but it is easy to convert \.{GF} files to the special format required by
+almost all digital phototypesetting equipment. There's a strong analogy
+between the \.{DVI} files written by \TeX\ and the \.{GF} files written
+by \MF; and, in fact, the file formats have a lot in common.
+
+A \.{GF} file is a stream of 8-bit bytes that may be
+regarded as a series of commands in a machine-like language. The first
+byte of each command is the operation code, and this code is followed by
+zero or more bytes that provide parameters to the command. The parameters
+themselves may consist of several consecutive bytes; for example, the
+`\\{boc}' (beginning of character) command has six parameters, each of
+which is four bytes long. Parameters are usually regarded as nonnegative
+integers; but four-byte-long parameters can be either positive or
+negative, hence they range in value from $-2^{31}$ to $2^{31}-1$.
+As in \.{TFM} files, numbers that occupy
+more than one byte position appear in BigEndian order,
+and negative numbers appear in two's complement notation.
+
+A \.{GF} file consists of a ``preamble,'' followed by a sequence of one or
+more ``characters,'' followed by a ``postamble.'' The preamble is simply a
+\\{pre} command, with its parameters that introduce the file; this must come
+first. Each ``character'' consists of a \\{boc} command, followed by any
+number of other commands that specify ``black'' pixels,
+followed by an \\{eoc} command. The characters appear in the order that \MF\
+generated them. If we ignore no-op commands (which are allowed between any
+two commands in the file), each \\{eoc} command is immediately followed by a
+\\{boc} command, or by a \\{post} command; in the latter case, there are no
+more characters in the file, and the remaining bytes form the postamble.
+Further details about the postamble will be explained later.
+
+Some parameters in \.{GF} commands are ``pointers.'' These are four-byte
+quantities that give the location number of some other byte in the file;
+the first file byte is number~0, then comes number~1, and so on.
+
+\fi
+
+\M1143. The \.{GF} format is intended to be both compact and easily interpreted
+by a machine. Compactness is achieved by making most of the information
+relative instead of absolute. When a \.{GF}-reading program reads the
+commands for a character, it keeps track of two quantities: (a)~the current
+column number,~\|m; and (b)~the current row number,~\|n. These are 32-bit
+signed integers, although most actual font formats produced from \.{GF}
+files will need to curtail this vast range because of practical
+limitations. (\MF\ output will never allow $\vert m\vert$ or $\vert
+n\vert$ to get extremely large, but the \.{GF} format tries to be more
+general.)
+
+How do \.{GF}'s row and column numbers correspond to the conventions
+of \TeX\ and \MF? Well, the ``reference point'' of a character, in \TeX's
+view, is considered to be at the lower left corner of the pixel in row~0
+and column~0. This point is the intersection of the baseline with the left
+edge of the type; it corresponds to location $(0,0)$ in \MF\ programs.
+Thus the pixel in \.{GF} row~0 and column~0 is \MF's unit square, comprising
+the
+region of the plane whose coordinates both lie between 0 and~1. The
+pixel in \.{GF} row~\|n and column~\|m consists of the points whose \MF\
+coordinates $(\|x,\|y)$ satisfy $\|m\L\|x\L\|m+1$ and $\|n\L\|y\L\|n+1$.
+Negative values of
+\|m and~\|x correspond to columns of pixels {\sl left\/} of the reference
+point; negative values of \|n and~\|y correspond to rows of pixels {\sl
+below\/} the baseline.
+
+Besides \|m and \|n, there's also a third aspect of the current
+state, namely the \\{paint\_switch}, which is always either \\{black} or
+\\{white}. Each \\{paint} command advances \|m by a specified amount~\|d,
+and blackens the intervening pixels if $\\{paint\_switch}=\\{black}$; then
+the \\{paint\_switch} changes to the opposite state. \.{GF}'s commands are
+designed so that \|m will never decrease within a row, and \|n will never
+increase within a character; hence there is no way to whiten a pixel that
+has been blackened.
+
+\fi
+
+\M1144. Here is a list of all the commands that may appear in a \.{GF} file.
+Each
+command is specified by its symbolic name (e.g., \\{boc}), its opcode byte
+(e.g., 67), and its parameters (if any). The parameters are followed
+by a bracketed number telling how many bytes they occupy; for example,
+`$\|d[2]$' means that parameter \|d is two bytes long.
+
+\yskip\hang\\{paint\_0} 0. This is a \\{paint} command with $\|d=0$; it does
+nothing but change the \\{paint\_switch} from \\{black} to \\{white} or
+vice~versa.
+
+\yskip\hang\\{paint\_1} through \\{paint\_63} (opcodes 1 to 63).
+These are \\{paint} commands with $\|d=1$ to~63, defined as follows: If
+$\\{paint\_switch}=\\{black}$, blacken \|d~pixels of the current row~\|n,
+in columns \|m through $\|m+\|d-1$ inclusive. Then, in any case,
+complement the \\{paint\_switch} and advance \|m by~\|d.
+
+\yskip\hang\\{paint1} 64 $\|d[1]$. This is a \\{paint} command with a specified
+value of~\|d; \MF\ uses it to paint when $64\L\|d<256$.
+
+\yskip\hang\\{paint2} 65 $\|d[2]$. Same as \\{paint1}, but \|d~can be as high
+as~65535.
+
+\yskip\hang\\{paint3} 66 $\|d[3]$. Same as \\{paint1}, but \|d~can be as high
+as $2^{24}-1$. \MF\ never needs this command, and it is hard to imagine
+anybody making practical use of it; surely a more compact encoding will be
+desirable when characters can be this large. But the command is there,
+anyway, just in case.
+
+\yskip\hang\\{boc} 67 $\|c[4]$ $\|p[4]$ $\\{min\_m}[4]$ $\\{max\_m}[4]$ $\\{min%
+\_n}[4]$
+$\\{max\_n}[4]$. Beginning of a character: Here \|c is the character code, and
+\|p points to the previous character beginning (if any) for characters having
+this code number modulo 256. (The pointer \|p is $-1$ if there was no
+prior character with an equivalent code.) The values of registers \|m and \|n
+defined by the instructions that follow for this character must
+satisfy $\\{min\_m}\L\|m\L\\{max\_m}$ and $\\{min\_n}\L\|n\L\\{max\_n}$. (The
+values of \\{max\_m} and
+\\{min\_n} need not be the tightest bounds possible.) When a \.{GF}-reading
+program sees a \\{boc}, it can use \\{min\_m}, \\{max\_m}, \\{min\_n}, and %
+\\{max\_n} to
+initialize the bounds of an array. Then it sets $\|m\K\\{min\_m}$, $\|n\K\\{max%
+\_n}$, and
+$\\{paint\_switch}\K\\{white}$.
+
+\yskip\hang\\{boc1} 68 $\|c[1]$ $\\{del\_m}[1]$ $\\{max\_m}[1]$ $\\{del\_n}[1]$
+$\\{max\_n}[1]$.
+Same as \\{boc}, but \|p is assumed to be~$-1$; also $\\{del\_m}=\\{max\_m}-%
+\\{min\_m}$
+and $\\{del\_n}=\\{max\_n}-\\{min\_n}$ are given instead of \\{min\_m} and %
+\\{min\_n}.
+The one-byte parameters must be between 0 and 255, inclusive.
+\ (This abbreviated \\{boc} saves 19~bytes per character, in common cases.)
+
+\yskip\hang\\{eoc} 69. End of character: All pixels blackened so far
+constitute the pattern for this character. In particular, a completely
+blank character might have \\{eoc} immediately following \\{boc}.
+
+\yskip\hang\\{skip0} 70. Decrease \|n by 1 and set $\|m\K\\{min\_m}$,
+$\\{paint\_switch}\K\\{white}$. \ (This finishes one row and begins another,
+ready to whiten the leftmost pixel in the new row.)
+
+\yskip\hang\\{skip1} 71 $\|d[1]$. Decrease \|n by $\|d+1$, set $\|m\K\\{min%
+\_m}$, and set
+$\\{paint\_switch}\K\\{white}$. This is a way to produce \|d all-white rows.
+
+\yskip\hang\\{skip2} 72 $\|d[2]$. Same as \\{skip1}, but \|d can be as large
+as 65535.
+
+\yskip\hang\\{skip3} 73 $\|d[3]$. Same as \\{skip1}, but \|d can be as large
+as $2^{24}-1$. \MF\ obviously never needs this command.
+
+\yskip\hang\\{new\_row\_0} 74. Decrease \|n by 1 and set $\|m\K\\{min\_m}$,
+$\\{paint\_switch}\K\\{black}$. \ (This finishes one row and begins another,
+ready to {\sl blacken\/} the leftmost pixel in the new row.)
+
+\yskip\hang\\{new\_row\_1} through \\{new\_row\_164} (opcodes 75 to 238). Same
+as
+\\{new\_row\_0}, but with $\|m\K\\{min\_m}+1$ through $\\{min\_m}+164$,
+respectively.
+
+\yskip\hang\\{xxx1} 239 $\|k[1]$ $\|x[\|k]$. This command is undefined in
+general; it functions as a $(k+2)$-byte \\{no\_op} unless special %
+\.{GF}-reading
+programs are being used. \MF\ generates \\{xxx} commands when encountering
+a \&{special} string; this occurs in the \.{GF} file only between
+characters, after the preamble, and before the postamble. However,
+\\{xxx} commands might appear within characters,
+in \.{GF} files generated by other
+processors. It is recommended that \|x be a string having the form of a
+keyword followed by possible parameters relevant to that keyword.
+
+\yskip\hang\\{xxx2} 240 $\|k[2]$ $\|x[\|k]$. Like \\{xxx1}, but $0\L\|k<65536$.
+
+\yskip\hang\\{xxx3} 241 $\|k[3]$ $\|x[\|k]$. Like \\{xxx1}, but $0\L\|k<%
+\hbox{$2^{24}$}$.
+\MF\ uses this when sending a \&{special} string whose length exceeds~255.
+
+\yskip\hang\\{xxx4} 242 $\|k[4]$ $\|x[\|k]$. Like \\{xxx1}, but \|k can be
+ridiculously large; \|k mustn't be negative.
+
+\yskip\hang\\{yyy} 243 $\|y[4]$. This command is undefined in general;
+it functions as a 5-byte \\{no\_op} unless special \.{GF}-reading programs
+are being used. \MF\ puts \\{scaled} numbers into \\{yyy}'s, as a
+result of \&{numspecial} commands; the intent is to provide numeric
+parameters to \\{xxx} commands that immediately precede.
+
+\yskip\hang\\{no\_op} 244. No operation, do nothing. Any number of \\{no\_op}'s
+may occur between \.{GF} commands, but a \\{no\_op} cannot be inserted between
+a command and its parameters or between two parameters.
+
+\yskip\hang\\{char\_loc} 245 $\|c[1]$ $\\{dx}[4]$ $\\{dy}[4]$ $\|w[4]$ $%
+\|p[4]$.
+This command will appear only in the postamble, which will be explained
+shortly.
+
+\yskip\hang\\{char\_loc0} 246 $\|c[1]$ $\\{dm}[1]$ $\|w[4]$ $\|p[4]$.
+Same as \\{char\_loc}, except that \\{dy} is assumed to be zero, and the value
+of~\\{dx} is taken to be $65536\ast\\{dm}$, where $0\L\\{dm}<256$.
+
+\yskip\hang\\{pre} 247 $\|i[1]$ $\|k[1]$ $\|x[\|k]$.
+Beginning of the preamble; this must come at the very beginning of the
+file. Parameter \|i is an identifying number for \.{GF} format, currently
+131. The other information is merely commentary; it is not given
+special interpretation like \\{xxx} commands are. (Note that \\{xxx}
+commands may immediately follow the preamble, before the first \\{boc}.)
+
+\yskip\hang\\{post} 248. Beginning of the postamble, see below.
+
+\yskip\hang\\{post\_post} 249. Ending of the postamble, see below.
+
+\yskip\noindent Commands 250--255 are undefined at the present time.
+
+\Y\P\D \37$\\{gf\_id\_byte}=131$\C{identifies the kind of \.{GF} files
+described here}\par
+\fi
+
+\M1145. \MF\ refers to the following opcodes explicitly.
+
+\Y\P\D \37$\\{paint\_0}=0$\C{beginning of the \\{paint} commands}\par
+\P\D \37$\\{paint1}=64$\C{move right a given number of columns, then black${}%
+\swap{}$white}\par
+\P\D \37$\\{boc}=67$\C{beginning of a character}\par
+\P\D \37$\\{boc1}=68$\C{short form of \\{boc}}\par
+\P\D \37$\\{eoc}=69$\C{end of a character}\par
+\P\D \37$\\{skip0}=70$\C{skip no blank rows}\par
+\P\D \37$\\{skip1}=71$\C{skip over blank rows}\par
+\P\D \37$\\{new\_row\_0}=74$\C{move down one row and then right}\par
+\P\D \37$\\{max\_new\_row}=164$\C{the largest \\{new\_row} command is \\{new%
+\_row\_164}}\par
+\P\D \37$\\{xxx1}=239$\C{for \&{special} strings}\par
+\P\D \37$\\{xxx3}=241$\C{for long \&{special} strings}\par
+\P\D \37$\\{yyy}=243$\C{for \&{numspecial} numbers}\par
+\P\D \37$\\{char\_loc}=245$\C{character locators in the postamble}\par
+\P\D \37$\\{pre}=247$\C{preamble}\par
+\P\D \37$\\{post}=248$\C{postamble beginning}\par
+\P\D \37$\\{post\_post}=249$\C{postamble ending}\par
+\fi
+
+\M1146. The last character in a \.{GF} file is followed by `\\{post}'; this
+command
+introduces the postamble, which summarizes important facts that \MF\ has
+accumulated. The postamble has the form
+$$\vbox{\halign{\hbox{#\hfil}\cr
+\\{post} $\|p[4]$ $\\{ds}[4]$ $\\{cs}[4]$ $\\{hppp}[4]$ $\\{vppp}[4]$
+$\\{min\_m}[4]$ $\\{max\_m}[4]$ $\\{min\_n}[4]$ $\\{max\_n}[4]$\cr
+$\langle\,$character locators$\,\rangle$\cr
+\\{post\_post} $\|q[4]$ $\|i[1]$ 223's$[{\G}4]$\cr}}$$
+Here \|p is a pointer to the byte following the final \\{eoc} in the file
+(or to the byte following the preamble, if there are no characters);
+it can be used to locate the beginning of \\{xxx} commands
+that might have preceded the postamble. The \\{ds} and \\{cs} parameters
+give the design size and check sum, respectively, which are exactly the
+values put into the header of the \.{TFM} file that \MF\ produces (or
+would produce) on this run. Parameters \\{hppp} and \\{vppp} are the ratios of
+pixels per point, horizontally and vertically, expressed as \\{scaled} integers
+(i.e., multiplied by $2^{16}$); they can be used to correlate the font
+with specific device resolutions, magnifications, and ``at sizes.'' Then
+come \\{min\_m}, \\{max\_m}, \\{min\_n}, and \\{max\_n}, which bound the values
+that
+registers \|m and~\|n assume in all characters in this \.{GF} file.
+(These bounds need not be the best possible; \\{max\_m} and \\{min\_n} may, on
+the
+other hand, be tighter than the similar bounds in \\{boc} commands. For
+example, some character may have $\\{min\_n}=-100$ in its \\{boc}, but it might
+turn out that \|n never gets lower than $-50$ in any character; then
+\\{min\_n} can have any value $\L-50$. If there are no characters in the file,
+it's possible to have $\\{min\_m}>\\{max\_m}$ and/or $\\{min\_n}>\\{max\_n}$.)
+
+\fi
+
+\M1147. Character locators are introduced by \\{char\_loc} commands,
+which specify a character residue~\|c, character escapements ($\\{dx},\\{dy}$),
+a character width~\|w, and a pointer~\|p
+to the beginning of that character. (If two or more characters have the
+same code~\|c modulo 256, only the last will be indicated; the others can be
+located by following backpointers. Characters whose codes differ by a
+multiple of 256 are assumed to share the same font metric information,
+hence the \.{TFM} file contains only residues of character codes modulo~256.
+This convention is intended for oriental languages, when there are many
+character shapes but few distinct widths.)
+
+The character escapements ($\\{dx},\\{dy}$) are the values of \MF's \&{chardx}
+and \&{chardy} parameters; they are in units of \\{scaled} pixels;
+i.e., \\{dx} is in horizontal pixel units times $2^{16}$, and \\{dy} is in
+vertical pixel units times $2^{16}$. This is the intended amount of
+displacement after typesetting the character; for \.{DVI} files, \\{dy}
+should be zero, but other document file formats allow nonzero vertical
+escapement.
+
+The character width~\|w duplicates the information in the \.{TFM} file; it
+is a \\{fix\_word} value relative to the design size, and it should be
+independent of magnification.
+
+The backpointer \|p points to the character's \\{boc}, or to the first of
+a sequence of consecutive \\{xxx} or \\{yyy} or \\{no\_op} commands that
+immediately precede the \\{boc}, if such commands exist; such ``special''
+commands essentially belong to the characters, while the special commands
+after the final character belong to the postamble (i.e., to the font
+as a whole). This convention about \|p applies also to the backpointers
+in \\{boc} commands, even though it wasn't explained in the description
+of~\\{boc}.
+
+Pointer \|p might be $-1$ if the character exists in the \.{TFM} file
+but not in the \.{GF} file. This unusual situation can arise in \MF\ output
+if the user had $\\{proofing}<0$ when the character was being shipped out,
+but then made $\\{proofing}\G0$ in order to get a \.{GF} file.
+
+\fi
+
+\M1148. The last part of the postamble, following the \\{post\_post} byte that
+signifies the end of the character locators, contains \|q, a pointer to the
+\\{post} command that started the postamble. An identification byte, \|i,
+comes next; this currently equals~131, as in the preamble.
+
+The \|i byte is followed by four or more bytes that are all equal to
+the decimal number 223 (i.e., \O{337} in octal). \MF\ puts out four to seven of
+these trailing bytes, until the total length of the file is a multiple of
+four bytes, since this works out best on machines that pack four bytes per
+word; but any number of 223's is allowed, as long as there are at least four
+of them. In effect, 223 is a sort of signature that is added at the very end.
+
+This curious way to finish off a \.{GF} file makes it feasible for
+\.{GF}-reading programs to find the postamble first, on most computers,
+even though \MF\ wants to write the postamble last. Most operating
+systems permit random access to individual words or bytes of a file, so
+the \.{GF} reader can start at the end and skip backwards over the 223's
+until finding the identification byte. Then it can back up four bytes, read
+\|q, and move to byte \|q of the file. This byte should, of course,
+contain the value 248 (\\{post}); now the postamble can be read, so the
+\.{GF} reader can discover all the information needed for individual
+characters.
+
+Unfortunately, however, standard \PASCAL\ does not include the ability to
+access a random position in a file, or even to determine the length of a file.
+Almost all systems nowadays provide the necessary capabilities, so \.{GF}
+format has been designed to work most efficiently with modern operating
+systems.
+But if \.{GF} files have to be processed under the restrictions of standard
+\PASCAL, one can simply read them from front to back. This will
+be adequate for most applications. However, the postamble-first approach
+would facilitate a program that merges two \.{GF} files, replacing data
+from one that is overridden by corresponding data in the other.
+
+\fi
+
+\N1149. \[47] Shipping characters out.
+The \\{ship\_out} procedure, to be described below, is given a pointer to
+an edge structure. Its mission is to describe the the positive pixels
+in \.{GF} form, outputting a ``character'' to \\{gf\_file}.
+
+Several global variables hold information about the font file as a whole:\
+\\{gf\_min\_m}, \\{gf\_max\_m}, \\{gf\_min\_n}, and \\{gf\_max\_n} are the
+minimum and
+maximum \.{GF} coordinates output so far; \\{gf\_prev\_ptr} is the byte number
+following the preamble or the last \\{eoc} command in the output;
+\\{total\_chars} is the total number of characters (i.e., $\\{boc}\to\\{eoc}$
+segments)
+shipped out. There's also an array, \\{char\_ptr}, containing the starting
+positions of each character in the file, as required for the postamble. If
+character code~\|c has not yet been output, $\\{char\_ptr}[\|c]=-1$.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{gf\_min\_m},\39\\{gf\_max\_m},\39\\{gf\_min\_n},\39\\{gf\_max\_n}$: \37%
+\\{integer};\C{bounding rectangle}\6
+\4\\{gf\_prev\_ptr}: \37\\{integer};\C{where the present/next character
+started/starts}\6
+\4\\{total\_chars}: \37\\{integer};\C{the number of characters output so far}\6
+\4\\{char\_ptr}: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+\\{integer};\C{where individual characters started}\2\6
+\4$\\{gf\_dx},\39\\{gf\_dy}$: \37\&{array} $[\\{eight\_bits}]$ \1\&{of}\5
+\\{integer};\C{device escapements}\2\par
+\fi
+
+\M1150. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{gf\_prev\_ptr}\K0$;\5
+$\\{total\_chars}\K0$;\par
+\fi
+
+\M1151. The \.{GF} bytes are output to a buffer instead of being sent
+byte-by-byte to \\{gf\_file}, because this tends to save a lot of
+subroutine-call overhead. \MF\ uses the same conventions for \\{gf\_file}
+as \TeX\ uses for its \\{dvi\_file}; hence if system-dependent
+changes are needed, they should probably be the same for both programs.
+
+The output buffer is divided into two parts of equal size; the bytes found
+in $\\{gf\_buf}[0\to\\{half\_buf}-1]$ constitute the first half, and those in
+$\\{gf\_buf}[\\{half\_buf}\to\\{gf\_buf\_size}-1]$ constitute the second. The
+global
+variable \\{gf\_ptr} points to the position that will receive the next
+output byte. When \\{gf\_ptr} reaches \\{gf\_limit}, which is always equal
+to one of the two values \\{half\_buf} or \\{gf\_buf\_size}, the half buffer
+that
+is about to be invaded next is sent to the output and \\{gf\_limit} is
+changed to its other value. Thus, there is always at least a half buffer's
+worth of information present, except at the very beginning of the job.
+
+Bytes of the \.{GF} file are numbered sequentially starting with 0;
+the next byte to be generated will be number $\\{gf\_offset}+\\{gf\_ptr}$.
+
+\Y\P$\4\X18:Types in the outer block\X\mathrel{+}\S$\6
+$\\{gf\_index}=0\to\\{gf\_buf\_size}$;\C{an index into the output buffer}\par
+\fi
+
+\M1152. Some systems may find it more efficient to make \\{gf\_buf} a %
+\&{packed}
+array, since output of four bytes at once may be facilitated.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{gf\_buf}: \37\&{array} $[\\{gf\_index}]$ \1\&{of}\5
+\\{eight\_bits};\C{buffer for \.{GF} output}\2\6
+\4\\{half\_buf}: \37\\{gf\_index};\C{half of \\{gf\_buf\_size}}\6
+\4\\{gf\_limit}: \37\\{gf\_index};\C{end of the current half buffer}\6
+\4\\{gf\_ptr}: \37\\{gf\_index};\C{the next available buffer address}\6
+\4\\{gf\_offset}: \37\\{integer};\C{\\{gf\_buf\_size} times the number of times
+the output buffer has been fully emptied}\par
+\fi
+
+\M1153. Initially the buffer is all in one piece; we will output half of it
+only
+after it first fills up.
+
+\Y\P$\4\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{half\_buf}\K\\{gf\_buf\_size}\mathbin{\&{div}}2$;\5
+$\\{gf\_limit}\K\\{gf\_buf\_size}$;\5
+$\\{gf\_ptr}\K0$;\5
+$\\{gf\_offset}\K0$;\par
+\fi
+
+\M1154. The actual output of $\\{gf\_buf}[\|a\to\|b]$ to \\{gf\_file} is
+performed by calling
+$\\{write\_gf}(\|a,\|b)$. It is safe to assume that \|a and $\|b+1$ will both
+be
+multiples of 4 when $\\{write\_gf}(\|a,\|b)$ is called; therefore it is
+possible on
+many machines to use efficient methods to pack four bytes per word and to
+output an array of words with one system call.
+
+\Y\P$\4\X1154:Declare generic font output procedures\X\S$\6
+\4\&{procedure}\1\ \37$\\{write\_gf}(\|a,\39\|b:\\{gf\_index})$;\6
+\4\&{var} \37\|k: \37\\{gf\_index};\2\6
+\&{begin} \37\&{for} $\|k\K\|a\mathrel{\&{to}}\|b$ \1\&{do}\5
+$\\{write}(\\{gf\_file},\39\\{gf\_buf}[\|k])$;\2\6
+\&{end};\par
+\As1155, 1157, 1158, 1159, 1160, 1161, 1163\ETs1165.
+\U989.\fi
+
+\M1155. To put a byte in the buffer without paying the cost of invoking a
+procedure
+each time, we use the macro \\{gf\_out}.
+
+\Y\P\D \37$\\{gf\_out}(\#)\S$\ \&{begin} \37$\\{gf\_buf}[\\{gf\_ptr}]\K\#$;\5
+$\\{incr}(\\{gf\_ptr})$;\6
+\&{if} $\\{gf\_ptr}=\\{gf\_limit}$ \1\&{then}\5
+\\{gf\_swap};\2\6
+\&{end}\par
+\Y\P$\4\X1154:Declare generic font output procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{gf\_swap};\C{outputs half of the buffer}\2\6
+\&{begin} \37\&{if} $\\{gf\_limit}=\\{gf\_buf\_size}$ \1\&{then}\6
+\&{begin} \37$\\{write\_gf}(0,\39\\{half\_buf}-1)$;\5
+$\\{gf\_limit}\K\\{half\_buf}$;\5
+$\\{gf\_offset}\K\\{gf\_offset}+\\{gf\_buf\_size}$;\5
+$\\{gf\_ptr}\K0$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{write\_gf}(\\{half\_buf},\39\\{gf\_buf\_size}-1)$;\5
+$\\{gf\_limit}\K\\{gf\_buf\_size}$;\6
+\&{end};\2\6
+\&{end};\par
+\fi
+
+\M1156. Here is how we clean out the buffer when \MF\ is all through; \\{gf%
+\_ptr}
+will be a multiple of~4.
+
+\Y\P$\4\X1156:Empty the last bytes out of \\{gf\_buf}\X\S$\6
+\&{if} $\\{gf\_limit}=\\{half\_buf}$ \1\&{then}\5
+$\\{write\_gf}(\\{half\_buf},\39\\{gf\_buf\_size}-1)$;\2\6
+\&{if} $\\{gf\_ptr}>0$ \1\&{then}\5
+$\\{write\_gf}(0,\39\\{gf\_ptr}-1)$\2\par
+\U1182.\fi
+
+\M1157. The \\{gf\_four} procedure outputs four bytes in two's complement
+notation,
+without risking arithmetic overflow.
+
+\Y\P$\4\X1154:Declare generic font output procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{gf\_four}(\|x:\\{integer})$;\2\6
+\&{begin} \37\&{if} $\|x\G0$ \1\&{then}\5
+$\\{gf\_out}(\|x\mathbin{\&{div}}\\{three\_bytes})$\6
+\4\&{else} \&{begin} \37$\|x\K\|x+\O{10000000000}$;\5
+$\|x\K\|x+\O{10000000000}$;\5
+$\\{gf\_out}((\|x\mathbin{\&{div}}\\{three\_bytes})+128)$;\6
+\&{end};\2\6
+$\|x\K\|x\mathbin{\&{mod}}\\{three\_bytes}$;\5
+$\\{gf\_out}(\|x\mathbin{\&{div}}\\{unity})$;\5
+$\|x\K\|x\mathbin{\&{mod}}\\{unity}$;\5
+$\\{gf\_out}(\|x\mathbin{\&{div}}\O{400})$;\5
+$\\{gf\_out}(\|x\mathbin{\&{mod}}\O{400})$;\6
+\&{end};\par
+\fi
+
+\M1158. Of course, it's even easier to output just two or three bytes.
+
+\Y\P$\4\X1154:Declare generic font output procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{gf\_two}(\|x:\\{integer})$;\2\6
+\&{begin} \37$\\{gf\_out}(\|x\mathbin{\&{div}}\O{400})$;\5
+$\\{gf\_out}(\|x\mathbin{\&{mod}}\O{400})$;\6
+\&{end};\7
+\4\&{procedure}\1\ \37$\\{gf\_three}(\|x:\\{integer})$;\2\6
+\&{begin} \37$\\{gf\_out}(\|x\mathbin{\&{div}}\\{unity})$;\5
+$\\{gf\_out}((\|x\mathbin{\&{mod}}\\{unity})\mathbin{\&{div}}\O{400})$;\5
+$\\{gf\_out}(\|x\mathbin{\&{mod}}\O{400})$;\6
+\&{end};\par
+\fi
+
+\M1159. We need a simple routine to generate a \\{paint}
+command of the appropriate type.
+
+\Y\P$\4\X1154:Declare generic font output procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{gf\_paint}(\|d:\\{integer})$;\C{here $0\L\|d<65536$}%
+\2\6
+\&{begin} \37\&{if} $\|d<64$ \1\&{then}\5
+$\\{gf\_out}(\\{paint\_0}+\|d)$\6
+\4\&{else} \&{if} $\|d<256$ \1\&{then}\6
+\&{begin} \37$\\{gf\_out}(\\{paint1})$;\5
+$\\{gf\_out}(\|d)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{gf\_out}(\\{paint1}+1)$;\5
+$\\{gf\_two}(\|d)$;\6
+\&{end};\2\2\6
+\&{end};\par
+\fi
+
+\M1160. And \\{gf\_string} outputs one or two strings. If the first string
+number
+is nonzero, an \\{xxx} command is generated.
+
+\Y\P$\4\X1154:Declare generic font output procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{gf\_string}(\|s,\39\|t:\\{str\_number})$;\6
+\4\&{var} \37\|k: \37\\{pool\_pointer};\5
+\|l: \37\\{integer};\C{length of the strings to output}\2\6
+\&{begin} \37\&{if} $\|s\I0$ \1\&{then}\6
+\&{begin} \37$\|l\K\\{length}(\|s)$;\6
+\&{if} $\|t\I0$ \1\&{then}\5
+$\|l\K\|l+\\{length}(\|t)$;\2\6
+\&{if} $\|l\L255$ \1\&{then}\6
+\&{begin} \37$\\{gf\_out}(\\{xxx1})$;\5
+$\\{gf\_out}(\|l)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{gf\_out}(\\{xxx3})$;\5
+$\\{gf\_three}(\|l)$;\6
+\&{end};\2\6
+\&{for} $\|k\K\\{str\_start}[\|s]\mathrel{\&{to}}\\{str\_start}[\|s+1]-1$ \1%
+\&{do}\5
+$\\{gf\_out}(\\{so}(\\{str\_pool}[\|k]))$;\2\6
+\&{end};\2\6
+\&{if} $\|t\I0$ \1\&{then}\6
+\&{for} $\|k\K\\{str\_start}[\|t]\mathrel{\&{to}}\\{str\_start}[\|t+1]-1$ \1%
+\&{do}\5
+$\\{gf\_out}(\\{so}(\\{str\_pool}[\|k]))$;\2\2\6
+\&{end};\par
+\fi
+
+\M1161. The choice between \\{boc} commands is handled by \\{gf\_boc}.
+
+\Y\P\D $\\{one\_byte}(\#)\S\#\G0$ \&{then} \6
+\&{if} $\#<256$\par
+\Y\P$\4\X1154:Declare generic font output procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{gf\_boc}(\\{min\_m},\39\\{max\_m},\39\\{min\_n},\39%
+\\{max\_n}:\\{integer})$;\6
+\4\&{label} \37\\{exit};\2\6
+\&{begin} \37\&{if} $\\{min\_m}<\\{gf\_min\_m}$ \1\&{then}\5
+$\\{gf\_min\_m}\K\\{min\_m}$;\2\6
+\&{if} $\\{max\_n}>\\{gf\_max\_n}$ \1\&{then}\5
+$\\{gf\_max\_n}\K\\{max\_n}$;\2\6
+\&{if} $\\{boc\_p}=-1$ \1\&{then}\6
+\&{if} $\\{one\_byte}(\\{boc\_c})$ \1\&{then}\6
+\&{if} $\\{one\_byte}(\\{max\_m}-\\{min\_m})$ \1\&{then}\6
+\&{if} $\\{one\_byte}(\\{max\_m})$ \1\&{then}\6
+\&{if} $\\{one\_byte}(\\{max\_n}-\\{min\_n})$ \1\&{then}\6
+\&{if} $\\{one\_byte}(\\{max\_n})$ \1\&{then}\6
+\&{begin} \37$\\{gf\_out}(\\{boc1})$;\5
+$\\{gf\_out}(\\{boc\_c})$;\6
+$\\{gf\_out}(\\{max\_m}-\\{min\_m})$;\5
+$\\{gf\_out}(\\{max\_m})$;\5
+$\\{gf\_out}(\\{max\_n}-\\{min\_n})$;\5
+$\\{gf\_out}(\\{max\_n})$;\5
+\&{return};\6
+\&{end};\2\2\2\2\2\2\6
+$\\{gf\_out}(\\{boc})$;\5
+$\\{gf\_four}(\\{boc\_c})$;\5
+$\\{gf\_four}(\\{boc\_p})$;\6
+$\\{gf\_four}(\\{min\_m})$;\5
+$\\{gf\_four}(\\{max\_m})$;\5
+$\\{gf\_four}(\\{min\_n})$;\5
+$\\{gf\_four}(\\{max\_n})$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M1162. Two of the parameters to \\{gf\_boc} are global.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4$\\{boc\_c},\39\\{boc\_p}$: \37\\{integer};\C{parameters of the next \\{boc}
+command}\par
+\fi
+
+\M1163. Here is a routine that gets a \.{GF} file off to a good start.
+
+\Y\P\D \37$\\{check\_gf}\S\hbox{}$\ \&{if} $\\{output\_file\_name}=0$ \1%
+\&{then}\5
+\\{init\_gf}\2\par
+\Y\P$\4\X1154:Declare generic font output procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{init\_gf};\6
+\4\&{var} \37\|k: \37\\{eight\_bits};\C{runs through all possible character
+codes}\6
+\|t: \37\\{integer};\C{the time of this run}\2\6
+\&{begin} \37$\\{gf\_min\_m}\K4096$;\5
+$\\{gf\_max\_m}\K-4096$;\5
+$\\{gf\_min\_n}\K4096$;\5
+$\\{gf\_max\_n}\K-4096$;\6
+\&{for} $\|k\K0\mathrel{\&{to}}255$ \1\&{do}\5
+$\\{char\_ptr}[\|k]\K-1$;\2\6
+\X1164:Determine the file extension, \\{gf\_ext}\X;\6
+\\{set\_output\_file\_name};\5
+$\\{gf\_out}(\\{pre})$;\5
+$\\{gf\_out}(\\{gf\_id\_byte})$;\C{begin to output the preamble}\6
+$\\{old\_setting}\K\\{selector}$;\5
+$\\{selector}\K\\{new\_string}$;\5
+$\\{print}(\.{"\ METAFONT\ output\ "})$;\5
+$\\{print\_int}(\\{round\_unscaled}(\\{internal}[\\{year}]))$;\5
+$\\{print\_char}(\.{"."})$;\5
+$\\{print\_dd}(\\{round\_unscaled}(\\{internal}[\\{month}]))$;\5
+$\\{print\_char}(\.{"."})$;\5
+$\\{print\_dd}(\\{round\_unscaled}(\\{internal}[\\{day}]))$;\5
+$\\{print\_char}(\.{":"})$;\6
+$\|t\K\\{round\_unscaled}(\\{internal}[\\{time}])$;\5
+$\\{print\_dd}(\|t\mathbin{\&{div}}60)$;\5
+$\\{print\_dd}(\|t\mathbin{\&{mod}}60)$;\6
+$\\{selector}\K\\{old\_setting}$;\5
+$\\{gf\_out}(\\{cur\_length})$;\5
+$\\{str\_start}[\\{str\_ptr}+1]\K\\{pool\_ptr}$;\5
+$\\{gf\_string}(0,\39\\{str\_ptr})$;\5
+$\\{pool\_ptr}\K\\{str\_start}[\\{str\_ptr}]$;\C{flush that string from memory}%
+\6
+$\\{gf\_prev\_ptr}\K\\{gf\_offset}+\\{gf\_ptr}$;\6
+\&{end};\par
+\fi
+
+\M1164. \P$\X1164:Determine the file extension, \\{gf\_ext}\X\S$\6
+\&{if} $\\{internal}[\\{hppp}]\L0$ \1\&{then}\5
+$\\{gf\_ext}\K\.{".gf"}$\6
+\4\&{else} \&{begin} \37$\\{old\_setting}\K\\{selector}$;\5
+$\\{selector}\K\\{new\_string}$;\5
+$\\{print\_char}(\.{"."})$;\5
+$\\{print\_int}(\\{make\_scaled}(\\{internal}[\\{hppp}],\3959429463))$;%
+\C{$2^{32}/72.27\approx59429463.07$}\6
+$\\{print}(\.{"gf"})$;\5
+$\\{gf\_ext}\K\\{make\_string}$;\5
+$\\{selector}\K\\{old\_setting}$;\6
+\&{end}\2\par
+\U1163.\fi
+
+\M1165. With those preliminaries out of the way, \\{ship\_out} is not
+especially
+difficult.
+
+\Y\P$\4\X1154:Declare generic font output procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37$\\{ship\_out}(\|c:\\{eight\_bits})$;\6
+\4\&{label} \37\\{done};\6
+\4\&{var} \37\|f: \37\\{integer};\C{current character extension}\6
+$\\{prev\_m},\39\|m,\39\\{mm}$: \37\\{integer};\C{previous and current pixel
+column numbers}\6
+$\\{prev\_n},\39\|n$: \37\\{integer};\C{previous and current pixel row numbers}%
+\6
+$\|p,\39\|q$: \37\\{pointer};\C{for list traversal}\6
+$\\{prev\_w},\39\|w,\39\\{ww}$: \37\\{integer};\C{old and new weights}\6
+\|d: \37\\{integer};\C{data from edge-weight node}\6
+\\{delta}: \37\\{integer};\C{number of rows to skip}\6
+\\{cur\_min\_m}: \37\\{integer};\C{starting column, relative to the current
+offset}\6
+$\\{x\_off},\39\\{y\_off}$: \37\\{integer};\C{offsets, rounded to integers}\2\6
+\&{begin} \37\\{check\_gf};\5
+$\|f\K\\{round\_unscaled}(\\{internal}[\\{char\_ext}])$;\6
+$\\{x\_off}\K\\{round\_unscaled}(\\{internal}[\\{x\_offset}])$;\5
+$\\{y\_off}\K\\{round\_unscaled}(\\{internal}[\\{y\_offset}])$;\6
+\&{if} $\\{term\_offset}>\\{max\_print\_line}-9$ \1\&{then}\5
+\\{print\_ln}\6
+\4\&{else} \&{if} $(\\{term\_offset}>0)\V(\\{file\_offset}>0)$ \1\&{then}\5
+$\\{print\_char}(\.{"\ "})$;\2\2\6
+$\\{print\_char}(\.{"["})$;\5
+$\\{print\_int}(\|c)$;\6
+\&{if} $\|f\I0$ \1\&{then}\6
+\&{begin} \37$\\{print\_char}(\.{"."})$;\5
+$\\{print\_int}(\|f)$;\6
+\&{end};\2\6
+\\{update\_terminal};\5
+$\\{boc\_c}\K256\ast\|f+\|c$;\5
+$\\{boc\_p}\K\\{char\_ptr}[\|c]$;\5
+$\\{char\_ptr}[\|c]\K\\{gf\_prev\_ptr}$;\6
+\&{if} $\\{internal}[\\{proofing}]>0$ \1\&{then}\5
+\X1166:Send nonzero offsets to the output file\X;\2\6
+\X1167:Output the character represented in \\{cur\_edges}\X;\6
+$\\{gf\_out}(\\{eoc})$;\5
+$\\{gf\_prev\_ptr}\K\\{gf\_offset}+\\{gf\_ptr}$;\5
+$\\{incr}(\\{total\_chars})$;\5
+$\\{print\_char}(\.{"]"})$;\5
+\\{update\_terminal};\C{progress report}\6
+\&{if} $\\{internal}[\\{tracing\_output}]>0$ \1\&{then}\5
+$\\{print\_edges}(\.{"\ (just\ shipped\ out)"},\39\\{true},\39\\{x\_off},\39%
+\\{y\_off})$;\2\6
+\&{end};\par
+\fi
+
+\M1166. \P$\X1166:Send nonzero offsets to the output file\X\S$\6
+\&{begin} \37\&{if} $\\{x\_off}\I0$ \1\&{then}\6
+\&{begin} \37$\\{gf\_string}(\.{"xoffset"},\390)$;\5
+$\\{gf\_out}(\\{yyy})$;\5
+$\\{gf\_four}(\\{x\_off}\ast\\{unity})$;\6
+\&{end};\2\6
+\&{if} $\\{y\_off}\I0$ \1\&{then}\6
+\&{begin} \37$\\{gf\_string}(\.{"yoffset"},\390)$;\5
+$\\{gf\_out}(\\{yyy})$;\5
+$\\{gf\_four}(\\{y\_off}\ast\\{unity})$;\6
+\&{end};\2\6
+\&{end}\par
+\U1165.\fi
+
+\M1167. \P$\X1167:Output the character represented in \\{cur\_edges}\X\S$\6
+$\\{prev\_n}\K4096$;\5
+$\|p\K\\{knil}(\\{cur\_edges})$;\5
+$\|n\K\\{n\_max}(\\{cur\_edges})-\\{zero\_field}$;\6
+\&{while} $\|p\I\\{cur\_edges}$ \1\&{do}\6
+\&{begin} \37\X1169:Output the pixels of edge row \|p to font row \|n\X;\6
+$\|p\K\\{knil}(\|p)$;\5
+$\\{decr}(\|n)$;\6
+\&{end};\2\6
+\&{if} $\\{prev\_n}=4096$ \1\&{then}\5
+\X1168:Finish off an entirely blank character\X\6
+\4\&{else} \&{if} $\\{prev\_n}+\\{y\_off}<\\{gf\_min\_n}$ \1\&{then}\5
+$\\{gf\_min\_n}\K\\{prev\_n}+\\{y\_off}$\2\2\par
+\U1165.\fi
+
+\M1168. \P$\X1168:Finish off an entirely blank character\X\S$\6
+\&{begin} \37$\\{gf\_boc}(0,\390,\390,\390)$;\6
+\&{if} $\\{gf\_max\_m}<0$ \1\&{then}\5
+$\\{gf\_max\_m}\K0$;\2\6
+\&{if} $\\{gf\_min\_n}>0$ \1\&{then}\5
+$\\{gf\_min\_n}\K0$;\2\6
+\&{end}\par
+\U1167.\fi
+
+\M1169. In this loop, \\{prev\_w} represents the weight at column \\{prev\_m},
+which is
+the most recent column reflected in the output so far; \|w represents the
+weight at column~\|m, which is the most recent column in the edge data.
+Several edges might cancel at the same column position, so we need to
+look ahead to column~\\{mm} before actually outputting anything.
+
+\Y\P$\4\X1169:Output the pixels of edge row \|p to font row \|n\X\S$\6
+\&{if} $\\{unsorted}(\|p)>\\{void}$ \1\&{then}\5
+$\\{sort\_edges}(\|p)$;\2\6
+$\|q\K\\{sorted}(\|p)$;\5
+$\|w\K0$;\5
+$\\{prev\_m}\K-\\{fraction\_one}$;\C{$\\{fraction\_one}\approx\infty$}\6
+$\\{ww}\K0$;\5
+$\\{prev\_w}\K0$;\5
+$\|m\K\\{prev\_m}$;\6
+\1\&{repeat} \37\&{if} $\|q=\\{sentinel}$ \1\&{then}\5
+$\\{mm}\K\\{fraction\_one}$\6
+\4\&{else} \&{begin} \37$\|d\K\\{ho}(\\{info}(\|q))$;\5
+$\\{mm}\K\|d\mathbin{\&{div}}8$;\5
+$\\{ww}\K\\{ww}+(\|d\mathbin{\&{mod}}8)-\\{zero\_w}$;\6
+\&{end};\2\6
+\&{if} $\\{mm}\I\|m$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{prev\_w}\L0$ \1\&{then}\6
+\&{begin} \37\&{if} $\|w>0$ \1\&{then}\5
+\X1170:Start black at $(m,n)$\X;\2\6
+\&{end}\6
+\4\&{else} \&{if} $\|w\L0$ \1\&{then}\5
+\X1171:Stop black at $(m,n)$\X;\2\2\6
+$\|m\K\\{mm}$;\6
+\&{end};\2\6
+$\|w\K\\{ww}$;\5
+$\|q\K\\{link}(\|q)$;\6
+\4\&{until}\5
+$\\{mm}=\\{fraction\_one}$;\2\6
+\&{if} $\|w\I0$ \1\&{then}\C{this should be impossible}\6
+$\\{print\_nl}(\.{"(There\'s\ unbounded\ black\ in\ character\ shipped\
+out!)"})$;\2\6
+\&{if} $\\{prev\_m}-\\{m\_offset}(\\{cur\_edges})+\\{x\_off}>\\{gf\_max\_m}$ \1%
+\&{then}\5
+$\\{gf\_max\_m}\K\\{prev\_m}-\\{m\_offset}(\\{cur\_edges})+\\{x\_off}$\2\par
+\U1167.\fi
+
+\M1170. \P$\X1170:Start black at $(m,n)$\X\S$\6
+\&{begin} \37\&{if} $\\{prev\_m}=-\\{fraction\_one}$ \1\&{then}\5
+\X1172:Start a new row at $(m,n)$\X\6
+\4\&{else} $\\{gf\_paint}(\|m-\\{prev\_m})$;\2\6
+$\\{prev\_m}\K\|m$;\5
+$\\{prev\_w}\K\|w$;\6
+\&{end}\par
+\U1169.\fi
+
+\M1171. \P$\X1171:Stop black at $(m,n)$\X\S$\6
+\&{begin} \37$\\{gf\_paint}(\|m-\\{prev\_m})$;\5
+$\\{prev\_m}\K\|m$;\5
+$\\{prev\_w}\K\|w$;\6
+\&{end}\par
+\U1169.\fi
+
+\M1172. \P$\X1172:Start a new row at $(m,n)$\X\S$\6
+\&{begin} \37\&{if} $\\{prev\_n}=4096$ \1\&{then}\6
+\&{begin} \37$\\{gf\_boc}(\\{m\_min}(\\{cur\_edges})+\\{x\_off}-\\{zero%
+\_field},\39\\{m\_max}(\\{cur\_edges})+\\{x\_off}-\\{zero\_field},\39\30\\{n%
+\_min}(\\{cur\_edges})+\\{y\_off}-\\{zero\_field},\39\|n+\\{y\_off})$;\5
+$\\{cur\_min\_m}\K\\{m\_min}(\\{cur\_edges})-\\{zero\_field}+\\{m\_offset}(%
+\\{cur\_edges})$;\6
+\&{end}\6
+\4\&{else} \&{if} $\\{prev\_n}>\|n+1$ \1\&{then}\5
+\X1174:Skip down $\\{prev\_n}-\|n$ rows\X\6
+\4\&{else} \X1173:Skip to column $m$ in the next row and \&{goto} \\{done}, or
+skip zero rows\X;\2\2\6
+$\\{gf\_paint}(\|m-\\{cur\_min\_m})$;\C{skip to column $m$, painting white}\6
+\4\\{done}: \37$\\{prev\_n}\K\|n$;\6
+\&{end}\par
+\U1170.\fi
+
+\M1173. \P$\X1173:Skip to column $m$ in the next row and \&{goto} \\{done}, or
+skip zero rows\X\S$\6
+\&{begin} \37$\\{delta}\K\|m-\\{cur\_min\_m}$;\6
+\&{if} $\\{delta}>\\{max\_new\_row}$ \1\&{then}\5
+$\\{gf\_out}(\\{skip0})$\6
+\4\&{else} \&{begin} \37$\\{gf\_out}(\\{new\_row\_0}+\\{delta})$;\5
+\&{goto} \37\\{done};\6
+\&{end};\2\6
+\&{end}\par
+\U1172.\fi
+
+\M1174. \P$\X1174:Skip down $\\{prev\_n}-\|n$ rows\X\S$\6
+\&{begin} \37$\\{delta}\K\\{prev\_n}-\|n-1$;\6
+\&{if} $\\{delta}<\O{400}$ \1\&{then}\6
+\&{begin} \37$\\{gf\_out}(\\{skip1})$;\5
+$\\{gf\_out}(\\{delta})$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{gf\_out}(\\{skip1}+1)$;\5
+$\\{gf\_two}(\\{delta})$;\6
+\&{end};\2\6
+\&{end}\par
+\U1172.\fi
+
+\M1175. Now that we've finished \\{ship\_out}, let's look at the other commands
+by which a user can send things to the \.{GF} file.
+
+\Y\P$\4\X1020:Cases of \\{do\_statement} that invoke particular commands\X%
+\mathrel{+}\S$\6
+\4\\{special\_command}: \37\\{do\_special};\par
+\fi
+
+\M1176. \P$\X192:Put each of \MF's primitives into the hash table\X\mathrel{+}%
+\S$\6
+$\\{primitive}(\.{"special"},\39\\{special\_command},\39\\{string\_type})$;\6
+$\\{primitive}(\.{"numspecial"},\39\\{special\_command},\39\\{known})$;\par
+\fi
+
+\M1177. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{do\_special};\6
+\4\&{var} \37\|m: \37\\{small\_number};\C{either \\{string\_type} or \\{known}}%
+\2\6
+\&{begin} \37$\|m\K\\{cur\_mod}$;\5
+\\{get\_x\_next};\5
+\\{scan\_expression};\6
+\&{if} $\\{internal}[\\{proofing}]\G0$ \1\&{then}\6
+\&{if} $\\{cur\_type}\I\|m$ \1\&{then}\5
+\X1178:Complain about improper special operation\X\6
+\4\&{else} \&{begin} \37\\{check\_gf};\6
+\&{if} $\|m=\\{string\_type}$ \1\&{then}\5
+$\\{gf\_string}(\\{cur\_exp},\390)$\6
+\4\&{else} \&{begin} \37$\\{gf\_out}(\\{yyy})$;\5
+$\\{gf\_four}(\\{cur\_exp})$;\6
+\&{end};\2\6
+\&{end};\2\2\6
+$\\{flush\_cur\_exp}(0)$;\6
+\&{end};\par
+\fi
+
+\M1178. \P$\X1178:Complain about improper special operation\X\S$\6
+\&{begin} \37$\\{exp\_err}(\.{"Unsuitable\ expression"})$;\5
+$\\{help1}(\.{"The\ expression\ shown\ above\ has\ the\ wrong\ type\ to\ be\
+output."})$;\5
+\\{put\_get\_error};\6
+\&{end}\par
+\U1177.\fi
+
+\M1179. \P$\X1179:Send the current expression as a title to the output file\X%
+\S$\6
+\&{begin} \37\\{check\_gf};\5
+$\\{gf\_string}(\.{"title\ "},\39\\{cur\_exp})$;\6
+\&{end}\par
+\U994.\fi
+
+\M1180. \P$\X212:Cases of \\{print\_cmd\_mod} for symbolic printing of
+primitives\X\mathrel{+}\S$\6
+\4\\{special\_command}: \37\&{if} $\|m=\\{known}$ \1\&{then}\5
+$\\{print}(\.{"numspecial"})$\6
+\4\&{else} $\\{print}(\.{"special"})$;\2\par
+\fi
+
+\M1181. \P$\X1181:Determine if a character has been shipped out\X\S$\6
+\&{begin} \37$\\{cur\_exp}\K\\{round\_unscaled}(\\{cur\_exp})\mathbin{%
+\&{mod}}256$;\6
+\&{if} $\\{cur\_exp}<0$ \1\&{then}\5
+$\\{cur\_exp}\K\\{cur\_exp}+256$;\2\6
+$\\{boolean\_reset}(\\{char\_exists}[\\{cur\_exp}])$;\5
+$\\{cur\_type}\K\\{boolean\_type}$;\6
+\&{end}\par
+\U906.\fi
+
+\M1182. At the end of the program we must finish things off by writing the
+postamble.
+The \.{TFM} information should have been computed first.
+
+An integer variable \|k and a \\{scaled} variable \|x will be declared for
+use by this routine.
+
+\Y\P$\4\X1182:Finish the \.{GF} file\X\S$\6
+\&{begin} \37$\\{gf\_out}(\\{post})$;\C{beginning of the postamble}\6
+$\\{gf\_four}(\\{gf\_prev\_ptr})$;\5
+$\\{gf\_prev\_ptr}\K\\{gf\_offset}+\\{gf\_ptr}-5$;\C{\\{post} location}\6
+$\\{gf\_four}(\\{internal}[\\{design\_size}]\ast16)$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}4$ \1\&{do}\5
+$\\{gf\_out}(\\{header\_byte}[\|k])$;\C{the check sum}\2\6
+$\\{gf\_four}(\\{internal}[\\{hppp}])$;\5
+$\\{gf\_four}(\\{internal}[\\{vppp}])$;\6
+$\\{gf\_four}(\\{gf\_min\_m})$;\5
+$\\{gf\_four}(\\{gf\_max\_m})$;\5
+$\\{gf\_four}(\\{gf\_min\_n})$;\5
+$\\{gf\_four}(\\{gf\_max\_n})$;\6
+\&{for} $\|k\K0\mathrel{\&{to}}255$ \1\&{do}\6
+\&{if} $\\{char\_exists}[\|k]$ \1\&{then}\6
+\&{begin} \37$\|x\K\\{gf\_dx}[\|k]\mathbin{\&{div}}\\{unity}$;\6
+\&{if} $(\\{gf\_dy}[\|k]=0)\W(\|x\G0)\W(\|x<256)\W(\\{gf\_dx}[\|k]=\|x\ast%
+\\{unity})$ \1\&{then}\6
+\&{begin} \37$\\{gf\_out}(\\{char\_loc}+1)$;\5
+$\\{gf\_out}(\|k)$;\5
+$\\{gf\_out}(\|x)$;\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{gf\_out}(\\{char\_loc})$;\5
+$\\{gf\_out}(\|k)$;\5
+$\\{gf\_four}(\\{gf\_dx}[\|k])$;\5
+$\\{gf\_four}(\\{gf\_dy}[\|k])$;\6
+\&{end};\2\6
+$\|x\K\\{value}(\\{tfm\_width}[\|k])$;\6
+\&{if} $\\{abs}(\|x)>\\{max\_tfm\_dimen}$ \1\&{then}\6
+\&{if} $\|x>0$ \1\&{then}\5
+$\|x\K\\{three\_bytes}-1$\ \&{else} $\|x\K1-\\{three\_bytes}$\2\6
+\4\&{else} $\|x\K\\{make\_scaled}(\|x\ast16,\39\\{internal}[\\{design%
+\_size}])$;\2\6
+$\\{gf\_four}(\|x)$;\5
+$\\{gf\_four}(\\{char\_ptr}[\|k])$;\6
+\&{end};\2\2\6
+$\\{gf\_out}(\\{post\_post})$;\5
+$\\{gf\_four}(\\{gf\_prev\_ptr})$;\5
+$\\{gf\_out}(\\{gf\_id\_byte})$;\6
+$\|k\K4+((\\{gf\_buf\_size}-\\{gf\_ptr})\mathbin{\&{mod}}4)$;\C{the number of
+223's}\6
+\&{while} $\|k>0$ \1\&{do}\6
+\&{begin} \37$\\{gf\_out}(223)$;\5
+$\\{decr}(\|k)$;\6
+\&{end};\2\6
+\X1156:Empty the last bytes out of \\{gf\_buf}\X;\6
+$\\{print\_nl}(\.{"Output\ written\ on\ "})$;\5
+$\\{slow\_print}(\\{output\_file\_name})$;\5
+$\\{print}(\.{"\ ("})$;\5
+$\\{print\_int}(\\{total\_chars})$;\5
+$\\{print}(\.{"\ character"})$;\6
+\&{if} $\\{total\_chars}\I1$ \1\&{then}\5
+$\\{print\_char}(\.{"s"})$;\2\6
+$\\{print}(\.{",\ "})$;\5
+$\\{print\_int}(\\{gf\_offset}+\\{gf\_ptr})$;\5
+$\\{print}(\.{"\ bytes)."})$;\5
+$\\{b\_close}(\\{gf\_file})$;\6
+\&{end}\par
+\U1206.\fi
+
+\N1183. \[48] Dumping and undumping the tables.
+After \.{INIMF} has seen a collection of macros, it
+can write all the necessary information on an auxiliary file so
+that production versions of \MF\ are able to initialize their
+memory at high speed. The present section of the program takes
+care of such output and input. We shall consider simultaneously
+the processes of storing and restoring,
+so that the inverse relation between them is clear.
+
+The global variable \\{base\_ident} is a string that is printed right
+after the \\{banner} line when \MF\ is ready to start. For \.{INIMF} this
+string says simply `\.{(INIMF)}'; for other versions of \MF\ it says,
+for example, `\.{(preloaded base=plain 84.2.29)}', showing the year,
+month, and day that the base file was created. We have $\\{base\_ident}=0$
+before \MF's tables are loaded.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{base\_ident}: \37\\{str\_number};\par
+\fi
+
+\M1184. \P$\X21:Set initial values of key variables\X\mathrel{+}\S$\6
+$\\{base\_ident}\K0$;\par
+\fi
+
+\M1185. \P$\X176:Initialize table entries (done by \.{INIMF} only)\X\mathrel{+}%
+\S$\6
+$\\{base\_ident}\K\.{"\ (INIMF)"}$;\par
+\fi
+
+\M1186. \P$\X995:Declare action procedures for use by \\{do\_statement}\X%
+\mathrel{+}\S$\6
+\&{init} \37\&{procedure}\1\ \37\\{store\_base\_file};\6
+\4\&{var} \37\|k: \37\\{integer};\C{all-purpose index}\6
+$\|p,\39\|q$: \37\\{pointer};\C{all-purpose pointers}\6
+\|x: \37\\{integer};\C{something to dump}\6
+\|w: \37\\{four\_quarters};\C{four ASCII codes}\2\6
+\&{begin} \37\X1200:Create the \\{base\_ident}, open the base file, and inform
+the user that dumping has begun\X;\6
+\X1190:Dump constants for consistency check\X;\6
+\X1192:Dump the string pool\X;\6
+\X1194:Dump the dynamic memory\X;\6
+\X1196:Dump the table of equivalents and the hash table\X;\6
+\X1198:Dump a few more things and the closing check word\X;\6
+\X1201:Close the base file\X;\6
+\&{end};\6
+\&{tini}\par
+\fi
+
+\M1187. Corresponding to the procedure that dumps a base file, we also have a
+function
+that reads~one~in. The function returns \\{false} if the dumped base is
+incompatible with the present \MF\ table sizes, etc.
+
+\Y\P\D \37$\\{off\_base}=6666$\C{go here if the base file is unacceptable}\par
+\P\D \37$\\{too\_small}(\#)\S$\1\6
+\&{begin} \37\\{wake\_up\_terminal};\5
+$\\{wterm\_ln}(\.{\'---!\ Must\ increase\ the\ \'},\39\#)$;\5
+\&{goto} \37\\{off\_base};\6
+\&{end}\2\par
+\Y\P\hbox{\4}\X779:Declare the function called \\{open\_base\_file}\X\6
+\4\&{function}\1\ \37\\{load\_base\_file}: \37\\{boolean};\6
+\4\&{label} \37$\\{off\_base},\39\\{exit}$;\6
+\4\&{var} \37\|k: \37\\{integer};\C{all-purpose index}\6
+$\|p,\39\|q$: \37\\{pointer};\C{all-purpose pointers}\6
+\|x: \37\\{integer};\C{something undumped}\6
+\|w: \37\\{four\_quarters};\C{four ASCII codes}\2\6
+\&{begin} \37\X1191:Undump constants for consistency check\X;\6
+\X1193:Undump the string pool\X;\6
+\X1195:Undump the dynamic memory\X;\6
+\X1197:Undump the table of equivalents and the hash table\X;\6
+\X1199:Undump a few more things and the closing check word\X;\6
+$\\{load\_base\_file}\K\\{true}$;\5
+\&{return};\C{it worked!}\6
+\4\\{off\_base}: \37\\{wake\_up\_terminal};\5
+$\\{wterm\_ln}(\.{\'(Fatal\ base\ file\ error;\ I\'}\.{\'m\ stymied)\'})$;\5
+$\\{load\_base\_file}\K\\{false}$;\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M1188. Base files consist of \\{memory\_word} items, and we use the following
+macros to dump words of different types:
+
+\Y\P\D \37$\\{dump\_wd}(\#)\S$\1\6
+\&{begin} \37$\\{base\_file}\^\K\#$;\5
+$\\{put}(\\{base\_file})$;\ \&{end}\2\par
+\P\D \37$\\{dump\_int}(\#)\S$\1\6
+\&{begin} \37$\\{base\_file}\^.\\{int}\K\#$;\5
+$\\{put}(\\{base\_file})$;\ \&{end}\2\par
+\P\D \37$\\{dump\_hh}(\#)\S$\1\6
+\&{begin} \37$\\{base\_file}\^.\\{hh}\K\#$;\5
+$\\{put}(\\{base\_file})$;\ \&{end}\2\par
+\P\D \37$\\{dump\_qqqq}(\#)\S$\1\6
+\&{begin} \37$\\{base\_file}\^.\\{qqqq}\K\#$;\5
+$\\{put}(\\{base\_file})$;\ \&{end}\2\par
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{base\_file}: \37\\{word\_file};\C{for input or output of base information}%
+\par
+\fi
+
+\M1189. The inverse macros are slightly more complicated, since we need to
+check
+the range of the values we are reading in. We say `$\\{undump}(\|a)(\|b)(\|x)$'
+to
+read an integer value \|x that is supposed to be in the range $\|a\L\|x\L\|b$.
+
+\Y\P\D \37$\\{undump\_wd}(\#)\S$\1\6
+\&{begin} \37$\\{get}(\\{base\_file})$;\5
+$\#\K\\{base\_file}\^$;\ \&{end}\2\par
+\P\D \37$\\{undump\_int}(\#)\S$\1\6
+\&{begin} \37$\\{get}(\\{base\_file})$;\5
+$\#\K\\{base\_file}\^.\\{int}$;\ \&{end}\2\par
+\P\D \37$\\{undump\_hh}(\#)\S$\1\6
+\&{begin} \37$\\{get}(\\{base\_file})$;\5
+$\#\K\\{base\_file}\^.\\{hh}$;\ \&{end}\2\par
+\P\D \37$\\{undump\_qqqq}(\#)\S$\1\6
+\&{begin} \37$\\{get}(\\{base\_file})$;\5
+$\#\K\\{base\_file}\^.\\{qqqq}$;\ \&{end}\2\par
+\P\D \37$\\{undump\_end\_end}(\#)\S\#\K\|x$;\ \&{end} \par
+\P\D $\\{undump\_end}(\#)\S(\|x>\#)$ \&{then} \&{goto} \37\\{off\_base}\ %
+\&{else} \37\\{undump\_end\_end}\par
+\P\D $\\{undump}(\#)\S$ \6
+\&{begin} \37$\\{undump\_int}(\|x)$; \6
+\&{if} $(\|x<\#)\V\\{undump\_end}$\par
+\P\D \37$\\{undump\_size\_end\_end}(\#)\S\\{too\_small}(\#)$\ \&{else} \37%
+\\{undump\_end\_end}\par
+\P\D \37$\\{undump\_size\_end}(\#)\S$\1\6
+\&{if} $\|x>\#$ \1\&{then}\5
+\\{undump\_size\_end\_end}\2\2\par
+\P\D $\\{undump\_size}(\#)\S$ \6
+\&{begin} \37$\\{undump\_int}(\|x)$;\6
+\&{if} $\|x<\#$ \1\&{then}\5
+\&{goto} \37\\{off\_base};\2\6
+\\{undump\_size\_end}\par
+\fi
+
+\M1190. The next few sections of the program should make it clear how we use
+the
+dump/undump macros.
+
+\Y\P$\4\X1190:Dump constants for consistency check\X\S$\6
+$\\{dump\_int}(\))$;\6
+$\\{dump\_int}(\\{mem\_min})$;\6
+$\\{dump\_int}(\\{mem\_top})$;\6
+$\\{dump\_int}(\\{hash\_size})$;\6
+$\\{dump\_int}(\\{hash\_prime})$;\6
+$\\{dump\_int}(\\{max\_in\_open})$\par
+\U1186.\fi
+
+\M1191. Sections of a \.{WEB} program that are ``commented out'' still
+contribute
+strings to the string pool; therefore \.{INIMF} and \MF\ will have
+the same strings. (And it is, of course, a good thing that they do.)
+
+\Y\P$\4\X1191:Undump constants for consistency check\X\S$\6
+$\|x\K\\{base\_file}\^.\\{int}$;\6
+\&{if} $\|x\I\)$ \1\&{then}\5
+\&{goto} \37\\{off\_base};\C{check that strings are the same}\2\6
+$\\{undump\_int}(\|x)$;\6
+\&{if} $\|x\I\\{mem\_min}$ \1\&{then}\5
+\&{goto} \37\\{off\_base};\2\6
+$\\{undump\_int}(\|x)$;\6
+\&{if} $\|x\I\\{mem\_top}$ \1\&{then}\5
+\&{goto} \37\\{off\_base};\2\6
+$\\{undump\_int}(\|x)$;\6
+\&{if} $\|x\I\\{hash\_size}$ \1\&{then}\5
+\&{goto} \37\\{off\_base};\2\6
+$\\{undump\_int}(\|x)$;\6
+\&{if} $\|x\I\\{hash\_prime}$ \1\&{then}\5
+\&{goto} \37\\{off\_base};\2\6
+$\\{undump\_int}(\|x)$;\6
+\&{if} $\|x\I\\{max\_in\_open}$ \1\&{then}\5
+\&{goto} \37\\{off\_base}\2\par
+\U1187.\fi
+
+\M1192. \P\D \37$\\{dump\_four\_ASCII}\S\|w.\\{b0}\K\\{qi}(\\{so}(\\{str%
+\_pool}[\|k]))$;\5
+$\|w.\\{b1}\K\\{qi}(\\{so}(\\{str\_pool}[\|k+1]))$;\5
+$\|w.\\{b2}\K\\{qi}(\\{so}(\\{str\_pool}[\|k+2]))$;\5
+$\|w.\\{b3}\K\\{qi}(\\{so}(\\{str\_pool}[\|k+3]))$;\5
+$\\{dump\_qqqq}(\|w)$\par
+\Y\P$\4\X1192:Dump the string pool\X\S$\6
+$\\{dump\_int}(\\{pool\_ptr})$;\5
+$\\{dump\_int}(\\{str\_ptr})$;\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{str\_ptr}$ \1\&{do}\5
+$\\{dump\_int}(\\{str\_start}[\|k])$;\2\6
+$\|k\K0$;\6
+\&{while} $\|k+4<\\{pool\_ptr}$ \1\&{do}\6
+\&{begin} \37\\{dump\_four\_ASCII};\5
+$\|k\K\|k+4$;\6
+\&{end};\2\6
+$\|k\K\\{pool\_ptr}-4$;\5
+\\{dump\_four\_ASCII};\5
+\\{print\_ln};\5
+$\\{print\_int}(\\{str\_ptr})$;\5
+$\\{print}(\.{"\ strings\ of\ total\ length\ "})$;\5
+$\\{print\_int}(\\{pool\_ptr})$\par
+\U1186.\fi
+
+\M1193. \P\D \37$\\{undump\_four\_ASCII}\S\\{undump\_qqqq}(\|w)$;\5
+$\\{str\_pool}[\|k]\K\\{si}(\\{qo}(\|w.\\{b0}))$;\5
+$\\{str\_pool}[\|k+1]\K\\{si}(\\{qo}(\|w.\\{b1}))$;\5
+$\\{str\_pool}[\|k+2]\K\\{si}(\\{qo}(\|w.\\{b2}))$;\5
+$\\{str\_pool}[\|k+3]\K\\{si}(\\{qo}(\|w.\\{b3}))$\par
+\Y\P$\4\X1193:Undump the string pool\X\S$\6
+$\\{undump\_size}(0)(\\{pool\_size})(\.{\'string\ pool\ size\'})(\\{pool%
+\_ptr})$;\5
+$\\{undump\_size}(0)(\\{max\_strings})(\.{\'max\ strings\'})(\\{str\_ptr})$;\6
+\&{for} $\|k\K0\mathrel{\&{to}}\\{str\_ptr}$ \1\&{do}\6
+\&{begin} \37$\\{undump}(0)(\\{pool\_ptr})(\\{str\_start}[\|k])$;\5
+$\\{str\_ref}[\|k]\K\\{max\_str\_ref}$;\6
+\&{end};\2\6
+$\|k\K0$;\6
+\&{while} $\|k+4<\\{pool\_ptr}$ \1\&{do}\6
+\&{begin} \37\\{undump\_four\_ASCII};\5
+$\|k\K\|k+4$;\6
+\&{end};\2\6
+$\|k\K\\{pool\_ptr}-4$;\5
+\\{undump\_four\_ASCII};\5
+$\\{init\_str\_ptr}\K\\{str\_ptr}$;\5
+$\\{init\_pool\_ptr}\K\\{pool\_ptr}$;\5
+$\\{max\_str\_ptr}\K\\{str\_ptr}$;\5
+$\\{max\_pool\_ptr}\K\\{pool\_ptr}$\par
+\U1187.\fi
+
+\M1194. By sorting the list of available spaces in the variable-size portion of
+\\{mem}, we are usually able to get by without having to dump very much
+of the dynamic memory.
+
+We recompute \\{var\_used} and \\{dyn\_used}, so that \.{INIMF} dumps valid
+information even when it has not been gathering statistics.
+
+\Y\P$\4\X1194:Dump the dynamic memory\X\S$\6
+\\{sort\_avail};\5
+$\\{var\_used}\K0$;\5
+$\\{dump\_int}(\\{lo\_mem\_max})$;\5
+$\\{dump\_int}(\\{rover})$;\5
+$\|p\K\\{mem\_min}$;\5
+$\|q\K\\{rover}$;\5
+$\|x\K0$;\6
+\1\&{repeat} \37\&{for} $\|k\K\|p\mathrel{\&{to}}\|q+1$ \1\&{do}\5
+$\\{dump\_wd}(\\{mem}[\|k])$;\2\6
+$\|x\K\|x+\|q+2-\|p$;\5
+$\\{var\_used}\K\\{var\_used}+\|q-\|p$;\5
+$\|p\K\|q+\\{node\_size}(\|q)$;\5
+$\|q\K\\{rlink}(\|q)$;\6
+\4\&{until}\5
+$\|q=\\{rover}$;\2\6
+$\\{var\_used}\K\\{var\_used}+\\{lo\_mem\_max}-\|p$;\5
+$\\{dyn\_used}\K\\{mem\_end}+1-\\{hi\_mem\_min}$;\6
+\&{for} $\|k\K\|p\mathrel{\&{to}}\\{lo\_mem\_max}$ \1\&{do}\5
+$\\{dump\_wd}(\\{mem}[\|k])$;\2\6
+$\|x\K\|x+\\{lo\_mem\_max}+1-\|p$;\5
+$\\{dump\_int}(\\{hi\_mem\_min})$;\5
+$\\{dump\_int}(\\{avail})$;\6
+\&{for} $\|k\K\\{hi\_mem\_min}\mathrel{\&{to}}\\{mem\_end}$ \1\&{do}\5
+$\\{dump\_wd}(\\{mem}[\|k])$;\2\6
+$\|x\K\|x+\\{mem\_end}+1-\\{hi\_mem\_min}$;\5
+$\|p\K\\{avail}$;\6
+\&{while} $\|p\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\\{decr}(\\{dyn\_used})$;\5
+$\|p\K\\{link}(\|p)$;\6
+\&{end};\2\6
+$\\{dump\_int}(\\{var\_used})$;\5
+$\\{dump\_int}(\\{dyn\_used})$;\5
+\\{print\_ln};\5
+$\\{print\_int}(\|x)$;\5
+$\\{print}(\.{"\ memory\ locations\ dumped;\ current\ usage\ is\ "})$;\5
+$\\{print\_int}(\\{var\_used})$;\5
+$\\{print\_char}(\.{"\&"})$;\5
+$\\{print\_int}(\\{dyn\_used})$\par
+\U1186.\fi
+
+\M1195. \P$\X1195:Undump the dynamic memory\X\S$\6
+$\\{undump}(\\{lo\_mem\_stat\_max}+1000)(\\{hi\_mem\_stat\_min}-1)(\\{lo\_mem%
+\_max})$;\5
+$\\{undump}(\\{lo\_mem\_stat\_max}+1)(\\{lo\_mem\_max})(\\{rover})$;\5
+$\|p\K\\{mem\_min}$;\5
+$\|q\K\\{rover}$;\6
+\1\&{repeat} \37\&{for} $\|k\K\|p\mathrel{\&{to}}\|q+1$ \1\&{do}\5
+$\\{undump\_wd}(\\{mem}[\|k])$;\2\6
+$\|p\K\|q+\\{node\_size}(\|q)$;\6
+\&{if} $(\|p>\\{lo\_mem\_max})\V((\|q\G\\{rlink}(\|q))\W(\\{rlink}(\|q)\I%
+\\{rover}))$ \1\&{then}\5
+\&{goto} \37\\{off\_base};\2\6
+$\|q\K\\{rlink}(\|q)$;\6
+\4\&{until}\5
+$\|q=\\{rover}$;\2\6
+\&{for} $\|k\K\|p\mathrel{\&{to}}\\{lo\_mem\_max}$ \1\&{do}\5
+$\\{undump\_wd}(\\{mem}[\|k])$;\2\6
+$\\{undump}(\\{lo\_mem\_max}+1)(\\{hi\_mem\_stat\_min})(\\{hi\_mem\_min})$;\5
+$\\{undump}(\\{null})(\\{mem\_top})(\\{avail})$;\5
+$\\{mem\_end}\K\\{mem\_top}$;\6
+\&{for} $\|k\K\\{hi\_mem\_min}\mathrel{\&{to}}\\{mem\_end}$ \1\&{do}\5
+$\\{undump\_wd}(\\{mem}[\|k])$;\2\6
+$\\{undump\_int}(\\{var\_used})$;\5
+$\\{undump\_int}(\\{dyn\_used})$\par
+\U1187.\fi
+
+\M1196. A different scheme is used to compress the hash table, since its lower
+region
+is usually sparse. When $\\{text}(\|p)\I0$ for $\|p\L\\{hash\_used}$, we output
+three
+words: \|p, $\\{hash}[\|p]$, and $\\{eqtb}[\|p]$. The hash table is, of course,
+densely
+packed for $\|p\G\\{hash\_used}$, so the remaining entries are output
+in~a~block.
+
+\Y\P$\4\X1196:Dump the table of equivalents and the hash table\X\S$\6
+$\\{dump\_int}(\\{hash\_used})$;\5
+$\\{st\_count}\K\\{frozen\_inaccessible}-1-\\{hash\_used}$;\6
+\&{for} $\|p\K1\mathrel{\&{to}}\\{hash\_used}$ \1\&{do}\6
+\&{if} $\\{text}(\|p)\I0$ \1\&{then}\6
+\&{begin} \37$\\{dump\_int}(\|p)$;\5
+$\\{dump\_hh}(\\{hash}[\|p])$;\5
+$\\{dump\_hh}(\\{eqtb}[\|p])$;\5
+$\\{incr}(\\{st\_count})$;\6
+\&{end};\2\2\6
+\&{for} $\|p\K\\{hash\_used}+1\mathrel{\&{to}}\\{hash\_end}$ \1\&{do}\6
+\&{begin} \37$\\{dump\_hh}(\\{hash}[\|p])$;\5
+$\\{dump\_hh}(\\{eqtb}[\|p])$;\6
+\&{end};\2\6
+$\\{dump\_int}(\\{st\_count})$;\6
+\\{print\_ln};\5
+$\\{print\_int}(\\{st\_count})$;\5
+$\\{print}(\.{"\ symbolic\ tokens"})$\par
+\U1186.\fi
+
+\M1197. \P$\X1197:Undump the table of equivalents and the hash table\X\S$\6
+$\\{undump}(1)(\\{frozen\_inaccessible})(\\{hash\_used})$;\5
+$\|p\K0$;\6
+\1\&{repeat} \37$\\{undump}(\|p+1)(\\{hash\_used})(\|p)$;\5
+$\\{undump\_hh}(\\{hash}[\|p])$;\5
+$\\{undump\_hh}(\\{eqtb}[\|p])$;\6
+\4\&{until}\5
+$\|p=\\{hash\_used}$;\2\6
+\&{for} $\|p\K\\{hash\_used}+1\mathrel{\&{to}}\\{hash\_end}$ \1\&{do}\6
+\&{begin} \37$\\{undump\_hh}(\\{hash}[\|p])$;\5
+$\\{undump\_hh}(\\{eqtb}[\|p])$;\6
+\&{end};\2\6
+$\\{undump\_int}(\\{st\_count})$\par
+\U1187.\fi
+
+\M1198. We have already printed a lot of statistics, so we set $\\{tracing%
+\_stats}\K0$
+to prevent them from appearing again.
+
+\Y\P$\4\X1198:Dump a few more things and the closing check word\X\S$\6
+$\\{dump\_int}(\\{int\_ptr})$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}\\{int\_ptr}$ \1\&{do}\6
+\&{begin} \37$\\{dump\_int}(\\{internal}[\|k])$;\5
+$\\{dump\_int}(\\{int\_name}[\|k])$;\6
+\&{end};\2\6
+$\\{dump\_int}(\\{start\_sym})$;\5
+$\\{dump\_int}(\\{interaction})$;\5
+$\\{dump\_int}(\\{base\_ident})$;\5
+$\\{dump\_int}(\\{bg\_loc})$;\5
+$\\{dump\_int}(\\{eg\_loc})$;\5
+$\\{dump\_int}(\\{serial\_no})$;\5
+$\\{dump\_int}(69069)$;\5
+$\\{internal}[\\{tracing\_stats}]\K0$\par
+\U1186.\fi
+
+\M1199. \P$\X1199:Undump a few more things and the closing check word\X\S$\6
+$\\{undump}(\\{max\_given\_internal})(\\{max\_internal})(\\{int\_ptr})$;\6
+\&{for} $\|k\K1\mathrel{\&{to}}\\{int\_ptr}$ \1\&{do}\6
+\&{begin} \37$\\{undump\_int}(\\{internal}[\|k])$;\5
+$\\{undump}(0)(\\{str\_ptr})(\\{int\_name}[\|k])$;\6
+\&{end};\2\6
+$\\{undump}(0)(\\{frozen\_inaccessible})(\\{start\_sym})$;\5
+$\\{undump}(\\{batch\_mode})(\\{error\_stop\_mode})(\\{interaction})$;\5
+$\\{undump}(0)(\\{str\_ptr})(\\{base\_ident})$;\5
+$\\{undump}(1)(\\{hash\_end})(\\{bg\_loc})$;\5
+$\\{undump}(1)(\\{hash\_end})(\\{eg\_loc})$;\5
+$\\{undump\_int}(\\{serial\_no})$;\6
+$\\{undump\_int}(\|x)$;\ \&{if} $(\|x\I69069)\V\\{eof}(\\{base\_file})$ \1%
+\&{then}\5
+\&{goto} \37\\{off\_base}\2\par
+\U1187.\fi
+
+\M1200. \P$\X1200:Create the \\{base\_ident}, open the base file, and inform
+the user that dumping has begun\X\S$\6
+$\\{selector}\K\\{new\_string}$;\5
+$\\{print}(\.{"\ (preloaded\ base="})$;\5
+$\\{print}(\\{job\_name})$;\5
+$\\{print\_char}(\.{"\ "})$;\5
+$\\{print\_int}(\\{round\_unscaled}(\\{internal}[\\{year}]))$;\5
+$\\{print\_char}(\.{"."})$;\5
+$\\{print\_int}(\\{round\_unscaled}(\\{internal}[\\{month}]))$;\5
+$\\{print\_char}(\.{"."})$;\5
+$\\{print\_int}(\\{round\_unscaled}(\\{internal}[\\{day}]))$;\5
+$\\{print\_char}(\.{")"})$;\6
+\&{if} $\\{interaction}=\\{batch\_mode}$ \1\&{then}\5
+$\\{selector}\K\\{log\_only}$\6
+\4\&{else} $\\{selector}\K\\{term\_and\_log}$;\2\6
+$\\{str\_room}(1)$;\5
+$\\{base\_ident}\K\\{make\_string}$;\5
+$\\{str\_ref}[\\{base\_ident}]\K\\{max\_str\_ref}$;\6
+$\\{pack\_job\_name}(\\{base\_extension})$;\6
+\&{while} $\R\\{w\_open\_out}(\\{base\_file})$ \1\&{do}\5
+$\\{prompt\_file\_name}(\.{"base\ file\ name"},\39\\{base\_extension})$;\2\6
+$\\{print\_nl}(\.{"Beginning\ to\ dump\ on\ file\ "})$;\5
+$\\{slow\_print}(\\{w\_make\_name\_string}(\\{base\_file}))$;\5
+$\\{flush\_string}(\\{str\_ptr}-1)$;\5
+$\\{print\_nl}(\.{""})$;\5
+$\\{slow\_print}(\\{base\_ident})$\par
+\U1186.\fi
+
+\M1201. \P$\X1201:Close the base file\X\S$\6
+$\\{w\_close}(\\{base\_file})$\par
+\U1186.\fi
+
+\N1202. \[49] The main program.
+This is it: the part of \MF\ that executes all those procedures we have
+written.
+
+Well---almost. We haven't put the parsing subroutines into the
+program yet; and we'd better leave space for a few more routines that may
+have been forgotten.
+
+\Y\P\X823:Declare the basic parsing subroutines\X\6
+\X224:Declare miscellaneous procedures that were declared \\{forward}\X\6
+\X1205:Last-minute procedures\X\par
+\fi
+
+\M1203. We've noted that there are two versions of \MF84. One, called %
+\.{INIMF},
+has to be run first; it initializes everything from scratch, without
+reading a base file, and it has the capability of dumping a base file.
+The other one is called `\.{VIRMF}'; it is a ``virgin'' program that needs
+to input a base file in order to get started. \.{VIRMF} typically has
+a bit more memory capacity than \.{INIMF}, because it does not need the
+space consumed by the dumping/undumping routines and the numerous calls on
+\\{primitive}, etc.
+
+The \.{VIRMF} program cannot read a base file instantaneously, of course;
+the best implementations therefore allow for production versions of \MF\ that
+not only avoid the loading routine for \PASCAL\ object code, they also have
+a base file pre-loaded. This is impossible to do if we stick to standard
+\PASCAL; but there is a simple way to fool many systems into avoiding the
+initialization, as follows:\quad(1)~We declare a global integer variable
+called \\{ready\_already}. The probability is negligible that this
+variable holds any particular value like 314159 when \.{VIRMF} is first
+loaded.\quad(2)~After we have read in a base file and initialized
+everything, we set $\\{ready\_already}\K314159$.\quad(3)~Soon \.{VIRMF}
+will print `\.*', waiting for more input; and at this point we
+interrupt the program and save its core image in some form that the
+operating system can reload speedily.\quad(4)~When that core image is
+activated, the program starts again at the beginning; but now
+$\\{ready\_already}=314159$ and all the other global variables have
+their initial values too. The former chastity has vanished!
+
+In other words, if we allow ourselves to test the condition
+$\\{ready\_already}=314159$, before \\{ready\_already} has been
+assigned a value, we can avoid the lengthy initialization. Dirty tricks
+rarely pay off so handsomely.
+
+On systems that allow such preloading, the standard program called \.{MF}
+should be the one that has \.{plain} base preloaded, since that agrees
+with {\sl The {\logos METAFONT\/}book}. Other versions, e.g., \.{cmbase},
+should also be provided for commonly used bases.
+
+\Y\P$\4\X13:Global variables\X\mathrel{+}\S$\6
+\4\\{ready\_already}: \37\\{integer};\C{a sacrifice of purity for economy}\par
+\fi
+
+\M1204. Now this is really it: \MF\ starts and ends here.
+
+The initial test involving \\{ready\_already} should be deleted if the
+\PASCAL\ runtime system is smart enough to detect such a ``mistake.''
+
+\Y\P\&{begin} \37\C{\\{start\_here}}\6
+$\\{history}\K\\{fatal\_error\_stop}$;\C{in case we quit during initialization}%
+\6
+\\{t\_open\_out};\C{open the terminal for output}\6
+\&{if} $\\{ready\_already}=314159$ \1\&{then}\5
+\&{goto} \37\\{start\_of\_MF};\2\6
+\X14:Check the ``constant'' values for consistency\X\6
+\&{if} $\\{bad}>0$ \1\&{then}\6
+\&{begin} \37$\\{wterm\_ln}(\.{\'Ouch---my\ internal\ constants\ have\ been\
+clobbered!\'},\39\.{\'---case\ \'},\39\\{bad}:1)$;\5
+\&{goto} \37\\{final\_end};\6
+\&{end};\2\6
+\\{initialize};\C{set global variables to their starting values}\6
+\&{init} \37\&{if} $\R\\{get\_strings\_started}$ \1\&{then}\5
+\&{goto} \37\\{final\_end};\2\6
+\\{init\_tab};\C{initialize the tables}\6
+\\{init\_prim};\C{call \\{primitive} for each primitive}\6
+$\\{init\_str\_ptr}\K\\{str\_ptr}$;\5
+$\\{init\_pool\_ptr}\K\\{pool\_ptr}$;\6
+$\\{max\_str\_ptr}\K\\{str\_ptr}$;\5
+$\\{max\_pool\_ptr}\K\\{pool\_ptr}$;\5
+\\{fix\_date\_and\_time};\6
+\&{tini}\6
+$\\{ready\_already}\K314159$;\6
+\4\\{start\_of\_MF}: \37\X55:Initialize the output routines\X;\6
+\X1211:Get the first line of input and prepare to start\X;\6
+$\\{history}\K\\{spotless}$;\C{ready to go!}\6
+\&{if} $\\{start\_sym}>0$ \1\&{then}\C{insert the `\&{everyjob}' symbol}\6
+\&{begin} \37$\\{cur\_sym}\K\\{start\_sym}$;\5
+\\{back\_input};\6
+\&{end};\2\6
+\\{main\_control};\C{come to life}\6
+\\{final\_cleanup};\C{prepare for death}\6
+\4\\{end\_of\_MF}: \37\\{close\_files\_and\_terminate};\6
+\4\\{final\_end}: \37$\\{ready\_already}\K0$;\6
+\&{end}.\par
+\fi
+
+\M1205. Here we do whatever is needed to complete \MF's job gracefully on the
+local operating system. The code here might come into play after a fatal
+error; it must therefore consist entirely of ``safe'' operations that
+cannot produce error messages. For example, it would be a mistake to call
+\\{str\_room} or \\{make\_string} at this time, because a call on \\{overflow}
+might lead to an infinite loop.
+
+This program doesn't bother to close the input files that may still be open.
+
+\Y\P$\4\X1205:Last-minute procedures\X\S$\6
+\4\&{procedure}\1\ \37\\{close\_files\_and\_terminate};\6
+\4\&{var} \37\|k: \37\\{integer};\C{all-purpose index}\6
+\\{lh}: \37\\{integer};\C{the length of the \.{TFM} header, in words}\6
+\\{lk\_offset}: \37$0\to256$;\C{extra words inserted at beginning of \\{lig%
+\_kern} array}\6
+\|p: \37\\{pointer};\C{runs through a list of \.{TFM} dimensions}\6
+\|x: \37\\{scaled};\C{a \\{tfm\_width} value being output to the \.{GF} file}\2%
+\6
+\&{begin} \37\&{stat} \37\&{if} $\\{internal}[\\{tracing\_stats}]>0$ \1\&{then}%
+\5
+\X1208:Output statistics about this job\X;\2\ \&{tats}\6
+\\{wake\_up\_terminal};\5
+\X1206:Finish the \.{TFM} and \.{GF} files\X;\6
+\&{if} $\\{log\_opened}$ \1\&{then}\6
+\&{begin} \37\\{wlog\_cr};\5
+$\\{a\_close}(\\{log\_file})$;\5
+$\\{selector}\K\\{selector}-2$;\6
+\&{if} $\\{selector}=\\{term\_only}$ \1\&{then}\6
+\&{begin} \37$\\{print\_nl}(\.{"Transcript\ written\ on\ "})$;\5
+$\\{slow\_print}(\\{log\_name})$;\5
+$\\{print\_char}(\.{"."})$;\6
+\&{end};\2\6
+\&{end};\2\6
+\&{end};\par
+\As1209, 1210\ETs1212.
+\U1202.\fi
+
+\M1206. We want to finish the \.{GF} file if and only if it has already been
+started;
+this will be true if and only if \\{gf\_prev\_ptr} is positive.
+We want to produce a \.{TFM} file if and only if \\{fontmaking} is positive.
+The \.{TFM} widths must be computed if there's a \.{GF} file, even if
+there's going to be no \.{TFM}~file.
+
+We reclaim all of the variable-size memory at this point, so that
+there is no chance of another memory overflow after the memory capacity
+has already been exceeded.
+
+\Y\P$\4\X1206:Finish the \.{TFM} and \.{GF} files\X\S$\6
+\&{if} $(\\{gf\_prev\_ptr}>0)\V(\\{internal}[\\{fontmaking}]>0)$ \1\&{then}\6
+\&{begin} \37\X1207:Make the dynamic memory into one big available node\X;\6
+\X1124:Massage the \.{TFM} widths\X;\6
+\\{fix\_design\_size};\5
+\\{fix\_check\_sum};\6
+\&{if} $\\{internal}[\\{fontmaking}]>0$ \1\&{then}\6
+\&{begin} \37\X1126:Massage the \.{TFM} heights, depths, and italic corrections%
+\X;\6
+$\\{internal}[\\{fontmaking}]\K0$;\C{avoid loop in case of fatal error}\6
+\X1134:Finish the \.{TFM} file\X;\6
+\&{end};\2\6
+\&{if} $\\{gf\_prev\_ptr}>0$ \1\&{then}\5
+\X1182:Finish the \.{GF} file\X;\2\6
+\&{end}\2\par
+\U1205.\fi
+
+\M1207. \P$\X1207:Make the dynamic memory into one big available node\X\S$\6
+$\\{rover}\K\\{lo\_mem\_stat\_max}+1$;\5
+$\\{link}(\\{rover})\K\\{empty\_flag}$;\5
+$\\{lo\_mem\_max}\K\\{hi\_mem\_min}-1$;\6
+\&{if} $\\{lo\_mem\_max}-\\{rover}>\\{max\_halfword}$ \1\&{then}\5
+$\\{lo\_mem\_max}\K\\{max\_halfword}+\\{rover}$;\2\6
+$\\{node\_size}(\\{rover})\K\\{lo\_mem\_max}-\\{rover}$;\5
+$\\{llink}(\\{rover})\K\\{rover}$;\5
+$\\{rlink}(\\{rover})\K\\{rover}$;\5
+$\\{link}(\\{lo\_mem\_max})\K\\{null}$;\5
+$\\{info}(\\{lo\_mem\_max})\K\\{null}$\par
+\U1206.\fi
+
+\M1208. The present section goes directly to the log file instead of using
+\\{print} commands, because there's no need for these strings to take
+up \\{str\_pool} memory when a non-{\bf stat} version of \MF\ is being used.
+
+\Y\P$\4\X1208:Output statistics about this job\X\S$\6
+\&{if} $\\{log\_opened}$ \1\&{then}\6
+\&{begin} \37$\\{wlog\_ln}(\.{\'\ \'})$;\5
+$\\{wlog\_ln}(\.{\'Here\ is\ how\ much\ of\ METAFONT\'}\.{\'s\ memory\'},\39\.{%
+\'\ you\ used:\'})$;\5
+$\\{wlog}(\.{\'\ \'},\39\\{max\_str\_ptr}-\\{init\_str\_ptr}:1,\39\.{\'\ string%
+\'})$;\6
+\&{if} $\\{max\_str\_ptr}\I\\{init\_str\_ptr}+1$ \1\&{then}\5
+$\\{wlog}(\.{\'s\'})$;\2\6
+$\\{wlog\_ln}(\.{\'\ out\ of\ \'},\39\\{max\_strings}-\\{init\_str\_ptr}:1)$;\6
+$\\{wlog\_ln}(\.{\'\ \'},\39\\{max\_pool\_ptr}-\\{init\_pool\_ptr}:1,\39\.{\'\
+string\ characters\ out\ of\ \'},\39\\{pool\_size}-\\{init\_pool\_ptr}:1)$;\6
+$\\{wlog\_ln}(\.{\'\ \'},\39\\{lo\_mem\_max}-\\{mem\_min}+\\{mem\_end}-\\{hi%
+\_mem\_min}+2:1,\39\30\.{\'\ words\ of\ memory\ out\ of\ \'},\39\\{mem\_end}+1-%
+\\{mem\_min}:1)$;\6
+$\\{wlog\_ln}(\.{\'\ \'},\39\\{st\_count}:1,\39\.{\'\ symbolic\ tokens\ out\ of%
+\ \'},\39\\{hash\_size}:1)$;\6
+$\\{wlog\_ln}(\.{\'\ \'},\39\\{max\_in\_stack}:1,\39\.{\'i,\'},\39\30\\{int%
+\_ptr}:1,\39\.{\'n,\'},\39\30\\{max\_rounding\_ptr}:1,\39\.{\'r,\'},\39\30%
+\\{max\_param\_stack}:1,\39\.{\'p,\'},\39\30\\{max\_buf\_stack}+1:1,\39\.{\'b\
+stack\ positions\ out\ of\ \'},\39\30\\{stack\_size}:1,\39\.{\'i,\'},\39\\{max%
+\_internal}:1,\39\.{\'n,\'},\39\\{max\_wiggle}:1,\39\.{\'r,\'},\39\\{param%
+\_size}:1,\39\.{\'p,\'},\39\\{buf\_size}:1,\39\.{\'b\'})$;\6
+\&{end}\2\par
+\U1205.\fi
+
+\M1209. We get to the \\{final\_cleanup} routine when \&{end} or \&{dump} has
+been scanned.
+
+\Y\P$\4\X1205:Last-minute procedures\X\mathrel{+}\S$\6
+\4\&{procedure}\1\ \37\\{final\_cleanup};\6
+\4\&{label} \37\\{exit};\6
+\4\&{var} \37\|c: \37\\{small\_number};\C{0 for \&{end}, 1 for \&{dump}}\2\6
+\&{begin} \37$\|c\K\\{cur\_mod}$;\6
+\&{if} $\\{job\_name}=0$ \1\&{then}\5
+\\{open\_log\_file};\2\6
+\&{while} $\\{input\_ptr}>0$ \1\&{do}\6
+\&{if} $\\{token\_state}$ \1\&{then}\5
+\\{end\_token\_list}\ \&{else} \\{end\_file\_reading};\2\2\6
+\&{while} $\\{loop\_ptr}\I\\{null}$ \1\&{do}\5
+\\{stop\_iteration};\2\6
+\&{while} $\\{open\_parens}>0$ \1\&{do}\6
+\&{begin} \37$\\{print}(\.{"\ )"})$;\5
+$\\{decr}(\\{open\_parens})$;\6
+\&{end};\2\6
+\&{while} $\\{cond\_ptr}\I\\{null}$ \1\&{do}\6
+\&{begin} \37$\\{print\_nl}(\.{"(end\ occurred\ when\ "})$;\6
+$\\{print\_cmd\_mod}(\\{fi\_or\_else},\39\\{cur\_if})$;\C{`\.{if}' or `%
+\.{elseif}' or `\.{else}'}\6
+\&{if} $\\{if\_line}\I0$ \1\&{then}\6
+\&{begin} \37$\\{print}(\.{"\ on\ line\ "})$;\5
+$\\{print\_int}(\\{if\_line})$;\6
+\&{end};\2\6
+$\\{print}(\.{"\ was\ incomplete)"})$;\5
+$\\{if\_line}\K\\{if\_line\_field}(\\{cond\_ptr})$;\5
+$\\{cur\_if}\K\\{name\_type}(\\{cond\_ptr})$;\5
+$\\{loop\_ptr}\K\\{cond\_ptr}$;\5
+$\\{cond\_ptr}\K\\{link}(\\{cond\_ptr})$;\5
+$\\{free\_node}(\\{loop\_ptr},\39\\{if\_node\_size})$;\6
+\&{end};\2\6
+\&{if} $\\{history}\I\\{spotless}$ \1\&{then}\6
+\&{if} $((\\{history}=\\{warning\_issued})\V(\\{interaction}<\\{error\_stop%
+\_mode}))$ \1\&{then}\6
+\&{if} $\\{selector}=\\{term\_and\_log}$ \1\&{then}\6
+\&{begin} \37$\\{selector}\K\\{term\_only}$;\5
+$\\{print\_nl}(\.{"(see\ the\ transcript\ file\ for\ additional\
+information)"})$;\5
+$\\{selector}\K\\{term\_and\_log}$;\6
+\&{end};\2\2\2\6
+\&{if} $\|c=1$ \1\&{then}\6
+\&{begin} \37\&{init} \37\\{store\_base\_file};\5
+\&{return};\ \&{tini}\6
+$\\{print\_nl}(\.{"(dump\ is\ performed\ only\ by\ INIMF)"})$;\5
+\&{return};\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\par
+\fi
+
+\M1210. \P$\X1205:Last-minute procedures\X\mathrel{+}\S$\6
+\&{init} \37\&{procedure}\1\ \37\\{init\_prim};\C{initialize all the
+primitives}\2\6
+\&{begin} \37\X192:Put each of \MF's primitives into the hash table\X;\6
+\&{end};\7
+\4\&{procedure}\1\ \37\\{init\_tab};\C{initialize other tables}\6
+\4\&{var} \37\|k: \37\\{integer};\C{all-purpose index}\2\6
+\&{begin} \37\X176:Initialize table entries (done by \.{INIMF} only)\X\6
+\&{end};\6
+\&{tini}\par
+\fi
+
+\M1211. When we begin the following code, \MF's tables may still contain
+garbage;
+the strings might not even be present. Thus we must proceed cautiously to get
+bootstrapped in.
+
+But when we finish this part of the program, \MF\ is ready to call on the
+\\{main\_control} routine to do its work.
+
+\Y\P$\4\X1211:Get the first line of input and prepare to start\X\S$\6
+\&{begin} \37\X657:Initialize the input routines\X;\6
+\&{if} $(\\{base\_ident}=0)\V(\\{buffer}[\\{loc}]=\.{"\&"})$ \1\&{then}\6
+\&{begin} \37\&{if} $\\{base\_ident}\I0$ \1\&{then}\5
+\\{initialize};\C{erase preloaded base}\2\6
+\&{if} $\R\\{open\_base\_file}$ \1\&{then}\5
+\&{goto} \37\\{final\_end};\2\6
+\&{if} $\R\\{load\_base\_file}$ \1\&{then}\6
+\&{begin} \37$\\{w\_close}(\\{base\_file})$;\5
+\&{goto} \37\\{final\_end};\6
+\&{end};\2\6
+$\\{w\_close}(\\{base\_file})$;\6
+\&{while} $(\\{loc}<\\{limit})\W(\\{buffer}[\\{loc}]=\.{"\ "})$ \1\&{do}\5
+$\\{incr}(\\{loc})$;\2\6
+\&{end};\2\6
+$\\{buffer}[\\{limit}]\K\.{"\%"}$;\6
+\\{fix\_date\_and\_time};\5
+$\\{init\_randoms}((\\{internal}[\\{time}]\mathbin{\&{div}}\\{unity})+%
+\\{internal}[\\{day}])$;\6
+\X70:Initialize the print \\{selector} based on \\{interaction}\X;\6
+\&{if} $\\{loc}<\\{limit}$ \1\&{then}\6
+\&{if} $\\{buffer}[\\{loc}]\I\.{"\\"}$ \1\&{then}\5
+\\{start\_input};\C{\&{input} assumed}\2\2\6
+\&{end}\par
+\U1204.\fi
+
+\N1212. \[50] Debugging.
+Once \MF\ is working, you should be able to diagnose most errors with
+the \.{show} commands and other diagnostic features. But for the initial
+stages of debugging, and for the revelation of really deep mysteries, you
+can compile \MF\ with a few more aids, including the \PASCAL\ runtime
+checks and its debugger. An additional routine called \\{debug\_help}
+will also come into play when you type `\.D' after an error message;
+\\{debug\_help} also occurs just before a fatal error causes \MF\ to succumb.
+
+The interface to \\{debug\_help} is primitive, but it is good enough when used
+with a \PASCAL\ debugger that allows you to set breakpoints and to read
+variables and change their values. After getting the prompt `\.{debug \#}', you
+type either a negative number (this exits \\{debug\_help}), or zero (this
+goes to a location where you can set a breakpoint, thereby entering into
+dialog with the \PASCAL\ debugger), or a positive number \|m followed by
+an argument \|n. The meaning of \|m and \|n will be clear from the
+program below. (If $\|m=13$, there is an additional argument, \|l.)
+
+\Y\P\D \37$\\{breakpoint}=888$\C{place where a breakpoint is desirable}\par
+\Y\P$\4\X1205:Last-minute procedures\X\mathrel{+}\S$\6
+\&{debug} \37\&{procedure}\1\ \37\\{debug\_help};\C{routine to display various
+things}\6
+\4\&{label} \37$\\{breakpoint},\39\\{exit}$;\6
+\4\&{var} \37$\|k,\39\|l,\39\|m,\39\|n$: \37\\{integer};\2\6
+\&{begin} \37\~ \1\&{loop}\6
+\&{begin} \37\\{wake\_up\_terminal};\5
+$\\{print\_nl}(\.{"debug\ \#\ (-1\ to\ exit):"})$;\5
+\\{update\_terminal};\5
+$\\{read}(\\{term\_in},\39\|m)$;\6
+\&{if} $\|m<0$ \1\&{then}\5
+\&{return}\6
+\4\&{else} \&{if} $\|m=0$ \1\&{then}\6
+\&{begin} \37\&{goto} \37\\{breakpoint};\5
+\]\C{go to every label at least once}\6
+\4\\{breakpoint}: \37$\|m\K0$;\5
+$\B\.{\'BREAKPOINT\'}\T\]$\6
+\&{end}\6
+\4\&{else} \&{begin} \37$\\{read}(\\{term\_in},\39\|n)$;\6
+\&{case} $\|m$ \1\&{of}\6
+\hbox{\4}\X1213:Numbered cases for \\{debug\_help}\X\6
+\4\&{othercases} \37$\\{print}(\.{"?"})$\2\6
+\&{endcases};\6
+\&{end};\2\2\6
+\&{end};\2\6
+\4\\{exit}: \37\&{end};\6
+\&{gubed}\par
+\fi
+
+\M1213. \P$\X1213:Numbered cases for \\{debug\_help}\X\S$\6
+\41: \37$\\{print\_word}(\\{mem}[\|n])$;\C{display $\\{mem}[\|n]$ in all forms}%
+\6
+\42: \37$\\{print\_int}(\\{info}(\|n))$;\6
+\43: \37$\\{print\_int}(\\{link}(\|n))$;\6
+\44: \37\&{begin} \37$\\{print\_int}(\\{eq\_type}(\|n))$;\5
+$\\{print\_char}(\.{":"})$;\5
+$\\{print\_int}(\\{equiv}(\|n))$;\6
+\&{end};\6
+\45: \37$\\{print\_variable\_name}(\|n)$;\6
+\46: \37$\\{print\_int}(\\{internal}[\|n])$;\6
+\47: \37\\{do\_show\_dependencies};\6
+\49: \37$\\{show\_token\_list}(\|n,\39\\{null},\39100000,\390)$;\6
+\410: \37$\\{slow\_print}(\|n)$;\6
+\411: \37$\\{check\_mem}(\|n>0)$;\C{check wellformedness; print new busy
+locations if $\|n>0$}\6
+\412: \37$\\{search\_mem}(\|n)$;\C{look for pointers to \|n}\6
+\413: \37\&{begin} \37$\\{read}(\\{term\_in},\39\|l)$;\5
+$\\{print\_cmd\_mod}(\|n,\39\|l)$;\6
+\&{end};\6
+\414: \37\&{for} $\|k\K0\mathrel{\&{to}}\|n$ \1\&{do}\5
+$\\{print}(\\{buffer}[\|k])$;\2\6
+\415: \37$\\{panicking}\K\R\\{panicking}$;\par
+\U1212.\fi
+
+\N1214. \[51] System-dependent changes.
+This section should be replaced, if necessary, by any special
+modifications of the program
+that are necessary to make \MF\ work at a particular installation.
+It is usually best to design your change file so that all changes to
+previous sections preserve the section numbering; then everybody's version
+will be consistent with the published program. More extensive changes,
+which introduce new sections, can be inserted here; then only the index
+itself will get a new section number.
+
+\fi
+
+\N1215. \[52] Index.
+Here is where you can find all uses of each identifier in the program,
+with underlined entries pointing to where the identifier was defined.
+If the identifier is only one letter long, however, you get to see only
+the underlined entries. {\sl All references are to section numbers instead of
+page numbers.}
+
+This index also lists error messages and other aspects of the program
+that you might want to look up some day. For example, the entry
+for ``system dependencies'' lists all sections that should receive
+special attention from people who are installing \MF\ in a new
+operating environment. A list of various things that can't happen appears
+under ``this can't happen''.
+Approximately 25 sections are listed under ``inner loop''; these account
+for more than 60\pct! of \MF's running time, exclusive of input and output.
+\fi
+
+
+\inx
+\:\9{!!!}{\.{\&} primitive}, \[893].
+\:\.{!\relax}, 68, 807.
+\:\9{* }{\.{*} primitive}, \[893].
+\:\.{**}, 36, 788.
+\:\.{*\relax}, 679.
+\:\9{+ }{\.{+} primitive}, \[893].
+\:\9{++\_}{\.{++} primitive}, \[893].
+\:\9{+-+\_}{\.{+-+} primitive}, \[893].
+\:\9{, }{\., primitive}, \[211].
+\:\9{- }{\.{-} primitive}, \[893].
+\:\.{->}, 227.
+\:\9{. }{\..\ token}, 669.
+\:\9{..\_}{\.{..} primitive}, \[211].
+\:\9{/ }{\.{/} primitive}, \[893].
+\:\9{: }{\.{:} primitive}, \[211].
+\:\9{:: }{\.{::} primitive}, \[211].
+\:\9{::: }{\.{\char'174\char'174:} primitive}, \[211].
+\:\9{:=\_}{\.{:=} primitive}, \[211].
+\:\9{; }{\.; primitive}, \[211].
+\:\9{< }{\.{<} primitive}, \[893].
+\:\9{<=\_}{\.{<=} primitive}, \[893].
+\:\9{<>\_}{\.{<>} primitive}, \[893].
+\:\9{= }{\.{=} primitive}, \[893].
+\:\9{=:/>\_}{\.{=:\char'174>} primitive}, \[1108].
+\:\9{=:/>\_}{\.{\char'174=:>} primitive}, \[1108].
+\:\9{=:/>\_}{\.{\char'174=:\char'174>>} primitive}, \[1108].
+\:\9{=:/>\_}{\.{\char'174=:\char'174>} primitive}, \[1108].
+\:\9{=:/\_}{\.{=:\char'174} primitive}, \[1108].
+\:\9{=:/\_}{\.{\char'174=:\char'174} primitive}, \[1108].
+\:\9{=:/\_}{\.{\char'174=:} primitive}, \[1108].
+\:\9{=:\_}{\.{=:} primitive}, \[1108].
+\:\.{=>}, 682.
+\:\9{> }{\.{>} primitive}, \[893].
+\:\9{>=\_}{\.{>=} primitive}, \[893].
+\:\.{>>}, 807, 1040.
+\:\.{>\relax}, 398, 1041.
+\:\.{??}, 261, 263.
+\:\.{???}, 59, 60, 257, 258.
+\:\.{?\relax}, 78, 638.
+\:\9{[ }{\.{[} primitive}, \[211].
+\:\9{] }{\.{]} primitive}, \[211].
+\:\9{][}{\.{\char`\{} primitive}, \[211].
+\:\9{]]\\}{\.{\char`\\} primitive}, \[211].
+\:\9{]]]\#\#\#\#\_}{\.{\#\#\#\#}}, 603.
+\:\9{]]]\#\#\#\_}{\.{\#\#\#}}, 817.
+\:\9{]]]\#\#\_}{\.{\#\#}}, 613.
+\:\9{]]]\#\AT!\_}{\.{\#\AT!} primitive}, \[688].
+\:\9{]]]\AT!\#\_}{\.{\AT!\#} primitive}, \[688].
+\:\9{]]]\AT!\_}{\.{\AT!} primitive}, \[688].
+\:\9{]]]\AT!\_Octant}{\.{\AT! Octant...}}, 509.
+\:\9{]]]\AT!\_retro\_}{\.{\AT! retrograde line...}}, 510.
+\:\9{]]]\AT!\_trans\_}{\.{\AT! transition line...}}, 515, 521.
+\:\9{]]}{\.{\char`\}} primitive}, \[211].
+\:\|{a}, \[47], \[102], \[117], \[124], \[126], \[321], \[391], \[429], \[431],
+\[433], \[440], \[568], \[722], \[773], \[774], \[778], \[976], \[977], \[978],
+\[1154].
+\:\.{a font metric dimension...}, 1140.
+\:\.{A group...never ended}, 832.
+\:\.{A primary expression...}, 823.
+\:\.{A secondary expression...}, 862.
+\:\.{A statement can't begin with x}, 990.
+\:\.{A tertiary expression...}, 864.
+\:\\{a\_close}, \[27], 51, 655, 1205.
+\:\\{a\_make\_name\_string}, \[780], 788, 793.
+\:\\{a\_minus\_b}, \[865], 866.
+\:\\{a\_open\_in}, \[26], 51, 793.
+\:\\{a\_open\_out}, \[26], 788.
+\:\\{a\_plus\_b}, \[865], 866.
+\:\\{a\_tension}, \[296].
+\:\\{aa}, \[286], 288, 290, 291, 301, \[321], 322, \[440], 444, 445, 446.
+\:\\{aaa}, \[321], 322.
+\:\\{ab\_vs\_cd}, \[117], 152, 300, 306, 317, 375, 376, 479, 488, 502, 516,
+522, 546, 548, 549, 943, 949.
+\:\\{abnegate}, \[390], 413, 421.
+\:\\{abort\_find}, \[242], 243.
+\:\\{abs}, 65, 124, 126, 150, 151, 152, 260, 288, 289, 292, 294, 295, 299, 300,
+302, 321, 326, 362, 378, 404, 408, 426, 433, 434, 437, 441, 445, 457, 459, 479,
+496, 498, 502, 529, 533, 540, 543, 589, 591, 595, 596, 598, 599, 600, 603, 611,
+612, 615, 616, 812, 814, 837, 866, 915, 943, 949, 965, 1008, 1056, 1098, 1129,
+1140, 1182.
+\:\\{absorbing}, \[659], 664, 665, 730.
+\:\\{acc}, \[116], \[286], 290.
+\:\\{add\_mac\_ref}, \[226], 720, 845, 862, 864, 868, 1035.
+\:\\{add\_mult\_dep}, \[971], 972.
+\:\\{add\_or\_subtract}, 929, \[930], 936, 939.
+\:\\{add\_pen\_ref}, \[487], 621, 855, 1063.
+\:\\{add\_str\_ref}, \[42], 621, 678, 855, 1083.
+\:\9{add\_to\_}{\&{addto} primitive}, \[211].
+\:\\{add\_to\_command}, \[186], 211, 212, 1058.
+\:\\{add\_to\_type}, \[1059], 1064.
+\:\\{after}, 426, \[427], 429, 436, 439, 440, 444, 446.
+\:\\{all\_safe}, \[426], \[440], 446.
+\:\\{alpha}, \[296], \[433], 436, 439, \[440], 444, \[527], 528, 529, 530, 533.
+\:\\{alpha\_file}, \[24], 26, 27, 30, 31, 50, 54, 631, 780.
+\:\\{already\_there}, \[577], 578, 583, 584.
+\:\9{also\_}{\&{also} primitive}, \[1052].
+\:\\{also\_code}, \[403], 1052, 1059.
+\:\\{ampersand}, \[186], 868, 869, 874, 886, 887, 891, 893, 894.
+\:\.{An expression...}, 868.
+\:\9{and\_}{\&{and} primitive}, \[893].
+\:\\{and\_command}, \[186], 882, 884, 893, 894.
+\:\\{and\_op}, \[189], 893, 940.
+\:\\{angle}, \[106], 137, 139, 144, 145, 256, 279, 283, 527, 542, 865, 875.
+\:\.{angle(0,0)...zero}, 140.
+\:\9{angle\_}{\&{angle} primitive}, \[893].
+\:\\{angle\_op}, \[189], 893, 907.
+\:\\{app\_lc\_hex}, \[48].
+\:\\{append\_char}, \[41], 48, 52, 58, 207, 671, 771, 780, 897, 912, 976, 977.
+\:\\{append\_to\_name}, \[774], 778.
+\:\\{appr\_t}, 556, \[557].
+\:\\{appr\_tt}, 556, \[557].
+\:\\{area\_delimiter}, \[768], 770, 771, 772.
+\:\\{arg\_list}, 719, \[720], 721, 724, 725, 726, 728, 734, 736.
+\:\\{arith\_error}, \[97], 98, 99, 100, 107, 109, 112, 114, 124, 135, 269, 270.
+\:\.{Arithmetic overflow}, 99.
+\:{ASCII code}, 17.
+\:\9{ASCII\_}{\&{ASCII} primitive}, \[893].
+\:\\{ASCII\_code}, \[18], 19, 20, 28, 29, 30, 37, 41, 54, 58, 77, 198, 667,
+771, 774, 778, 913.
+\:\\{ASCII\_op}, \[189], 893, 912, 913.
+\:\\{assignment}, \[186], 211, 212, 693, 733, 755, 821, 841, 868, 993, 995,
+996, 1021, 1035.
+\:\9{at\_}{\&{at} primitive}, \[211].
+\:\\{at\_least}, \[186], 211, 212, 882.
+\:\9{at\_least\_}{\&{atleast} primitive}, \[211], \[256], \[300].
+\:\\{at\_token}, \[186], 211, 212, 1073.
+\:\\{attr}, \[188], 229, 236, 239, 240, 245.
+\:\\{attr\_head}, \[228], 229, 239, 241, 242, 244, 245, 246, 247, 850, 1047.
+\:\\{attr\_loc}, \[229], 236, 239, 241, 244, 245, 246, 850.
+\:\\{attr\_loc\_loc}, \[229], 241.
+\:\\{attr\_node\_size}, \[229], 239, 241, 245, 247.
+\:\\{autorounding}, \[190], 192, 193, 402.
+\:\9{autorounding\_}{\&{autorounding} primitive}, \[192].
+\:\\{avail}, \[161], 163, 164, 165, 176, 177, 181, 1194, 1195.
+\:\.{AVAIL list clobbered...}, 181.
+\:\\{axis}, \[393], 459, 507, 517, 519.
+\:\|{b}, \[124], \[126], \[321], \[391], \[429], \[431], \[433], \[440], %
+\[568], \[580], \[723], \[778], \[913], \[919], \[976], \[977], \[978], %
+\[1072], \[1154].
+\:\\{b\_close}, \[27], 1134, 1182.
+\:\\{b\_make\_name\_string}, \[780], 791, 1134.
+\:\\{b\_open\_out}, \[26], 791, 1134.
+\:\\{b\_tension}, \[296].
+\:\\{back\_error}, \[653], 693, 703, 713, 726, 727, 734, 735, 747, 755, 756,
+765, 820, 832, 839, 859, 861, 875, 878, 881, 990, 991, 1021, 1032, 1034, 1035,
+1106, 1107, 1113.
+\:\\{back\_expr}, 847, \[848].
+\:\\{back\_input}, \[652], 653, 715, 716, 733, 751, 824, 825, 837, 841, 847,
+854, 862, 864, 868, 881, 1012, 1034, 1107, 1204.
+\:\\{back\_list}, \[649], 652, 662, 715, 848.
+\:\\{backed\_up}, \[632], 635, 636, 638, 649, 650.
+\:{backpointers}, 1147.
+\:\.{Backwards path...}, 1068.
+\:\.{BAD}, 219.
+\:\\{bad}, \[13], 14, 154, 204, 214, 310, 553, 777, 1204.
+\:\.{Bad culling amounts}, 1074.
+\:\.{Bad flag...}, 183.
+\:\.{Bad PREVDEP...}, 617.
+\:\.{Bad window number}, 1071.
+\:\\{bad\_binary}, \[923], 929, 936, 940, 941, 948, 951, 952, 975, 983, 988.
+\:\\{bad\_char}, \[913], 914.
+\:\\{bad\_exp}, 823, \[824], 862, 864, 868.
+\:\\{bad\_for}, \[754], 765.
+\:\\{bad\_pool}, \[51], 52, 53.
+\:\\{bad\_subscript}, 846, \[849], 861.
+\:\\{bad\_unary}, 898, \[901], 903, 905, 906, 907, 909, 912, 915, 917, 921.
+\:\\{bad\_vardef}, \[175], 698, 701, 702.
+\:\\{balance}, \[685], 687, \[730], 731, 732.
+\:\\{banner}, \[2], 61, 790, 1183.
+\:\\{base}, \[374], 375, 376, \[697], 703, 704.
+\:\\{base\_area\_length}, \[775], 779.
+\:\\{base\_default\_length}, \[775], 777, 778, 779.
+\:\\{base\_ext\_length}, \[775], 778, 779.
+\:\\{base\_extension}, \[775], 784, 1200.
+\:\\{base\_file}, 779, \[1188], 1189, 1191, 1199, 1200, 1201, 1211.
+\:\\{base\_ident}, 34, 61, 790, \[1183], 1184, 1185, 1198, 1199, 1200, 1211.
+\:\\{batch\_mode}, \[68], 70, 81, 86, 87, 88, 789, 1024, 1025, 1199, 1200.
+\:\9{batch\_mode\_}{\&{batchmode} primitive}, \[1024].
+\:\\{bb}, \[286], 287, 288, 291, \[440], 444, 445, 446.
+\:\\{bc}, 1088, 1089, 1091, 1093, \[1096], 1097, 1099, 1124, 1126, 1132, 1135,
+1136.
+\:\\{bch\_label}, \[1096], 1097, 1111, 1137, 1141.
+\:\\{bchar}, \[1096], 1137, 1139.
+\:\\{bchar\_label}, \[186], 211, 212, 1107.
+\:\\{be\_careful}, \[107], 108, \[109], \[112], \[114], 115, \[119].
+\:\\{before}, 426, \[427], 429, 436, 439, 444, 446.
+\:\\{before\_and\_after}, \[429], 434, 437, 441.
+\:\&{begin}, 7, 8.
+\:\\{begin\_diagnostic}, 71, \[195], 197, 254, 603, 613, 626, 721, 728, 734,
+750, 762, 817, 902, 924, 945, 997, 998.
+\:\\{begin\_edge\_tracing}, \[372], 465, 506.
+\:\\{begin\_file\_reading}, 73, 82, \[654], 717, 793, 897.
+\:\\{begin\_group}, \[186], 211, 212, 732, 823.
+\:\9{begin\_group\_}{\&{begingroup} primitive}, \[211].
+\:\\{begin\_iteration}, 706, 707, \[755], 764.
+\:\\{begin\_name}, 767, \[770], 781, 787.
+\:\\{begin\_pseudoprint}, \[642], 644, 645.
+\:\\{begin\_token\_list}, \[649], 677, 736, 760.
+\:\.{Beginning to dump...}, 1200.
+\:{Bernshte{\u\i}n, Serge{\u\i} Natanovich}, 303.
+\:\\{beta}, \[296], \[440], 444, \[527], 528, 529, 530, 533, 536.
+\:\9{Bezier}{B\'ezier, Pierre Etienne}, 255.
+\:\\{bg\_loc}, 211, 698, \[699], 1198, 1199.
+\:\\{big}, \[124], \[126].
+\:\\{big\_node\_size}, \[230], 231, 232, 803, 810, 857, 919, 928, 939, 966,
+1005.
+\:\\{big\_trans}, 952, \[966].
+\:{BigEndian order}, \[1088].
+\:\\{bilin1}, 967, \[968], 972.
+\:\\{bilin2}, 970, \[972].
+\:\\{bilin3}, 973, \[974].
+\:\\{binary\_mac}, 862, \[863], 864, 868.
+\:\\{bisect\_ptr}, \[309], 311, 312, 314, 553, 558, 559, 561.
+\:\\{bisect\_stack}, \[309], 553.
+\:\\{bistack\_size}, \[11], 309, 310, 553, 557.
+\:\\{black}, \[565], 568, 577, 579, 580, 583, 584, 1143, 1144.
+\:\\{blank\_line}, \[195].
+\:\\{blank\_rectangle}, 564, 566, \[567], 569, 571, 572, 574, 577.
+\:\\{boc}, 1142, 1144, \[1145], 1146, 1147, 1149, 1161, 1162.
+\:\\{boc\_c}, 1161, \[1162], 1165.
+\:\\{boc\_p}, 1161, \[1162], 1165.
+\:\\{boc1}, 1144, \[1145], 1161.
+\:\\{boolean}, 26, 30, 36, 45, 47, 71, 74, 91, 97, 107, 109, 112, 114, 124,
+126, 178, 180, 195, 197, 238, 246, 249, 257, 332, 406, 426, 440, 453, 455, 473,
+497, 527, 564, 569, 572, 577, 592, 599, 600, 621, 661, 680, 771, 779, 782, 801,
+868, 899, 913, 943, 977, 978, 1006, 1054, 1072, 1084, 1096, 1187.
+\:\9{boolean\_}{\&{boolean} primitive}, \[1013].
+\:\\{boolean\_reset}, \[906], 937, 1181.
+\:\\{boolean\_type}, \[187], 216, 248, 621, 798, 799, 802, 809, 855, 892, 895,
+905, 906, 918, 919, 920, 936, 937, 940, 1003, 1013, 1181.
+\:\\{bot}, \[1094].
+\:\\{bot\_row}, \[567], \[572], 574, 577.
+\:\\{boundary\_char}, \[190], 192, 193, 1097, 1137.
+\:\9{boundary\_char\_}{\&{boundarychar} primitive}, \[192].
+\:\\{break}, 33.
+\:\\{break\_in}, 33.
+\:\\{breakpoint}, \[1212].
+\:{Brocot, Achille}, 526.
+\:\\{buf\_size}, \[11], 29, 30, 34, 66, 154, 641, 654, 667, 682, 707, 717, 779,
+786, 788, 1208.
+\:\\{buffer}, \[29], 30, 35, 36, 45, 66, 78, 82, 83, 205, 206, 207, 208, 210,
+629, 630, 641, 644, 667, 669, 671, 673, 674, 679, 681, 682, 717, 778, 779, 781,
+786, 787, 788, 794, 897, 1211, 1213.
+\:\.{Buffer size exceeded}, 34.
+\:\\{bypass\_eoln}, \[30].
+\:\\{byte\_file}, \[24], 26, 27, 780, 791, 1087.
+\:\\{b0}, 153, \[156], 157, 214, 255, 1093, 1094, 1133, 1192, 1193.
+\:\\{b1}, 153, \[156], 157, 214, 255, 1093, 1094, \[1131], 1132, 1133, 1192,
+1193.
+\:\\{b2}, 153, \[156], 157, 1093, 1094, \[1131], 1132, 1133, 1192, 1193.
+\:\\{b3}, 153, \[156], 157, 1093, 1094, \[1131], 1132, 1133, 1192, 1193.
+\:\\{b4}, \[1131], 1132.
+\:\|{c}, \[47], \[77], \[189], \[210], \[217], \[391], \[440], \[491], \[527], %
+\[567], \[568], \[625], \[626], \[667], \[697], \[771], \[774], \[778], \[823],
+\[862], \[863], \[864], \[868], \[895], \[898], \[901], \[910], \[913], \[919],
+\[922], \[923], \[930], \[953], \[960], \[962], \[963], \[966], \[985], %
+\[1070], \[1072], \[1103], \[1104], \[1106], \[1165], \[1209].
+\:\\{cancel\_skips}, \[1110], 1139.
+\:\.{CAPSULE}, 237.
+\:\\{capsule}, \[188], 214, 219, 233, 237, 238, 619, 799, 806, 830, 856, 857,
+911, 931, 982.
+\:\\{capsule\_token}, \[186], 651, 676, 678, 823, 1042.
+\:\\{cat}, 975, \[976].
+\:\\{cc}, \[286], 288, 289, 290, 294, 295, \[440], 444, 445, 446, \[1106].
+\:\\{cf}, \[116], 297, \[298], 299, 300, 301.
+\:\\{change\_if\_limit}, \[746], 748.
+\:\\{char}, 19, 25, 775, 788.
+\:\9{char\_}{\&{char} primitive}, \[893].
+\:\\{char\_class}, 22, \[198], 199, 217, 223, 669, 673, 674.
+\:\\{char\_code}, \[190], 192, 193, 1070.
+\:\9{char\_code\_}{\&{charcode} primitive}, \[192].
+\:\\{char\_dp}, \[190], 192, 193, 1099, 1126.
+\:\9{char\_dp\_}{\&{chardp} primitive}, \[192].
+\:\\{char\_dx}, \[190], 192, 193, 1099.
+\:\9{char\_dx\_}{\&{chardx} primitive}, \[192].
+\:\\{char\_dy}, \[190], 192, 193, 1099.
+\:\9{char\_dy\_}{\&{chardy} primitive}, \[192].
+\:\\{char\_exists}, \[1096], 1097, 1099, 1124, 1126, 1132, 1136, 1181, 1182.
+\:\9{char\_exists\_}{\&{charexists} primitive}, \[893].
+\:\\{char\_exists\_op}, \[189], 893, 906.
+\:\\{char\_ext}, \[190], 192, 193, 1165.
+\:\9{char\_ext\_}{\&{charext} primitive}, \[192].
+\:\\{char\_ht}, \[190], 192, 193, 1099, 1126.
+\:\9{char\_ht\_}{\&{charht} primitive}, \[192].
+\:\\{char\_ic}, \[190], 192, 193, 1099, 1126.
+\:\9{char\_ic\_}{\&{charic} primitive}, \[192].
+\:\\{char\_info}, 1091.
+\:\\{char\_info\_word}, 1089, \[1091], 1092.
+\:\9{char\_list\_}{\&{charlist} primitive}, \[1101].
+\:\\{char\_list\_code}, \[1101], 1102, 1106.
+\:\\{char\_loc}, 1144, \[1145], 1147, 1182.
+\:\\{char\_loc0}, \[1144].
+\:\\{char\_op}, \[189], 893, 912.
+\:\\{char\_ptr}, \[1149], 1163, 1165, 1182.
+\:\\{char\_remainder}, \[1096], 1097, 1104, 1136, 1138.
+\:\\{char\_tag}, \[1096], 1097, 1104, 1105, 1136.
+\:\\{char\_wd}, \[190], 192, 193, 1099, 1124.
+\:\9{char\_wd\_}{\&{charwd} primitive}, \[192].
+\:\.{Character c is already...}, 1105.
+\:{character set dependencies}, 22, 49.
+\:{check sum}, 53, 1090, 1131, 1146.
+\:\\{check\_arith}, \[99], 269, 815, 823, 837, 895, 898, 922, 1001.
+\:\\{check\_colon}, \[747], 748.
+\:\\{check\_delimiter}, 703, 826, 830, \[1032].
+\:\\{check\_equals}, \[693], 694, 697.
+\:\\{check\_gf}, \[1163], 1165, 1177, 1179.
+\:\\{check\_interrupt}, \[91], 650, 669, 825.
+\:\\{check\_mem}, 178, \[180], 617, 825, 1213.
+\:\\{check\_outer\_validity}, \[661], 668, 681.
+\:{Chinese characters}, 1147.
+\:\\{chop\_path}, 975, \[978].
+\:\\{chop\_string}, 975, \[977].
+\:\\{chopped}, \[402], 404.
+\:\\{chr}, 19, 20, 23.
+\:\\{class}, \[217], 220, 221, 223, \[667], 669.
+\:\\{clear\_arith}, \[99].
+\:\\{clear\_for\_error\_prompt}, 73, 78, \[656], 670, 672.
+\:\\{clear\_symbol}, \[249], 252, 254, 692, 1011, 1035.
+\:\\{clear\_terminal}, \[33], 656, 786.
+\:\\{clear\_the\_list}, \[1117], 1124, 1126.
+\:\.{CLOBBERED}, 218.
+\:\\{clobbered}, \[180], 181, 182.
+\:\\{clockwise}, 452, \[453], 454, 458.
+\:\\{close}, 27.
+\:\\{close\_files\_and\_terminate}, 73, 76, 1204, \[1205].
+\:\.{cmbase}, 1203.
+\:\\{coef\_bound}, \[592], 595, 596, 598, 599, 600, 932, 943, 949.
+\:\\{collective\_subscript}, \[229], 239, 241, 244, 246, 850, 1012.
+\:\\{colon}, \[186], 211, 212, 747, 756, 764, 1106, 1107, 1111, 1113.
+\:\\{comma}, \[186], 211, 212, 704, 725, 726, 727, 764, 826, 859, 878, 1015,
+1016, 1029, 1033, 1036, 1040, 1044, 1049, 1107, 1113, 1114, 1115.
+\:\\{command\_code}, \[186], 685, 694, 1072.
+\:\\{common\_ending}, \[15], 865, 1071.
+\:\\{compromise}, \[432], 435, 438, 443.
+\:\\{concatenate}, \[189], 893, 975.
+\:\\{cond\_ptr}, \[738], 739, 744, 745, 746, 748, 749, 1209.
+\:\\{conditional}, 706, 707, \[748].
+\:\\{confusion}, \[90], 107, 114, 216, 236, 239, 311, 362, 378, 517, 523, 589,
+655, 746, 802, 809, 855.
+\:\\{const\_dependency}, \[607], 608, 969, 972, 1007.
+\:\\{constant\_x}, \[406], 407, 413, 417.
+\:\\{continue}, \[15], 77, 78, 79, 83, 84, 311, 314, 402, 406, 417, 447, 556,
+755, 764, 862, 864, 868, 1106, 1107, 1111.
+\:\\{continue\_path}, \[868], 869.
+\:\9{contour\_}{\&{contour} primitive}, \[1052].
+\:\\{contour\_code}, \[403], 917, 1052, 1053.
+\:\.{control?}, 258.
+\:\\{controls}, \[186], 211, 212, 881.
+\:\9{controls\_}{\&{controls} primitive}, \[211].
+\:\\{coord\_node\_size}, 175, \[472], 476, 481, 487.
+\:{coordinates, explained}, 576.
+\:\\{copied}, \[1006], 1009.
+\:\\{copy\_dep\_list}, \[609], 855, 858, 947.
+\:\\{copy\_edges}, \[334], 621, 855.
+\:\\{copy\_knot}, \[264], 870, 885, 980, 981.
+\:\\{copy\_path}, \[265], 621, 855.
+\:\9{cos\_d\_}{\&{cosd} primitive}, \[893].
+\:\\{cos\_d\_op}, \[189], 893, 906.
+\:\\{cosine}, \[280], 281.
+\:\\{crossing\_point}, \[391], 392, 407, 411, 413, 415, 420, 424, 497, 499,
+503, 545, 547, 549.
+\:\\{cs}, \[1146].
+\:\\{ct}, \[116], 297, \[298], 299, 300, 301.
+\:\\{cubic\_intersection}, 555, \[556], 557, 562.
+\:\9{cull\_}{\&{cull} primitive}, \[211].
+\:\\{cull\_command}, \[186], 211, 212, 1069.
+\:\\{cull\_edges}, \[348], 1074.
+\:\\{cull\_op}, \[186], 1052, 1053, 1074.
+\:\\{cur\_area}, \[767], 772, 784, 786, 793, 795.
+\:\\{cur\_cmd}, 83, 186, \[624], 626, 651, 652, 658, 667, 668, 671, 675, 676,
+678, 685, 686, 691, 693, 697, 700, 703, 704, 705, 706, 707, 713, 715, 718, 725,
+726, 727, 731, 732, 733, 734, 735, 742, 743, 747, 755, 756, 764, 765, 796, 823,
+824, 826, 832, 837, 839, 841, 844, 846, 847, 851, 852, 859, 860, 861, 862, 864,
+868, 869, 874, 875, 878, 881, 882, 884, 989, 990, 991, 992, 993, 995, 996,
+1011, 1012, 1015, 1016, 1017, 1021, 1029, 1032, 1033, 1034, 1035, 1036, 1040,
+1041, 1042, 1044, 1049, 1051, 1062, 1072, 1074, 1106, 1107, 1111, 1113, 1114,
+1115.
+\:\\{cur\_edges}, \[327], 328, 329, 330, 331, 332, 333, 336, 337, 340, 341,
+342, 343, 348, 352, 353, 354, 355, 356, 364, 365, 366, 367, 373, 374, 375, 376,
+377, 378, 381, 382, 383, 384, 465, 577, 581, 804, 929, 963, 964, 965, 1057,
+1061, 1064, 1070, 1071, 1074, 1167, 1169, 1172.
+\:\\{cur\_exp}, 603, 615, 651, 713, 716, 717, 718, 726, 728, 730, 748, 750,
+760, 761, 764, 765, \[796], 797, 798, 799, 800, 801, 808, 816, 819, 823, 827,
+829, 830, 833, 837, 840, 841, 846, 852, 855, 856, 857, 860, 861, 863, 865, 870,
+872, 875, 876, 877, 878, 879, 880, 882, 883, 885, 891, 895, 896, 897, 898, 901,
+903, 905, 906, 907, 908, 910, 912, 913, 915, 916, 917, 919, 920, 921, 923, 927,
+929, 930, 931, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 946, 948, 949,
+951, 953, 955, 956, 962, 963, 964, 967, 968, 970, 972, 973, 976, 977, 978, 979,
+984, 985, 988, 992, 994, 995, 996, 999, 1003, 1004, 1005, 1006, 1009, 1022,
+1056, 1059, 1061, 1062, 1063, 1070, 1071, 1072, 1073, 1074, 1082, 1083, 1086,
+1103, 1106, 1112, 1115, 1177, 1179, 1181.
+\:\\{cur\_ext}, \[767], 772, 784, 786, 793, 795.
+\:\\{cur\_file}, \[631], 655, 681, 793, 794.
+\:\\{cur\_gran}, \[430], 431, 432, 433, 442.
+\:\\{cur\_if}, \[738], 739, 744, 745, 748, 1209.
+\:\\{cur\_input}, 34, 35, 82, \[628], 629, 635, 647, 648, 788.
+\:\\{cur\_length}, \[40], 1163.
+\:\\{cur\_min\_m}, \[1165], 1172, 1173.
+\:\\{cur\_mod}, 83, \[624], 626, 651, 652, 658, 667, 668, 671, 675, 676, 678,
+687, 690, 691, 694, 697, 700, 703, 705, 707, 711, 718, 726, 727, 731, 735, 742,
+743, 748, 749, 751, 755, 796, 823, 824, 826, 833, 834, 835, 837, 839, 841, 846,
+847, 851, 860, 861, 862, 864, 868, 990, 992, 1011, 1015, 1023, 1029, 1032,
+1034, 1035, 1040, 1041, 1042, 1049, 1051, 1054, 1059, 1074, 1082, 1106, 1112,
+1177, 1209.
+\:\\{cur\_name}, \[767], 772, 784, 786, 793, 795.
+\:\\{cur\_path\_type}, \[403], 435, 438, 442, 917, 1064, 1068.
+\:\\{cur\_pen}, 402, \[403], 435, 438, 442, 506, 917, 1062, 1063, 1064, 1068.
+\:\\{cur\_rounding\_ptr}, 426, \[427], 429, 433, 436, 439, 440, 444, 446.
+\:\\{cur\_spec}, 394, 399, 400, 402, \[403], 404, 406, 407, 417, 419, 421, 433,
+440, 447, 450, 452.
+\:\\{cur\_sym}, 83, 210, 211, \[624], 651, 652, 658, 661, 662, 663, 664, 667,
+668, 669, 676, 677, 683, 685, 686, 690, 691, 692, 694, 700, 703, 704, 705, 707,
+718, 726, 735, 740, 751, 755, 796, 823, 824, 826, 837, 846, 847, 851, 860, 862,
+864, 868, 893, 1011, 1012, 1029, 1031, 1032, 1033, 1034, 1035, 1036, 1041,
+1049, 1076, 1204.
+\:\\{cur\_t}, \[555], 556, 558, 559, 560, 561, 562, 988.
+\:\\{cur\_tok}, \[651], 652, 685, 715, 730, 844.
+\:\\{cur\_tt}, \[555], 556, 558, 559, 560, 561, 562, 988.
+\:\\{cur\_type}, 603, 615, 651, 716, 718, 726, 728, 730, 760, 764, 765, \[796],
+798, 799, 800, 801, 808, 816, 819, 823, 826, 827, 830, 832, 833, 837, 840, 841,
+846, 852, 855, 856, 857, 860, 861, 864, 865, 870, 872, 876, 877, 878, 883, 885,
+891, 892, 895, 896, 897, 898, 901, 903, 905, 906, 907, 908, 909, 910, 912, 915,
+917, 918, 919, 920, 921, 923, 927, 929, 930, 931, 934, 935, 936, 937, 939, 940,
+941, 942, 944, 946, 948, 951, 953, 955, 960, 962, 967, 970, 973, 975, 982, 983,
+988, 989, 992, 993, 995, 996, 999, 1000, 1002, 1003, 1004, 1006, 1009, 1021,
+1054, 1059, 1061, 1062, 1070, 1071, 1072, 1073, 1074, 1082, 1103, 1106, 1112,
+1115, 1177, 1181.
+\:\\{cur\_wt}, \[327], 372, 373, 374, 375, 376, 378, 381, 382, 383, 384, 465,
+1064, 1068.
+\:\\{cur\_x}, 387, 388, \[389], 390, 394, 413, 421, 445, 447, 451, 454, 457,
+481, 485, 488, 489, 510, 871, 872, 873, 877, 878, 884, 984, 1072, 1073, 1074,
+1075.
+\:\\{cur\_y}, 387, 388, \[389], 390, 394, 413, 421, 445, 447, 451, 454, 457,
+481, 485, 488, 489, 510, 871, 872, 873, 877, 878, 884, 984, 1072, 1073, 1074,
+1075.
+\:\\{curl}, \[256], 258, 259, 263, 271, 282, 284, 285, 290, 875, 876, 888, 889,
+890, 891.
+\:\9{curl\_}{\&{curl} primitive}, \[211].
+\:\\{curl\_command}, \[186], 211, 212, 875.
+\:\\{curl\_ratio}, 294, 295, \[296].
+\:{curvature}, 275.
+\:\.{Curve out of range}, 404.
+\:\\{cycle}, \[186], 823, 869, 893, 894.
+\:{cycle spec}, \[393].
+\:\.{Cycle spec at line...}, 394.
+\:\9{cycle\_}{\&{cycle} primitive}, \[893].
+\:\\{cycle\_hit}, \[868], 869, 886, 891.
+\:\\{cycle\_op}, \[189], 893, 920.
+\:\\{c0}, \[574], 575, 576, \[1073].
+\:\\{c1}, \[574], 575, \[1073].
+\:\|{d}, \[333], \[348], \[373], \[391], \[440], \[527], \[580], \[862], %
+\[864], \[868], \[944], \[1118], \[1120], \[1121], \[1128], \[1159], \[1165].
+\:{data structure assumptions}, 176.
+\:\\{day}, \[190], 192, 193, 194, 790, 1163, 1200, 1211.
+\:\9{day\_}{\&{day} primitive}, \[192].
+\:\\{dd}, \[286], 288, 289, \[440], 444, 445, 446.
+\:{dead cubics}, \[402].
+\:\&{debug}, \[7], \[9], \[73], \[79], \[88], \[157], \[178], \[179], \[180], %
+\[185], \[1212].
+\:\.{debug \#}, 1212.
+\:\\{debug\_help}, 73, 79, 88, \[1212].
+\:{debugging}, 7, 79, 91, 157, 178, 1212.
+\:\\{decimal}, \[189], 893, 912.
+\:\9{decimal\_}{\&{decimal} primitive}, \[893].
+\:\.{Declared variable conflicts...}, 1015.
+\:\\{decr}, \[16], 43, 46, 63, 66, 81, 83, 84, 86, 87, 102, 121, 123, 149, 163,
+164, 177, 195, 207, 226, 291, 315, 322, 330, 331, 332, 333, 352, 364, 375, 376,
+377, 382, 383, 384, 436, 439, 458, 459, 483, 487, 488, 497, 515, 516, 521, 522,
+556, 560, 577, 635, 648, 650, 655, 681, 687, 731, 732, 742, 854, 862, 864, 868,
+1051, 1122, 1135, 1138, 1139, 1141, 1167, 1182, 1194, 1209.
+\:\9{def\_}{\&{def} primitive}, \[683].
+\:\\{def\_delims}, 1030, \[1031].
+\:\\{def\_ref}, \[720], 721, 736.
+\:\\{defined\_macro}, \[186], 249, 700, 706, 707, 718, 1035, 1041, 1043.
+\:\\{del}, \[406], 407, 408, 413, \[419], 420, \[453], 454.
+\:\\{del\_m}, \[1144].
+\:\\{del\_n}, \[1144].
+\:\\{delete\_mac\_ref}, \[226], 249, 650, 809.
+\:\\{delete\_pen\_ref}, \[487], 808, 809, 1062, 1063.
+\:\\{delete\_str\_ref}, \[43], 216, 691, 743, 808, 809, 976, 977, 1042, 1083.
+\:\\{deletions\_allowed}, \[71], 72, 79, 80, 93, 661, 670, 672, 675.
+\:\\{delimiters}, \[186], 211, 212, 1030.
+\:\9{delimiters\_}{\&{delimiters} primitive}, \[211].
+\:\\{delta}, \[103], \[279], 281, 288, \[328], \[329], 330, 331, \[342], 343, %
+\[366], 367, \[378], 381, 382, 383, 384, \[527], 530, 531, 533, 534, 535, %
+\[968], \[974], \[1165], 1173, 1174.
+\:\\{delta\_a}, \[426].
+\:\\{delta\_b}, \[426].
+\:\\{delta\_x}, \[279], 281, 292, 293, 299, 301, 302.
+\:\\{delta\_y}, \[279], 281, 292, 293, 299, 301, 302.
+\:\\{delx}, \[280], 282, \[374], 375, 376, \[511], 516, 522, 552, 553, 556, %
+\[557], 558, 559, 560, 561.
+\:\\{dely}, \[280], 282, \[374], 375, 376, \[511], 516, 522, 552, 553, 556, %
+\[557], 558, 559, 560, 561.
+\:\\{del1}, \[406], 407, 408, 409, 413, 414, \[419], 420, 421, 423.
+\:\\{del2}, \[406], 407, 408, 409, 411, 413, 414, 415, \[419], 420, 421, 423,
+424.
+\:\\{del3}, \[406], 407, 408, 409, 411, 413, 414, 415, \[419], 420, 421, 423,
+424.
+\:\\{denom}, \[116], \[296], \[836], 837.
+\:\\{dep\_div}, 948, \[949].
+\:\\{dep\_final}, \[592], 594, 597, 601, 606, 607, 608, 609, 615, 818, 819,
+829, 855, 856, 858, 971, 972, 1007.
+\:\\{dep\_finish}, 934, \[935], 943, 949.
+\:\\{dep\_head}, \[175], 587, 588, 604, 606, 614, 617, 812, 1050.
+\:\\{dep\_list}, 585, \[587], 604, 605, 606, 614, 617, 798, 799, 801, 803, 811,
+812, 816, 818, 819, 827, 855, 858, 903, 930, 931, 932, 935, 943, 947, 949, 959,
+968, 969, 971, 972, 1007, 1009, 1050.
+\:\\{dep\_mult}, 942, \[943], 944, 946, 968.
+\:\\{dep\_node\_size}, \[587], 595, 596, 597, 598, 599, 600, 601, 603, 605,
+607, 608, 609, 612, 615, 616, 818, 819, 829, 1008.
+\:\\{dependent}, \[187], 216, 248, 585, 587, 588, 589, 590, 594, 595, 596, 597,
+599, 600, 601, 603, 610, 612, 613, 615, 798, 799, 800, 801, 802, 808, 809, 812,
+813, 815, 816, 817, 818, 819, 829, 855, 857, 858, 900, 903, 930, 932, 943, 949,
+969, 1003, 1006, 1007, 1009, 1010, 1050.
+\:\\{depth\_index}, \[1091].
+\:{design size}, 1146.
+\:\\{design\_size}, \[190], 192, 193, 1128, 1129, 1182.
+\:\9{design\_size\_}{\&{designsize} primitive}, \[192].
+\:\\{dest\_x}, \[406], 407, 409, 411, 412, 413, 415, 416, \[419], 421, 423,
+424, 425.
+\:\\{dest\_y}, \[406], 407, 411, 412, 413, 414, 415, 416, \[419], 421, 423,
+424, 425.
+\:\\{diag\_offset}, \[442], 443.
+\:\\{diag\_round}, 402, \[440].
+\:\\{diagonal}, \[393], 459, 507, 508, 509, 519, 523.
+\:\\{dig}, \[54], 63, 64, 102, 674.
+\:\\{digit\_class}, \[198], 199, 220, 669, 673, 674.
+\:\\{dimen\_head}, 1124, \[1125], 1126, 1136.
+\:\\{dimen\_out}, \[1129], 1132, 1136, 1139, 1140.
+\:\9{direction\_time\_}{\&{directiontime} primitive}, \[893].
+\:\\{direction\_time\_of}, \[189], 893, 983.
+\:{dirty \PASCAL}, \[3], 157, 185, 1203.
+\:\\{discard\_suffixes}, \[246].
+\:\\{disp\_edges}, \[577], 1071.
+\:\\{disp\_err}, 716, 754, \[807], 873, 923, 937, 955, 1002.
+\:\\{disp\_token}, \[1041], 1043, 1044, 1049.
+\:\\{disp\_var}, \[1046], 1047, 1049.
+\:\9{display\_}{\&{display} primitive}, \[211].
+\:\\{display\_command}, \[186], 211, 212, 1069.
+\:\&{div}, \[95].
+\:\.{Division by zero}, 838, 950.
+\:\\{dm}, \[1144].
+\:\\{dmax}, 404, \[406], 408, \[419], \[453], 457.
+\:\\{do\_add\_to}, 1058, \[1059].
+\:\\{do\_assignment}, 993, 995, \[996].
+\:\\{do\_binary}, 834, 837, 839, 859, 862, 864, 868, 893, \[922], 966.
+\:\\{do\_cull}, 1069, \[1074].
+\:\\{do\_display}, 1069, \[1071].
+\:\\{do\_equation}, 993, \[995], 996.
+\:\\{do\_expression}, 996.
+\:\\{do\_interim}, 1033, \[1034].
+\:\\{do\_let}, 1033, \[1035].
+\:\\{do\_message}, 1081, \[1082].
+\:\\{do\_new\_internal}, 1033, \[1036].
+\:\\{do\_nothing}, \[16], 33, 57, 58, 79, 146, 216, 223, 249, 669, 707, 794,
+808, 809, 919, 957, 1003, 1035.
+\:\\{do\_nullary}, 834, 893, \[895].
+\:\\{do\_open\_window}, 1069, \[1073].
+\:\\{do\_protection}, 1026, \[1029].
+\:\\{do\_random\_seed}, 1020, \[1021].
+\:\\{do\_ship\_out}, 1069, \[1070].
+\:\\{do\_show}, \[1040], 1051.
+\:\\{do\_show\_dependencies}, \[1050], 1051, 1213.
+\:\\{do\_show\_stats}, \[1045], 1051.
+\:\\{do\_show\_token}, \[1044], 1051.
+\:\\{do\_show\_var}, 1046, \[1049], 1051.
+\:\\{do\_show\_whatever}, 1039, \[1051].
+\:\\{do\_special}, 1175, \[1177].
+\:\\{do\_statement}, 832, \[989], 992, 1017, 1020, 1034.
+\:\\{do\_tfm\_command}, 1100, \[1106].
+\:\\{do\_type\_declaration}, 992, \[1015].
+\:\\{do\_unary}, 834, 835, 893, \[898].
+\:\\{done}, \[15], 47, 53, 124, 125, 126, 127, 177, 257, 269, 272, 311, 317,
+344, 345, 346, 347, 348, 349, 354, 358, 366, 368, 374, 375, 378, 381, 382, 383,
+384, 394, 402, 452, 458, 477, 479, 488, 491, 502, 506, 512, 518, 527, 531, 532,
+539, 546, 547, 548, 577, 578, 584, 594, 597, 604, 605, 609, 635, 650, 667, 673,
+685, 687, 730, 731, 732, 742, 748, 749, 755, 764, 765, 781, 786, 787, 793, 809,
+812, 823, 835, 837, 839, 840, 841, 852, 860, 868, 881, 919, 922, 930, 932, 936,
+953, 955, 957, 958, 959, 1001, 1003, 1004, 1005, 1006, 1007, 1011, 1012, 1049,
+1059, 1068, 1106, 1107, 1110, 1165, 1172, 1173.
+\:\\{done1}, \[15], 180, 181, 257, 258, 261, 374, 376, 477, 481, 506, 516, 518,
+522, 527, 536, 823, 844, 922, 939, 1006, 1009.
+\:\\{done2}, \[15], 180, 182, 823, 850.
+\:\\{done3}, \[15].
+\:\\{done4}, \[15].
+\:\\{done5}, \[15].
+\:\\{done6}, \[15].
+\:\\{double}, \[16], 108, 115, 123, 132, 142, 143, 392, 408, 457, 496, 543,
+556, 559.
+\:\.{Double-AVAIL list clobbered...}, 182.
+\:\\{double\_colon}, \[186], 211, 212, 1107.
+\:\\{double\_dot}, \[189].
+\:\9{double\_path\_}{\&{doublepath} primitive}, \[1052].
+\:\\{double\_path\_code}, \[403], 435, 438, 442, 1052, 1053, 1059, 1064, 1068.
+\:\.{Doubly free location...}, 182.
+\:\\{drop\_code}, \[1052], 1053, 1074, 1075.
+\:\9{dropping\_}{\&{dropping} primitive}, \[1052].
+\:{dry rot}, 90.
+\:\\{ds}, \[1146].
+\:\\{du}, \[495], \[497], 498.
+\:\\{dual\_moves}, 512, \[518].
+\:\.{dump...only by INIMF}, 1209.
+\:\9{dump\_}{\&{dump} primitive}, \[1018].
+\:\\{dump\_four\_ASCII}, \[1192].
+\:\\{dump\_hh}, \[1188], 1196.
+\:\\{dump\_int}, \[1188], 1190, 1192, 1194, 1196, 1198.
+\:\\{dump\_qqqq}, \[1188], 1192.
+\:\\{dump\_wd}, \[1188], 1194.
+\:\\{dup\_offset}, \[476], 483.
+\:\\{dv}, \[495], \[497], 498.
+\:\\{dw}, \[357], 358.
+\:\\{dx}, \[378], 380, 381, 382, 383, 384, \[477], 479, 480, 494, \[495], 501,
+502, 1144, 1147.
+\:\\{dx1}, \[453], 454, 457.
+\:\\{dx2}, \[453], 454, 457.
+\:\\{dy}, \[477], 479, 480, \[495], 501, 502, 1144, 1147.
+\:\\{dyn\_used}, \[160], 163, 164, 165, 176, 177, 1045, 1194, 1195.
+\:\\{dy1}, \[453], 454, 457.
+\:\\{dy2}, \[453], 454, 457.
+\:\\{d0}, \[464], 467, 468, 508, 517, 523.
+\:\\{d1}, 463, \[464], 467, 468, 508, 517, 523.
+\:\|{e}, \[773], \[774], \[786], \[1071], \[1074].
+\:\\{east\_edge}, \[435].
+\:\\{east\_west\_edge}, \[435].
+\:\\{ec}, 1088, 1089, 1091, 1093, \[1096], 1097, 1099, 1124, 1126, 1132, 1135,
+1136.
+\:\\{edge\_and\_weight}, \[378], 381, 382, 383, 384.
+\:\\{edge\_header\_size}, \[326], 334, 385, 895, 964.
+\:\\{edge\_prep}, \[329], 366, 375, 376, 380.
+\:\\{edges\_trans}, 952, \[963].
+\:\\{ee}, \[286], 288, 289.
+\:\\{eg\_loc}, 211, 698, \[699], 1198, 1199.
+\:\\{eight\_bits}, \[24], 63, 624, 1096, 1103, 1131, 1149, 1152, 1163, 1165.
+\:\\{eighth\_octant}, \[139], 141, 380, 387, 388, 390, 396, 426, 443, 449, 461,
+462.
+\:\\{el\_gordo}, \[95], 100, 107, 109, 112, 114, 124, 135, 235, 244, 917, 1118,
+1140.
+\:\&{else}, 10.
+\:\9{else\_}{\&{else} primitive}, \[740].
+\:\\{else\_code}, \[738], 740, 741.
+\:\9{else\_if\_}{\&{elseif} primitive}, \[740].
+\:\\{else\_if\_code}, \[738], 740, 748.
+\:\.{Emergency stop}, 88.
+\:\\{empty\_edges}, \[326], 329, 963.
+\:\\{empty\_flag}, \[166], 168, 172, 176, 1207.
+\:\\{encapsulate}, 855, \[856].
+\:\&{end}, 7, 8, 10.
+\:\.{end occurred...}, 1209.
+\:\.{End of file on the terminal}, 36, 66.
+\:\9{end\_}{\&{end} primitive}, \[1018].
+\:\\{end\_attr}, \[175], 229, 239, 247, 1047.
+\:\\{end\_cycle}, \[272], 281, 282, 284, 287.
+\:\\{end\_def}, \[683], 992.
+\:\9{end\_def\_}{\&{enddef} primitive}, \[683].
+\:\\{end\_diagnostic}, \[195], 254, 257, 332, 372, 394, 473, 603, 613, 626,
+721, 728, 734, 750, 762, 817, 902, 924, 945, 997, 998.
+\:\\{end\_edge\_tracing}, \[372], 465, 506.
+\:\\{end\_file\_reading}, \[655], 656, 679, 681, 714, 793, 897, 1209.
+\:\\{end\_for}, \[683], 707.
+\:\9{end\_for\_}{\&{endfor} primitive}, \[683].
+\:\\{end\_group}, \[186], 211, 212, 732, 832, 991, 992, 993, 1017.
+\:\9{end\_input\_}{\&{endinput} primitive}, \[709].
+\:\\{end\_name}, 767, \[772], 781, 787.
+\:\\{end\_of\_MF}, \[6], 76, 1204.
+\:\\{end\_of\_statement}, \[186], 732, 991, 1015, 1016.
+\:\\{end\_round}, \[463], 464, 467, 508.
+\:\\{end\_token\_list}, \[650], 652, 676, 712, 714, 736, 795, 1209.
+\:\&{endcases}, \[10].
+\:\9{endgroup\_}{\&{endgroup} primitive}, \[211].
+\:\\{endpoint}, \[255], 256, 257, 258, 266, 273, 393, 394, 398, 399, 400, 401,
+402, 451, 452, 457, 465, 466, 491, 506, 512, 518, 539, 562, 563, 865, 868, 870,
+871, 885, 891, 916, 917, 920, 921, 962, 978, 979, 985, 987, 1064.
+\:\.{Enormous chardp...}, 1098.
+\:\.{Enormous charht...}, 1098.
+\:\.{Enormous charic...}, 1098.
+\:\.{Enormous charwd...}, 1098.
+\:\.{Enormous designsize...}, 1098.
+\:\.{Enormous number...}, 675.
+\:\.{entering the nth octant}, 394.
+\:\\{env\_move}, \[507], 513, 514, 515, 516, 517, 519, 520, 521, 522, 523.
+\:\\{eoc}, 1142, 1144, \[1145], 1146, 1149, 1165.
+\:\\{eof}, 25, 30, 52, 1199.
+\:\\{eoln}, 30, 52.
+\:\\{eq\_type}, \[200], 202, 203, 210, 211, 213, 229, 242, 249, 254, 668, 694,
+700, 702, 759, 850, 1011, 1029, 1031, 1035, 1036, 1041, 1213.
+\:\\{eqtb}, 158, 200, \[201], 202, 210, 211, 212, 213, 249, 250, 252, 254, 625,
+632, 683, 740, 893, 1196, 1197.
+\:\\{equal\_to}, \[189], 893, 936, 937.
+\:\\{equals}, \[186], 693, 733, 755, 868, 893, 894, 993, 995, 996, 1035.
+\:\.{Equation cannot be performed}, 1002.
+\:\\{equiv}, \[200], 202, 209, 210, 211, 213, 229, 234, 239, 242, 249, 254,
+664, 668, 694, 700, 702, 850, 1011, 1015, 1030, 1031, 1035, 1036, 1213.
+\:\\{err\_help}, \[74], 75, 85, 1083, 1086.
+\:\9{err\_help\_}{\&{errhelp} primitive}, \[1079].
+\:\\{err\_help\_code}, \[1079], 1082.
+\:\9{err\_message\_}{\&{errmessage} primitive}, \[1079].
+\:\\{err\_message\_code}, \[1079], 1080, 1082.
+\:\\{error}, 67, 70, 71, 73, 74, \[77], 83, 88, 93, 99, 122, 128, 134, 140,
+602, 653, 670, 672, 675, 701, 708, 712, 713, 725, 751, 778, 789, 795, 820, 838,
+996, 1032, 1051, 1110.
+\:\\{error\_count}, \[71], 72, 77, 81, 989, 1051.
+\:\\{error\_line}, \[11], 14, 54, 58, 635, 641, 642, 643, 665.
+\:\\{error\_message\_issued}, \[71], 77, 90.
+\:\\{error\_stop\_mode}, 67, \[68], 69, 77, 88, 93, 398, 807, 1024, 1051, 1086,
+1199, 1209.
+\:\9{error\_stop\_mode\_}{\&{errorstopmode} primitive}, \[1024].
+\:\\{erstat}, \[26].
+\:\\{eta\_corr}, 306, \[311], 313, 314, 317.
+\:\.{ETC}, 217, 227.
+\:\9{every\_job\_}{\&{everyjob} primitive}, \[211].
+\:\\{every\_job\_command}, \[186], 211, 212, 1076.
+\:\\{excess}, \[1119], 1120, 1122.
+\:\\{exit}, \[15], 16, 36, 46, 47, 77, 117, 167, 217, 227, 235, 242, 246, 265,
+266, 284, 311, 391, 406, 488, 497, 539, 556, 562, 589, 622, 667, 746, 748, 760,
+779, 868, 899, 904, 922, 928, 930, 943, 949, 953, 962, 963, 966, 1032, 1070,
+1071, 1073, 1074, 1131, 1161, 1187, 1209, 1212.
+\:\9{exit\_if\_}{\&{exitif} primitive}, \[211].
+\:\\{exit\_test}, \[186], 211, 212, 706, 707.
+\:\\{exp\_err}, \[807], 830, 849, 872, 876, 878, 883, 892, 901, 914, 923, 937,
+950, 960, 993, 996, 999, 1002, 1021, 1055, 1060, 1061, 1062, 1071, 1082, 1103,
+1106, 1112, 1115, 1178.
+\:\\{expand}, \[707], 715, 718.
+\:\\{expand\_after}, \[186], 211, 212, 706, 707.
+\:\9{expand\_after\_}{\&{expandafter} primitive}, \[211].
+\:\\{explicit}, \[256], 258, 261, 262, 266, 271, 273, 280, 282, 299, 302, 393,
+407, 486, 563, 874, 880, 884, 1066.
+\:\.{EXPR}, 222.
+\:\9{expr\_}{\&{expr} primitive}, \[695].
+\:\\{expr\_base}, \[214], 218, 222, 676, 683, 684, 694, 695, 696, 697, 703,
+705, 725, 727, 755, 764.
+\:\\{expr\_macro}, \[226], 227, 705, 733.
+\:\\{expression\_binary}, \[186], 893, 894.
+\:\\{expression\_tertiary\_macro}, \[186], 249, 683, 868, 1035, 1043.
+\:\\{ext\_bot}, \[1094], 1113.
+\:\\{ext\_delimiter}, \[768], 770, 771, 772.
+\:\\{ext\_mid}, \[1094], 1113.
+\:\\{ext\_rep}, \[1094], 1113.
+\:\\{ext\_tag}, \[1092], 1096, 1105, 1113.
+\:\\{ext\_top}, \[1094], 1113.
+\:\\{exten}, \[1092], 1094, \[1096], 1140.
+\:\9{extensible\_}{\&{extensible} primitive}, \[1101].
+\:\\{extensible\_code}, \[1101], 1102, 1106.
+\:\\{extensible\_recipe}, 1089, \[1094].
+\:{extensions to \MF}, 2.
+\:\.{Extra `endfor'}, 708.
+\:\.{Extra `endgroup'}, 1017.
+\:\.{Extra else}, 751.
+\:\.{Extra elseif}, 751.
+\:\.{Extra fi}, 751.
+\:\.{Extra tokens will be flushed}, 991.
+\:\\{extra\_space}, 1095.
+\:\\{extra\_space\_code}, \[1095].
+\:\\{extras}, 362, \[363].
+\:\|{f}, \[26], \[27], \[30], \[107], \[109], \[112], \[114], \[398], \[594], %
+\[667], \[780], \[1165].
+\:\\{false}, 26, 30, 36, 45, 47, 51, 71, 75, 83, 84, 93, 98, 99, 107, 110, 114,
+124, 126, 179, 180, 181, 182, 254, 269, 270, 407, 426, 446, 452, 454, 455, 456,
+474, 497, 503, 505, 530, 564, 570, 573, 577, 592, 593, 600, 603, 604, 613, 626,
+653, 657, 661, 670, 672, 675, 680, 681, 692, 721, 728, 734, 750, 762, 767, 771,
+779, 783, 794, 801, 804, 817, 825, 869, 899, 902, 913, 924, 944, 945, 977, 978,
+997, 998, 1003, 1009, 1010, 1011, 1015, 1035, 1045, 1054, 1064, 1072, 1085,
+1086, 1097, 1107, 1137, 1138, 1187.
+\:\9{false\_}{\&{false} primitive}, \[893].
+\:\\{false\_code}, \[189], 798, 892, 893, 895, 905, 906, 918, 919, 920, 937,
+940.
+\:\\{fast\_case\_down}, \[378], 380.
+\:\\{fast\_case\_up}, \[378], 380.
+\:\\{fast\_get\_avail}, \[165], 381, 382, 383, 384, 651, 844.
+\:\.{Fatal base file error}, 1187.
+\:\\{fatal\_error}, 66, \[88], 679, 714, 786, 789, 897.
+\:\\{fatal\_error\_stop}, \[71], 72, 77, 88, 1204.
+\:\\{ff}, \[286], 287, 289, 290, 295, \[296], 302.
+\:\9{fi\_}{\&{fi} primitive}, \[740].
+\:\\{fi\_code}, \[738], 740, 741, 742, 748, 749, 751.
+\:\\{fi\_or\_else}, \[186], 706, 707, 738, 740, 741, 742, 751, 1209.
+\:\\{fifth\_octant}, \[139], 141, 380, 387, 388, 390, 396, 426, 443, 449, 461,
+462.
+\:\.{File ended while scanning...}, 663.
+\:\.{File names can't...}, 795.
+\:\\{file\_name\_size}, \[11], 25, 774, 777, 778, 780.
+\:\\{file\_offset}, \[54], 55, 57, 58, 62, 333, 372, 793, 1048, 1165.
+\:\\{file\_ptr}, 79, 80, \[634], 635, 636, 637.
+\:\\{file\_state}, \[632], 635, 636, 656, 667, 714, 795.
+\:\\{fill\_envelope}, 481, \[506], 518, 1064.
+\:\\{fill\_spec}, \[465], 506, 511, 1064.
+\:\\{fillin}, \[190], 192, 193, 525, 533.
+\:\9{fillin\_}{\&{fillin} primitive}, \[192].
+\:\\{fin\_numeric\_token}, \[667], 669, 673.
+\:\\{fin\_offset\_prep}, \[497], 503, 504, 505.
+\:\\{final\_cleanup}, 1204, \[1209].
+\:\\{final\_end}, \[6], 34, 657, 1204, 1211.
+\:\\{final\_node}, \[610], 612, 615.
+\:\\{final\_value}, \[752], 761, 765.
+\:\\{find\_direction\_time}, \[539], 540, 984.
+\:\\{find\_edges\_var}, \[1057], 1061, 1064, 1070, 1071, 1074.
+\:\\{find\_offset}, \[488], 984.
+\:\\{find\_point}, 983, \[985].
+\:\\{find\_variable}, \[242], 700, 852, 1000, 1015, 1057.
+\:\\{finish\_path}, \[868], 869, 874.
+\:\\{firm\_up\_the\_line}, 666, 681, \[682], 794.
+\:\\{first}, \[29], 30, 34, 35, 36, 66, 78, 82, 83, 654, 655, 657, 679, 681,
+682, 717, 787, 794.
+\:\\{first\_count}, \[54], 641, 642, 643.
+\:\\{first\_octant}, \[139], 141, 378, 379, 380, 387, 388, 390, 395, 396, 406,
+407, 409, 411, 426, 435, 443, 448, 449, 461, 462, 473, 480, 484, 488, 489.
+\:\\{first\_text\_char}, \[19], 23.
+\:\\{first\_x}, \[406], 407, \[440], 444, 445.
+\:\\{first\_y}, \[406], 407, \[440], 444, 445.
+\:\\{fix\_check\_sum}, \[1131], 1206.
+\:\\{fix\_date\_and\_time}, \[194], 1204, 1211.
+\:\\{fix\_dependencies}, \[604], 610, 815, 935, 968, 971.
+\:\\{fix\_design\_size}, \[1128], 1206.
+\:\\{fix\_needed}, \[592], 593, 595, 596, 598, 599, 600, 604, 610, 815, 932,
+935, 968, 971.
+\:\\{fix\_offset}, \[328], 329, 965.
+\:\\{fix\_word}, \[1089], 1090, 1095, 1129, 1147.
+\:\9{floor\_}{\&{floor} primitive}, \[893].
+\:\\{floor\_op}, \[189], 893, 906.
+\:\\{floor\_scaled}, \[119], 516, 522, 906.
+\:\\{floor\_unscaled}, \[119], 306, 463, 513, 515, 516, 519, 521, 522, 1074.
+\:\\{flush\_below\_variable}, 246, \[247], 249.
+\:\\{flush\_cur\_exp}, 717, \[808], 820, 872, 907, 913, 915, 917, 918, 919,
+920, 921, 935, 936, 938, 956, 962, 982, 984, 993, 1040, 1061, 1063, 1070, 1072,
+1082, 1177.
+\:\\{flush\_error}, \[820], 849, 1017.
+\:\\{flush\_list}, \[177], 385, 700, 736, 1015.
+\:\\{flush\_node\_list}, \[177], 685, 811, 815, 852, 996, 1009, 1057.
+\:\\{flush\_p}, \[621].
+\:\\{flush\_string}, \[43], 210, 793, 1200.
+\:\\{flush\_token\_list}, \[216], 224, 226, 235, 650, 698, 763, 840, 1062,
+1071, 1074.
+\:\\{flush\_variable}, \[246], 700, 1015.
+\:\\{flushing}, \[659], 664, 665, 991, 1016.
+\:\.{font metric dimensions...}, 1140.
+\:{font metric files}, 1087.
+\:\.{Font metrics written...}, 1134.
+\:\9{font\_dimen\_}{\&{fontdimen} primitive}, \[1101].
+\:\\{font\_dimen\_code}, \[1101], 1106.
+\:\\{fontmaking}, \[190], 192, 193, 1206.
+\:\9{fontmaking\_}{\&{fontmaking} primitive}, \[192].
+\:\9{for\_}{\&{for} primitive}, \[683].
+\:\9{for\_suffixes\_}{\&{forsuffixes} primitive}, \[683].
+\:\.{Forbidden token found...}, 663.
+\:\\{force\_eof}, 657, \[680], 681, 711.
+\:\9{forever\_}{\&{forever} primitive}, \[683].
+\:\\{forever\_text}, \[632], 638, 714, 760.
+\:\\{forty\_five\_deg}, \[106], 145.
+\:\\{forward}, 73, 216, 217, 224, 225, 666, 706, 820, 995, 1034.
+\:\\{found}, \[15], 167, 170, 171, 205, 206, 207, 235, 236, 284, 291, 292, 295,
+477, 527, 532, 539, 541, 543, 544, 547, 548, 577, 582, 667, 669, 685, 686, 720,
+726, 748, 755, 779, 1103, 1117.
+\:\\{found1}, \[15].
+\:\\{found2}, \[15].
+\:\\{four\_quarters}, \[156], 1096, 1133, 1186, 1187.
+\:\\{fourth\_octant}, \[139], 141, 380, 387, 388, 390, 393, 396, 426, 435, 443,
+449, 461, 462, 472.
+\:\\{frac\_mult}, 837, \[944].
+\:\\{fraction}, \[105], 107, 109, 114, 116, 119, 124, 126, 144, 145, 148, 149,
+150, 187, 259, 280, 283, 286, 296, 298, 299, 391, 406, 410, 419, 433, 440, 493,
+495, 497, 542, 585, 587, 591, 592, 594, 599, 612, 932, 944.
+\:\\{fraction\_four}, \[105], 111, 113, 116, 121, 123, 125, 126, 127, 132, 133,
+296, 1116.
+\:\\{fraction\_half}, \[105], 111, 152, 288, 408, 496, 543, 1098, 1128, 1140.
+\:\\{fraction\_one}, \[105], 107, 108, 109, 142, 145, 148, 149, 150, 285, 288,
+290, 291, 295, 300, 311, 391, 392, 402, 407, 411, 413, 415, 420, 424, 436, 439,
+444, 457, 477, 478, 497, 499, 503, 530, 540, 547, 549, 599, 603, 612, 615, 816,
+917, 1169, 1170.
+\:\\{fraction\_three}, \[105], 116, 288, 296.
+\:\\{fraction\_threshold}, \[594], 597.
+\:\\{fraction\_two}, \[105], 116, 121, 124, 142.
+\:\\{free}, \[178], 180, 181, 182, 183, 184.
+\:\\{free\_avail}, \[164], 177, 216, 254, 349, 360, 604, 760, 763, 852, 860.
+\:\\{free\_node}, \[172], 177, 216, 246, 247, 249, 254, 268, 352, 353, 354,
+358, 385, 405, 452, 487, 532, 537, 595, 598, 599, 600, 601, 603, 605, 612, 615,
+616, 650, 745, 763, 800, 808, 810, 818, 819, 827, 829, 837, 855, 858, 866, 890,
+903, 910, 922, 925, 942, 944, 947, 955, 970, 980, 1001, 1006, 1008, 1065, 1209.
+\:\9{from\_}{\&{from} primitive}, \[211].
+\:\\{from\_token}, \[186], 211, 212, 1073.
+\:\\{frozen\_bad\_vardef}, \[201], 203, 702.
+\:\\{frozen\_colon}, \[201], 203, 211, 751.
+\:\\{frozen\_end\_def}, \[201], 203, 664, 683.
+\:\\{frozen\_end\_for}, \[201], 203, 664, 683.
+\:\\{frozen\_end\_group}, \[201], 203, 211, 664, 698.
+\:\\{frozen\_fi}, \[201], 203, 661, 740.
+\:\\{frozen\_inaccessible}, \[201], 203, 691, 1196, 1197, 1199.
+\:\\{frozen\_left\_bracket}, \[201], 203, 211, 847.
+\:\\{frozen\_repeat\_loop}, \[201], 757, 758, 759.
+\:\\{frozen\_right\_delimiter}, \[201], 203, 664.
+\:\\{frozen\_semicolon}, \[201], 203, 211, 664.
+\:\\{frozen\_slash}, \[201], 203, 837, 893.
+\:\\{frozen\_undefined}, \[201], 249.
+\:{Fuchs, David Raymond}, 2, 1148.
+\:\\{future\_pen}, \[187], 216, 248, 798, 802, 804, 808, 809, 855, 864, 865,
+896, 918, 919, 921, 952, 962, 983.
+\:\|{g}, \[47].
+\:\\{g\_pointer}, 216, 219, 224, \[225], 1042.
+\:\\{gamma}, \[296], \[527], 528, 529, 530.
+\:\\{general\_macro}, \[226], 227, 694, 697, 725.
+\:\\{get}, 25, 28, 30, 32, 794, 1189.
+\:\\{get\_avail}, \[163], 165, 235, 236, 250, 335, 350, 362, 375, 376, 605,
+662, 694, 697, 698, 704, 728, 734, 758, 764, 841, 845, 853, 854, 860, 863, 1011.
+\:\\{get\_boolean}, 706, 713, 748, \[892].
+\:\\{get\_clear\_symbol}, \[692], 694, 700, 1031, 1036.
+\:\\{get\_code}, \[1103], 1106, 1107, 1110, 1112, 1113, 1114.
+\:\\{get\_next}, 71, 73, 83, 624, 658, 659, 666, \[667], 676, 679, 685, 690,
+691, 694, 700, 703, 704, 705, 706, 715, 718, 720, 730, 742, 781, 991, 1016,
+1044, 1049.
+\:\\{get\_node}, \[167], 173, 215, 232, 233, 234, 239, 240, 241, 244, 245, 252,
+253, 264, 265, 266, 330, 331, 334, 341, 355, 364, 410, 451, 476, 477, 481, 486,
+528, 535, 536, 537, 596, 597, 607, 608, 609, 619, 651, 694, 704, 705, 744, 755,
+765, 799, 830, 856, 857, 871, 895, 896, 931, 964, 982, 1117.
+\:\\{get\_pair}, \[1072], 1073, 1074.
+\:\\{get\_strings\_started}, \[47], 51, 1204.
+\:\\{get\_symbol}, \[691], 692, 694, 704, 705, 755, 757, 1011, 1029, 1033,
+1035, 1076.
+\:\\{get\_x\_next}, 694, 697, 706, 707, 716, \[718], 726, 729, 733, 734, 735,
+748, 751, 752, 755, 764, 765, 799, 800, 820, 823, 824, 825, 826, 830, 835, 837,
+839, 840, 841, 844, 846, 850, 851, 853, 854, 859, 860, 861, 862, 864, 868, 874,
+875, 876, 878, 881, 882, 884, 886, 892, 989, 990, 995, 996, 1011, 1012, 1021,
+1023, 1029, 1031, 1033, 1034, 1035, 1036, 1040, 1044, 1045, 1049, 1050, 1054,
+1059, 1070, 1071, 1072, 1073, 1074, 1076, 1082, 1103, 1106, 1107, 1112, 1115,
+1177.
+\:\\{gf\_boc}, \[1161], 1162, 1168, 1172.
+\:\\{gf\_buf}, 1151, \[1152], 1154, 1155.
+\:\\{gf\_buf\_size}, \[11], 14, 1151, 1152, 1153, 1155, 1156, 1182.
+\:\\{gf\_dx}, 1099, \[1149], 1182.
+\:\\{gf\_dy}, 1099, \[1149], 1182.
+\:\\{gf\_ext}, \[785], 791, 1164.
+\:\\{gf\_file}, \[791], 1149, 1151, 1154, 1182.
+\:\\{gf\_four}, \[1157], 1161, 1166, 1177, 1182.
+\:\\{gf\_id\_byte}, \[1144], 1163, 1182.
+\:\\{gf\_index}, \[1151], 1152, 1154.
+\:\\{gf\_limit}, 1151, \[1152], 1153, 1155, 1156.
+\:\\{gf\_max\_m}, \[1149], 1163, 1168, 1169, 1182.
+\:\\{gf\_max\_n}, \[1149], 1161, 1163, 1182.
+\:\\{gf\_min\_m}, \[1149], 1161, 1163, 1182.
+\:\\{gf\_min\_n}, \[1149], 1163, 1167, 1168, 1182.
+\:\\{gf\_offset}, 1151, \[1152], 1153, 1155, 1163, 1165, 1182.
+\:\\{gf\_out}, \[1155], 1157, 1158, 1159, 1160, 1161, 1163, 1165, 1166, 1173,
+1174, 1177, 1182.
+\:\\{gf\_paint}, \[1159], 1170, 1171, 1172.
+\:\\{gf\_prev\_ptr}, \[1149], 1150, 1163, 1165, 1182, 1206.
+\:\\{gf\_ptr}, 1151, \[1152], 1153, 1155, 1156, 1163, 1165, 1182.
+\:\\{gf\_string}, \[1160], 1163, 1166, 1177, 1179.
+\:\\{gf\_swap}, \[1155].
+\:\\{gf\_three}, \[1158], 1160.
+\:\\{gf\_two}, \[1158], 1159, 1174.
+\:\\{given}, \[256], 258, 259, 273, 282, 284, 285, 875, 877, 888, 889.
+\:\\{good\_val}, \[431], 432, 435, 438, 442.
+\:\&{goto}, \[34], \[76].
+\:\\{granularity}, \[190], 192, 193, 430, 433.
+\:\9{granularity\_}{\&{granularity} primitive}, \[192].
+\:\\{greater\_or\_equal}, \[189], 893, 936, 937.
+\:\\{greater\_than}, \[189], 893, 936, 937.
+\:\\{group\_line}, \[831], 832.
+\:\&{gubed}, \[7].
+\:{Guibas, Leonidas Ioannis}, 2, 469.
+\:\|{h}, \[205], \[257], \[269], \[326], \[334], \[344], \[346], \[366], %
+\[369], \[385], \[402], \[465], \[473], \[477], \[484], \[488], \[491], \[506],
+\[518], \[527], \[539], \[562], \[860], \[1011].
+\:\\{half}, \[96], 102, 111, 113, 121, 126, 133, 142, 150, 232, 313, 314, 317,
+392, 432, 442, 445, 556, 559, 561, 596, 866, 939, 1122.
+\:\\{half\_buf}, 1151, \[1152], 1153, 1155, 1156.
+\:\\{half\_error\_line}, \[11], 14, 635, 641, 642, 643.
+\:\\{half\_fraction\_threshold}, \[594], 599, 600, 612, 616.
+\:\\{half\_scaled\_threshold}, \[594], 599, 600.
+\:\\{half\_unit}, \[101], 113, 119, 374, 402, 462, 463, 468, 477, 478, 512,
+515, 518, 521, 528, 530, 533, 917, 1106.
+\:\\{halfword}, 153, \[156], 158, 172, 210, 246, 253, 284, 329, 346, 366, 491,
+497, 624, 627, 697, 755, 862, 864, 868, 1029, 1077, 1104.
+\:\\{hard\_times}, 941, \[946].
+\:\\{hash}, 200, \[201], 202, 205, 207, 625, 658, 1196, 1197.
+\:\\{hash\_base}, \[200], 201, 205.
+\:\\{hash\_end}, \[201], 202, 204, 209, 214, 229, 250, 253, 254, 699, 841, 996,
+998, 999, 1049, 1196, 1197, 1199.
+\:\\{hash\_is\_full}, \[200], 207.
+\:\\{hash\_prime}, \[12], 14, 205, 208, 1190, 1191.
+\:\\{hash\_size}, \[12], 14, 201, 207, 208, 1190, 1191, 1208.
+\:\\{hash\_top}, \[201].
+\:\\{hash\_used}, \[200], 203, 207, 1196, 1197.
+\:\\{header}, 1090.
+\:\\{header\_byte}, \[1096], 1097, 1106, 1114, 1128, 1131, 1135, 1182.
+\:\9{header\_byte\_}{\&{headerbyte} primitive}, \[1101].
+\:\\{header\_byte\_code}, \[1101], 1102, 1106.
+\:\\{header\_size}, \[11], 14, 1096, 1097, 1114, 1135.
+\:{Hedrick, Charles Locke}, 3.
+\:\\{height\_index}, \[1091].
+\:\\{help\_line}, \[74], 84, 86, 661, 664, 691, 852, 1016, 1055.
+\:\\{help\_ptr}, \[74], 75, 84, 86.
+\:\\{help0}, \[74], 1051.
+\:\\{help1}, \[74], 88, 90, 703, 713, 734, 751, 838, 839, 876, 881, 883, 914,
+937, 1021, 1034, 1051, 1056, 1071, 1074, 1082, 1086, 1098, 1106, 1107, 1110,
+1113, 1115, 1178.
+\:\\{help2}, 67, \[74], 83, 84, 89, 90, 122, 128, 134, 140, 270, 478, 623, 670,
+675, 701, 708, 712, 713, 716, 727, 735, 747, 765, 832, 865, 878, 892, 937, 950,
+996, 999, 1002, 1004, 1008, 1015, 1017, 1021, 1032, 1055, 1057, 1061, 1062,
+1067, 1073, 1103, 1105, 1106, 1112.
+\:\\{help3}, 67, \[74], 93, 340, 342, 478, 661, 672, 691, 725, 726, 727, 755,
+756, 795, 849, 859, 861, 875, 887, 901, 923, 955, 960, 963, 965, 993, 1032,
+1035, 1068.
+\:\\{help4}, \[74], 84, 99, 404, 602, 663, 754, 824, 830, 1060, 1086.
+\:\\{help5}, \[74], 693, 851, 872, 873, 878, 990, 1016.
+\:\\{help6}, \[74], 991.
+\:\.{Here is how much...}, 1208.
+\:\9{hex\_}{\&{hex} primitive}, \[893].
+\:\\{hex\_op}, \[189], 893, 912.
+\:\\{hh}, 153, \[156], 157, 161, 214, 250, 255, \[334], \[477], 479, \[562],
+563, 1188, 1189.
+\:\\{hi\_mem\_min}, \[159], 161, 163, 167, 168, 176, 177, 178, 180, 181, 184,
+185, 216, 218, 242, 676, 850, 1045, 1194, 1195, 1207, 1208.
+\:\\{hi\_mem\_stat\_min}, \[175], 176, 1195.
+\:\\{history}, \[71], 72, 77, 88, 90, 195, 1204, 1209.
+\:\\{hlp1}, \[74].
+\:\\{hlp2}, \[74].
+\:\\{hlp3}, \[74].
+\:\\{hlp4}, \[74].
+\:\\{hlp5}, \[74].
+\:\\{hlp6}, \[74].
+\:\\{ho}, \[155], 324, 333, 343, 344, 349, 352, 358, 359, 360, 370, 373, 582,
+1169.
+\:{Hobby, John Douglas}, 274, 354, 432, 524.
+\:\\{hold\_head}, \[175], 665, 685, 697, 730.
+\:\\{hppp}, \[190], 192, 193, 785, \[1146], 1164, 1182.
+\:\9{hppp\_}{\&{hppp} primitive}, \[192].
+\:\\{htap\_ypoc}, \[266], 921, 978, 1064, 1065.
+\:\|{i}, \[19], \[150], \[641].
+\:\.{I can't find file x}, 786.
+\:\.{I can't find PLAIN...}, 779.
+\:\.{I can't go on...}, 90.
+\:\.{I can't read MF.POOL}, 51.
+\:\.{I can't write on file x}, 786.
+\:\\{id\_lookup}, \[205], 210, 669.
+\:\\{id\_transform}, \[233], 955.
+\:\9{if\_}{\&{if} primitive}, \[740].
+\:\\{if\_code}, \[738], 740, 741, 744, 751.
+\:\\{if\_limit}, \[738], 739, 744, 745, 746, 748, 751.
+\:\\{if\_line}, \[738], 739, 744, 745, 748, 1209.
+\:\\{if\_line\_field}, \[738], 744, 745, 1209.
+\:\\{if\_node\_size}, \[738], 744, 745, 1209.
+\:\\{if\_test}, \[186], 706, 707, 740, 741, 742, 748.
+\:\.{illegal design size...}, 1128.
+\:\.{Illegal ligtable step}, 1107.
+\:\.{Illegal suffix...flushed}, 1016.
+\:\.{IMPOSSIBLE}, 218.
+\:\.{Improper `:='}, 996.
+\:\.{Improper `addto'}, 1061, 1062.
+\:\.{Improper `openwindow'}, 1073.
+\:\.{Improper curl}, 876.
+\:\.{Improper font parameter}, 1115.
+\:\.{Improper kern}, 1112.
+\:\.{Improper location}, 1106.
+\:\.{Improper subscript...}, 849.
+\:\.{Improper tension}, 883.
+\:\.{Improper transformation argument}, 955.
+\:\.{Improper type}, 1055.
+\:\.{Improper...replaced by 0}, 754.
+\:\\{in\_open}, \[631], 654, 655, 657.
+\:\\{in\_state\_record}, \[627], 628.
+\:\\{in\_window}, \[186], 211, 212, 1071.
+\:\9{in\_window\_}{\&{inwindow} primitive}, \[211].
+\:\.{Incomplete if...}, 661.
+\:\.{Incomplete string token...}, 672.
+\:\.{Inconsistent equation}, 1004, 1008.
+\:\\{incr}, \[16], 30, 36, 41, 42, 44, 45, 46, 53, 58, 59, 60, 64, 66, 77, 85,
+86, 93, 108, 115, 123, 136, 143, 147, 163, 165, 183, 207, 226, 281, 284, 297,
+314, 315, 317, 319, 320, 321, 322, 333, 348, 352, 362, 364, 366, 375, 376, 377,
+381, 382, 383, 384, 404, 429, 458, 459, 481, 483, 487, 497, 502, 514, 515, 516,
+520, 521, 522, 560, 568, 574, 577, 583, 584, 647, 654, 669, 671, 673, 674, 681,
+687, 704, 705, 717, 721, 724, 728, 731, 732, 734, 736, 737, 742, 772, 774, 779,
+781, 787, 793, 1036, 1104, 1107, 1112, 1113, 1114, 1115, 1118, 1121, 1129,
+1137, 1138, 1140, 1155, 1165, 1196, 1211.
+\:\\{independent}, \[187], 216, 219, 232, 248, 585, 589, 592, 604, 615, 798,
+799, 800, 801, 802, 803, 808, 809, 816, 827, 828, 855, 857, 858, 903, 918, 925,
+926, 927, 928, 944, 1003, 1006, 1007, 1009.
+\:\\{independent\_being\_fixed}, \[605].
+\:\\{independent\_needing\_fix}, \[592], 595, 596, 598, 599, 600.
+\:\\{index}, 627, \[629], 630, 631, 632, 654, 655, 657.
+\:\\{index\_field}, \[627], 629.
+\:\\{inf\_val}, \[175], 617, 1116, 1117, 1118, 1121, 1136.
+\:\\{info}, \[161], 166, 168, 176, 185, 214, 218, 221, 226, 227, 228, 229, 235,
+236, 242, 245, 246, 250, 252, 253, 254, 324, 325, 326, 328, 333, 335, 337, 338,
+339, 342, 343, 344, 345, 346, 347, 349, 350, 351, 358, 359, 360, 362, 366, 367,
+368, 370, 373, 375, 376, 378, 381, 382, 383, 384, 472, 473, 475, 481, 484, 488,
+491, 509, 512, 519, 580, 582, 587, 589, 591, 594, 595, 596, 597, 598, 599, 600,
+601, 604, 605, 607, 608, 609, 610, 611, 612, 614, 615, 616, 617, 651, 662, 676,
+685, 686, 694, 697, 698, 700, 704, 705, 714, 719, 721, 722, 725, 726, 727, 728,
+729, 733, 734, 736, 752, 755, 758, 760, 763, 764, 805, 811, 812, 816, 818, 819,
+841, 850, 853, 854, 860, 863, 904, 931, 933, 935, 968, 996, 998, 999, 1006,
+1007, 1010, 1011, 1015, 1050, 1121, 1122, 1127, 1136, 1169, 1207, 1213.
+\:\.{INIMF}, 8, 11, 12, 47, 50, 159, 1183, 1203.
+\:\&{init}, \[8], \[47], \[50], \[173], \[210], \[564], \[567], \[568], %
+\[1186], \[1204], \[1209], \[1210].
+\:\\{init\_big\_node}, \[232], 233, 830, 857, 982.
+\:\\{init\_edges}, \[326], 353, 364, 895, 964.
+\:\\{init\_gf}, \[1163].
+\:\\{init\_pool\_ptr}, \[38], 41, 1045, 1193, 1204, 1208.
+\:\\{init\_prim}, 1204, \[1210].
+\:\\{init\_randoms}, \[150], 1022, 1211.
+\:\\{init\_screen}, \[564], 567, 568, 569, 570, 571.
+\:\\{init\_str\_ptr}, \[38], 44, 772, 1045, 1193, 1204, 1208.
+\:\\{init\_tab}, 1204, \[1210].
+\:\\{init\_terminal}, \[36], 657.
+\:\\{initialize}, \[4], 1204, 1211.
+\:{inner loop}, 30, 107, 108, 109, 111, 112, 113, 163, 165, 167, 169, 172, 177,
+242, 244, 408, 650, 651, 667, 668, 669, 676, 718, 850.
+\:\9{inner\_}{\&{inner} primitive}, \[1027].
+\:\\{input}, \[186], 706, 707, 709, 710.
+\:\9{input\_}{\&{input} primitive}, \[709].
+\:\\{input\_file}, \[631].
+\:\\{input\_ln}, 29, \[30], 36, 58, 66, 681, 794.
+\:\\{input\_ptr}, \[628], 635, 636, 647, 648, 656, 657, 679, 788, 1209.
+\:\\{input\_stack}, 79, \[628], 635, 647, 648, 788.
+\:\\{ins\_error}, \[653], 661, 663, 691, 751, 824.
+\:\.{insert>}, 82.
+\:\\{inserted}, \[632], 638, 650, 653.
+\:\\{install}, 857, \[858], 957, 959.
+\:\\{int}, 153, \[156], 157, 214, 326, 435, 738, 1188, 1189, 1191.
+\:\\{int\_increment}, \[553], 559, 561.
+\:\\{int\_name}, \[190], 193, 254, 998, 999, 1036, 1043, 1098, 1123, 1198, 1199.
+\:\\{int\_packets}, \[553], 558, 560.
+\:\\{int\_ptr}, \[190], 191, 1036, 1198, 1199, 1208.
+\:\\{integer}, 13, 19, 45, 46, 47, 54, 59, 60, 64, 65, 77, 89, 91, 100, 101,
+102, 105, 106, 107, 109, 112, 114, 116, 117, 119, 121, 124, 126, 129, 130, 132,
+135, 139, 145, 152, 153, 156, 160, 167, 185, 200, 205, 217, 227, 242, 299, 308,
+309, 311, 321, 327, 328, 329, 332, 333, 337, 340, 342, 348, 354, 357, 363, 366,
+369, 371, 373, 374, 378, 391, 398, 402, 403, 453, 464, 473, 477, 484, 488, 495,
+497, 507, 511, 527, 555, 557, 562, 572, 574, 577, 580, 585, 589, 594, 597, 599,
+600, 601, 608, 610, 621, 624, 625, 626, 631, 633, 641, 651, 659, 667, 685, 707,
+720, 723, 730, 738, 742, 773, 774, 778, 788, 796, 801, 809, 813, 831, 895, 898,
+899, 900, 913, 922, 930, 943, 977, 1001, 1059, 1070, 1073, 1074, 1096, 1103,
+1106, 1118, 1119, 1120, 1121, 1129, 1130, 1131, 1133, 1149, 1152, 1157, 1158,
+1159, 1160, 1161, 1162, 1163, 1165, 1186, 1187, 1203, 1205, 1210, 1212.
+\:\\{interaction}, 66, 67, \[68], 69, 70, 77, 79, 81, 86, 87, 88, 93, 398, 679,
+682, 786, 807, 897, 1023, 1051, 1086, 1198, 1199, 1200, 1209.
+\:\\{interesting}, \[238], 603, 613, 817, 1050.
+\:\9{interim\_}{\&{interim} primitive}, \[211].
+\:\\{interim\_command}, \[186], 211, 212, 1033.
+\:\\{internal}, \[190], 191, 194, 195, 238, 253, 254, 269, 375, 376, 381, 382,
+383, 384, 402, 430, 433, 465, 468, 477, 506, 508, 510, 515, 517, 521, 523, 533,
+602, 603, 610, 682, 707, 713, 720, 728, 734, 748, 760, 790, 804, 816, 832, 841,
+895, 898, 922, 944, 992, 994, 995, 996, 999, 1036, 1051, 1064, 1068, 1070,
+1097, 1098, 1099, 1128, 1129, 1134, 1137, 1163, 1164, 1165, 1177, 1182, 1198,
+1199, 1200, 1205, 1206, 1211, 1213.
+\:\.{Internal quantity...}, 999.
+\:\\{internal\_quantity}, \[186], 192, 823, 844, 860, 1011, 1034, 1036, 1043.
+\:\\{interrupt}, \[91], 92, 93, 825.
+\:\.{Interruption}, 93.
+\:\\{intersect}, \[189], 893, 988.
+\:\9{intersection\_times\_}{\&{intersectiontimes} primitive}, \[893].
+\:\.{Invalid code...}, 1103.
+\:\\{invalid\_class}, \[198], 199, 669.
+\:\\{is\_empty}, \[166], 169, 182, 183.
+\:\.{Isolated expression}, 993.
+\:\\{isolated\_classes}, \[198], 223, 669.
+\:\\{italic\_index}, \[1091].
+\:\\{iteration}, \[186], 683, 684, 685, 706, 707, 758.
+\:\|{j}, \[45], \[46], \[59], \[60], \[77], \[150], \[205], \[210], \[357], %
+\[378], \[707], \[774], \[778], \[779], \[1106].
+\:\\{j\_random}, \[148], 149, 151, 152.
+\:{Japanese characters}, 1147.
+\:{Jensen, Kathleen}, 10.
+\:\\{jj}, \[150], \[357], 364.
+\:\.{job aborted}, 679.
+\:\.{job aborted, file error...}, 786.
+\:\\{job\_name}, 87, \[782], 783, 784, 788, 791, 793, 895, 1134, 1200, 1209.
+\:\9{job\_name\_}{\&{jobname} primitive}, \[893].
+\:\\{job\_name\_op}, \[189], 893, 895.
+\:\\{jump\_out}, \[76], 77, 79, 88.
+\:\|{k}, \[45], \[46], \[47], \[63], \[64], \[66], \[102], \[121], \[130], %
+\[132], \[135], \[139], \[145], \[149], \[150], \[205], \[210], \[264], \[280],
+\[284], \[299], \[321], \[346], \[363], \[366], \[378], \[402], \[426], \[440],
+\[473], \[477], \[484], \[487], \[491], \[497], \[511], \[568], \[574], \[577],
+\[667], \[682], \[697], \[707], \[774], \[778], \[780], \[786], \[788], \[895],
+\[913], \[976], \[977], \[978], \[1073], \[1106], \[1131], \[1154], \[1160], %
+\[1163], \[1186], \[1187], \[1205], \[1210], \[1212].
+\:\\{keep\_code}, \[1052], 1074.
+\:\\{keeping}, \[1074], 1075.
+\:\9{keeping\_}{\&{keeping} primitive}, \[1052].
+\:\\{kern}, 1093, \[1096], 1106, 1112, 1139.
+\:\9{kern\_}{\&{kern} primitive}, \[1108].
+\:\\{kern\_flag}, \[1093], 1112.
+\:\\{knil}, \[325], 326, 330, 331, 332, 334, 336, 341, 352, 354, 355, 364, 376,
+377, 382, 384, 442, 472, 473, 475, 476, 482, 483, 484, 497, 503, 505, 508, 509,
+513, 515, 517, 519, 521, 523, 1167.
+\:\\{knot\_node\_size}, \[255], 264, 265, 266, 268, 405, 410, 451, 452, 486,
+528, 532, 535, 536, 537, 866, 871, 890, 896, 980, 1065.
+\:\\{knots}, \[269], 271, 272.
+\:\\{known}, \[187], 214, 215, 216, 219, 233, 248, 585, 594, 603, 615, 651,
+678, 726, 760, 765, 798, 799, 802, 803, 808, 809, 823, 826, 827, 829, 830, 837,
+841, 846, 855, 857, 858, 861, 873, 876, 878, 883, 895, 899, 903, 906, 912, 915,
+918, 919, 930, 931, 932, 935, 937, 939, 941, 942, 943, 944, 948, 949, 951, 953,
+956, 957, 959, 960, 966, 968, 969, 970, 971, 972, 974, 982, 983, 999, 1003,
+1006, 1007, 1009, 1021, 1052, 1054, 1062, 1071, 1073, 1074, 1103, 1106, 1112,
+1115, 1176, 1177, 1180.
+\:\9{known\_}{\&{known} primitive}, \[893].
+\:\\{known\_op}, \[189], 893, 918, 919.
+\:\\{known\_pair}, 871, \[872], 877, 884.
+\:{Knuth, Donald Ervin}, 2, 81.
+\:\|{l}, \[46], \[47], \[152], \[205], \[210], \[217], \[227], \[311], \[641], %
+\[742], \[746], \[788], \[977], \[978], \[1006], \[1011], \[1035], \[1118], %
+\[1121], \[1160], \[1212].
+\:\\{l\_delim}, \[697], 703, \[720], 726, 727, 729, \[730], 731, 735, \[823],
+826, 830, \[1031], \[1032].
+\:\\{l\_packet}, 560.
+\:\\{l\_packets}, \[553], 559.
+\:\\{label\_char}, \[1096], 1104, 1137, 1138.
+\:\\{label\_loc}, \[1096], 1097, 1104, 1137, 1138, 1139.
+\:\\{label\_ptr}, \[1096], 1097, 1104, 1137, 1138, 1139.
+\:{Lane, Jeffrey Michael}, 303.
+\:\\{last}, \[29], 30, 34, 35, 36, 66, 78, 82, 83, 657, 679, 682, 779, 787, 897.
+\:\\{last\_nonblank}, \[30].
+\:\\{last\_text\_char}, \[19], 23.
+\:\\{last\_window}, \[326], 334, 577.
+\:\\{last\_window\_time}, \[326], 334, 336, 337, 340, 342, 344, 348, 364, 577,
+965.
+\:\\{left\_brace}, \[186], 211, 212, 874.
+\:\\{left\_bracket}, \[186], 211, 212, 823, 844, 847, 860, 1011, 1012.
+\:\\{left\_bracket\_class}, \[198], 199, 220, 221.
+\:\\{left\_col}, \[567], \[572], 574, 577, 581.
+\:\\{left\_curl}, \[256], 259, 263, 271, 282, 295, 879, 890, 891.
+\:\\{left\_delimiter}, \[186], 697, 703, 726, 731, 735, 823, 1030, 1031, 1043.
+\:\\{left\_given}, \[256], 259, 263, 282, 292, 301, 879, 880, 888.
+\:\\{left\_length}, \[528], 531, 532, 534, 535.
+\:\\{left\_octant}, \[393], 394, 398, 401, 451, 452, 458, 459, 465, 506.
+\:\\{left\_tension}, \[256], 258, 260, 288, 289, 294, 295, 299, 300, 302, 880.
+\:\\{left\_transition}, \[393], 459, 508.
+\:\\{left\_type}, \[255], 256, 257, 258, 259, 261, 262, 263, 265, 266, 269,
+271, 272, 273, 281, 282, 284, 285, 287, 299, 302, 393, 394, 397, 398, 399, 400,
+401, 402, 404, 410, 451, 452, 465, 486, 506, 528, 865, 870, 871, 879, 885, 887,
+888, 890, 891, 896, 916, 917, 920, 962, 978, 979, 985, 987, 1064, 1066.
+\:\\{left\_v}, \[528], 531, 534, 535.
+\:\\{left\_x}, \[255], 256, 261, 265, 266, 271, 282, 299, 302, 393, 397, 404,
+407, 409, 410, 411, 412, 415, 416, 418, 419, 421, 423, 424, 425, 434, 436, 441,
+444, 447, 451, 457, 468, 486, 492, 496, 512, 518, 528, 543, 558, 563, 866, 880,
+887, 896, 962, 987, 1066.
+\:\\{left\_y}, \[255], 256, 261, 265, 266, 271, 282, 299, 302, 393, 397, 404,
+409, 410, 413, 414, 415, 416, 419, 423, 424, 425, 437, 439, 444, 447, 451, 457,
+468, 486, 492, 496, 512, 518, 528, 543, 558, 563, 866, 880, 887, 896, 962, 987,
+1066.
+\:\\{length}, \[39], 46, 205, 671, 716, 717, 793, 912, 913, 915, 976, 977,
+1083, 1103, 1160.
+\:\9{length\_}{\&{length} primitive}, \[893].
+\:\\{length\_op}, \[189], 893, 915.
+\:\\{less\_or\_equal}, \[189], 893, 936, 937.
+\:\\{less\_than}, \[189], 893, 936, 937.
+\:\9{let\_}{\&{let} primitive}, \[211].
+\:\\{let\_command}, \[186], 211, 212, 1033.
+\:\\{letter\_class}, \[198], 199, 218, 223.
+\:\\{lf}, 1088.
+\:\\{lh}, 153, \[156], 157, 161, 200, \[491], 502, 505, 1088, 1089, 1135, %
+\[1205].
+\:\\{lhs}, \[995], \[996], 997, 998, 999, 1000, \[1001], 1002, 1003, \[1059],
+1061, 1062, 1064.
+\:\\{lig\_kern}, 1092, 1093, \[1096], 1137, 1139, 1205.
+\:\\{lig\_kern\_command}, 1089, \[1093].
+\:\\{lig\_kern\_token}, \[186], 1107, 1108, 1109.
+\:\9{lig\_table\_}{\&{ligtable} primitive}, \[1101].
+\:\\{lig\_table\_code}, \[1101], 1102, 1106.
+\:\\{lig\_table\_size}, \[11], 14, 1096, 1107, 1137, 1141.
+\:\\{lig\_tag}, \[1092], 1104, 1105, 1111.
+\:\\{limit}, 627, \[629], 630, 632, 644, 654, 656, 657, 669, 671, 672, 679,
+681, 682, 717, 793, 794, 1211.
+\:\\{limit\_field}, 34, 82, \[627], 629, 788.
+\:\\{line}, 79, 197, \[631], 637, 654, 655, 657, 681, 742, 744, 748, 794, 832.
+\:\\{line\_edges}, \[374], 378, 507, 510.
+\:\\{line\_stack}, \[631], 654, 655.
+\:\\{linear\_eq}, \[610], 1006.
+\:\\{link}, \[161], 163, 164, 165, 166, 167, 168, 172, 176, 177, 181, 185, 216,
+217, 227, 228, 229, 230, 232, 234, 235, 236, 237, 238, 239, 240, 241, 242, 244,
+245, 246, 247, 250, 252, 253, 254, 255, 257, 265, 266, 268, 271, 272, 273, 281,
+284, 297, 324, 325, 326, 328, 330, 331, 332, 334, 335, 336, 337, 338, 339, 341,
+343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 359, 360, 362,
+364, 366, 367, 368, 369, 370, 375, 376, 377, 381, 382, 383, 384, 385, 394, 398,
+399, 400, 401, 402, 404, 405, 406, 410, 411, 412, 413, 415, 416, 418, 419, 424,
+425, 433, 435, 436, 439, 440, 442, 444, 447, 450, 451, 452, 458, 459, 465, 466,
+468, 472, 473, 475, 476, 477, 479, 481, 482, 483, 484, 485, 487, 488, 491, 492,
+493, 497, 499, 502, 503, 504, 506, 508, 509, 512, 513, 515, 517, 518, 519, 521,
+523, 528, 532, 535, 536, 537, 539, 556, 558, 562, 577, 582, 587, 589, 591, 594,
+595, 596, 597, 598, 599, 600, 601, 603, 604, 605, 606, 608, 609, 611, 612, 614,
+616, 617, 639, 640, 650, 651, 665, 676, 678, 685, 686, 694, 697, 698, 700, 702,
+704, 705, 719, 720, 721, 722, 723, 724, 725, 727, 728, 730, 734, 736, 738, 744,
+745, 746, 752, 758, 760, 762, 763, 764, 799, 805, 811, 812, 814, 815, 816, 818,
+819, 827, 844, 845, 848, 850, 851, 852, 853, 854, 860, 863, 867, 870, 871, 885,
+887, 890, 891, 896, 904, 910, 916, 921, 931, 933, 947, 962, 968, 978, 980, 981,
+985, 986, 1007, 1010, 1011, 1015, 1043, 1047, 1050, 1065, 1068, 1117, 1118,
+1121, 1122, 1124, 1126, 1136, 1169, 1194, 1207, 1209, 1213.
+\:\\{list\_tag}, \[1092], 1105, 1106.
+\:\\{lk\_offset}, 1135, 1137, 1138, 1139, \[1205].
+\:\\{lk\_started}, \[1096], 1107, 1112, 1137, 1138, 1139.
+\:\\{ll}, \[1096], 1110, 1111, 1139.
+\:\\{llink}, \[166], 168, 169, 171, 172, 173, 176, 182, 1207.
+\:\\{lll}, \[1096], 1110, 1111.
+\:\\{lo\_mem\_max}, \[159], 163, 167, 168, 176, 178, 180, 182, 183, 184, 185,
+1045, 1194, 1195, 1207, 1208.
+\:\\{lo\_mem\_stat\_max}, \[175], 176, 1195, 1207.
+\:\\{load\_base\_file}, \[1187], 1211.
+\:\\{loc}, \[35], 36, 82, 627, \[629], 630, 632, 636, 638, 644, 645, 649, 652,
+654, 656, 657, 669, 671, 672, 673, 674, 676, 678, 679, 681, 712, 717, 736, 779,
+781, 793, 794, 795, 1211.
+\:\\{loc\_field}, 34, 35, \[627], 629.
+\:\.{local label l:: was missing}, 1139.
+\:\\{log\_file}, \[54], 56, 70, 788, 1205.
+\:\\{log\_name}, \[782], 788, 1205.
+\:\\{log\_only}, \[54], 57, 58, 62, 70, 93, 679, 788, 1022, 1200.
+\:\\{log\_opened}, 87, 88, \[782], 783, 788, 789, 1023, 1205, 1208.
+\:\.{Logarithm...replaced by 0}, 134.
+\:\\{long\_help\_seen}, \[1084], 1085, 1086.
+\:\&{loop}, 15, \[16].
+\:\.{loop confusion}, 714.
+\:\.{loop value=n}, 762.
+\:\\{loop\_defining}, \[659], 664, 665, 758.
+\:\\{loop\_list}, \[752], 760, 763, 764.
+\:\\{loop\_list\_loc}, \[752], 764.
+\:\\{loop\_node\_size}, \[752], 755, 763.
+\:\\{loop\_ptr}, 712, 713, 714, \[752], 753, 758, 760, 763, 1209.
+\:\\{loop\_repeat}, 685.
+\:\\{loop\_text}, \[632], 638, 714, 760.
+\:\\{loop\_type}, \[752], 755, 760, 763, 764, 765.
+\:\.{Lost loop}, 712.
+\:\\{ls}, \[46].
+\:\\{lt}, \[46], \[286], 289, 294, 295, \[299], 302.
+\:\|{m}, \[47], \[64], \[311], \[333], \[337], \[348], \[357], \[369], \[373], %
+\[473], \[484], \[511], \[574], \[580], \[608], \[625], \[626], \[641], \[694],
+\[697], \[755], \[788], \[913], \[1029], \[1082], \[1098], \[1118], \[1120], %
+\[1121], \[1123], \[1165], \[1177], \[1212].
+\:\\{m\_adjustment}, \[580], 581, 582.
+\:\\{m\_exp}, \[135], 906.
+\:\9{m\_exp\_}{\&{mexp} primitive}, \[893].
+\:\\{m\_exp\_op}, \[189], 893, 906.
+\:\\{m\_log}, \[132], 134, 152, 906.
+\:\9{m\_log\_}{\&{mlog} primitive}, \[893].
+\:\\{m\_log\_op}, \[189], 893, 906.
+\:\\{m\_magic}, \[354], 361, 362, 365.
+\:\\{m\_max}, \[326], 329, 334, 337, 342, 348, 352, 354, 356, 357, 364, 366,
+965, 1172.
+\:\\{m\_min}, \[326], 329, 334, 337, 342, 348, 352, 354, 356, 357, 364, 365,
+366, 965, 1172.
+\:\\{m\_offset}, \[326], 328, 329, 333, 334, 337, 342, 348, 352, 364, 365, 366,
+367, 373, 375, 376, 381, 382, 383, 384, 581, 965, 1169, 1172.
+\:\\{m\_spread}, 356, \[357], 364.
+\:\\{m\_window}, \[572], 576, 581.
+\:\\{mac\_name}, \[862], \[864], \[868].
+\:\\{macro}, \[632], 638, 645, 649, 736.
+\:\\{macro\_at}, \[688], 689.
+\:\\{macro\_call}, 707, 718, 719, \[720], 853, 854, 863.
+\:\\{macro\_def}, \[186], 683, 684, 685, 694, 698, 992, 1043.
+\:\\{macro\_name}, \[720], 721, 725, 726, 734, 736.
+\:\\{macro\_prefix}, \[688], 689.
+\:\\{macro\_ref}, \[843], 845, 854.
+\:\\{macro\_special}, \[186], 685, 688, 689, 700.
+\:\\{macro\_suffix}, \[688], 689, 700.
+\:\\{main\_control}, \[1017], 1204, 1211.
+\:\\{major\_axis}, \[527], 530, 533, \[865], 866.
+\:\\{make\_choices}, \[269], 274, 277, 278, 891.
+\:\\{make\_ellipse}, \[527], 528, 866.
+\:\\{make\_eq}, 995, 1000, \[1001].
+\:\\{make\_exp\_copy}, 651, 823, 852, \[855], 859, 903, 910, 926, 927, 944,
+967, 970, 973, 1000.
+\:\\{make\_fraction}, \[107], 109, 116, 125, 127, 145, 152, 281, 288, 289, 290,
+291, 294, 295, 296, 300, 302, 375, 376, 436, 439, 444, 454, 498, 516, 522, 530,
+533, 540, 548, 549, 612, 818, 944.
+\:\\{make\_known}, \[603], 604, 614, 818, 819.
+\:\\{make\_moves}, 309, \[311], 321, 468, 512, 514, 518, 550.
+\:\\{make\_name\_string}, \[780].
+\:\\{make\_op\_def}, \[694], 992.
+\:\\{make\_path}, \[484], 921, 962.
+\:\9{make\_path\_}{\&{makepath} primitive}, \[893].
+\:\\{make\_path\_op}, \[189], 893, 921.
+\:\\{make\_pen}, \[477], 865.
+\:\9{make\_pen\_}{\&{makepen} primitive}, \[893].
+\:\\{make\_pen\_op}, \[189], 893, 921.
+\:\\{make\_safe}, \[426], 427, 436, 439, 440, 446.
+\:\\{make\_scaled}, \[114], 116, 600, 612, 819, 837, 948, 949, 980, 1128, 1129,
+1164, 1182.
+\:\\{make\_spec}, \[402], 403, 409, 448, 460, 493, 917, 1064.
+\:\\{make\_string}, \[44], 48, 52, 207, 671, 772, 780, 840, 897, 912, 976, 977,
+1164, 1200, 1205.
+\:{Marple, Jane}, 1086.
+\:\\{materialize\_pen}, 864, \[865], 921, 983.
+\:\\{max}, \[539], 543.
+\:\\{max\_allowed}, 402, \[403], 404, 434, 437.
+\:\\{max\_buf\_stack}, \[29], 30, 657, 717, 1208.
+\:\\{max\_c}, 812, \[813], 814, 815, 816, 817.
+\:\\{max\_class}, \[198].
+\:\\{max\_coef}, \[495], 496, \[591], 932, 943, 949.
+\:\\{max\_command\_code}, \[186], 821, 823, 824, 868.
+\:\\{max\_d}, \[348], 351, 352.
+\:\\{max\_expression\_command}, \[186], 868.
+\:\\{max\_font\_dimen}, \[11], 1096, 1115, 1141.
+\:\\{max\_given\_internal}, \[190], 191, 1199.
+\:\\{max\_halfword}, 11, 12, 14, \[153], 154, 156, 166, 167, 168, 173, 174,
+204, 214, 324, 348, 351, 358, 1207.
+\:\\{max\_in\_open}, \[12], 631, 632, 654, 1190, 1191.
+\:\\{max\_in\_stack}, \[628], 647, 657, 1208.
+\:\\{max\_internal}, \[11], 190, 204, 1036, 1199, 1208.
+\:\\{max\_kerns}, \[11], 1096, 1106, 1112, 1141.
+\:\\{max\_link}, 812, \[813], 814, 815, 818, 819.
+\:\\{max\_m}, 1144, \[1146], \[1161].
+\:\\{max\_n}, \[348], 351, 352, 1144, \[1146], \[1161].
+\:\\{max\_new\_row}, \[1145], 1173.
+\:\\{max\_offset}, \[472], 475, 477, 962, 1064.
+\:\\{max\_param\_stack}, \[633], 657, 736, 737, 1208.
+\:\\{max\_patience}, \[555], 556.
+\:\\{max\_pool\_ptr}, \[38], 41, 47, 1045, 1193, 1204, 1208.
+\:\\{max\_primary\_command}, \[186], 823, 836, 862, 864, 868, 989, 990.
+\:\\{max\_print\_line}, \[11], 14, 54, 58, 61, 67, 333, 372, 793, 1046, 1048,
+1165.
+\:\\{max\_ptr}, \[813], 814, 815, 816.
+\:\\{max\_quarterword}, \[153], 154, 156, 399, 404, 481.
+\:\\{max\_rounding\_ptr}, \[427], 428, 429, 1208.
+\:\\{max\_secondary\_command}, \[186], 862.
+\:\\{max\_selector}, \[54], 196, 635, 788.
+\:\\{max\_statement\_command}, \[186], 989.
+\:\\{max\_str\_ptr}, \[38], 44, 47, 772, 1045, 1193, 1204, 1208.
+\:\\{max\_str\_ref}, \[42], 43, 48, 52, 207, 793, 1193, 1200.
+\:\\{max\_strings}, \[11], 37, 44, 154, 772, 780, 1045, 1193, 1208.
+\:\\{max\_suffix\_token}, \[186], 844.
+\:\\{max\_t}, \[555], 556.
+\:\\{max\_tertiary\_command}, \[186], 864.
+\:\\{max\_tfm\_dimen}, 1128, 1129, \[1130], 1182.
+\:\\{max\_wiggle}, \[11], 426, 427, 429, 440, 1208.
+\:\\{mc}, \[477], 478, 479.
+\:{Meggitt, John E.}, 143.
+\:\\{mem}, 11, 12, 158, \[159], 161, 166, 168, 173, 175, 176, 178, 180, 185,
+214, 216, 229, 241, 242, 244, 250, 255, 264, 326, 334, 435, 472, 475, 587, 594,
+738, 752, 827, 947, 961, 1194, 1195, 1213.
+\:\\{mem\_end}, 159, \[161], 163, 176, 178, 180, 181, 184, 185, 218, 1194,
+1195, 1208.
+\:\\{mem\_max}, \[11], 12, 14, 153, 154, 159, 163, 166, 167, 178, 179.
+\:\\{mem\_min}, \[12], 14, 154, 158, 159, 163, 167, 168, 175, 176, 178, 179,
+180, 182, 183, 184, 185, 218, 1190, 1191, 1194, 1195, 1208.
+\:\\{mem\_top}, 11, \[12], 14, 154, 159, 175, 176, 1190, 1191, 1195.
+\:\.{Memory usage...}, 1045.
+\:\\{memory\_word}, 153, \[156], 157, 159, 242, 1188.
+\:\\{merge\_edges}, \[366], 929, 1061.
+\:\9{message\_}{\&{message} primitive}, \[1079].
+\:\\{message\_code}, \[1079], 1082.
+\:\\{message\_command}, \[186], 1079, 1080, 1081.
+\:\.{METAFONT capacity exceeded ...}, 89.
+\:\9{METAFONT capacity exceeded buffer size}{\quad buffer size}, 34, 654, 717.
+\:\9{METAFONT capacity exceeded extensible}{\quad extensible}, 1113.
+\:\9{METAFONT capacity exceeded fontdimen}{\quad fontdimen}, 1115.
+\:\9{METAFONT capacity exceeded hash size}{\quad hash size}, 207.
+\:\9{METAFONT capacity exceeded headerbyte}{\quad headerbyte}, 1114.
+\:\9{METAFONT capacity exceeded input stack size}{\quad input stack size}, 647.
+\:\9{METAFONT capacity exceeded kern}{\quad kern}, 1112.
+\:\9{METAFONT capacity exceeded ligtable size}{\quad ligtable size}, 1107.
+\:\9{METAFONT capacity exceeded main memory size}{\quad main memory size}, 163,
+167.
+\:\9{METAFONT capacity exceeded move table size}{\quad move table size}, 356,
+468, 508.
+\:\9{METAFONT capacity exceeded number of int}{\quad number of internals}, 1036.
+\:\9{METAFONT capacity exceeded number of strings}{\quad number of strings},
+44, 772.
+\:\9{METAFONT capacity exceeded parameter stack size}{\quad parameter stack
+size}, 704, 736, 737.
+\:\9{METAFONT capacity exceeded path size}{\quad path size}, 281.
+\:\9{METAFONT capacity exceeded pen polygon size}{\quad pen polygon size}, 481.
+\:\9{METAFONT capacity exceeded pool size}{\quad pool size}, 41.
+\:\9{METAFONT capacity exceeded rounding table size}{\quad rounding table
+size}, 429.
+\:\9{METAFONT capacity exceeded text input levels}{\quad text input levels},
+654.
+\:\9{METAFONTbook}{\sl The {\logos METAFONT\/}book}, 1, 199, 574, 824, 872,
+873, 878, 990, 991, 1068, 1203.
+\:\9{METAFONT84}{\MF84}, \[1].
+\:\\{metric\_file\_name}, \[1087], 1134.
+\:\\{MF}, \[4].
+\:\.{MF.POOL check sum...}, 53.
+\:\.{MF.POOL doesn't match}, 53.
+\:\.{MF.POOL has no check sum}, 52.
+\:\.{MF.POOL line doesn't...}, 52.
+\:\\{MF\_area}, \[769], 793.
+\:\\{MF\_base\_default}, \[775], 776, 778.
+\:\.{MFbases}, 11, 776.
+\:\.{MFinputs}, 769.
+\:\.{mfput}, 34, 788.
+\:\\{mid}, \[1094].
+\:\\{min\_col}, \[580], 581, 582, 583.
+\:\\{min\_command}, \[186], 706, 715, 718.
+\:\\{min\_cover}, \[1118], 1120.
+\:\\{min\_d}, \[348], 351, 352.
+\:\\{min\_expression\_command}, \[186], 868, 869.
+\:\\{min\_halfword}, 12, \[153], 154, 155, 156, 324, 326, 337, 342, 348, 350,
+365, 375, 376, 381, 382, 383, 384, 580.
+\:\\{min\_m}, 1144, \[1146], \[1161].
+\:\\{min\_n}, \[348], 351, 352, 1144, \[1146], \[1161].
+\:\\{min\_of}, \[189], 923.
+\:\\{min\_primary\_command}, \[186], 823, 837, 862, 864, 868, 989.
+\:\\{min\_quarterword}, \[153], 154, 155, 156, 1093.
+\:\\{min\_secondary\_command}, \[186], 862.
+\:\\{min\_suffix\_token}, \[186], 844.
+\:\\{min\_tension}, \[883].
+\:\\{min\_tertiary\_command}, \[186], 864.
+\:\\{minor\_axis}, \[527], 530, 533, \[865], 866.
+\:\\{minus}, \[189], 859, 893, 898, 903, 922, 929, 930, 936, 939.
+\:\.{Missing `)'}, 727, 735, 1032.
+\:\.{Missing `)'...}, 725.
+\:\.{Missing `,'}, 727, 878.
+\:\.{Missing `..'}, 881.
+\:\.{Missing `:'}, 747, 751, 756, 1106.
+\:\.{Missing `:='}, 1021.
+\:\.{Missing `;'}, 713.
+\:\.{Missing `='}, 693, 755, 1035.
+\:\.{Missing `\char`\#'}, 1113.
+\:\.{Missing `\char`\}'}, 875.
+\:\.{Missing `]'}, 859, 861.
+\:\.{Missing `of'}, 734, 839.
+\:\.{Missing `until'}, 765.
+\:\.{Missing argument...}, 726.
+\:\.{Missing parameter type}, 703.
+\:\.{Missing symbolic token...}, 691.
+\:\.{Missing...inserted}, 94.
+\:\\{missing\_err}, \[94], 693, 713, 727, 734, 735, 747, 751, 755, 756, 765,
+839, 859, 861, 875, 878, 881, 1021, 1032, 1035, 1106, 1113.
+\:\\{missing\_extensible\_punctuation}, \[1113].
+\:\\{ml}, \[329].
+\:\\{mm}, \[348], 349, \[357], 358, 362, 364, \[580], 582, \[1165], 1169.
+\:\\{mm0}, \[511], 513, 517, 519, 523.
+\:\\{mm1}, \[511], 513, 517, 519, 523.
+\:{mock curvature}, 275.
+\:\\{mode\_command}, \[186], 1023, 1024, 1025.
+\:{Moler, Cleve Barry}, 124.
+\:\\{month}, \[190], 192, 193, 194, 790, 1163, 1200.
+\:\9{month\_}{\&{month} primitive}, \[192].
+\:\\{months}, \[788], 790.
+\:\\{more\_name}, 767, \[771], 781, 787.
+\:{Morrison, Donald Ross}, 124.
+\:\\{move}, \[308], 311, 315, 316, 319, 320, 321, 322, 354, 356, 357, 362, 364,
+378, 379, 381, 382, 383, 384, 468, 507, 512, 514, 517, 518, 520, 523.
+\:\\{move\_increment}, \[309], 310, 312, 314.
+\:\\{move\_ptr}, \[308], 311, 315, 316, 319, 320, 468, 511, 512, 513, 514, 515,
+516, 517, 518, 519, 520, 521, 522, 523.
+\:\\{move\_size}, \[11], 308, 311, 321, 356, 357, 362, 378, 468, 507, 508, 511.
+\:\\{move\_to\_edges}, \[378], 465, 517, 523.
+\:\\{mr}, \[329].
+\:\&{mtype}, \[4].
+\:\.{Must increase the x}, 1187.
+\:\\{my\_var\_flag}, \[823], 841, 852, \[868].
+\:\\{m0}, \[374], 375, 376, \[378], 380, 381, 382, 383, 384, \[464], 465, 467,
+508, 511, 517, 523.
+\:\\{m1}, \[374], 375, 376, \[378], 380, 463, \[464], 465, 467, 508, 511, 517,
+523.
+\:\|{n}, \[47], \[64], \[65], \[89], \[107], \[109], \[112], \[114], \[242], %
+\[246], \[280], \[284], \[311], \[332], \[348], \[366], \[369], \[373], \[374],
+\[378], \[473], \[477], \[484], \[488], \[491], \[497], \[511], \[539], \[562],
+\[568], \[574], \[580], \[610], \[641], \[667], \[697], \[720], \[722], \[723],
+\[755], \[773], \[774], \[778], \[863], \[913], \[916], \[944], \[985], %
+\[1046], \[1165], \[1212].
+\:\\{n\_arg}, \[139], 140, 141, 147, 256, 281, 282, 292, 293, 301, 387, 541,
+544, 866, 877, 907.
+\:\\{n\_cos}, \[144], 145, 259, 263, 297, 301, 530, 533, 906, 958.
+\:\\{n\_magic}, \[354], 361, 362, 365.
+\:\\{n\_max}, \[326], 329, 331, 332, 334, 336, 340, 348, 352, 364, 365, 366,
+965, 1167.
+\:\\{n\_min}, \[326], 329, 330, 334, 336, 340, 348, 352, 364, 366, 577, 965,
+1172.
+\:\\{n\_pos}, \[326], 330, 331, 334, 336, 352, 364, 374, 377, 378, 965.
+\:\\{n\_rover}, \[326], 330, 331, 334, 352, 364, 374, 377, 378.
+\:\\{n\_sin}, \[144], 145, 259, 263, 297, 301, 530, 533, 906, 958.
+\:\\{n\_sin\_cos}, 144, \[145], 147, 259, 263, 297, 301, 530, 906, 958.
+\:\\{n\_window}, \[572], 576, 577.
+\:\\{name}, 627, \[629], 630, 631, 632, 635, 637, 638, 649, 654, 655, 657, 679,
+717, 736, 793, 897.
+\:\\{name\_field}, 79, \[627], 629.
+\:\\{name\_length}, \[25], 51, 774, 778, 780.
+\:\\{name\_of\_file}, \[25], 26, 51, 774, 778, 780, 786.
+\:\\{name\_type}, 188, \[214], 215, 219, 228, 229, 230, 232, 233, 234, 235,
+236, 237, 238, 239, 240, 244, 245, 246, 247, 249, 254, 619, 651, 678, 702, 738,
+744, 745, 799, 806, 830, 856, 857, 911, 931, 982, 1047, 1209.
+\:\\{nd}, 1088, 1089, \[1096], 1126, 1135, 1141.
+\:\\{ne}, 1088, 1089, \[1096], 1097, 1113, 1135, 1140, 1141.
+\:\\{NE\_SW\_edge}, \[435].
+\:\\{negate}, \[16], 64, 103, 107, 110, 114, 118, 139, 146, 380, 409, 411, 412,
+414, 415, 416, 418, 423, 424, 425, 480, 882, 903, 904, 930, 959, 1007, 1068.
+\:\\{negate\_dep\_list}, 903, \[904], 930, 959.
+\:\\{negate\_edges}, \[344], 345, 903, 929.
+\:\\{negate\_x}, \[139], 390, 406, 409, 411, 418, 480, 489.
+\:\\{negate\_y}, \[139], 390, 406, 414, 415, 418, 437, 438, 439, 480, 489.
+\:\\{negative}, \[107], \[109], 110, \[112], \[114].
+\:\.{New busy locs}, 184.
+\:\\{new\_boundary}, \[451], 452, 458.
+\:\\{new\_dep}, \[606], 615, 829, 856, 858, 947, 969, 972.
+\:\\{new\_if\_limit}, \[748].
+\:\\{new\_indep}, \[585], 586, 816, 855.
+\:\\{new\_internal}, \[186], 211, 212, 1033.
+\:\9{new\_internal\_}{\&{newinternal} primitive}, \[211].
+\:\\{new\_knot}, 870, \[871], 885, 908.
+\:\\{new\_num\_tok}, \[215], 236, 860.
+\:\\{new\_randoms}, 148, \[149], 150.
+\:\\{new\_ring\_entry}, \[619], 855.
+\:\\{new\_root}, \[234], 242, 1011.
+\:\\{new\_row\_0}, 1144, \[1145], 1173.
+\:\\{new\_row\_1}, \[1144].
+\:\\{new\_row\_164}, \[1144], 1145.
+\:\\{new\_string}, \[54], 57, 58, 840, 912, 1163, 1164, 1200.
+\:\\{new\_structure}, \[239], 243.
+\:\\{next}, \[200], 202, 205, 207.
+\:\\{next\_a}, \[426], \[440], 446.
+\:\\{next\_char}, \[1093], 1107, 1112, 1137.
+\:\\{next\_random}, \[149], 151, 152.
+\:\\{nh}, 1088, 1089, \[1096], 1126, 1135, 1141.
+\:\\{ni}, 1088, 1089, \[1096], 1126, 1135, 1141.
+\:\\{nice\_pair}, \[899], 900, 907, 915, 941, 975, 983, 1072.
+\:\&{nil}, 16.
+\:\\{ninety\_deg}, \[106], 141, 530.
+\:\\{nk}, 1088, 1089, \[1096], 1097, 1112, 1135, 1139, 1141.
+\:\\{nl}, \[329], 330, 1088, 1089, 1093, \[1096], 1097, 1107, 1110, 1111, 1112,
+1135, 1137, 1139, 1141.
+\:\\{nn}, \[562].
+\:\.{No loop is in progress}, 713.
+\:\.{No new edges added}, 372.
+\:\\{no\_crossing}, \[391], 392.
+\:\\{no\_op}, \[1144], 1147.
+\:\\{no\_print}, \[54], 57, 58, 70, 93.
+\:\\{no\_tag}, \[1092], 1096, 1097, 1104.
+\:\\{node\_size}, \[166], 168, 169, 170, 172, 176, 182, 1194, 1195, 1207.
+\:\\{node\_to\_round}, 426, \[427], 429, 436, 439, 444, 445, 446.
+\:\.{NONEXISTENT}, 218.
+\:\\{nonlinear\_eq}, \[621], 1003.
+\:\.{Nonnumeric...replaced by 0}, 830.
+\:\\{nonstop\_mode}, \[68], 81, 679, 682, 897, 1024, 1025.
+\:\9{nonstop\_mode\_}{\&{nonstopmode} primitive}, \[1024].
+\:\\{norm\_rand}, \[152], 895.
+\:\\{normal}, \[659], 660, 661, 694, 697, 730, 738, 739, 742, 758, 991, 1016.
+\:\\{normal\_deviate}, \[189], 893, 895.
+\:\9{normal\_deviate\_}{\&{normaldeviate} primitive}, \[893].
+\:\\{normalize\_selector}, 73, \[87], 88, 89, 90.
+\:\\{north\_edge}, \[435], 438.
+\:\\{north\_south\_edge}, \[435].
+\:\.{Not a cycle}, 1067.
+\:\.{Not a string}, 716, 1082.
+\:\.{Not a suitable variable}, 1060.
+\:\.{Not implemented...}, 901, 923.
+\:\9{not\_}{\&{not} primitive}, \[893].
+\:\\{not\_found}, \[15], 45, 394, 477, 479, 491, 494, 496, 539, 541, 556, 560,
+561, 760, 1001, 1004, 1059, 1064, 1067, 1071, 1073, 1074, 1075.
+\:\\{not\_op}, \[189], 893, 905.
+\:\\{nothing\_printed}, \[473], 474.
+\:\\{np}, 1088, 1089, \[1096], 1097, 1115, 1135, 1140, 1141.
+\:\\{nr}, \[329], 331.
+\:\\{nuline}, \[197], \[257], \[332], \[473].
+\:\\{null}, \[158], 159, 161, 163, 165, 167, 168, 176, 177, 181, 182, 202, 214,
+216, 217, 226, 227, 229, 232, 233, 234, 235, 237, 242, 246, 249, 251, 252, 253,
+254, 257, 258, 324, 346, 355, 364, 368, 398, 472, 475, 477, 479, 487, 528, 532,
+536, 537, 587, 589, 591, 594, 597, 599, 600, 604, 605, 607, 609, 611, 612, 614,
+615, 616, 617, 618, 619, 620, 632, 636, 638, 639, 640, 650, 651, 652, 665, 676,
+685, 686, 694, 697, 698, 700, 707, 712, 713, 714, 716, 718, 719, 720, 721, 722,
+723, 724, 726, 728, 730, 734, 735, 736, 738, 739, 746, 752, 753, 754, 755, 760,
+762, 763, 764, 795, 801, 802, 805, 806, 807, 810, 811, 812, 816, 818, 819, 840,
+844, 845, 848, 850, 851, 852, 853, 854, 857, 902, 904, 924, 925, 926, 927, 928,
+929, 930, 931, 933, 934, 935, 936, 942, 943, 944, 945, 948, 949, 968, 970, 972,
+997, 998, 1000, 1003, 1006, 1007, 1008, 1009, 1010, 1011, 1015, 1035, 1040,
+1041, 1043, 1048, 1049, 1050, 1057, 1061, 1064, 1068, 1070, 1071, 1074, 1194,
+1195, 1207, 1209, 1213.
+\:\\{null\_coords}, \[175], 214, 475.
+\:\\{null\_pen}, \[175], 435, 438, 442, 475, 477, 487, 865, 895, 917, 962, 1062.
+\:\9{null\_pen\_}{\&{nullpen} primitive}, \[893].
+\:\\{null\_pen\_code}, \[189], 893, 895.
+\:\9{null\_picture\_}{\&{nullpicture} primitive}, \[893].
+\:\\{null\_picture\_code}, \[189], 893, 895.
+\:\\{null\_tally}, \[217].
+\:\\{nullary}, \[186], 713, 823, 893, 894, 895.
+\:\\{num}, \[116], \[296], \[836], 837.
+\:\9{num\_special\_}{\&{numspecial} primitive}, \[1176].
+\:\.{Number too large}, 914.
+\:\9{numeric\_}{\&{numeric} primitive}, \[1013].
+\:\\{numeric\_token}, \[186], 651, 675, 678, 823, 824, 836, 837, 844, 846, 860,
+861, 1016, 1042.
+\:\\{numeric\_type}, \[187], 189, 229, 242, 248, 585, 798, 802, 809, 855, 918,
+1013.
+\:\\{nw}, 1088, 1089, \[1096], 1124, 1135, 1141.
+\:\\{NW\_SE\_edge}, \[435].
+\:\\{n0}, \[373], \[374], 375, 376, 377, \[378], 380, 382, 383, 384, \[464],
+465, 467, 468, 508, 513, 515, 517, 519, 521, 523.
+\:\\{n1}, \[373], \[374], 375, 376, \[378], 380, 463, \[464], 465, 467, 468,
+508, 513, 517, 519, 523.
+\:\|{o}, \[210], \[431], \[477].
+\:\\{obliterated}, \[851], 852, 1000, 1057.
+\:\9{oct\_}{\&{oct} primitive}, \[893].
+\:\\{oct\_op}, \[189], 893, 912, 913, 914.
+\:\\{octant}, \[139], 141, \[379], 380, \[387], \[388], \[394], 434, 437, %
+\[451], 463, 465, 468, 473, 479, 480, 481, 484, 485, \[488], 489, 506, 508,
+509, 510, 512, 513, 515, 516, 518, 519, 521, 522.
+\:\\{octant\_after}, \[390].
+\:\\{octant\_before}, \[390].
+\:\\{octant\_code}, \[448], 449, 458, 473, 481, 484.
+\:\\{octant\_dir}, 394, \[395], 396, 398, 401, 509.
+\:\\{octant\_number}, \[448], 449, 452, 459, 479, 488, 508, 512.
+\:\\{octant\_subdivide}, 402, \[419].
+\:\\{odd}, 62, 111, 113, 145, 390, 417, 434, 435, 436, 442, 445, 459, 473, 482,
+483, 484, 488, 508, 512, 530, 560, 906.
+\:\9{odd\_}{\&{odd} primitive}, \[893].
+\:\\{odd\_op}, \[189], 893, 906.
+\:\9{of\_}{\&{of} primitive}, \[211].
+\:\\{of\_macro}, \[226], 227, 705, 733.
+\:\\{of\_token}, \[186], 211, 212, 705, 734, 839.
+\:\\{off\_base}, \[1187], 1189, 1191, 1195, 1199.
+\:\\{offset\_prep}, \[491], 494, 500, 506.
+\:\.{OK}, 1051.
+\:\\{OK\_to\_interrupt}, 83, \[91], 92, 93, 653, 825.
+\:\\{old\_exp}, \[922], 925, 927, \[944].
+\:\\{old\_p}, \[922], 925, 926.
+\:\\{old\_rover}, \[173].
+\:\\{old\_setting}, 195, \[196], \[635], 636, \[788], 840, 912, 1022, 1163,
+1164.
+\:\\{one\_byte}, \[1161].
+\:\\{one\_crossing}, \[391].
+\:\\{one\_eighty\_deg}, \[106], 139, 141, 292, 544.
+\:\\{oo}, \[477], 479.
+\:\\{op\_byte}, \[1093], 1107, 1112, 1137.
+\:\\{op\_defining}, \[659], 664, 665, 694, 700.
+\:\\{open}, \[256], 258, 262, 263, 271, 272, 273, 280, 282, 284, 285, 865, 868,
+870, 874, 875, 877, 879, 885, 887, 888, 889, 890, 891, 896.
+\:\.{open?}, 258, 262.
+\:\\{open\_a\_window}, \[574], 1073.
+\:\\{open\_base\_file}, \[779], 1211.
+\:\\{open\_log\_file}, 73, 87, 679, \[788], 789, 791, 793, 895, 1134, 1209.
+\:\\{open\_parens}, \[631], 657, 681, 793, 1209.
+\:\\{open\_window}, \[186], 211, 212, 1069.
+\:\9{open\_window\_}{\&{openwindow} primitive}, \[211].
+\:\9{or\_}{\&{or} primitive}, \[893].
+\:\\{or\_op}, \[189], 893, 940.
+\:\\{ord}, 20.
+\:{oriental characters}, 1147.
+\:\&{othercases}, \[10].
+\:\\{others}, 10.
+\:\.{Ouch...clobbered}, 1204.
+\:\.{Out of order...}, 617.
+\:\9{outer\_}{\&{outer} primitive}, \[1027].
+\:\\{outer\_tag}, \[186], 242, 249, 254, 668, 759, 850, 1029, 1041.
+\:\\{output}, \[4].
+\:\.{Output written...}, 1182.
+\:\\{output\_file\_name}, \[791], 792, 1163, 1182.
+\:\\{over}, \[189], 837, 893, 948.
+\:\\{overflow}, 34, 41, 44, \[89], 163, 167, 207, 281, 356, 429, 468, 481, 508,
+647, 654, 704, 705, 717, 736, 737, 772, 1036, 1107, 1112, 1113, 1114, 1115,
+1205.
+\:{Overflow in arithmetic}, 9.
+\:\\{o1}, 452, \[453], 458, 459.
+\:\\{o2}, 452, \[453], 458, 459.
+\:\|{p}, \[107], \[109], \[112], \[114], \[163], \[167], \[172], \[173], %
+\[177], \[180], \[185], \[205], \[215], \[216], \[217], \[226], \[227], \[232],
+\[233], \[234], \[235], \[238], \[239], \[242], \[246], \[247], \[248], \[249],
+\[252], \[253], \[254], \[257], \[264], \[265], \[266], \[268], \[269], \[284],
+\[299], \[328], \[329], \[332], \[334], \[336], \[337], \[340], \[342], \[344],
+\[346], \[348], \[354], \[366], \[369], \[374], \[378], \[385], \[394], \[398],
+\[402], \[405], \[406], \[410], \[419], \[429], \[433], \[440], \[451], \[465],
+\[473], \[477], \[484], \[486], \[487], \[488], \[491], \[493], \[497], \[506],
+\[510], \[518], \[527], \[539], \[556], \[562], \[577], \[589], \[591], \[594],
+\[597], \[599], \[600], \[601], \[603], \[604], \[606], \[608], \[609], \[610],
+\[619], \[620], \[621], \[622], \[641], \[649], \[650], \[651], \[652], \[661],
+\[685], \[694], \[697], \[707], \[720], \[722], \[730], \[737], \[746], \[748],
+\[755], \[760], \[763], \[799], \[800], \[801], \[805], \[807], \[809], \[823],
+\[827], \[848], \[855], \[856], \[858], \[860], \[862], \[863], \[864], \[865],
+\[868], \[872], \[898], \[899], \[904], \[910], \[916], \[919], \[922], \[923],
+\[928], \[930], \[935], \[943], \[944], \[946], \[949], \[953], \[961], \[962],
+\[963], \[966], \[968], \[971], \[972], \[974], \[976], \[977], \[978], \[982],
+\[984], \[985], \[995], \[996], \[1001], \[1006], \[1015], \[1046], \[1050], %
+\[1057], \[1059], \[1072], \[1117], \[1118], \[1121], \[1165], \[1186], %
+\[1187], \[1205].
+\:\\{p\_over\_v}, \[600], 819, 932, 949.
+\:\\{p\_plus\_fq}, 592, \[594], 597, 601, 818, 819, 932, 968, 971, 1010.
+\:\\{p\_plus\_q}, \[597], 932, 1010.
+\:\\{p\_times\_v}, \[599], 943, 969.
+\:\\{p\_with\_x\_becoming\_q}, \[601], 614.
+\:\\{pack\_buffered\_name}, \[778], 779.
+\:\\{pack\_cur\_name}, \[784], 786, 793.
+\:\\{pack\_file\_name}, \[774], 784, 793.
+\:\\{pack\_job\_name}, \[784], 788, 791, 1134, 1200.
+\:\\{packed\_ASCII\_code}, \[37], 38.
+\:\\{page}, \[631].
+\:\\{page\_stack}, \[631].
+\:\\{paint\_row}, 3, 564, 566, \[568], 569, 571, 578, 579.
+\:\\{paint\_switch}, \[1143], 1144.
+\:\\{paint\_0}, 1144, \[1145], 1159.
+\:\\{paint1}, 1144, \[1145], 1159.
+\:\\{paint2}, \[1144].
+\:\\{paint3}, \[1144].
+\:\9{pair\_}{\&{pair} primitive}, \[1013].
+\:\\{pair\_node\_size}, \[230], 231.
+\:\\{pair\_to\_path}, \[908], 921, 975, 983, 988, 1003, 1062.
+\:\\{pair\_type}, \[187], 216, 230, 231, 232, 248, 798, 799, 800, 802, 808,
+809, 830, 837, 855, 868, 870, 872, 877, 898, 899, 900, 903, 909, 917, 918, 919,
+921, 926, 927, 929, 936, 941, 942, 944, 946, 948, 952, 957, 975, 982, 983, 988,
+995, 1001, 1002, 1003, 1013, 1062.
+\:\\{pair\_value}, \[982], 984, 987, 988.
+\:\\{panicking}, \[178], 179, 825, 1213.
+\:\\{param}, 1090, 1095, \[1096], 1106, 1115, 1140.
+\:\\{param\_ptr}, \[633], 649, 650, 657, 736, 737.
+\:\\{param\_size}, \[12], 214, 633, 677, 697, 704, 705, 736, 737, 1208.
+\:\\{param\_stack}, 632, \[633], 639, 640, 650, 676, 677, 720, 736, 737.
+\:\\{param\_start}, \[632], 639, 640, 649, 650, 676, 677.
+\:\\{param\_type}, \[186], 227, 695, 696, 697, 703.
+\:\\{parameter}, \[632], 638, 677.
+\:\\{parent}, \[229], 236, 239, 240, 241, 245.
+\:\9{PASCAL H}{\ph}, \[3], 26.
+\:\9{PASCAL}{\PASCAL}, 1, 10.
+\:\\{pass\_text}, 706, \[742], 749, 751.
+\:\.{Path at line...}, 257.
+\:\9{path\_}{\&{path} primitive}, \[1013].
+\:\\{path\_intersection}, \[562], 988.
+\:\\{path\_join}, \[186], 211, 212, 874, 881, 886, 887.
+\:\\{path\_length}, 915, \[916], 978.
+\:\\{path\_size}, \[11], 279, 280, 281, 283, 284.
+\:\\{path\_tail}, 266, \[267], 1065.
+\:\\{path\_trans}, 952, \[962].
+\:\\{path\_type}, \[187], 216, 248, 621, 798, 802, 804, 808, 809, 855, 868,
+870, 885, 891, 908, 915, 917, 918, 919, 920, 921, 952, 975, 983, 988, 1003,
+1013, 1062.
+\:\.{Paths don't touch}, 887.
+\:\\{pause\_for\_instructions}, 91, \[93].
+\:\\{pausing}, \[190], 192, 193, 682.
+\:\9{pausing\_}{\&{pausing} primitive}, \[192].
+\:\\{pd}, \[357], 358, 360.
+\:\.{Pen cycle must be convex}, 478.
+\:\.{Pen path must be a cycle}, 865.
+\:\.{Pen too large}, 478.
+\:\9{pen\_}{\&{pen} primitive}, \[1013].
+\:\\{pen\_circle}, \[189], 893, 895.
+\:\9{pen\_circle\_}{\&{pencircle} primitive}, \[893].
+\:\\{pen\_edge}, \[433], 435, 438, \[440], 442, 443.
+\:\\{pen\_head}, \[484].
+\:\\{pen\_node\_size}, 175, \[472], 477, 487.
+\:\9{pen\_offset\_}{\&{penoffset} primitive}, \[893].
+\:\\{pen\_offset\_of}, \[189], 893, 983.
+\:\\{pen\_type}, \[187], 216, 248, 621, 798, 802, 804, 808, 809, 855, 865, 895,
+918, 919, 921, 952, 962, 983, 1003, 1013, 1052, 1053, 1054, 1055.
+\:\\{percent\_class}, \[198], 199, 217, 669.
+\:\\{period\_class}, \[198], 199, 669.
+\:\\{perturbation}, 1118, \[1119], 1120, 1121, 1122, 1123, 1124, 1126.
+\:\\{phi}, 541, \[542], 544.
+\:\9{picture\_}{\&{picture} primitive}, \[1013].
+\:\\{picture\_type}, \[187], 216, 248, 621, 798, 802, 804, 808, 809, 855, 895,
+898, 903, 918, 919, 921, 929, 952, 1003, 1013, 1057, 1061, 1070.
+\:\\{pixel\_color}, \[565], 566, 568, 580.
+\:\.{plain}, 776, 779, 1203.
+\:\.{Please type...}, 679, 786.
+\:\\{plus}, \[189], 859, 893, 898, 922, 930.
+\:\\{plus\_or\_minus}, \[186], 823, 836, 837, 893, 894.
+\:\\{pm}, \[357], 358, 360.
+\:\9{point\_}{\&{point} primitive}, \[893].
+\:\\{point\_of}, \[189], 893, 983, 987.
+\:\\{pointer}, \[158], 159, 161, 163, 166, 167, 172, 173, 177, 178, 180, 185,
+200, 205, 215, 216, 225, 226, 227, 232, 233, 234, 235, 238, 239, 242, 246, 247,
+248, 249, 250, 252, 253, 254, 257, 264, 265, 266, 267, 268, 269, 280, 284, 299,
+326, 327, 328, 329, 332, 333, 334, 336, 337, 340, 342, 344, 346, 348, 354, 366,
+369, 373, 374, 378, 385, 394, 398, 402, 403, 405, 406, 410, 419, 427, 429, 433,
+440, 451, 465, 473, 476, 477, 484, 486, 487, 488, 491, 493, 497, 506, 510, 511,
+518, 527, 539, 556, 562, 577, 589, 591, 592, 594, 597, 599, 600, 601, 603, 604,
+606, 607, 608, 609, 610, 619, 620, 621, 622, 633, 649, 650, 651, 652, 661, 685,
+694, 697, 707, 718, 720, 722, 723, 730, 737, 738, 746, 748, 752, 755, 760, 763,
+799, 800, 801, 805, 807, 809, 813, 823, 827, 843, 848, 851, 855, 856, 858, 860,
+862, 863, 864, 865, 868, 871, 872, 898, 904, 910, 916, 919, 922, 923, 928, 930,
+935, 943, 944, 946, 949, 953, 961, 962, 963, 966, 968, 971, 972, 974, 976, 977,
+978, 982, 984, 985, 995, 996, 1001, 1006, 1011, 1015, 1031, 1032, 1035, 1046,
+1050, 1057, 1059, 1071, 1072, 1074, 1117, 1118, 1121, 1125, 1165, 1186, 1187,
+1205.
+\:\\{pool\_file}, 47, \[50], 51, 52, 53.
+\:\\{pool\_name}, \[11], 51.
+\:\\{pool\_pointer}, \[37], 38, 45, 46, 59, 60, 77, 210, 707, 768, 774, 913,
+976, 1160.
+\:\\{pool\_ptr}, 37, \[38], 40, 41, 43, 44, 47, 52, 58, 771, 780, 1045, 1163,
+1192, 1193, 1204.
+\:\\{pool\_size}, \[11], 37, 41, 52, 58, 780, 1045, 1193, 1208.
+\:\\{pop\_input}, \[648], 650, 655.
+\:\\{post}, 1142, 1144, \[1145], 1146, 1148, 1182.
+\:\\{post\_head}, 842, \[843], 844, 845, 851, 852, 854.
+\:\\{post\_post}, 1144, \[1145], 1146, 1148, 1182.
+\:\9{postcontrol\_}{\&{postcontrol} primitive}, \[893].
+\:\\{postcontrol\_of}, \[189], 893, 983, 987.
+\:\\{pp}, \[242], 243, 244, 245, \[265], \[266], \[334], 335, \[340], 341, %
+\[366], 367, 368, \[406], 413, 414, 415, 416, 417, 418, \[440], 444, 445, 446, %
+\[556], 558, \[562], \[589], 590, \[594], 595, \[597], 598, \[755], 765, %
+\[809], 816, \[868], 885, 886, 887, 889, 890, \[966], 970, \[978], 980, 981, %
+\[1006], 1009, 1010.
+\:\\{pre}, 1142, 1144, \[1145], 1163.
+\:\\{pre\_head}, 842, \[843], 844, 850, 851, 852, 853, 854.
+\:\9{precontrol\_}{\&{precontrol} primitive}, \[893].
+\:\\{precontrol\_of}, \[189], 893, 983, 987.
+\:\\{prev\_dep}, \[587], 603, 606, 617, 799, 811, 816, 827, 931, 947, 1007.
+\:\\{prev\_m}, \[1165], 1169, 1170, 1171.
+\:\\{prev\_n}, \[1165], 1167, 1172, 1174.
+\:\\{prev\_r}, \[610], 614.
+\:\\{prev\_w}, \[348], 349, 350, \[1165], 1169, 1170, 1171.
+\:\9{primary\_}{\&{primary} primitive}, \[695].
+\:\\{primary\_binary}, \[186], 189, 823, 839, 893, 894.
+\:\9{primary\_def\_}{\&{primarydef} primitive}, \[683].
+\:\\{primary\_macro}, \[226], 227, 695, 733.
+\:\\{primitive}, 192, \[210], 211, 212, 625, 683, 688, 695, 709, 740, 893,
+1013, 1018, 1024, 1027, 1037, 1052, 1079, 1101, 1108, 1176, 1203, 1204.
+\:\\{print}, 54, \[59], 60, 62, 66, 68, 79, 80, 81, 84, 85, 89, 90, 94, 122,
+128, 134, 187, 189, 197, 212, 217, 218, 219, 221, 222, 227, 235, 237, 257, 258,
+259, 260, 261, 262, 263, 332, 372, 394, 397, 398, 401, 509, 510, 515, 521, 589,
+613, 625, 638, 639, 643, 644, 663, 664, 665, 682, 684, 689, 696, 710, 721, 723,
+725, 734, 741, 750, 754, 786, 788, 790, 802, 804, 805, 807, 817, 824, 832, 839,
+851, 900, 902, 923, 924, 945, 997, 998, 999, 1002, 1008, 1019, 1025, 1028,
+1032, 1034, 1038, 1041, 1043, 1045, 1048, 1050, 1053, 1057, 1080, 1098, 1102,
+1105, 1109, 1123, 1139, 1140, 1163, 1164, 1180, 1182, 1192, 1194, 1196, 1200,
+1208, 1209, 1212, 1213.
+\:\\{print\_arg}, 721, \[723], 728, 734.
+\:\\{print\_capsule}, 217, 219, \[224], 1042.
+\:\\{print\_char}, \[58], 59, 60, 63, 64, 65, 77, 85, 89, 90, 103, 104, 157,
+184, 185, 189, 197, 209, 212, 219, 220, 221, 222, 223, 224, 227, 237, 254, 259,
+263, 332, 333, 372, 373, 394, 398, 401, 509, 589, 590, 602, 603, 613, 626, 637,
+643, 681, 689, 725, 762, 790, 793, 802, 803, 806, 817, 824, 900, 902, 914, 924,
+945, 990, 998, 1002, 1008, 1022, 1041, 1042, 1045, 1046, 1050, 1057, 1134,
+1163, 1164, 1165, 1182, 1194, 1200, 1205, 1213.
+\:\\{print\_cmd\_mod}, 212, 227, \[625], 626, 751, 824, 839, 990, 1041, 1043,
+1209, 1213.
+\:\\{print\_dd}, \[65], 790, 1163.
+\:\\{print\_dependency}, \[589], 613, 805, 817, 1050.
+\:\\{print\_diagnostic}, \[197], 257, 332, 372, 394, 473.
+\:\\{print\_dp}, 802, 803, \[805].
+\:\\{print\_edges}, \[332], 804, 1165.
+\:\\{print\_err}, 67, \[68], 88, 89, 90, 93, 94, 99, 122, 128, 134, 140, 270,
+340, 342, 398, 404, 478, 602, 623, 661, 663, 670, 672, 675, 691, 701, 703, 708,
+712, 713, 725, 726, 751, 786, 795, 807, 824, 832, 838, 851, 865, 887, 914, 963,
+965, 990, 991, 1004, 1008, 1015, 1016, 1017, 1032, 1034, 1051, 1056, 1057,
+1067, 1073, 1074, 1086, 1098, 1105, 1107, 1110.
+\:\\{print\_exp}, 224, 639, 723, 762, \[801], 807, 902, 924, 945, 997, 998,
+1040, 1046.
+\:\\{print\_file\_name}, \[773], 786.
+\:\\{print\_int}, \[64], 79, 89, 103, 157, 181, 182, 183, 184, 185, 197, 209,
+222, 237, 332, 333, 372, 397, 398, 509, 515, 521, 617, 637, 661, 723, 790, 832,
+914, 1045, 1105, 1139, 1140, 1163, 1164, 1165, 1182, 1192, 1194, 1196, 1200,
+1209, 1213.
+\:\\{print\_known\_or\_unknown\_type}, \[900], 901, 923.
+\:\\{print\_ln}, \[57], 58, 61, 62, 66, 81, 84, 85, 86, 157, 195, 257, 394,
+473, 638, 643, 656, 665, 679, 682, 721, 788, 793, 1023, 1041, 1043, 1045, 1165,
+1192, 1194, 1196.
+\:\\{print\_locs}, \[180].
+\:\\{print\_macro\_name}, 721, \[722], 725, 726, 734.
+\:\\{print\_nl}, \[62], 68, 77, 79, 80, 86, 181, 182, 183, 184, 185, 195, 197,
+209, 254, 257, 259, 332, 333, 372, 373, 394, 397, 398, 473, 474, 509, 510, 515,
+521, 603, 613, 617, 626, 637, 638, 639, 665, 679, 723, 725, 762, 786, 788, 807,
+817, 902, 924, 945, 994, 997, 998, 1022, 1040, 1041, 1045, 1046, 1048, 1050,
+1082, 1123, 1128, 1134, 1139, 1140, 1169, 1182, 1200, 1205, 1209, 1212.
+\:\\{print\_op}, \[189], 894, 901, 902, 923, 924.
+\:\\{print\_path}, \[257], 269, 402, 804.
+\:\\{print\_pen}, \[473], 477, 484, 804.
+\:\\{print\_scaled}, \[103], 104, 122, 128, 134, 157, 220, 254, 259, 260, 263,
+589, 590, 602, 603, 802, 803, 817, 912, 945, 1008, 1022, 1042, 1123.
+\:\\{print\_spec}, \[394], 402.
+\:\\{print\_strange}, \[398], 399, 1068.
+\:\\{print\_the\_digs}, \[63], 64.
+\:\\{print\_two}, \[104], 258, 261, 394, 473, 510.
+\:\\{print\_two\_true}, \[394], 397, 474, 509, 515, 521.
+\:\\{print\_type}, \[187], 189, 802, 804, 806, 900, 1002, 1014, 1057.
+\:\\{print\_variable\_name}, 221, \[235], 589, 603, 613, 664, 802, 803, 806,
+817, 1046, 1048, 1050, 1213.
+\:\\{print\_weight}, 332, \[333].
+\:\\{print\_word}, \[157], 1213.
+\:\\{procrustes}, \[404].
+\:\\{progression\_node\_size}, \[752], 763, 765.
+\:\\{prompt\_file\_name}, \[786], 789, 791, 793, 1134, 1200.
+\:\\{prompt\_input}, \[66], 78, 82, 679, 682, 786, 897.
+\:\\{proofing}, \[190], 192, 193, 994, 1070, 1147, 1165, 1177.
+\:\9{proofing\_}{\&{proofing} primitive}, \[192].
+\:\\{protection\_command}, \[186], 1026, 1027, 1028.
+\:\\{proto\_dependent}, \[187], 216, 248, 588, 589, 594, 597, 599, 601, 603,
+610, 612, 798, 799, 800, 802, 808, 809, 812, 813, 815, 817, 818, 819, 855, 857,
+903, 932, 943, 949, 968, 969, 971, 972, 1003, 1010.
+\:\\{pseudo}, \[54], 57, 58, 59, 60, 642.
+\:\\{psi}, \[279], 281, 290, 294, 297.
+\:\\{push\_input}, \[647], 649, 654.
+\:\\{put}, 25, 28, 1188.
+\:\\{put\_get\_error}, 270, 340, 342, 404, 478, 623, \[820], 865, 873, 887,
+901, 914, 923, 950, 955, 963, 965, 993, 999, 1000, 1002, 1004, 1008, 1015,
+1016, 1051, 1057, 1067, 1068, 1073, 1074, 1082, 1086, 1098, 1105, 1106, 1178.
+\:\\{put\_get\_flush\_error}, 716, 754, \[820], 830, 852, 872, 876, 878, 883,
+892, 937, 960, 1021, 1055, 1056, 1060, 1061, 1062, 1071, 1103, 1112, 1115.
+\:\\{pyth\_add}, \[124], 145, 281, 454, 530, 533, 866, 915, 951.
+\:\\{pyth\_sub}, \[126], 951.
+\:\\{pythag\_add}, \[189], 893, 951.
+\:\\{pythag\_sub}, \[189], 893, 951.
+\:\.{Pythagorean...}, 128.
+\:\|{q}, \[107], \[109], \[112], \[114], \[117], \[121], \[145], \[167], %
+\[172], \[173], \[177], \[180], \[185], \[216], \[217], \[227], \[232], \[233],
+\[235], \[239], \[242], \[246], \[247], \[249], \[252], \[253], \[254], \[257],
+\[264], \[265], \[266], \[268], \[269], \[284], \[299], \[311], \[328], \[329],
+\[332], \[333], \[336], \[337], \[340], \[342], \[344], \[346], \[348], \[354],
+\[366], \[369], \[385], \[394], \[398], \[402], \[405], \[406], \[410], \[419],
+\[433], \[440], \[451], \[465], \[477], \[491], \[493], \[506], \[518], \[527],
+\[539], \[556], \[577], \[589], \[594], \[597], \[601], \[603], \[604], \[606],
+\[608], \[609], \[610], \[619], \[620], \[621], \[622], \[641], \[685], \[694],
+\[697], \[720], \[722], \[723], \[746], \[755], \[760], \[763], \[801], \[805],
+\[809], \[823], \[827], \[851], \[855], \[858], \[863], \[865], \[868], \[871],
+\[898], \[919], \[922], \[928], \[930], \[935], \[943], \[946], \[949], \[953],
+\[961], \[962], \[966], \[968], \[972], \[978], \[985], \[996], \[1001], %
+\[1006], \[1015], \[1046], \[1059], \[1117], \[1121], \[1165], \[1186], \[1187].
+\:\\{qi}, \[155], 1107, 1110, 1111, 1112, 1113, 1137, 1192.
+\:\\{qo}, \[155], 1110, 1111, 1133, 1193.
+\:\\{qq}, 229, \[242], 245, \[265], \[266], \[334], \[366], 367, 368, \[406],
+413, 414, 415, 416, 417, 418, \[556], 558, \[594], 595, 596, \[597], 598, %
+\[868], 885, 886, 887, 890, \[966], 970, \[978], 980, 981.
+\:\\{qqq}, 229.
+\:\\{qqqq}, 153, \[156], 157, 1188, 1189.
+\:\\{qqq1}, 229.
+\:\\{qqq2}, 229.
+\:\\{qq1}, 229.
+\:\\{qq2}, 229.
+\:\\{quad}, 1095.
+\:\\{quad\_code}, \[1095].
+\:\\{quadrant\_subdivide}, 402, \[406], 426.
+\:\\{quarter\_unit}, \[101].
+\:\\{quarterword}, 153, \[156], 189, 627, 649, 823, 895, 898, 899, 901, 910,
+913, 919, 922, 923, 930, 953, 960, 962, 963, 966, 985.
+\:\\{quote}, \[688], 690.
+\:\9{quote\_}{\&{quote} primitive}, \[688].
+\:\\{q1}, 229.
+\:\|{r}, \[117], \[124], \[126], \[145], \[167], \[173], \[177], \[180], %
+\[217], \[227], \[233], \[235], \[239], \[242], \[246], \[247], \[268], \[284],
+\[311], \[332], \[334], \[336], \[337], \[340], \[344], \[346], \[348], \[354],
+\[366], \[373], \[374], \[378], \[402], \[406], \[410], \[419], \[451], \[465],
+\[476], \[477], \[491], \[493], \[506], \[518], \[527], \[567], \[568], \[577],
+\[594], \[597], \[599], \[600], \[601], \[604], \[606], \[610], \[621], \[622],
+\[694], \[697], \[720], \[809], \[823], \[855], \[858], \[863], \[868], \[922],
+\[928], \[930], \[946], \[953], \[966], \[968], \[971], \[1006], \[1104], %
+\[1117], \[1121].
+\:\\{r\_delim}, \[697], 703, \[720], 725, 726, 727, 729, \[730], 731, 735, %
+\[823], 826, 830, 1031, \[1032].
+\:\\{r\_packet}, 560.
+\:\\{r\_packets}, \[553], 558.
+\:{Ramshaw, Lyle Harold}, 2, 469, 1087.
+\:\\{random\_seed}, \[186], 211, 212, 1020.
+\:\9{random\_seed\_}{\&{randomseed} primitive}, \[211].
+\:\\{randoms}, \[148], 149, 150, 151, 152.
+\:\\{rd}, \[357], 358, 359.
+\:\\{read}, 52, 53, 1212, 1213.
+\:\\{read\_ln}, 52.
+\:\9{read\_string\_}{\&{readstring} primitive}, \[893].
+\:\\{read\_string\_op}, \[189], 893, 895.
+\:\\{ready\_already}, \[1203], 1204.
+\:\\{real}, 3, 120.
+\:{recursion}, 71, 73, 217, 224, 246, 706, 719, 748, 796, 995, 1041.
+\:\\{recycle\_value}, 224, 246, 247, 650, 763, 808, \[809], 810, 829, 873, 903,
+910, 922, 925, 935, 944, 955, 968, 970, 972, 1000, 1001.
+\:\\{reduce\_angle}, \[292], 293.
+\:\.{Redundant equation}, 623.
+\:\.{Redundant or inconsistent equation}, 1004.
+\:\\{ref\_count}, \[226], 475, 477, 487, 694, 697, 854, 862, 864, 868.
+\:{reference counts}, 42, 226, 632.
+\:\\{relax}, \[186], 211, 212, 686, 706, 707.
+\:\\{rem\_byte}, \[1093], 1107, 1112, 1137.
+\:\\{remainder}, \[1091], 1092, 1093, 1096.
+\:\\{remove\_cubic}, \[405], 417, 447, 492.
+\:\\{rep}, \[1094].
+\:\\{repeat\_loop}, \[186], 706, 707, 759, 1043.
+\:\\{reset}, 25, 26, 32.
+\:\\{reset\_OK}, \[26].
+\:\\{restart}, \[15], 167, 168, 667, 668, 670, 672, 676, 677, 679, 681, 691,
+823, 853, 854, 855, 862, 864, 868, 1001, 1003.
+\:\\{restore\_cur\_exp}, \[801].
+\:\\{result}, \[45], \[1054], 1056.
+\:\\{resume\_iteration}, 706, 712, 755, \[760], 763.
+\:\\{reswitch}, \[15], 748.
+\:\.{retrograde line...}, 510.
+\:\&{return}, 15, \[16].
+\:\\{return\_sign}, \[117], 118.
+\:\\{rev\_turns}, 452, 454, \[455], 456, 1064.
+\:\\{reverse}, \[189], 893, 921.
+\:\9{reverse\_}{\&{reverse} primitive}, \[893].
+\:\\{reversed}, \[977], \[978].
+\:\\{rewrite}, 25, 26, 32.
+\:\\{rewrite\_OK}, \[26].
+\:\\{rh}, 153, \[156], 157, 161, 200.
+\:\\{rhs}, \[1059], 1062, 1064, 1065, 1066, 1067.
+\:{Riesenfeld, Richard Franklin}, 303.
+\:\\{right\_brace}, \[186], 211, 212, 875.
+\:\\{right\_bracket}, \[186], 211, 212, 846, 859, 861, 1012.
+\:\\{right\_bracket\_class}, \[198], 199, 220, 221.
+\:\\{right\_class}, \[528], 531, 532, 534, 535.
+\:\\{right\_col}, \[567], \[572], 574, 577, 581, 583, 584.
+\:\\{right\_curl}, \[256], 263, 271, 282, 294, 890, 891.
+\:\\{right\_delimiter}, \[186], 203, 726, 727, 731, 735, 1030, 1031, 1032, 1043.
+\:\\{right\_edge}, \[580], 581, 582.
+\:\\{right\_given}, \[256], 263, 282, 293, 301, 879, 888, 889.
+\:\\{right\_octant}, \[393], 451, 452, 458, 459.
+\:\\{right\_paren\_class}, \[198], 199, 219, 222.
+\:\\{right\_tension}, \[256], 258, 260, 288, 289, 294, 295, 299, 300, 302, 881,
+882, 886, 887.
+\:\\{right\_transition}, \[393], 459, 509, 517, 523.
+\:\\{right\_type}, \[255], 256, 258, 263, 265, 266, 269, 271, 272, 273, 282,
+285, 290, 299, 302, 393, 394, 404, 405, 407, 409, 410, 411, 412, 413, 414, 415,
+416, 417, 418, 421, 423, 424, 425, 426, 434, 435, 436, 437, 438, 439, 441, 442,
+443, 445, 447, 450, 451, 452, 454, 457, 466, 479, 481, 486, 491, 494, 497, 499,
+512, 515, 518, 521, 528, 539, 562, 563, 870, 871, 874, 879, 880, 884, 885, 888,
+889, 890, 891, 896, 921, 962, 978, 987, 1065, 1066.
+\:\\{right\_u}, \[528], 531, 532, 534, 535, 537.
+\:\\{right\_x}, \[255], 256, 261, 265, 266, 271, 282, 299, 302, 393, 397, 404,
+405, 407, 409, 410, 411, 412, 415, 416, 418, 419, 421, 423, 424, 425, 434, 436,
+441, 444, 447, 457, 468, 486, 492, 496, 512, 518, 528, 543, 558, 563, 866, 884,
+890, 896, 962, 987, 1065, 1066.
+\:\\{right\_y}, \[255], 256, 261, 265, 266, 271, 282, 299, 302, 393, 397, 404,
+405, 410, 413, 414, 415, 416, 419, 423, 424, 425, 437, 439, 444, 447, 457, 468,
+486, 492, 496, 512, 518, 528, 543, 558, 563, 866, 884, 890, 896, 962, 987,
+1065, 1066.
+\:\\{ring\_delete}, \[620], 809.
+\:\\{ring\_merge}, \[622], 1003.
+\:\\{rising}, \[497].
+\:\\{rlink}, \[166], 167, 168, 169, 171, 172, 173, 174, 176, 182, 1194, 1195,
+1207.
+\:\\{rm}, \[357], 358, 359.
+\:\\{root}, \[188], 229, 230, 234, 239, 254, 702.
+\:\\{rotate}, 389.
+\:\9{rotated\_}{\&{rotated} primitive}, \[893].
+\:\\{rotated\_by}, \[189], 893, 952, 957.
+\:\\{round\_decimals}, \[102], 103, 674.
+\:\\{round\_fraction}, \[119], 590, 600, 817, 819, 906, 958, 1010.
+\:\\{round\_unscaled}, \[119], 374, 375, 376, 575, 576, 790, 906, 912, 965,
+977, 1056, 1070, 1071, 1073, 1103, 1106, 1137, 1163, 1165, 1181, 1200.
+\:\\{rover}, \[166], 167, 168, 169, 170, 171, 172, 173, 174, 176, 182, 1194,
+1195, 1207.
+\:\\{row\_node\_size}, \[325], 330, 331, 334, 341, 352, 353, 354, 355, 358,
+364, 385.
+\:\\{row\_transition}, 578, \[579], 580, 582, 583, 584.
+\:\\{rr}, \[242], 245, \[266], \[299], 300, \[334], 335, \[340], \[366], 368, %
+\[922], 939, \[978], 980.
+\:\\{rt}, \[286], 289, 294, 295, \[299], 302.
+\:\\{runaway}, 163, 663, \[665].
+\:\\{r0}, \[574], 575, 576, \[1073].
+\:\\{r1}, 229, \[574], 575, \[1073].
+\:\|{s}, \[43], \[45], \[46], \[58], \[59], \[60], \[62], \[88], \[89], \[90], %
+\[94], \[103], \[167], \[172], \[197], \[210], \[232], \[242], \[257], \[280], %
+\[284], \[311], \[332], \[337], \[340], \[342], \[344], \[346], \[348], \[354],
+\[394], \[398], \[402], \[406], \[419], \[465], \[473], \[477], \[488], \[495],
+\[497], \[506], \[518], \[527], \[594], \[597], \[599], \[600], \[601], \[604],
+\[610], \[754], \[755], \[784], \[786], \[807], \[809], \[824], \[930], \[943],
+\[949], \[966], \[977], \[1160].
+\:\\{s\_scale}, \[585], 589, 608, 610, 817.
+\:\\{safety\_margin}, \[402].
+\:\9{save\_}{\&{save} primitive}, \[211].
+\:\\{save\_boundary\_item}, \[250], 832.
+\:\\{save\_command}, \[186], 211, 212, 1033.
+\:\\{save\_cond\_ptr}, \[748], 749.
+\:\\{save\_exp}, \[651], \[718].
+\:\\{save\_flag}, \[824].
+\:\\{save\_internal}, \[253], 1034.
+\:\\{save\_node\_size}, \[250], 252, 253, 254.
+\:\\{save\_ptr}, \[250], 251, 252, 253, 254.
+\:\\{save\_type}, \[651].
+\:\\{save\_variable}, \[252], 1033.
+\:\\{save\_word}, \[242], 244.
+\:\.{SAVED}, 235.
+\:\\{saved\_equiv}, \[250], 252, 254.
+\:\\{saved\_root}, \[188], 230, 235, 247, 249.
+\:\\{saving}, \[249].
+\:\\{sc}, 153, \[156], 157, 229, 255, 472, 752, 961.
+\:\\{scaled}, \[101], 102, 103, 104, 105, 112, 114, 116, 119, 121, 132, 135,
+150, 151, 152, 153, 156, 187, 190, 194, 214, 215, 228, 229, 250, 259, 279, 280,
+286, 296, 299, 304, 306, 311, 369, 374, 387, 388, 389, 390, 402, 403, 406, 410,
+419, 426, 427, 429, 430, 431, 432, 433, 434, 440, 463, 477, 486, 488, 497, 510,
+511, 527, 539, 542, 555, 574, 585, 587, 588, 594, 599, 600, 602, 607, 612, 798,
+808, 820, 836, 865, 868, 875, 916, 917, 935, 944, 946, 949, 954, 961, 968, 971,
+972, 974, 978, 982, 985, 1073, 1096, 1098, 1117, 1118, 1119, 1120, 1121, 1128,
+1129, 1130, 1144, 1146, 1147, 1182, 1205.
+\:\.{Scaled picture...big}, 340, 342.
+\:\9{scaled\_}{\&{scaled} primitive}, \[893].
+\:\\{scaled\_by}, \[189], 893, 952, 957.
+\:\\{scaled\_threshold}, \[594], 597.
+\:\\{scaling\_down}, \[599], \[600].
+\:\\{scan\_declared\_variable}, 700, \[1011], 1015.
+\:\\{scan\_def}, \[697], 992.
+\:\\{scan\_direction}, \[875], 879, 880.
+\:\\{scan\_expression}, 706, 729, 733, 734, 764, 765, 796, 798, 821, 826, 830,
+839, 846, 859, 861, \[868], 876, 877, 878, 892, 993, 995, 996, 1021, 1040,
+1054, 1059, 1070, 1071, 1072, 1073, 1082, 1103, 1106, 1112, 1115, 1177.
+\:\\{scan\_file\_name}, \[781], 795.
+\:\\{scan\_primary}, 706, 716, 733, 734, 796, 798, 821, \[823], 835, 837, 839,
+842, 862, 882, 884, 893, 1059, 1071, 1074.
+\:\\{scan\_secondary}, 706, 733, 796, 798, 821, \[862], 864.
+\:\\{scan\_suffix}, 706, 729, 735, 764, 840, \[860].
+\:\\{scan\_tertiary}, 706, 733, 796, 798, 821, \[864], 868, 869.
+\:\\{scan\_text\_arg}, 729, \[730], 733.
+\:\\{scan\_tokens}, \[186], 211, 212, 706, 707.
+\:\9{scan\_tokens\_}{\&{scantokens} primitive}, \[211].
+\:\\{scan\_toks}, \[685], 694, 698, 758.
+\:\\{scan\_with}, \[1054], 1062, 1074.
+\:\\{scanner\_status}, \[659], 660, 661, 663, 664, 665, 694, 697, 700, 730,
+742, 758, 991, 1016.
+\:\\{screen\_col}, \[565], 566, 567, 568, 572, 580.
+\:\\{screen\_depth}, \[11], 565, 567, 568, 575.
+\:\\{screen\_OK}, \[569], 570, 574, 577.
+\:\\{screen\_pixel}, \[566], 567, 568.
+\:\\{screen\_row}, \[565], 566, 567, 568, 572.
+\:\\{screen\_started}, \[569], 570.
+\:\\{screen\_width}, \[11], 565, 567, 568, 575.
+\:\\{scroll\_mode}, 66, \[68], 79, 81, 88, 786, 1024, 1025, 1084.
+\:\9{scroll\_mode\_}{\&{scrollmode} primitive}, \[1024].
+\:\\{search\_mem}, 178, \[185], 1213.
+\:\\{second\_octant}, \[139], 141, 380, 387, 388, 396, 435, 443, 449, 461, 462.
+\:\9{secondary\_}{\&{secondary} primitive}, \[695].
+\:\\{secondary\_binary}, \[186], 893, 894.
+\:\9{secondary\_def\_}{\&{secondarydef} primitive}, \[683].
+\:\\{secondary\_macro}, \[226], 227, 695, 696, 733.
+\:\\{secondary\_primary\_macro}, \[186], 249, 683, 684, 862, 1035, 1043.
+\:\.{see the transcript file...}, 1209.
+\:\\{seed}, \[150].
+\:\\{selector}, \[54], 55, 57, 58, 59, 60, 62, 66, 70, 81, 86, 87, 93, 195,
+635, 636, 642, 679, 788, 789, 804, 840, 912, 1022, 1023, 1163, 1164, 1200,
+1205, 1209.
+\:\\{semicolon}, \[186], 211, 212, 713, 732, 832, 989, 990, 991, 1017, 1051,
+1070.
+\:\\{sentinel}, \[175], 177, 324, 328, 330, 331, 332, 335, 339, 343, 344, 345,
+346, 347, 348, 349, 355, 356, 358, 364, 367, 368, 369, 582, 1169.
+\:\\{serial\_no}, \[585], 587, 1198, 1199.
+\:\\{set\_controls}, 297, 298, \[299], 301.
+\:\\{set\_min\_max}, \[554], 558, 559.
+\:\\{set\_output\_file\_name}, \[791], 1163.
+\:\\{set\_tag}, \[1104], 1106, 1111, 1113.
+\:\\{set\_trick\_count}, \[642], 643, 644, 646.
+\:\\{set\_two}, \[387], 388.
+\:\\{set\_two\_end}, \[387].
+\:\\{set\_up\_direction\_time}, 983, \[984].
+\:\\{set\_up\_known\_trans}, \[960], 962, 963, 967.
+\:\\{set\_up\_offset}, 983, \[984].
+\:\\{set\_up\_trans}, \[953], 960, 970.
+\:\\{seventh\_octant}, \[139], 141, 380, 387, 388, 396, 435, 443, 449, 461, 462.
+\:\\{sf}, \[116], 297, \[298], 299, 300, 301.
+\:\9{shifted\_}{\&{shifted} primitive}, \[893].
+\:\\{shifted\_by}, \[189], 893, 952, 957.
+\:\\{ship\_out}, 1070, 1149, \[1165], 1175.
+\:\9{ship\_out\_}{\&{shipout} primitive}, \[211].
+\:\\{ship\_out\_command}, \[186], 211, 212, 1069.
+\:\9{show\_}{\&{show} primitive}, \[1037].
+\:\\{show\_cmd\_mod}, \[626], 713, 895.
+\:\\{show\_code}, \[1037], 1038, 1040, 1051.
+\:\\{show\_command}, \[186], 1037, 1038, 1039.
+\:\\{show\_context}, 54, 73, 77, 83, 634, \[635], 644, 786, 789, 793.
+\:\\{show\_cur\_cmd\_mod}, \[626], 707, 832, 992.
+\:\9{show\_dependencies\_}{\&{showdependencies} primitive}, \[1037].
+\:\\{show\_dependencies\_code}, \[1037], 1051.
+\:\\{show\_macro}, \[227], 645, 721, 1041, 1048.
+\:\9{show\_stats\_}{\&{showstats} primitive}, \[1037].
+\:\\{show\_stats\_code}, \[1037], 1038, 1051.
+\:\9{show\_token\_}{\&{showtoken} primitive}, \[1037].
+\:\\{show\_token\_code}, \[1037], 1038, 1051.
+\:\\{show\_token\_list}, \[217], 224, 227, 235, 639, 640, 645, 646, 665, 722,
+723, 762, 840, 851, 998, 1043, 1057, 1213.
+\:\9{show\_var\_}{\&{showvariable} primitive}, \[1037].
+\:\\{show\_var\_code}, \[1037], 1038, 1051.
+\:\\{showstopping}, \[190], 192, 193, 1051.
+\:\9{showstopping\_}{\&{showstopping} primitive}, \[192].
+\:\\{si}, \[37], 41, 85, 1193.
+\:\9{sin\_d\_}{\&{sind} primitive}, \[893].
+\:\\{sin\_d\_op}, \[189], 893, 906.
+\:\\{sine}, \[280], 281, \[299], 300.
+\:\\{single\_dependency}, \[608], 829, 855, 858, 1007, 1009.
+\:\\{sixth\_octant}, \[139], 141, 379, 380, 387, 388, 395, 396, 443, 448, 449,
+461, 462, 488.
+\:\\{skew}, \[387], 421, 445, 447, 451, 457, 481.
+\:\\{skew\_line\_edges}, 508, \[510], 517, 523.
+\:\\{skimp}, \[1121], 1124, 1126.
+\:\\{skip\_byte}, \[1093], 1107, 1110, 1111, 1112, 1137.
+\:\\{skip\_error}, \[1110], 1111.
+\:\\{skip\_table}, \[1096], 1097, 1110, 1111, 1139.
+\:\\{skip\_to}, \[186], 211, 212, 1107.
+\:\9{skip\_to\_}{\&{skipto} primitive}, \[211].
+\:\\{skipping}, \[659], 661, 742.
+\:\\{skip0}, 1144, \[1145], 1173.
+\:\\{skip1}, 1144, \[1145], 1174.
+\:\\{skip2}, \[1144].
+\:\\{skip3}, \[1144].
+\:\\{slant}, 1095.
+\:\\{slant\_code}, \[1095].
+\:\9{slanted\_}{\&{slanted} primitive}, \[893].
+\:\\{slanted\_by}, \[189], 893, 952, 957.
+\:\\{slash}, \[186], 837, 893, 894.
+\:\\{slow\_add}, \[100], 594, 597, 930, 931, 933.
+\:\\{slow\_case\_down}, \[378], 380.
+\:\\{slow\_case\_up}, \[378], 380.
+\:\\{slow\_print}, \[60], 61, 79, 219, 223, 254, 638, 664, 722, 725, 773, 790,
+793, 802, 994, 998, 999, 1032, 1034, 1041, 1042, 1043, 1082, 1086, 1134, 1182,
+1200, 1205, 1213.
+\:{small computers}, 95.
+\:\\{small\_number}, \[101], 102, 121, 135, 139, 145, 187, 210, 217, 230, 232,
+238, 248, 311, 387, 388, 390, 394, 451, 453, 477, 589, 594, 597, 599, 600, 601,
+610, 621, 651, 685, 738, 746, 778, 796, 801, 805, 809, 843, 875, 900, 930, 935,
+943, 949, 966, 1001, 1015, 1054, 1098, 1104, 1123, 1177, 1209.
+\:\\{smooth\_bot}, \[511], 512, 517, 518, 523.
+\:\\{smooth\_moves}, \[321], 468, 517, 523.
+\:\\{smooth\_top}, \[511], 512, 517, 518, 523.
+\:\\{smoothing}, \[190], 192, 193, 468, 517, 523.
+\:\9{smoothing\_}{\&{smoothing} primitive}, \[192].
+\:\\{so}, \[37], 45, 59, 60, 85, 210, 223, 717, 774, 913, 976, 977, 1103, 1160,
+1192.
+\:\\{solve\_choices}, 278, \[284].
+\:\.{some chardps...}, 1123.
+\:\.{some charhts...}, 1123.
+\:\.{some charics...}, 1123.
+\:\.{some charwds...}, 1123.
+\:\.{Some number got too big}, 270.
+\:\.{Sorry, I can't find...}, 779.
+\:\\{sort\_avail}, \[173], 1194.
+\:\\{sort\_edges}, \[346], 348, 354, 578, 1169.
+\:\\{sort\_in}, \[1117], 1124, 1126.
+\:\\{sorted}, 324, \[325], 328, 330, 331, 332, 335, 339, 343, 344, 345, 346,
+347, 348, 349, 355, 356, 358, 364, 367, 368, 369, 385, 580, 582, 1169.
+\:\\{sorted\_loc}, \[325], 335, 345, 347, 368.
+\:\\{south\_edge}, \[435], 438.
+\:\\{space}, 1095.
+\:\\{space\_class}, \[198], 199, 669.
+\:\\{space\_code}, \[1095].
+\:\\{space\_shrink}, 1095.
+\:\\{space\_shrink\_code}, \[1095].
+\:\\{space\_stretch}, 1095.
+\:\\{space\_stretch\_code}, \[1095].
+\:\\{spec\_atan}, \[137], 138, 143, 147.
+\:\\{spec\_head}, \[506].
+\:\\{spec\_log}, \[129], 131, 133, 136.
+\:\9{special\_}{\&{special} primitive}, \[1176].
+\:\\{special\_command}, \[186], 1175, 1176, 1180.
+\:\\{split\_cubic}, \[410], 411, 412, 415, 416, 424, 425, 493, 980, 981, 986.
+\:\\{split\_for\_offset}, \[493], 499, 503, 504.
+\:\\{spotless}, \[71], 72, 195, 1204, 1209.
+\:\9{sqrt\_}{\&{sqrt} primitive}, \[893].
+\:\\{sqrt\_op}, \[189], 893, 906.
+\:\.{Square root...replaced by 0}, 122.
+\:\\{square\_rt}, \[121], 122, 906.
+\:\\{ss}, \[242], 243, 245, \[299], 300, \[334], 335, \[340], \[978], 980.
+\:\\{st}, \[116], 297, \[298], 299, 300, 301.
+\:\\{st\_count}, \[200], 203, 207, 1196, 1197, 1208.
+\:\\{stack\_argument}, \[737], 760.
+\:\\{stack\_dx}, \[553], 559, 561.
+\:\\{stack\_dy}, \[553], 559, 561.
+\:\\{stack\_l}, \[309], 312, 314.
+\:\\{stack\_m}, \[309], 312, 314.
+\:\\{stack\_max}, \[553], 554, 556.
+\:\\{stack\_min}, \[553], 554, 556.
+\:\\{stack\_n}, \[309], 312, 314.
+\:\\{stack\_r}, \[309], 312, 314.
+\:\\{stack\_s}, \[309], 312, 314.
+\:\\{stack\_size}, \[11], 628, 634, 647, 1208.
+\:\\{stack\_tol}, \[553], 559, 561.
+\:\\{stack\_uv}, \[553], 559, 561.
+\:\\{stack\_xy}, \[553], 559, 561.
+\:\\{stack\_x1}, \[309], 312, 314.
+\:\\{stack\_x2}, \[309], 312, 314.
+\:\\{stack\_x3}, \[309], 312, 314.
+\:\\{stack\_y1}, \[309], 312, 314.
+\:\\{stack\_y2}, \[309], 312, 314.
+\:\\{stack\_y3}, \[309], 312, 314.
+\:\\{stack\_1}, \[553], 554, 559, 560.
+\:\\{stack\_2}, \[553], 554, 559, 560.
+\:\\{stack\_3}, \[553], 554, 559, 560.
+\:\\{start}, 627, \[629], 630, 632, 644, 645, 649, 650, 654, 655, 657, 679,
+681, 682, 714, 717, 794, 897.
+\:\\{start\_decimal\_token}, \[667], 669.
+\:\\{start\_def}, \[683], 684, 697, 698, 700.
+\:\\{start\_field}, \[627], 629.
+\:\\{start\_forever}, \[683], 684, 755.
+\:\\{start\_here}, 5, \[1204].
+\:\\{start\_input}, 706, 709, 711, \[793], 1211.
+\:\\{start\_numeric\_token}, \[667], 669.
+\:\\{start\_of\_MF}, \[6], 1204.
+\:\\{start\_screen}, \[570], 574.
+\:\\{start\_sym}, 1076, \[1077], 1078, 1198, 1199, 1204.
+\:\\{stash\_cur\_exp}, 651, 718, 728, 734, 760, 764, \[799], 800, 801, 837,
+839, 848, 859, 862, 863, 864, 868, 926, 946, 955, 970, 988, 995, 1000.
+\:\\{stash\_in}, \[827], 830, 903.
+\:\&{stat}, \[7], \[160], \[163], \[164], \[165], \[167], \[172], \[177], %
+\[207], \[508], \[510], \[515], \[521], \[1045], \[1134], \[1205].
+\:\\{state}, 670.
+\:\9{step\_}{\&{step} primitive}, \[211].
+\:\\{step\_size}, \[752], 760, 761, 765.
+\:\\{step\_token}, \[186], 211, 212, 764.
+\:{Stern, Moritz Abraham}, 526.
+\:{Stolfi, Jorge}, 469.
+\:\\{stop}, \[186], 732, 991, 1017, 1018, 1019.
+\:\\{stop\_flag}, \[1093], 1107, 1110.
+\:\\{stop\_iteration}, 706, 714, 760, \[763], 1209.
+\:\\{store\_base\_file}, \[1186], 1209.
+\:\9{str\_}{\&{str} primitive}, \[211].
+\:\\{str\_eq\_buf}, \[45], 205.
+\:\\{str\_number}, \[37], 38, 42, 43, 44, 45, 46, 47, 62, 74, 88, 89, 90, 94,
+190, 197, 210, 214, 257, 332, 394, 395, 398, 473, 754, 767, 774, 780, 782, 784,
+785, 786, 791, 807, 824, 976, 977, 1087, 1160, 1183.
+\:\\{str\_op}, \[186], 211, 212, 823.
+\:\\{str\_pool}, 37, \[38], 41, 44, 45, 46, 47, 59, 60, 85, 200, 210, 223, 630,
+707, 717, 774, 913, 976, 977, 1103, 1160, 1192, 1193, 1208.
+\:\\{str\_ptr}, 37, \[38], 40, 43, 44, 47, 59, 60, 210, 218, 772, 780, 793,
+798, 1045, 1163, 1192, 1193, 1199, 1200, 1204.
+\:\\{str\_ref}, \[42], 43, 44, 48, 52, 207, 793, 1193, 1200.
+\:\\{str\_room}, \[41], 207, 671, 771, 780, 897, 912, 976, 977, 1200, 1205.
+\:\\{str\_start}, 37, \[38], 39, 40, 43, 44, 45, 46, 47, 59, 60, 85, 200, 210,
+223, 717, 772, 774, 913, 976, 977, 1103, 1160, 1163, 1192, 1193.
+\:\\{str\_to\_num}, 912, \[913].
+\:\\{str\_vs\_str}, \[46], 936, 1004.
+\:\.{Strange path...}, 1068.
+\:\.{String contains illegal digits}, 914.
+\:{string pool}, 47, 1191.
+\:\9{string\_}{\&{string} primitive}, \[1013].
+\:\\{string\_class}, \[198], 199, 219, 669.
+\:\\{string\_token}, \[186], 671, 678, 691, 743, 823.
+\:\\{string\_type}, \[187], 189, 214, 216, 219, 248, 621, 651, 716, 798, 802,
+808, 809, 833, 840, 855, 895, 897, 912, 915, 918, 919, 936, 975, 993, 1003,
+1004, 1013, 1082, 1103, 1176, 1177.
+\:\\{string\_vacancies}, \[11], 52.
+\:\\{structured}, \[187], 188, 228, 229, 239, 242, 243, 246, 247, 809, 850,
+1046.
+\:\\{structured\_root}, \[188], 229, 236, 239.
+\:\9{subpath\_}{\&{subpath} primitive}, \[893].
+\:\\{subpath\_of}, \[189], 893, 975.
+\:\\{subscr}, \[188], 229, 236, 239, 244, 246, 247, 1047.
+\:\\{subscr\_head}, \[228], 229, 239, 240, 244, 246, 247, 1047.
+\:\\{subscr\_head\_loc}, \[228], 240, 241, 244, 246.
+\:\\{subscr\_node\_size}, \[229], 240, 244, 246, 247.
+\:\\{subscript}, \[229], 236, 240, 244.
+\:\\{subscript\_loc}, \[229], 244.
+\:\\{subst\_list}, \[685], 686.
+\:\9{substring\_}{\&{substring} primitive}, \[893].
+\:\\{substring\_of}, \[189], 893, 975.
+\:\\{succumb}, \[88], 89, 90.
+\:\.{SUFFIX}, 222.
+\:\9{suffix\_}{\&{suffix} primitive}, \[695].
+\:\\{suffix\_base}, \[214], 222, 676, 677, 683, 690, 695, 696, 697, 705, 726,
+729, 755, 764.
+\:\\{suffix\_count}, \[685], 690.
+\:\\{suffix\_macro}, \[226], 227, 705, 733.
+\:\\{suffixed\_macro}, \[187], 700, 798, 809, 845, 1048.
+\:\\{sum}, \[378].
+\:\\{switch}, \[667], 669, 670, 672.
+\:\\{switch\_x\_and\_y}, \[139], 406, 423, 424, 441, 442, 445, 480, 489.
+\:\\{sx}, \[601].
+\:\\{symmetric}, \[527], 528, 530.
+\:{system dependencies}, 2, \[3], 4, 9, 10, 11, 12, 19, 21, 22, 25, 26, 27, 31,
+32, 33, 34, 36, 49, 56, 59, 67, 76, 79, 91, 107, 109, 153, 155, 156, 194, 199,
+564, 567, 568, 631, 637, 654, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775,
+776, 778, 780, 781, 794, 1148, 1152, 1154, 1203, 1204, 1205, 1212, 1214.
+\:\\{s1}, \[77], 83.
+\:\\{s2}, \[77], 83.
+\:\\{s3}, \[77], 83.
+\:\|{t}, \[46], \[116], \[139], \[145], \[167], \[187], \[197], \[238], \[242],
+\[246], \[280], \[284], \[311], \[321], \[340], \[342], \[344], \[398], \[406],
+\[410], \[419], \[493], \[495], \[497], \[542], \[589], \[594], \[597], \[601],
+\[603], \[604], \[610], \[621], \[649], \[801], \[805], \[809], \[843], \[855],
+\[860], \[868], \[875], \[899], \[900], \[930], \[935], \[943], \[949], \[968],
+\[972], \[974], \[1001], \[1006], \[1011], \[1015], \[1029], \[1054], \[1057], %
+\[1104], \[1160], \[1163].
+\:\\{t\_of\_the\_way}, \[410], 411, 415, 424, 499, 503, 504, 547, 548.
+\:\\{t\_of\_the\_way\_end}, \[410].
+\:\\{t\_open\_in}, \[32], 36.
+\:\\{t\_open\_out}, \[32], 1204.
+\:\\{tag}, \[1091], 1092.
+\:\\{tag\_token}, \[186], 202, 229, 234, 242, 249, 254, 702, 823, 844, 850,
+860, 1011, 1035, 1043, 1049.
+\:\\{tail}, \[720], 724, 728, 734, 842, \[843], 844, 845.
+\:\\{tail\_end}, \[685].
+\:\\{take\_fraction}, \[109], 112, 116, 125, 127, 151, 152, 281, 287, 288, 289,
+290, 291, 294, 295, 296, 297, 299, 300, 302, 375, 376, 410, 436, 439, 444, 454,
+498, 516, 522, 530, 533, 543, 594, 595, 596, 599, 943, 944.
+\:\\{take\_part}, 909, \[910], 939.
+\:\\{take\_scaled}, \[112], 594, 595, 596, 599, 942, 943, 961, 968, 971, 974.
+\:\\{tally}, \[54], 55, 57, 58, 217, 227, 235, 636, 639, 640, 641, 642, 643.
+\:\\{tarnished}, 926, 927, \[928], 944.
+\:\&{tats}, \[7].
+\:\\{temp\_head}, \[175], 335, 346, 347, 349, 351, 484, 594, 597, 599, 600,
+601, 612, 616, 1117, 1118, 1121, 1124, 1126.
+\:\\{temp\_val}, \[175], 910, 911.
+\:\\{tension}, \[186], 211, 212, 881.
+\:\9{tension\_}{\&{tension} primitive}, \[211].
+\:\\{term\_and\_log}, \[54], 57, 58, 66, 70, 87, 195, 788, 804, 1200, 1209.
+\:\\{term\_in}, \[31], 32, 33, 35, 36, 66, 1212, 1213.
+\:\\{term\_input}, \[66], 73.
+\:\\{term\_offset}, \[54], 55, 57, 58, 61, 62, 66, 793, 1165.
+\:\\{term\_only}, \[54], 55, 57, 58, 66, 70, 87, 789, 804, 1205, 1209.
+\:\\{term\_out}, \[31], 32, 33, 34, 35, 36, 51, 56.
+\:\\{terminal\_input}, \[631], 637, 654, 656.
+\:\\{terminator}, \[685].
+\:\9{tertiary\_}{\&{tertiary} primitive}, \[695].
+\:\\{tertiary\_binary}, \[186], 893, 894.
+\:\9{tertiary\_def\_}{\&{tertiarydef} primitive}, \[683].
+\:\\{tertiary\_macro}, \[226], 227, 695, 733.
+\:\\{tertiary\_secondary\_macro}, \[186], 249, 683, 684, 864, 1035, 1043.
+\:\\{test\_known}, 918, \[919].
+\:\\{text}, \[200], 202, 203, 205, 206, 207, 210, 218, 254, 638, 664, 722, 725,
+727, 735, 759, 1032, 1034, 1036, 1041, 1043, 1196.
+\:\.{TEXT}, 222.
+\:\.{Text line contains...}, 670.
+\:\9{text\_}{\&{text} primitive}, \[695].
+\:\\{text\_base}, \[214], 222, 677, 695, 697, 723, 729.
+\:\\{text\_char}, \[19], 20, 24, 26, 47.
+\:\\{text\_macro}, \[226], 227, 697, 705, 723, 733.
+\:\9{TFM files}{\.{TFM} files}, 1087.
+\:\\{tfm\_changed}, 1129, \[1130], 1132, 1136, 1140.
+\:\\{tfm\_check}, \[1098], 1099.
+\:\\{tfm\_command}, \[186], 1100, 1101, 1102.
+\:\\{tfm\_depth}, \[1096], 1097, 1099, 1126, 1136.
+\:\\{tfm\_file}, \[1087], 1133, 1134.
+\:\\{tfm\_four}, \[1133], 1136, 1139, 1140.
+\:\\{tfm\_height}, \[1096], 1097, 1099, 1126, 1136.
+\:\\{tfm\_ital\_corr}, \[1096], 1097, 1099, 1126, 1136.
+\:\\{tfm\_out}, \[1133], 1135, 1136, 1139.
+\:\\{tfm\_qqqq}, \[1133], 1139, 1140.
+\:\\{tfm\_two}, \[1133], 1135, 1139.
+\:\\{tfm\_warning}, \[1123], 1124, 1126.
+\:\\{tfm\_width}, \[1096], 1097, 1099, 1124, 1131, 1132, 1136, 1182, 1205.
+\:\.{That makes 100 errors...}, 77.
+\:\.{That transformation...}, 963.
+\:\.{The token...delimiter}, 1032.
+\:\.{The token...quantity}, 1034.
+\:\.{There's unbounded black...}, 1169.
+\:\\{theta}, \[283], 291, 292, 295, 297, \[527], 530, 533, \[542], 544, \[865],
+866.
+\:\\{thing\_to\_add}, \[186], 1052, 1053, 1059.
+\:\\{third\_octant}, \[139], 141, 379, 380, 387, 388, 393, 396, 406, 443, 449,
+461, 462.
+\:\.{This can't happen}, 90.
+\:\9{this can't happen /}{\quad \./}, 107, 114.
+\:\9{this can't happen copy}{\quad copy}, 855.
+\:\9{this can't happen dep}{\quad dep}, 589.
+\:\9{this can't happen endinput}{\quad endinput}, 655.
+\:\9{this can't happen exp}{\quad exp}, 802.
+\:\9{this can't happen if}{\quad if}, 746.
+\:\9{this can't happen m}{\quad m}, 311.
+\:\9{this can't happen recycle}{\quad recycle}, 809.
+\:\9{this can't happen struct}{\quad struct}, 239.
+\:\9{this can't happen token}{\quad token}, 216.
+\:\9{this can't happen var}{\quad var}, 236.
+\:\9{this can't happen xy}{\quad xy}, 362.
+\:\9{this can't happen 0}{\quad 0}, 378.
+\:\.{This variable already...}, 701.
+\:\\{three}, \[101], 296.
+\:\\{three\_bytes}, \[1128], 1129, 1133, 1157, 1182.
+\:\\{three\_choices}, \[156].
+\:\\{three\_l}, \[557], 558, 559, 560, 561.
+\:\\{three\_quarter\_unit}, \[101], 883.
+\:\\{three\_sixty\_deg}, \[106], 145, 292.
+\:\\{three\_sixty\_units}, \[906], 958.
+\:\\{threshold}, \[594], 595, 596, \[597], 598, \[599], \[600], \[1120], 1121.
+\:\\{time}, \[190], 192, 193, 194, 790, 1163, 1211.
+\:\9{time\_}{\&{time} primitive}, \[192].
+\:\\{time\_to\_go}, \[555], 556.
+\:\\{times}, \[189], 837, 859, 893, 941, 944.
+\:\&{tini}, \[8].
+\:\9{to\_}{\&{to} primitive}, \[211].
+\:\\{to\_token}, \[186], 211, 212, 1073.
+\:{token}, 214.
+\:\\{token}, \[188], 214, 215, 219, 651, 678.
+\:\\{token\_list}, \[187], 670, 726, 728, 730, 798, 799, 809, 841, 852, 860,
+996, 1059, 1070, 1071, 1074.
+\:\\{token\_node\_size}, \[214], 215, 216, 651, 694, 704, 705, 755.
+\:\\{token\_recycle}, 216, \[224].
+\:\\{token\_state}, \[632], 652, 672, 712, 736, 795, 1209.
+\:\\{token\_type}, \[632], 635, 636, 638, 645, 649, 650, 653, 714.
+\:\\{tol}, 552, 553, 556, \[557], 558, 559, 560, 561.
+\:\\{tol\_step}, \[552], 557, 559, 561, 562.
+\:\.{Too far to shift}, 965.
+\:\.{Too far to skip}, 1110.
+\:\.{Too many arguments...}, 725.
+\:\\{too\_small}, \[1187], 1189.
+\:\\{top}, \[1094].
+\:\\{top\_row}, \[567], \[572], 574, 577.
+\:\\{toss\_edges}, \[385], 808, 809, 964.
+\:\\{toss\_knot\_list}, \[268], 465, 506, 808, 809, 865, 921, 978, 1064, 1067.
+\:\\{toss\_pen}, 475, \[487].
+\:\\{total\_chars}, \[1149], 1150, 1165, 1182.
+\:\\{total\_weight}, \[369], 921.
+\:\9{total\_weight\_}{\&{totalweight} primitive}, \[893].
+\:\\{total\_weight\_op}, \[189], 893, 921.
+\:\\{trace\_a\_corner}, \[372], 373.
+\:\\{trace\_new\_edge}, \[373], 375, 376, 381, 382, 383, 384.
+\:\\{trace\_x}, \[371], 372, 373.
+\:\\{trace\_y}, \[371], 372, 373.
+\:\\{trace\_yy}, \[371], 372, 373.
+\:\\{tracing}, \[402].
+\:\\{tracing\_capsules}, \[190], 192, 193, 238.
+\:\9{tracing\_capsules\_}{\&{tracingcapsules} primitive}, \[192].
+\:\\{tracing\_choices}, \[190], 192, 193, 269.
+\:\9{tracing\_choices\_}{\&{tracingchoices} primitive}, \[192].
+\:\\{tracing\_commands}, \[190], 192, 193, 707, 713, 748, 760, 832, 895, 898,
+922, 944, 992, 995, 996.
+\:\9{tracing\_commands\_}{\&{tracingcommands} primitive}, \[192].
+\:\\{tracing\_edges}, \[190], 192, 193, 371, 375, 376, 381, 382, 383, 384, 465,
+506, 508, 510, 515, 521.
+\:\9{tracing\_edges\_}{\&{tracingedges} primitive}, \[192].
+\:\\{tracing\_equations}, \[190], 192, 193, 603, 610, 816.
+\:\9{tracing\_equations\_}{\&{tracingequations} primitive}, \[192].
+\:\\{tracing\_macros}, \[190], 192, 193, 720, 728, 734.
+\:\9{tracing\_macros\_}{\&{tracingmacros} primitive}, \[192].
+\:\\{tracing\_online}, \[190], 192, 193, 195, 804.
+\:\9{tracing\_online\_}{\&{tracingonline} primitive}, \[192].
+\:\\{tracing\_output}, \[190], 192, 193, 1165.
+\:\9{tracing\_output\_}{\&{tracingoutput} primitive}, \[192].
+\:\\{tracing\_pens}, \[190], 192, 193, 253, 477.
+\:\9{tracing\_pens\_}{\&{tracingpens} primitive}, \[192].
+\:\\{tracing\_restores}, \[190], 192, 193, 254.
+\:\9{tracing\_restores\_}{\&{tracingrestores} primitive}, \[192].
+\:\\{tracing\_specs}, \[190], 192, 193, 1064.
+\:\9{tracing\_specs\_}{\&{tracingspecs} primitive}, \[192].
+\:\\{tracing\_stats}, 160, \[190], 192, 193, 1134, 1198, 1205.
+\:\9{tracing\_stats\_}{\&{tracingstats} primitive}, \[192].
+\:\\{tracing\_titles}, \[190], 192, 193, 994.
+\:\9{tracingtitles\_}{\&{tracingtitles} primitive}, \[192].
+\:\\{trans}, \[961], 962.
+\:\\{trans\_spec}, \[565], 568, 579.
+\:\.{Transcript written...}, 1205.
+\:\.{Transform components...}, 960.
+\:\9{transform\_}{\&{transform} primitive}, \[1013].
+\:\\{transform\_node\_size}, \[230], 231, 233, 956.
+\:\\{transform\_type}, \[187], 216, 230, 231, 232, 233, 248, 798, 799, 800,
+802, 808, 809, 855, 909, 918, 919, 926, 927, 936, 944, 952, 953, 955, 967, 970,
+973, 1003, 1013, 1015.
+\:\9{transformed\_}{\&{transformed} primitive}, \[893].
+\:\\{transformed\_by}, \[189], 893, 952, 953, 957.
+\:\.{transition line...}, 515, 521.
+\:\\{trick\_buf}, \[54], 58, 641, 643.
+\:\\{trick\_count}, \[54], 58, 641, 642, 643.
+\:\\{trivial\_knot}, 484, 485, \[486].
+\:\\{true}, 4, 16, 30, 33, 36, 45, 49, 51, 53, 66, 72, 83, 92, 93, 97, 100,
+107, 109, 110, 112, 114, 124, 126, 135, 181, 182, 238, 257, 269, 332, 372, 394,
+402, 407, 426, 446, 452, 454, 455, 473, 477, 497, 503, 504, 530, 564, 567, 568,
+569, 570, 574, 577, 592, 593, 595, 596, 598, 599, 600, 621, 653, 654, 661, 670,
+672, 675, 680, 681, 700, 711, 767, 771, 779, 788, 801, 886, 899, 913, 942, 946,
+968, 969, 977, 978, 1003, 1009, 1010, 1054, 1056, 1064, 1072, 1086, 1099, 1112,
+1137, 1165, 1187.
+\:\9{true\_}{\&{true} primitive}, \[893].
+\:\\{true\_code}, \[189], 713, 748, 750, 798, 802, 892, 893, 895, 905, 906,
+918, 919, 920, 940.
+\:\\{try\_eq}, 1003, 1005, \[1006].
+\:\\{tt}, \[167], 169, \[539], 541, 547, 548, \[594], 595, 596, 842, \[843],
+844, 845, 850, \[1006], 1009, 1010.
+\:\\{turning\_check}, \[190], 192, 193, 1068.
+\:\9{turning\_check\_}{\&{turningcheck} primitive}, \[192].
+\:\\{turning\_number}, \[403], 450, 459, 917, 1068.
+\:\9{turning\_number\_}{\&{turningnumber} primitive}, \[893].
+\:\\{turning\_op}, \[189], 893, 917.
+\:\\{two}, \[101], 102, 256, 294, 295, 556, 895, 898, 922, 944, 995, 996.
+\:\\{two\_choices}, \[156].
+\:\\{two\_halves}, \[156], 161, 166, 185, 201.
+\:\\{two\_to\_the}, \[129], 131, 133, 136, 143, 147, 314, 317, 608, 616.
+\:\\{tx}, \[374], 375, 376, \[511], 516, 522, 866, 867, 953, \[954], 956, 960,
+961, 962, 965, 967, 973.
+\:\\{txx}, 866, 953, \[954], 956, 960, 961, 963, 964, 967, 973.
+\:\\{txy}, 866, 953, \[954], 956, 960, 961, 963, 967, 973.
+\:\\{ty}, \[511], 516, 522, 866, 867, 953, \[954], 956, 960, 961, 962, 965,
+967, 973.
+\:\\{type}, \[4], 188, \[214], 215, 216, 219, 228, 229, 232, 233, 234, 239,
+242, 243, 244, 245, 246, 247, 248, 585, 587, 589, 595, 596, 598, 599, 600, 603,
+604, 605, 614, 615, 619, 621, 651, 678, 700, 738, 744, 745, 746, 799, 800, 801,
+803, 809, 812, 819, 827, 829, 830, 842, 850, 855, 856, 857, 858, 868, 873, 899,
+903, 910, 919, 923, 926, 928, 929, 930, 931, 932, 935, 936, 939, 940, 941, 942,
+943, 946, 947, 948, 949, 951, 952, 956, 957, 959, 966, 968, 969, 971, 972, 975,
+982, 983, 988, 995, 1000, 1001, 1002, 1006, 1007, 1009, 1015, 1046, 1048, 1050,
+1057.
+\:\.{Type <return> to proceed...}, 80.
+\:\\{type\_name}, \[186], 823, 989, 992, 1013, 1014, 1015.
+\:\\{type\_range}, \[918].
+\:\\{type\_range\_end}, \[918].
+\:\\{type\_test}, \[918].
+\:\\{type\_test\_end}, \[918].
+\:\\{tyx}, 866, 953, \[954], 956, 960, 961, 963, 967, 973.
+\:\\{tyy}, 866, 953, \[954], 956, 960, 961, 963, 964, 967, 973.
+\:\\{t0}, \[495], \[497], 498, 503, \[599], \[600].
+\:\\{t1}, \[495], \[497], 498, 499, 503, \[599], \[600].
+\:\\{t2}, \[495], \[497], 498, 499, 503.
+\:\|{u}, \[152], \[311], \[344], \[432], \[527], \[946], \[968], \[972], \[974].
+\:\\{u\_packet}, \[553], 556, 559, 560.
+\:\\{ul\_packet}, \[553], 559.
+\:\\{unary}, \[186], 823, 893, 894.
+\:\\{und\_type}, \[248], 1000.
+\:\\{undefined}, \[187], 229, 234, 239, 242, 244, 245, 247, 248, 585, 809, 842,
+844, 845, 850, 1046.
+\:\.{Undefined condition...}, 892.
+\:\.{Undefined coordinates...}, 872, 873, 878.
+\:\\{undefined\_label}, \[1096], 1097, 1110, 1111, 1137, 1139, 1141.
+\:\\{undump}, \[1189], 1193, 1195, 1197, 1199.
+\:\\{undump\_end}, \[1189].
+\:\\{undump\_end\_end}, \[1189].
+\:\\{undump\_four\_ASCII}, \[1193].
+\:\\{undump\_hh}, \[1189], 1197.
+\:\\{undump\_int}, \[1189], 1191, 1195, 1197, 1199.
+\:\\{undump\_qqqq}, \[1189], 1193.
+\:\\{undump\_size}, \[1189], 1193.
+\:\\{undump\_size\_end}, \[1189].
+\:\\{undump\_size\_end\_end}, \[1189].
+\:\\{undump\_wd}, \[1189], 1195.
+\:\\{unequal\_to}, \[189], 893, 936, 937.
+\:\\{unif\_rand}, \[151], 906.
+\:\\{uniform\_deviate}, \[189], 893, 906.
+\:\9{uniform\_deviate\_}{\&{uniformdeviate} primitive}, \[893].
+\:\\{unity}, \[101], 103, 112, 114, 115, 116, 119, 132, 194, 233, 256, 258,
+271, 282, 288, 294, 295, 296, 300, 302, 311, 374, 375, 376, 402, 430, 431, 433,
+462, 463, 508, 510, 515, 516, 521, 522, 530, 539, 548, 555, 556, 562, 590, 674,
+675, 707, 713, 748, 760, 816, 817, 819, 876, 881, 883, 886, 887, 890, 891, 896,
+906, 913, 915, 916, 917, 932, 943, 949, 960, 963, 964, 968, 969, 972, 974, 978,
+980, 985, 1010, 1068, 1071, 1074, 1097, 1128, 1133, 1157, 1158, 1166, 1182,
+1211.
+\:\.{Unknown relation...}, 937.
+\:\.{Unknown value...ignored}, 1021.
+\:\9{unknown\_}{\&{unknown} primitive}, \[893].
+\:\\{unknown\_boolean}, \[187], 229, 248, 618, 798, 799, 918, 936.
+\:\\{unknown\_op}, \[189], 893, 918.
+\:\\{unknown\_path}, \[187], 248, 618, 798, 918, 995, 1003.
+\:\\{unknown\_pen}, \[187], 248, 618, 798.
+\:\\{unknown\_picture}, \[187], 248, 618, 798, 918.
+\:\\{unknown\_string}, \[187], 248, 618, 798, 918, 936.
+\:\\{unknown\_tag}, \[187], 621, 1003, 1015.
+\:\\{unknown\_types}, \[187], 216, 799, 800, 802, 808, 809, 855, 1003.
+\:\\{unrotate}, 389.
+\:\\{unsave}, \[254], 832.
+\:\\{unskew}, \[388], 394, 421, 445, 447, 451, 454, 457, 485, 488, 510.
+\:\\{unsorted}, 324, \[325], 326, 328, 330, 331, 332, 335, 338, 343, 344, 346,
+348, 354, 355, 364, 367, 368, 369, 375, 376, 381, 382, 383, 384, 385, 578, 1169.
+\:\\{unstash\_cur\_exp}, 718, \[800], 801, 859, 870, 926, 942, 946, 948, 962,
+963, 988, 995, 1000.
+\:\\{unsuffixed\_macro}, \[187], 700, 798, 809, 842, 844, 845, 1046, 1048.
+\:\.{Unsuitable expression}, 1178.
+\:\9{until\_}{\&{until} primitive}, \[211].
+\:\\{until\_token}, \[186], 211, 212, 765.
+\:\\{update\_screen}, \[564], 569, 571, 574, 577.
+\:\\{update\_terminal}, \[33], 36, 61, 66, 81, 564, 681, 779, 793, 994, 1165,
+1212.
+\:\\{ur\_packet}, \[553], 558, 559.
+\:\\{use\_err\_help}, \[74], 75, 84, 86, 1086.
+\:\\{uu}, \[283], 285, 287, 288, 290, 291, 293, 294, 295, 297.
+\:\\{uv}, 553, 556, \[557], 558, 559, 560, 561.
+\:\\{u1l}, \[553], 559.
+\:\\{u1r}, \[553], 558, 559.
+\:\\{u2l}, \[553], 559.
+\:\\{u2r}, \[553], 558, 559.
+\:\\{u3l}, \[553], 559.
+\:\\{u3r}, \[553], 558, 559.
+\:\|{v}, \[215], \[217], \[410], \[432], \[497], \[527], \[589], \[594], %
+\[597], \[599], \[600], \[601], \[607], \[610], \[621], \[801], \[808], \[809],
+\[820], \[900], \[922], \[930], \[935], \[943], \[944], \[946], \[949], \[961],
+\[971], \[972], \[974], \[985], \[1001], \[1117], \[1121].
+\:\\{v\_is\_scaled}, \[599], \[943].
+\:\\{v\_packet}, \[553], 556, 559, 560.
+\:\\{vacuous}, \[187], 216, 219, 248, 621, 764, 798, 799, 800, 802, 809, 827,
+844, 855, 919, 989, 992, 993, 996, 1003, 1054, 1059, 1070, 1071, 1074.
+\:\\{val\_too\_big}, \[602], 603, 615.
+\:\\{valid\_range}, \[326], 329, 965.
+\:\\{value}, \[214], 215, 216, 219, 220, 228, 229, 230, 232, 233, 239, 242,
+244, 246, 250, 253, 254, 585, 587, 589, 590, 591, 594, 595, 596, 597, 598, 599,
+600, 601, 603, 604, 605, 607, 608, 609, 610, 611, 612, 615, 616, 617, 619, 620,
+621, 622, 651, 678, 685, 686, 694, 698, 700, 704, 705, 752, 755, 760, 765, 798,
+799, 800, 801, 803, 806, 809, 812, 814, 816, 817, 818, 819, 827, 829, 830, 845,
+853, 855, 857, 858, 872, 873, 899, 903, 904, 907, 910, 915, 919, 928, 929, 930,
+931, 933, 935, 936, 938, 939, 940, 942, 943, 944, 946, 948, 949, 951, 955, 956,
+957, 958, 959, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978,
+982, 983, 984, 988, 1000, 1001, 1005, 1006, 1007, 1008, 1009, 1010, 1015, 1048,
+1057, 1072, 1116, 1117, 1118, 1121, 1122, 1127, 1132, 1136, 1182.
+\:\.{Value is too large}, 602.
+\:\\{value\_loc}, \[214], 587, 605, 812, 827, 947.
+\:\\{value\_node\_size}, \[228], 233, 234, 239, 247, 249, 603, 615, 619, 650,
+763, 799, 800, 808, 827, 830, 837, 855, 856, 857, 858, 903, 910, 922, 925, 931,
+942, 944, 947, 955, 970, 982, 1001, 1006, 1117.
+\:\\{var\_def}, \[683], 684, 697, 992.
+\:\9{var\_def\_}{\&{vardef} primitive}, \[683].
+\:\\{var\_defining}, \[659], 664, 665, 700.
+\:\\{var\_flag}, \[821], 822, 823, 824, 868, 993, 995, 996, 1059, 1070, 1071,
+1074.
+\:\\{var\_used}, \[160], 167, 172, 176, 1045, 1194, 1195.
+\:\.{Variable x is the wrong type}, 1057.
+\:\.{Variable...obliterated}, 851.
+\:\\{velocity}, \[116], 275, 299.
+\:\\{verbosity}, \[801], 802, 803, 804, \[805], 1040.
+\:\.{VIRMF}, 1203.
+\:{virtual memory}, 168.
+\:{Vitter, Jeffrey Scott}, 208.
+\:\\{vl\_packet}, \[553], 559.
+\:\\{void}, \[324], 326, 328, 330, 331, 332, 335, 338, 343, 344, 346, 348, 354,
+367, 368, 369, 385, 578, 639, 650, 719, 723, 752, 755, 760, 762, 763, 799, 926,
+927, 928, 944, 1169.
+\:\\{vppp}, \[190], 192, 193, \[1146], 1182.
+\:\9{vppp\_}{\&{vppp} primitive}, \[192].
+\:\\{vr\_packet}, \[553], 558, 559.
+\:\\{vv}, \[283], 285, 290, 291, 293, 294, 295, 297, \[809], 817, \[935], %
+\[972].
+\:\\{v1l}, \[553], 559.
+\:\\{v1r}, \[553], 558, 559.
+\:\\{v2l}, \[553], 559.
+\:\\{v2r}, \[553], 558, 559.
+\:\\{v3l}, \[553], 559.
+\:\\{v3r}, \[553], 558, 559.
+\:\|{w}, \[157], \[333], \[342], \[348], \[357], \[373], \[473], \[476], %
+\[477], \[484], \[487], \[488], \[491], \[497], \[510], \[511], \[580], \[599],
+\[600], \[610], \[1059], \[1074], \[1165], \[1186], \[1187].
+\:\\{w\_close}, \[27], 1201, 1211.
+\:\\{w\_hi}, \[348], 349.
+\:\\{w\_in}, \[348], 349, \[1074], 1075.
+\:\\{w\_lo}, \[348], 349.
+\:\\{w\_make\_name\_string}, \[780], 1200.
+\:\\{w\_open\_in}, \[26], 779.
+\:\\{w\_open\_out}, \[26], 1200.
+\:\\{w\_out}, \[348], 349, \[1074], 1075.
+\:\\{wake\_up\_terminal}, \[33], 36, 51, 66, 68, 398, 682, 779, 786, 807, 1051,
+1187, 1205, 1212.
+\:\\{warning\_check}, \[190], 192, 193, 602.
+\:\9{warning\_check\_}{\&{warningcheck} primitive}, \[192].
+\:\\{warning\_info}, \[659], 661, 664, 694, 698, 700, 701, 730, 742, 758.
+\:\\{warning\_issued}, \[71], 195, 1209.
+\:\\{was\_free}, \[178], 180, 184.
+\:\\{was\_hi\_min}, \[178], 179, 180, 184.
+\:\\{was\_lo\_max}, \[178], 179, 180, 184.
+\:\\{was\_mem\_end}, \[178], 179, 180, 184.
+\:\\{watch\_coefs}, \[592], 593, 595, 596, 598, 1010.
+\:\\{we\_found\_it}, \[547], 548, 549.
+\:\.{WEB}, 1, 4, 37, 39, 50, 1191.
+\:\.{Weight must be...}, 1056.
+\:\\{west\_edge}, \[435].
+\:\\{white}, \[565], 567, 568, 577, 579, 583, 584, 1143, 1144.
+\:\\{width\_index}, \[1091].
+\:\\{window\_number}, \[571], 572, 574, 577.
+\:\\{window\_open}, \[572], 573, 574, 1071.
+\:\\{window\_time}, \[572], 573, 574, 577.
+\:{Wirth, Niklaus}, 10.
+\:\\{with\_option}, \[186], 1052, 1053, 1062, 1074.
+\:\9{with\_pen\_}{\&{withpen} primitive}, \[1052].
+\:\9{with\_weight\_}{\&{withweight} primitive}, \[1052].
+\:\\{wlog}, \[56], 58, 564, 568, 790, 1208.
+\:\\{wlog\_cr}, \[56], 57, 58, 567, 1205.
+\:\\{wlog\_ln}, \[56], 564, 567, 568, 1141, 1208.
+\:\\{word\_file}, 24, 26, 27, \[156], 780, 1188.
+\:\\{write}, 36, 56, 1133, 1154.
+\:\\{write\_gf}, \[1154], 1155, 1156.
+\:\\{write\_ln}, 34, 36, 51, 56.
+\:\\{wterm}, \[56], 58, 61.
+\:\\{wterm\_cr}, \[56], 57, 58.
+\:\\{wterm\_ln}, \[56], 61, 779, 1187, 1204.
+\:\\{ww}, \[283], 285, 290, 291, 293, 294, \[348], 349, \[357], 362, \[473],
+474, \[484], 485, \[487], \[488], \[491], \[497], 498, 502, 503, 508, 509, %
+\[510], \[511], 513, 519, \[580], 582, 583, 584, \[1165], 1169.
+\:\\{www}, \[506], 508.
+\:\|{x}, \[100], \[104], \[119], \[121], \[132], \[135], \[139], \[145], %
+\[149], \[151], \[152], \[234], \[387], \[388], \[390], \[391], \[463], \[486],
+\[488], \[539], \[574], \[591], \[601], \[602], \[604], \[610], \[868], \[875],
+\[898], \[982], \[1011], \[1129], \[1131], \[1133], \[1157], \[1158], \[1186], %
+\[1187], \[1205].
+\:\\{x\_coord}, \[255], 256, 258, 265, 266, 271, 281, 282, 299, 302, 393, 394,
+397, 404, 405, 406, 407, 409, 410, 411, 412, 413, 415, 416, 418, 419, 421, 423,
+424, 425, 434, 436, 441, 442, 444, 445, 447, 451, 457, 467, 468, 472, 473, 474,
+475, 476, 477, 479, 481, 483, 484, 485, 486, 488, 492, 493, 496, 498, 502, 508,
+509, 510, 512, 513, 515, 518, 519, 521, 528, 534, 535, 536, 537, 543, 558, 563,
+866, 867, 871, 887, 896, 962, 980, 981, 986, 987, 1066.
+\:\\{x\_corr}, \[461], 462, 463.
+\:\\{x\_height}, 1095.
+\:\\{x\_height\_code}, \[1095].
+\:\\{x\_off}, \[332], \[333], \[1165], 1166, 1169, 1172.
+\:\\{x\_offset}, \[190], 192, 193, 1165.
+\:\9{x\_offset\_}{\&{xoffset} primitive}, \[192].
+\:\\{x\_packet}, \[553], 556, 559, 560.
+\:\\{x\_part}, \[189], 893, 909, 910, 939.
+\:\9{x\_part\_}{\&{xpart} primitive}, \[893].
+\:\\{x\_part\_loc}, \[230], 830, 873, 899, 903, 907, 915, 929, 942, 944, 946,
+947, 948, 956, 957, 959, 967, 970, 973, 977, 978, 982, 984, 1072.
+\:\\{x\_part\_sector}, \[188], 230, 232, 235, 237, 238.
+\:\\{x\_reflect\_edges}, \[337], 964.
+\:\\{x\_scale\_edges}, \[342], 964.
+\:\\{x\_scaled}, \[189], 893, 952, 957.
+\:\9{x\_scaled\_}{\&{xscaled} primitive}, \[893].
+\:\\{xchr}, \[20], 21, 22, 23, 37, 49, 58, 774.
+\:\&{xclause}, 16.
+\:\\{xi\_corr}, 306, \[311], 313, 314, 317.
+\:\\{xl\_packet}, \[553], 559.
+\:\\{xord}, \[20], 23, 30, 52, 53, 778, 780.
+\:\\{xp}, \[511], 515, 516, 521, 522.
+\:\\{xq}, \[410].
+\:\\{xr\_packet}, \[553], 558, 559.
+\:\\{xw}, 362, \[363].
+\:\\{xx}, \[391], 392, \[511], 515, 516, 521, 522.
+\:\\{xx\_part}, \[189], 893, 909.
+\:\9{xx\_part\_}{\&{xxpart} primitive}, \[893].
+\:\\{xx\_part\_loc}, \[230], 233, 956, 957, 958, 959, 967, 970, 973.
+\:\\{xx\_part\_sector}, \[188], 230, 237.
+\:\\{xxx1}, 1144, \[1145], 1160.
+\:\\{xxx2}, \[1144].
+\:\\{xxx3}, 1144, \[1145], 1160.
+\:\\{xxx4}, \[1144].
+\:\\{xx0}, \[311].
+\:\\{xx1}, \[311].
+\:\\{xx2}, \[311].
+\:\\{xx3}, \[311].
+\:\\{xy}, 553, 556, \[557], 558, 559, 560, 561.
+\:\\{xy\_corr}, \[461], 462, 468, 512, 513, 515, 516, 518, 519, 521, 522.
+\:\\{xy\_part}, \[189], 893, 909.
+\:\9{xy\_part\_}{\&{xypart} primitive}, \[893].
+\:\\{xy\_part\_loc}, \[230], 956, 957, 958, 959, 967, 970, 973.
+\:\\{xy\_part\_sector}, \[188], 230, 237.
+\:\\{xy\_round}, 402, \[433].
+\:\\{xy\_swap\_edges}, \[354], 963.
+\:\\{x0}, \[374], 375, 376, \[391], 392, \[495], 496, \[497], 498, 499, 501,
+503, 504, 505, \[510].
+\:\\{x0a}, \[495], 504.
+\:\\{x1}, \[311], 312, 313, 314, 317, 318, \[374], \[391], 392, \[495], 496, %
+\[497], 498, 499, 501, 503, 504, 505, \[510], 541, \[542], 543, 544, 546, 547,
+548, 549.
+\:\\{x1a}, \[495], 503, 504.
+\:\\{x1l}, \[553], 559.
+\:\\{x1r}, \[553], 558, 559.
+\:\\{x2}, \[311], 312, 313, 314, 317, 318, \[391], 392, \[495], 496, \[497],
+498, 499, 501, 503, 504, 505, \[542], 543, 546, 547, 548, 549.
+\:\\{x2a}, \[311], 317, 318, \[495], 503.
+\:\\{x2l}, \[553], 559.
+\:\\{x2r}, \[553], 558, 559.
+\:\\{x3}, \[311], 312, 313, 314, 317, 318, 541, \[542], 543, 546, 547, 548, 549.
+\:\\{x3a}, \[311], 317, 318.
+\:\\{x3l}, \[553], 559.
+\:\\{x3r}, \[553], 558, 559.
+\:\|{y}, \[100], \[104], \[121], \[132], \[135], \[139], \[145], \[151], %
+\[387], \[388], \[390], \[463], \[486], \[488], \[539], \[574], \[868], \[982].
+\:\\{y\_coord}, \[255], 256, 258, 265, 266, 271, 281, 282, 299, 302, 393, 394,
+397, 404, 405, 406, 407, 409, 410, 413, 414, 415, 416, 419, 421, 423, 424, 425,
+435, 437, 439, 444, 445, 447, 451, 457, 467, 468, 472, 473, 474, 475, 476, 477,
+479, 481, 483, 484, 485, 486, 488, 492, 493, 496, 498, 502, 508, 509, 510, 512,
+515, 518, 521, 528, 534, 535, 536, 537, 543, 558, 563, 866, 867, 871, 887, 896,
+962, 980, 981, 986, 987, 1066.
+\:\\{y\_corr}, \[461], 462, 463, 468, 512, 515, 516, 518, 521, 522.
+\:\\{y\_off}, \[332], \[1165], 1166, 1167, 1172.
+\:\\{y\_offset}, \[190], 192, 193, 1165.
+\:\9{y\_offset\_}{\&{yoffset} primitive}, \[192].
+\:\\{y\_packet}, \[553], 556, 559, 560.
+\:\\{y\_part}, \[189], 893, 909.
+\:\9{y\_part\_}{\&{ypart} primitive}, \[893].
+\:\\{y\_part\_loc}, \[230], 830, 873, 899, 903, 907, 915, 929, 942, 944, 946,
+947, 948, 956, 957, 959, 967, 970, 973, 977, 978, 982, 984, 1072.
+\:\\{y\_part\_sector}, \[188], 230, 237.
+\:\\{y\_reflect\_edges}, \[336], 964.
+\:\\{y\_scale\_edges}, \[340], 964.
+\:\\{y\_scaled}, \[189], 893, 952, 957.
+\:\9{y\_scaled\_}{\&{yscaled} primitive}, \[893].
+\:\\{year}, \[190], 192, 193, 194, 790, 1163, 1200.
+\:\9{year\_}{\&{year} primitive}, \[192].
+\:\\{yl\_packet}, \[553], 559.
+\:\.{You have to increase POOLSIZE}, 52.
+\:\.{You want to edit file x}, 79.
+\:\\{yp}, \[511], 515, 516, 521, 522.
+\:\\{yq}, \[410].
+\:\\{yr\_packet}, \[553], 558, 559.
+\:\\{yt}, \[374].
+\:\\{yx\_part}, \[189], 893, 909.
+\:\9{yx\_part\_}{\&{yxpart} primitive}, \[893].
+\:\\{yx\_part\_loc}, \[230], 956, 958, 959, 967, 970, 973.
+\:\\{yx\_part\_sector}, \[188], 230, 237.
+\:\\{yy}, \[511], 515, 516, 521, 522.
+\:\\{yy\_part}, \[189], 893, 909.
+\:\9{yy\_part\_}{\&{yypart} primitive}, \[893].
+\:\\{yy\_part\_loc}, \[230], 233, 956, 957, 958, 959, 967, 970, 973.
+\:\\{yy\_part\_sector}, \[188], 230, 237.
+\:\\{yyy}, 1144, \[1145], 1147, 1166, 1177.
+\:\\{yy0}, \[311].
+\:\\{yy1}, \[311].
+\:\\{yy2}, \[311].
+\:\\{yy3}, \[311].
+\:\\{y0}, \[374], 375, 376, \[495], 496, \[497], 498, 499, 501, 503, 504, 505, %
+\[510].
+\:\\{y0a}, \[495], 504.
+\:\\{y1}, \[311], 312, 313, 314, 317, 318, \[374], 375, 376, \[495], 496, %
+\[497], 498, 499, 501, 503, 504, 505, \[510], 541, \[542], 543, 544, 546, 547,
+548.
+\:\\{y1a}, \[495], 503, 504.
+\:\\{y1l}, \[553], 559.
+\:\\{y1r}, \[553], 558, 559.
+\:\\{y2}, \[311], 312, 313, 314, 317, 318, \[495], 496, \[497], 498, 499, 501,
+503, 504, 505, \[542], 543, 546, 547, 548.
+\:\\{y2a}, \[311], 317, 318, \[495], 503.
+\:\\{y2l}, \[553], 559.
+\:\\{y2r}, \[553], 558, 559.
+\:\\{y3}, \[311], 312, 313, 314, 317, 318, 541, \[542], 543, 546, 547, 548.
+\:\\{y3a}, \[311], 317, 318.
+\:\\{y3l}, \[553], 559.
+\:\\{y3r}, \[553], 558, 559.
+\:\|{z}, \[132], \[135], \[139], \[145].
+\:\\{z\_corr}, \[461], 462, 463.
+\:\\{z\_scaled}, \[189], 893, 952, 957.
+\:\9{z\_scaled\_}{\&{zscaled} primitive}, \[893].
+\:{Zabala Salelles, Ignacio Andres}, 812.
+\:\\{zero\_crossing}, \[391].
+\:\\{zero\_field}, \[326], 328, 329, 332, 336, 337, 340, 342, 352, 364, 365,
+366, 370, 374, 377, 378, 577, 1167, 1172.
+\:\\{zero\_val}, \[175], 1126, 1127.
+\:\\{zero\_w}, \[324], 326, 333, 337, 349, 350, 358, 365, 370, 373, 375, 376,
+381, 382, 383, 384, 582, 1169.
+\fin
+\:\X1060:Abandon edges command because there's no variable\X
+\Us1059, 1070, 1071\ETs1074.
+\:\X703:Absorb delimited parameters, putting them into lists \|q and \|r\X
+\U697.
+\:\X704:Absorb parameter tokens for type \\{base}\X
+\U703.
+\:\X705:Absorb undelimited parameters, putting them into list \|r\X
+\U697.
+\:\X931:Add a known value to the constant term of $\\{dep\_list}(\|p)$\X
+\U930.
+\:\X1010:Add dependency list \\{pp} of type \\{tt} to dependency list~\|p of
+type~\|t\X
+\U1009.
+\:\X382:Add edges for fifth or eighth octants, then \&{goto} \\{done}\X
+\U378.
+\:\X381:Add edges for first or fourth octants, then \&{goto} \\{done}\X
+\U378.
+\:\X383:Add edges for second or third octants, then \&{goto} \\{done}\X
+\U378.
+\:\X384:Add edges for sixth or seventh octants, then \&{goto} \\{done}\X
+\U378.
+\:\X932:Add operand \|p to the dependency list \|v\X
+\U930.
+\:\X929:Add or subtract the current expression from \|p\X
+\U922.
+\:\X370:Add the contribution of node \|q to the total weight, and set $\|q\K%
+\\{link}(\|q)$\X
+\Us369\ET369.
+\:\X933:Add the known $\\{value}(\|p)$ to the constant term of \|v\X
+\U932.
+\:\X1009:Add the right operand to list \|p\X
+\U1006.
+\:\X936, 940, 941, 948, 951, 952, 975, 983, 988:Additional cases of binary
+operators\X
+\U922.
+\:\X905, 906, 907, 909, 912, 915, 917, 918, 920, 921:Additional cases of unary
+operators\X
+\U898.
+\:\X291:Adjust $\theta_n$ to equal $\theta_0$ and \&{goto} \\{found}\X
+\U287.
+\:\X731:Adjust the balance for a delimited argument; \&{goto} \\{done} if done\X
+\U730.
+\:\X732:Adjust the balance for an undelimited argument; \&{goto} \\{done} if
+done\X
+\U730.
+\:\X687:Adjust the balance; \&{goto} \\{done} if it's zero\X
+\U685.
+\:\X575:Adjust the coordinates $(\\{r0},\\{c0})$ and $(\\{r1},\\{c1})$ so that
+they lie in the proper range\X
+\U574.
+\:\X367:Adjust the data of \|h to account for a difference of offsets\X
+\U366.
+\:\X364:Adjust the header to reflect the new edges\X
+\U354.
+\:\X360:Advance pointer \|p to the next vertical edge, after destroying the
+previous one\X
+\U358.
+\:\X359:Advance pointer \|r to the next vertical edge\X
+\U358.
+\:\X560:Advance to the next pair $(\\{cur\_t},\\{cur\_tt})$\X
+\U556.
+\:\X492:Advance \|p to node \|q, removing any ``dead'' cubics that might have
+been introduced by the splitting process\X
+\U491.
+\:\X171:Allocate entire node \|p and \&{goto} \\{found}\X
+\U169.
+\:\X170:Allocate from the top of node \|p and \&{goto} \\{found}\X
+\U169.
+\:\X1002:Announce that the equation cannot be performed\X
+\U1001.
+\:\X728:Append the current expression to \\{arg\_list}\X
+\Us726\ET733.
+\:\X236:Ascend one level, pushing a token onto list \|q and replacing \|p by
+its parent\X
+\U235.
+\:\X999:Assign the current expression to an internal variable\X
+\U996.
+\:\X1000:Assign the current expression to the variable \\{lhs}\X
+\U996.
+\:\X698:Attach the replacement text to the tail of node \|p\X
+\U697.
+\:\X1061:Augment some edges by others\X
+\U1059.
+\:\X662:Back up an outer symbolic token so that it can be reread\X
+\U661.
+\:\X57, 58, 59, 60, 62, 63, 64, 103, 104, 187, 195, 197, 773:Basic printing
+procedures\X
+\U4.
+\:\X530:Calculate integers $\alpha$, $\beta$, $\gamma$ for the vertex
+coordinates\X
+\U528.
+\:\X292:Calculate the given value of $\theta_n$ and \&{goto} \\{found}\X
+\U284.
+\:\X289:Calculate the ratio $\\{ff}=C_k/(C_k+B_k-u_{k-1}A_k)$\X
+\U287.
+\:\X281:Calculate the turning angles $\psi_k$ and the distances $d_{k,k+1}$;
+set $n$ to the length of the path\X
+\U278.
+\:\X288:Calculate the values $\\{aa}=A_k/B_k$, $\\{bb}=D_k/C_k$, $\\{dd}=(3-%
+\alpha_{k-1})d_{k,k+1}$, $\\{ee}=(3-\beta\k)d_{k-1,k}$, and $%
+\\{cc}=(B_k-u_{k-1}A_k)/B_k$\X
+\U287.
+\:\X290:Calculate the values of $v_k$ and $w_k$\X
+\U287.
+\:\X1020, 1023, 1026, 1030, 1033, 1039, 1058, 1069, 1076, 1081, 1100,
+1175:Cases of \\{do\_statement} that invoke particular commands\X
+\U992.
+\:\X212, 684, 689, 696, 710, 741, 894, 1014, 1019, 1025, 1028, 1038, 1043,
+1053, 1080, 1102, 1109, 1180:Cases of \\{print\_cmd\_mod} for symbolic printing
+of primitives\X
+\U625.
+\:\X866:Change node \|q to a path for an elliptical pen\X
+\U865.
+\:\X563:Change one-point paths into dead cycles\X
+\U562.
+\:\X81:Change the interaction level and \&{return}\X
+\U79.
+\:\X1063:Change the tentative pen\X
+\U1062.
+\:\X701:Change to `\.{a bad variable}'\X
+\U700.
+\:\X615:Change variable \|x from \\{independent} to \\{dependent} or \\{known}\X
+\U610.
+\:\X49:Character \|k cannot be printed\X
+\U48.
+\:\X183:Check flags of unavailable nodes\X
+\U180.
+\:\X756:Check for the presence of a colon\X
+\U755.
+\:\X938:Check if unknowns have been equated\X
+\U936.
+\:\X181:Check single-word \\{avail} list\X
+\U180.
+\:\X727:Check that the proper right delimiter was present\X
+\U726.
+\:\X14, 154, 204, 214, 310, 553, 777:Check the ``constant'' values for
+consistency\X
+\U1204.
+\:\X617:Check the list of linear dependencies\X
+\U180.
+\:\X547:Check the places where $B(y_1,y_2,y_3;t)=0$ to see if $B(x_1,x_2,x_3;t)%
+\ge0$\X
+\U546.
+\:\X53:Check the pool check sum\X
+\U52.
+\:\X1056:Check the tentative weight\X
+\U1054.
+\:\X1068:Check the turning number\X
+\U1064.
+\:\X182:Check variable-size \\{avail} list\X
+\U180.
+\:\X815:Choose a dependent variable to take the place of the disappearing
+independent variable, and change all remaining dependencies accordingly\X
+\U812.
+\:\X891:Choose control points for the path and put the result into \\{cur\_exp}%
+\X
+\U869.
+\:\X1201:Close the base file\X
+\U1186.
+\:\X937:Compare the current expression with zero\X
+\U936.
+\:\X1112:Compile a ligature/kern command\X
+\U1107.
+\:\X9:Compiler directives\X
+\U4.
+\:\X478:Complain about a bad pen path\X
+\U477.
+\:\X1105:Complain about a character tag conflict\X
+\U1104.
+\:\X1178:Complain about improper special operation\X
+\U1177.
+\:\X1055:Complain about improper type\X
+\U1054.
+\:\X1067:Complain about non-cycle and \&{goto} \\{not\_found}\X
+\U1064.
+\:\X409:Complement the \|x coordinates of the cubic between \|p and~\|q\X
+\U407.
+\:\X414:Complement the \|y coordinates of the cubic between \\{pp} and~\\{qq}\X
+\Us413\ET417.
+\:\X1064:Complete the contour filling operation\X
+\U1062.
+\:\X537:Complete the ellipse by copying the negative of the half already
+computed\X
+\U527.
+\:\X664:Complete the error message, and set \\{cur\_sym} to a token that might
+help recover from the error\X
+\U663.
+\:\X536:Complete the half ellipse by reflecting the quarter already computed\X
+\U527.
+\:\X503:Complete the offset splitting process\X
+\U494.
+\:\X115:Compute $f=\lfloor 2^{16}(1+p/q)+{1\over2}\rfloor$\X
+\U114.
+\:\X108:Compute $f=\lfloor 2^{28}(1+p/q)+{1\over2}\rfloor$\X
+\U107.
+\:\X113:Compute $p=\lfloor qf/2^{16}+{1\over2}\rfloor-q$\X
+\U112.
+\:\X111:Compute $p=\lfloor qf/2^{28}+{1\over2}\rfloor-q$\X
+\U109.
+\:\X1132:Compute a check sum in $(\\{b1},\\{b2},\\{b3},\\{b4})$\X
+\U1131.
+\:\X443:Compute a compromise \\{pen\_edge}\X
+\U442.
+\:\X442:Compute a good coordinate at a diagonal transition\X
+\U441.
+\:\X435:Compute before-and-after \|x values based on the current pen\X
+\U434.
+\:\X438:Compute before-and-after \|y values based on the current pen\X
+\U437.
+\:\X498:Compute test coefficients $(\\{t0},\\{t1},\\{t2})$ for $s(t)$ versus
+$s_k$ or $s_{k-1}$\X
+\Us497\ET503.
+\:\X533:Compute the distance \|d from class~0 to the edge of the ellipse in
+direction $(\|u,\|v)$, times $\psqrt{u^2+v^2}$, rounded to the nearest integer\X
+\U531.
+\:\X208:Compute the hash code \|h\X
+\U205.
+\:\X457:Compute the incoming and outgoing directions\X
+\U454.
+\:\X1137:Compute the ligature/kern program offset and implant the left boundary
+label\X
+\U1135.
+\:\X365:Compute the magic offset values\X
+\U354.
+\:\X489:Compute the octant code; skew and rotate the coordinates $(\|x,\|y)$\X
+\U488.
+\:\X576:Compute the offsets between screen coordinates and actual coordinates\X
+\U574.
+\:\X11:Constants in the outer block\X
+\U4.
+\:\X980:Construct a path from \\{pp} to \\{qq} of length $\lceil b\rceil$\X
+\U978.
+\:\X981:Construct a path from \\{pp} to \\{qq} of length zero\X
+\U978.
+\:\X481:Construct the offset list for the \|kth octant\X
+\U477.
+\:\X598:Contribute a term from \|p, plus the corresponding term from \|q\X
+\U597.
+\:\X595:Contribute a term from \|p, plus \|f times the corresponding term from %
+\|q\X
+\U594.
+\:\X596:Contribute a term from \|q, multiplied by~\|f\X
+\U594.
+\:\X840:Convert a suffix to a string\X
+\U823.
+\:\X870:Convert the left operand, \|p, into a partial path ending at~\|q; but %
+\&{return} if \|p doesn't have a suitable type\X
+\U869.
+\:\X885:Convert the right operand, \\{cur\_exp}, into a partial path from %
+\\{pp} to~\\{qq}\X
+\U869.
+\:\X146:Convert $(\|x,\|y)$ to the octant determined by~\|q\X
+\U145.
+\:\X335:Copy both \\{sorted} and \\{unsorted} lists of \|p to \\{pp}\X
+\Us334\ET341.
+\:\X857:Copy the big node \|p\X
+\U855.
+\:\X485:Copy the unskewed and unrotated coordinates of node \\{ww}\X
+\U484.
+\:\X418:Correct the octant code in segments with decreasing \|y\X
+\U413.
+\:\X1200:Create the \\{base\_ident}, open the base file, and inform the user
+that dumping has begun\X
+\U1186.
+\:\X349:Cull superfluous edge-weight entries from $\\{sorted}(\|p)$\X
+\U348.
+\:\X1008:Deal with redundant or inconsistent equation\X
+\U1006.
+\:\X454:Decide whether or not to go clockwise\X
+\U452.
+\:\X995, 996, 1015, 1021, 1029, 1031, 1034, 1035, 1036, 1040, 1041, 1044, 1045,
+1046, 1049, 1050, 1051, 1054, 1057, 1059, 1070, 1071, 1072, 1073, 1074, 1082,
+1103, 1104, 1106, 1177, 1186:Declare action procedures for use by \\{do%
+\_statement}\X
+\U989.
+\:\X594, 600, 602, 603, 604:Declare basic dependency-list subroutines\X
+\U246.
+\:\X923, 928, 930, 943, 946, 949, 953, 960, 961, 962, 963, 966, 976, 977, 978,
+982, 984, 985:Declare binary action procedures\X
+\U922.
+\:\X1154, 1155, 1157, 1158, 1159, 1160, 1161, 1163, 1165:Declare generic font
+output procedures\X
+\U989.
+\:\X224:Declare miscellaneous procedures that were declared \\{forward}\X
+\U1202.
+\:\X257, 332, 388, 473, 589, 801, 807:Declare subroutines for printing
+expressions\X
+\U246.
+\:\X968, 971, 972, 974:Declare subroutines needed by \\{big\_trans}\X
+\U966.
+\:\X856, 858:Declare subroutines needed by \\{make\_exp\_copy}\X
+\U855.
+\:\X405, 406, 419, 426, 429, 431, 432, 433, 440, 451:Declare subroutines needed
+by \\{make\_spec}\X
+\U402.
+\:\X493, 497:Declare subroutines needed by \\{offset\_prep}\X
+\U491.
+\:\X296, 299:Declare subroutines needed by \\{solve\_choices}\X
+\U284.
+\:\X823, 860, 862, 864, 868, 892:Declare the basic parsing subroutines\X
+\U1202.
+\:\X779:Declare the function called \\{open\_base\_file}\X
+\U1187.
+\:\X1011:Declare the function called \\{scan\_declared\_variable}\X
+\U697.
+\:\X1098:Declare the function called \\{tfm\_check}\X
+\U1070.
+\:\X486:Declare the function called \\{trivial\_knot}\X
+\U484.
+\:\X1032:Declare the procedure called \\{check\_delimiter}\X
+\U697.
+\:\X935:Declare the procedure called \\{dep\_finish}\X
+\U930.
+\:\X518:Declare the procedure called \\{dual\_moves}\X
+\U506.
+\:\X247:Declare the procedure called \\{flush\_below\_variable}\X
+\U246.
+\:\X808, 820:Declare the procedure called \\{flush\_cur\_exp}\X
+\U246.
+\:\X43:Declare the procedure called \\{flush\_string}\X
+\U73.
+\:\X872:Declare the procedure called \\{known\_pair}\X
+\U871.
+\:\X720:Declare the procedure called \\{macro\_call}\X
+\U706.
+\:\X1001:Declare the procedure called \\{make\_eq}\X
+\U995.
+\:\X855:Declare the procedure called \\{make\_exp\_copy}\X
+\U651.
+\:\X723:Declare the procedure called \\{print\_arg}\X
+\U720.
+\:\X625:Declare the procedure called \\{print\_cmd\_mod}\X
+\U227.
+\:\X805:Declare the procedure called \\{print\_dp}\X
+\U801.
+\:\X722:Declare the procedure called \\{print\_macro\_name}\X
+\U720.
+\:\X333:Declare the procedure called \\{print\_weight}\X
+\U332.
+\:\X665:Declare the procedure called \\{runaway}\X
+\U162.
+\:\X730:Declare the procedure called \\{scan\_text\_arg}\X
+\U720.
+\:\X217:Declare the procedure called \\{show\_token\_list}\X
+\U162.
+\:\X510:Declare the procedure called \\{skew\_line\_edges}\X
+\U506.
+\:\X284:Declare the procedure called \\{solve\_choices}\X
+\U269.
+\:\X410:Declare the procedure called \\{split\_cubic}\X
+\U406.
+\:\X1006:Declare the procedure called \\{try\_eq}\X
+\U995.
+\:\X268, 385, 487, 620, 809:Declare the recycling subroutines\X
+\U246.
+\:\X799, 800:Declare the stashing/unstashing routines\X
+\U801.
+\:\X899, 900, 901, 904, 908, 910, 913, 916, 919:Declare unary action procedures%
+\X
+\U898.
+\:\X743:Decrease the string reference count, if the current token is a string\X
+\Us83, 742, 991\ETs1016.
+\:\X300:Decrease the velocities, if necessary, to stay inside the bounding
+triangle\X
+\U299.
+\:\X123:Decrease \|k by 1, maintaining the invariant relations between \|x, %
+\|y, and~\|q\X
+\U121.
+\:\X670:Decry the invalid character and \&{goto} \\{restart}\X
+\U669.
+\:\X672:Decry the missing string delimiter and \&{goto} \\{restart}\X
+\U671.
+\:\X1113:Define an extensible recipe\X
+\U1106.
+\:\X353:Delete all the row headers\X
+\U352.
+\:\X352:Delete empty rows at the top and/or bottom; update the boundary values
+in the header\X
+\U348.
+\:\X83:Delete $\|c-\.{"0"}$ tokens and \&{goto} \\{continue}\X
+\U79.
+\:\X245:Descend one level for the attribute $\\{info}(\|t)$\X
+\U242.
+\:\X244:Descend one level for the subscript $\\{value}(\|t)$\X
+\U242.
+\:\X1012:Descend past a collective subscript\X
+\U1011.
+\:\X1047:Descend the structure\X
+\U1046.
+\:\X561:Descend to the previous level and \&{goto} \\{not\_found}\X
+\U560.
+\:\X1181:Determine if a character has been shipped out\X
+\U906.
+\:\X445:Determine the before-and-after values of both coordinates\X
+\Us444\ET446.
+\:\X816:Determine the dependency list \|s to substitute for the independent
+variable~\|p\X
+\U815.
+\:\X508:Determine the envelope's starting and ending lattice points $(\\{m0},%
+\\{n0})$ and $(\\{m1},\\{n1})$\X
+\U506.
+\:\X1164:Determine the file extension, \\{gf\_ext}\X
+\U1163.
+\:\X724:Determine the number \|n of arguments already supplied, and set %
+\\{tail} to the tail of \\{arg\_list}\X
+\U720.
+\:\X400:Determine the octant boundary \|q that precedes \|f\X
+\U398.
+\:\X480:Determine the octant code for direction $(\\{dx},\\{dy})$\X
+\U479.
+\:\X874:Determine the path join parameters; but \&{goto} \\{finish\_path} if
+there's only a direction specifier\X
+\U869.
+\:\X467:Determine the starting and ending lattice points $(\\{m0},\\{n0})$ and
+$(\\{m1},\\{n1})$\X
+\U465.
+\:\X881:Determine the tension and/or control points\X
+\U874.
+\:\X979:Dispense with the cases $\|a<0$ and/or $\|b>\|l$\X
+\U978.
+\:\X803:Display a big node\X
+\U802.
+\:\X221:Display a collective subscript\X
+\U218.
+\:\X804:Display a complex type\X
+\U802.
+\:\X220:Display a numeric token\X
+\U219.
+\:\X222:Display a parameter token\X
+\U218.
+\:\X1048:Display a variable macro\X
+\U1046.
+\:\X806:Display a variable that's been declared but not defined\X
+\U802.
+\:\X750:Display the boolean value of \\{cur\_exp}\X
+\U748.
+\:\X636:Display the current context\X
+\U635.
+\:\X613:Display the new dependency\X
+\U610.
+\:\X578:Display the pixels of edge row \|p in screen row \|r\X
+\U577.
+\:\X218:Display token \|p and set \|c to its class; but \&{return} if there are
+problems\X
+\U217.
+\:\X219:Display two-word token\X
+\U218.
+\:\X616:Divide list \|p by $2^n$\X
+\U615.
+\:\X612:Divide list \|p by $-\|v$, removing node \|q\X
+\U610.
+\:\X313:Divide the variables by two, to avoid overflow problems\X
+\U311.
+\:\X992:Do a statement that doesn't begin with an expression\X
+\U989.
+\:\X994:Do a title\X
+\U993.
+\:\X993:Do an equation, assignment, title, or `$\langle\,$expression$\,\rangle%
+\,$\&{endgroup}'\X
+\U989.
+\:\X417:Do any special actions needed when \|y is constant; \&{return} or %
+\&{goto} \\{continue} if a dead cubic from \|p to \|q is removed\X
+\U413.
+\:\X646:Do magic computation\X
+\U217.
+\:\X1005:Do multiple equations and \&{goto} \\{done}\X
+\U1003.
+\:\X1065:Double the path\X
+\U1064.
+\:\X1198:Dump a few more things and the closing check word\X
+\U1186.
+\:\X1190:Dump constants for consistency check\X
+\U1186.
+\:\X1194:Dump the dynamic memory\X
+\U1186.
+\:\X1192:Dump the string pool\X
+\U1186.
+\:\X1196:Dump the table of equivalents and the hash table\X
+\U1186.
+\:\X845:Either begin an unsuffixed macro call or prepare for a suffixed one\X
+\U844.
+\:\X1156:Empty the last bytes out of \\{gf\_buf}\X
+\U1182.
+\:\X969:Ensure that $\\{type}(\|p)=\\{proto\_dependent}$\X
+\U968.
+\:\X73, 76, 77, 88, 89, 90:Error handling procedures\X
+\U4.
+\:\X623:Exclaim about a redundant equation\X
+\Us622, 1004\ETs1008.
+\:\X713:Exit a loop if the proper time has come\X
+\U707.
+\:\X714:Exit prematurely from an iteration\X
+\U713.
+\:\X544:Exit to \\{found} if an eastward direction occurs at knot \|p\X
+\U541.
+\:\X546:Exit to \\{found} if the curve whose derivatives are specified by $%
+\\{x1},\\{x2},\\{x3},\\{y1},\\{y2},\\{y3}$ travels eastward at some time~\\{tt}%
+\X
+\U541.
+\:\X549:Exit to \\{found} if the derivative $B(x_1,x_2,x_3;t)$ becomes $\G0$\X
+\U548.
+\:\X715:Expand the token after the next token\X
+\U707.
+\:\X736:Feed the arguments and replacement text to the scanner\X
+\U720.
+\:\X278:Fill in the control information between consecutive breakpoints \|p and
+\|q\X
+\U273.
+\:\X273:Fill in the control points between \|p and the next breakpoint, then
+advance \|p to that breakpoint\X
+\U269.
+\:\X611:Find a node \|q in list \|p whose coefficient \|v is largest\X
+\U610.
+\:\X850:Find the approximate type \\{tt} and corresponding~\|q\X
+\U844.
+\:\X272:Find the first breakpoint, \|h, on the path; insert an artificial
+breakpoint if the path is an unbroken cycle\X
+\U269.
+\:\X502:Find the index \|k such that $s_{k-1}\L\\{dy}/\\{dx}<s_k$\X
+\U494.
+\:\X501:Find the initial slope, $\\{dy}/\\{dx}$\X
+\U494.
+\:\X1138:Find the minimum \\{lk\_offset} and adjust all remainders\X
+\U1137.
+\:\X399:Find the starting point, \|f\X
+\U398.
+\:\X297:Finish choosing angles and assigning control points\X
+\U284.
+\:\X668:Finish getting the symbolic token in \\{cur\_sym}; \&{goto} \\{restart}
+if it is illegal\X
+\U667.
+\:\X483:Finish linking the offset nodes, and duplicate the borderline offset
+nodes if necessary\X
+\U481.
+\:\X1168:Finish off an entirely blank character\X
+\U1167.
+\:\X1182:Finish the \.{GF} file\X
+\U1206.
+\:\X1206:Finish the \.{TFM} and \.{GF} files\X
+\U1205.
+\:\X1134:Finish the \.{TFM} file\X
+\U1206.
+\:\X459:Fix up the transition fields and adjust the turning number\X
+\U452.
+\:\X1016:Flush spurious symbols after the declared variable\X
+\U1015.
+\:\X991:Flush unparsable junk that was found after the statement\X
+\U989.
+\:\X957:For each of the eight cases, change the relevant fields of \\{cur\_exp}
+and \&{goto} \\{done}; but do nothing if capsule \|p doesn't have the
+appropriate type\X
+\U955.
+\:\X1003:For each type \|t, make an equation and \&{goto} \\{done} unless %
+\\{cur\_type} is incompatible with~\|t\X
+\U1001.
+\:\X678:Get a stored numeric or string or capsule token and \&{return}\X
+\U676.
+\:\X671:Get a string token and \&{return}\X
+\U669.
+\:\X878:Get given directions separated by commas\X
+\U877.
+\:\X886:Get ready to close a cycle\X
+\U869.
+\:\X1062:Get ready to fill a contour, and fill it\X
+\U1059.
+\:\X1211:Get the first line of input and prepare to start\X
+\U1204.
+\:\X674:Get the fraction part \|f of a numeric token\X
+\U669.
+\:\X673:Get the integer part \|n of a numeric token; set $\|f\K0$ and \&{goto} %
+\\{fin\_numeric\_token} if there is no decimal point\X
+\U669.
+\:\X285:Get the linear equations started; or \&{return} with the control points
+in place, if linear equations needn't be solved\X
+\U284.
+\:\X78:Get user's advice and \&{return}\X
+\U77.
+\:\X914:Give error messages if \\{bad\_char} or $\|n\G4096$\X
+\U913.
+\:\X13, 20, 25, 29, 31, 38, 42, 50, 54, 68, 71, 74, 91, 97, 129, 137, 144, 148,
+159, 160, 161, 166, 178, 190, 196, 198, 200, 201, 225, 230, 250, 267, 279, 283,
+298, 308, 309, 327, 371, 379, 389, 395, 403, 427, 430, 448, 455, 461, 464, 507,
+552, 555, 557, 566, 569, 572, 579, 585, 592, 624, 628, 631, 633, 634, 659, 680,
+699, 738, 752, 767, 768, 775, 782, 785, 791, 796, 813, 821, 954, 1077, 1084,
+1087, 1096, 1119, 1125, 1130, 1149, 1152, 1162, 1183, 1188, 1203:Global
+variables\X
+\U4.
+\:\X168:Grow more variable-size memory and \&{goto} \\{restart}\X
+\U167.
+\:\X128:Handle erroneous \\{pyth\_sub} and set $\|a\K0$\X
+\U126.
+\:\X134:Handle non-positive logarithm\X
+\U132.
+\:\X690:Handle quoted symbols, \.{\#\AT!}, \.{\AT!}, or \.{\AT!\#}\X
+\U685.
+\:\X122:Handle square root of zero or negative argument\X
+\U121.
+\:\X505:Handle the special case of infinite slope\X
+\U494.
+\:\X548:Handle the test for eastward directions when $y_1y_3=y_2^2$; either %
+\&{goto} \\{found} or \&{goto} \\{done}\X
+\U546.
+\:\X140:Handle undefined arg\X
+\U139.
+\:\X852:Handle unusual cases that masquerade as variables, and \&{goto} %
+\\{restart} or \&{goto} \\{done} if appropriate; otherwise make a copy of the
+variable and \&{goto} \\{done}\X
+\U844.
+\:\X271:If consecutive knots are equal, join them explicitly\X
+\U269.
+\:\X441:If node \|q is a transition point between octants, compute and save its
+before-and-after coordinates\X
+\U440.
+\:\X434:If node \|q is a transition point for \|x coordinates, compute and save
+its before-and-after coordinates\X
+\U433.
+\:\X437:If node \|q is a transition point for \|y coordinates, compute and save
+its before-and-after coordinates\X
+\U433.
+\:\X956:If the current transform is entirely known, stash it in global
+variables; otherwise \&{return}\X
+\U953.
+\:\X322:Increase and decrease $\\{move}[\|k-1]$ and $\\{move}[\|k]$ by $%
+\delta_k$\X
+\U321.
+\:\X133:Increase \|k until \|x can be multiplied by a factor of $2^{-k}$, and
+adjust $y$ accordingly\X
+\U132.
+\:\X143:Increase \|z to the arg of $(x,y)$\X
+\U142.
+\:\X519:Initialize for dual envelope moves\X
+\U518.
+\:\X558:Initialize for intersections at level zero\X
+\U556.
+\:\X513:Initialize for ordinary envelope moves\X
+\U512.
+\:\X581:Initialize for the display computations\X
+\U577.
+\:\X176, 193, 203, 229, 324, 475, 587, 702, 759, 911, 1116, 1127,
+1185:Initialize table entries (done by \.{INIMF} only)\X
+\U1210.
+\:\X356:Initialize the array of new edge list heads\X
+\U354.
+\:\X528:Initialize the ellipse data structure by beginning with directions
+$(0,-1)$, $(1,0)$, $(0,1)$\X
+\U527.
+\:\X657, 660:Initialize the input routines\X
+\U1211.
+\:\X55, 61, 783, 792:Initialize the output routines\X
+\U1204.
+\:\X70:Initialize the print \\{selector} based on \\{interaction}\X
+\Us1023\ET1211.
+\:\X1022:Initialize the random seed to \\{cur\_exp}\X
+\U1021.
+\:\X711:Initiate or terminate input from a file\X
+\U707.
+\:\X669:Input from external file; \&{goto} \\{restart} if no input found, or %
+\&{return} if a non-symbolic token is found\X
+\U667.
+\:\X676:Input from token list; \&{goto} \\{restart} if end of list or if a
+parameter needs to be expanded, or \&{return} if a non-symbolic token is found\X
+\U667.
+\:\X986:Insert a fractional node by splitting the cubic\X
+\U985.
+\:\X521:Insert a line segment dually to approach the correct offset\X
+\U518.
+\:\X515:Insert a line segment to approach the correct offset\X
+\U512.
+\:\X535:Insert a new line for direction $(\|u,\|v)$ between \|p and~\|q\X
+\U531.
+\:\X207:Insert a new symbolic token after \|p, then make \|p point to it and %
+\&{goto} \\{found}\X
+\U205.
+\:\X677:Insert a suffix or text parameter and \&{goto} \\{restart}\X
+\U676.
+\:\X458:Insert additional boundary nodes, then \&{goto} \\{done}\X
+\U452.
+\:\X350:Insert an edge-weight for edge \|m, if the new pixel weight has changed%
+\X
+\U349.
+\:\X355:Insert blank rows at the top and bottom, and set \|p to the new top row%
+\X
+\U354.
+\:\X376:Insert downward edges for a line\X
+\U374.
+\:\X330:Insert exactly $\\{n\_min}(\\{cur\_edges})-\\{nl}$ empty rows at the
+bottom\X
+\U329.
+\:\X331:Insert exactly $\\{nr}-\\{n\_max}(\\{cur\_edges})$ empty rows at the
+top\X
+\U329.
+\:\X362:Insert horizontal edges of weight \|w between \|m and~\\{mm}\X
+\U358.
+\:\X450:Insert octant boundaries and compute the turning number\X
+\U402.
+\:\X452:Insert one or more octant boundary nodes just before~\|q\X
+\U450.
+\:\X358:Insert the horizontal edges defined by adjacent rows $\|p,\|q$, and
+destroy row~\|p\X
+\U354.
+\:\X523:Insert the new envelope moves dually in the pixel data\X
+\U518.
+\:\X517:Insert the new envelope moves in the pixel data\X
+\U512.
+\:\X375:Insert upward edges for a line\X
+\U374.
+\:\X959:Install a complex multiplier, then \&{goto} \\{done}\X
+\U957.
+\:\X958:Install sines and cosines, then \&{goto} \\{done}\X
+\U957.
+\:\X531:Interpolate new vertices in the ellipse data structure until
+improvement is impossible\X
+\U527.
+\:\X79:Interpret code \|c and \&{return} if done\X
+\U78.
+\:\X82:Introduce new material from the terminal and \&{return}\X
+\U79.
+\:\X887:Join the partial paths and reset \|p and \|q to the head and tail of
+the result\X
+\U869.
+\:\X6:Labels in the outer block\X
+\U4.
+\:\X1205, 1209, 1210, 1212:Last-minute procedures\X
+\U1202.
+\:\X241:Link a new attribute node \|r in place of node \|p\X
+\U239.
+\:\X240:Link a new subscript node \|r in place of node \|p\X
+\U239.
+\:\X482:Link node \|r to the previous node\X
+\U481.
+\:\X641:Local variables for formatting calculations\X
+\U635.
+\:\X19, 130:Local variables for initialization\X
+\U4.
+\:\X1141:Log the subfile sizes of the \.{TFM} file\X
+\U1134.
+\:\X896:Make a special knot node for \&{pencircle}\X
+\U895.
+\:\X1066:Make a trivial one-point path cycle\X
+\U1065.
+\:\X314:Make moves for current subinterval; if bisection is necessary, push the
+second subinterval onto the stack, and \&{goto} \\{continue} in order to handle
+the first subinterval\X
+\U311.
+\:\X317:Make one move of each kind\X
+\U314.
+\:\X446:Make sure that all the diagonal roundings are safe\X
+\U444.
+\:\X243:Make sure that both nodes \|p and \\{pp} are of \\{structured} type\X
+\U242.
+\:\X873:Make sure that both \|x and \|y parts of \|p are known; copy them into %
+\\{cur\_x} and \\{cur\_y}\X
+\U872.
+\:\X883:Make sure that the current expression is a valid tension setting\X
+\Us882\ET882.
+\:\X1207:Make the dynamic memory into one big available node\X
+\U1206.
+\:\X512:Make the envelope moves for the current octant and insert them in the
+pixel data\X
+\U506.
+\:\X48:Make the first 256 strings\X
+\U47.
+\:\X468:Make the moves for the current octant\X
+\U465.
+\:\X586:Make variable $\|q+\|s$ newly independent\X
+\U232.
+\:\X1126:Massage the \.{TFM} heights, depths, and italic corrections\X
+\U1206.
+\:\X1124:Massage the \.{TFM} widths\X
+\U1206.
+\:\X368:Merge row \\{pp} into row \|p\X
+\U366.
+\:\X347:Merge the \\{temp\_head} list into $\\{sorted}(\|h)$\X
+\U346.
+\:\X319:Move right then up\X
+\Us317\ET317.
+\:\X947:Move the dependent variable \|p into both parts of the pair node \|r\X
+\U946.
+\:\X679:Move to next line of file, or \&{goto} \\{restart} if there is no next
+line\X
+\U669.
+\:\X377:Move to row \\{n0}, pointed to by \|p\X
+\Us375, 376, 381, 382, 383\ETs384.
+\:\X532:Move to the next remaining triple $(\|p,\|q,\|r)$, removing and
+skipping past zero-length lines that might be present; \&{goto} \\{done} if all
+triples have been processed\X
+\U531.
+\:\X316:Move to the right \|m steps\X
+\U314.
+\:\X320:Move up then right\X
+\Us317\ET317.
+\:\X315:Move upward \|n steps\X
+\U314.
+\:\X942:Multiply when at least one operand is known\X
+\U941.
+\:\X136:Multiply \|y by $\exp(-z/2^{27})$\X
+\U135.
+\:\X903:Negate the current expression\X
+\U898.
+\:\X540:Normalize the given direction for better accuracy; but \&{return} with
+zero result if it's zero\X
+\U539.
+\:\X1213:Numbered cases for \\{debug\_help}\X
+\U1212.
+\:\X580:Other local variables for \\{disp\_edges}\X
+\U577.
+\:\X511:Other local variables for \\{fill\_envelope}\X
+\Us506\ET518.
+\:\X542:Other local variables for \\{find\_direction\_time}\X
+\U539.
+\:\X280:Other local variables for \\{make\_choices}\X
+\U269.
+\:\X453:Other local variables for \\{make\_spec}\X
+\U402.
+\:\X495:Other local variables for \\{offset\_prep}\X
+\U491.
+\:\X831, 836, 843:Other local variables for \\{scan\_primary}\X
+\U823.
+\:\X286:Other local variables for \\{solve\_choices}\X
+\U284.
+\:\X357, 363:Other local variables for \\{xy\_swap\_edges}\X
+\U354.
+\:\X1208:Output statistics about this job\X
+\U1205.
+\:\X934:Output the answer, \|v (which might have become \\{known})\X
+\U932.
+\:\X1136:Output the character information bytes, then output the dimensions
+themselves\X
+\U1134.
+\:\X1167:Output the character represented in \\{cur\_edges}\X
+\U1165.
+\:\X1140:Output the extensible character recipes and the font metric parameters%
+\X
+\U1134.
+\:\X1139:Output the ligature/kern program\X
+\U1134.
+\:\X1169:Output the pixels of edge row \|p to font row \|n\X
+\U1167.
+\:\X1135:Output the subfile sizes and header bytes\X
+\U1134.
+\:\X675:Pack the numeric and fraction parts of a numeric token and \&{return}\X
+\U669.
+\:\X889:Plug an opening in $\\{right\_type}(\\{pp})$, if possible\X
+\U887.
+\:\X888:Plug an opening in $\\{right\_type}(\|q)$, if possible\X
+\U887.
+\:\X745:Pop the condition stack\X
+\Us748, 749\ETs751.
+\:\X237:Preface the output with a part specifier; \&{return} in the case of a
+capsule\X
+\U235.
+\:\X380:Prepare for and switch to the appropriate case, based on \\{octant}\X
+\U378.
+\:\X496:Prepare for derivative computations; \&{goto} \\{not\_found} if the
+current cubic is dead\X
+\U494.
+\:\X765:Prepare for step-until construction and \&{goto} \\{done}\X
+\U764.
+\:\X717:Pretend we're reading a new one-line file\X
+\U716.
+\:\X509:Print a line of diagnostic info to introduce this octant\X
+\U508.
+\:\X802:Print an abbreviated value of \|v with format depending on \|t\X
+\U801.
+\:\X261:Print control points between \|p and \|q, then \&{goto} \\{done1}\X
+\U258.
+\:\X263:Print information for a curve that begins \\{curl} or \\{given}\X
+\U258.
+\:\X262:Print information for a curve that begins \\{open}\X
+\U258.
+\:\X258:Print information for adjacent knots \|p and \|q\X
+\U257.
+\:\X637:Print location of current line\X
+\U636.
+\:\X184:Print newly busy locations\X
+\U180.
+\:\X1086:Print string \\{cur\_exp} as an error message\X
+\U1082.
+\:\X223:Print string \|r as a symbolic token and set \|c to its class\X
+\U218.
+\:\X260:Print tension between \|p and \|q\X
+\U258.
+\:\X790:Print the banner line, including the date and time\X
+\U788.
+\:\X590:Print the coefficient, unless it's $\pm1.0$\X
+\U589.
+\:\X397:Print the cubic between \|p and \|q\X
+\U394.
+\:\X639:Print the current loop value\X
+\U638.
+\:\X84:Print the help information and \&{goto} \\{continue}\X
+\U79.
+\:\X80:Print the menu of available options\X
+\U79.
+\:\X640:Print the name of a \&{vardef}'d macro\X
+\U638.
+\:\X85:Print the string \\{err\_help}, possibly on several lines\X
+\Us84\ET86.
+\:\X401:Print the turns, if any, that start at \|q, and advance \|q\X
+\Us398\ET398.
+\:\X474:Print the unskewed and unrotated coordinates of node \\{ww}\X
+\U473.
+\:\X259:Print two dots, followed by \\{given} or \\{curl} if present\X
+\U257.
+\:\X643:Print two lines using the tricky pseudoprinted information\X
+\U636.
+\:\X638:Print type of token list\X
+\U636.
+\:\X1110:Process a \\{skip\_to} command and \&{goto} \\{done}\X
+\U1107.
+\:\X838:Protest division by zero\X
+\U837.
+\:\X644:Pseudoprint the line\X
+\U636.
+\:\X645:Pseudoprint the token list\X
+\U636.
+\:\X744:Push the condition stack\X
+\U748.
+\:\X716:Put a string into the input buffer\X
+\U707.
+\:\X192, 211, 683, 688, 695, 709, 740, 893, 1013, 1018, 1024, 1027, 1037, 1052,
+1079, 1101, 1108, 1176:Put each of \MF's primitives into the hash table\X
+\U1210.
+\:\X86:Put help message on the transcript file\X
+\U77.
+\:\X955:Put the current transform into \\{cur\_exp}\X
+\U953.
+\:\X795:Put the desired file name in $(\\{cur\_name},\\{cur\_ext},\\{cur%
+\_area})$\X
+\U793.
+\:\X847:Put the left bracket and the expression back to be rescanned\X
+\Us846\ET859.
+\:\X345:Put the list $\\{sorted}(\|p)$ back into sort\X
+\U344.
+\:\X880:Put the post-join direction information into \|x and \|t\X
+\U874.
+\:\X879:Put the pre-join direction information into node \|q\X
+\U874.
+\:\X897:Read a string from the terminal\X
+\U895.
+\:\X681:Read next line of file into \\{buffer}, or \&{goto} \\{restart} if the
+file has ended\X
+\U679.
+\:\X52:Read one string, but return \\{false} if the string memory space is
+getting too tight for comfort\X
+\U51.
+\:\X794:Read the first line of the new file\X
+\U793.
+\:\X51:Read the other strings from the \.{MF.POOL} file and return \\{true}, or
+give an error message and return \\{false}\X
+\U47.
+\:\X1111:Record a label in a lig/kern subprogram and \&{goto} \\{continue}\X
+\U1107.
+\:\X522:Record a line segment from $(\\{xx},\\{yy})$ to $(\\{xp},\\{yp})$
+dually in \\{env\_move}\X
+\U521.
+\:\X516:Record a line segment from $(\\{xx},\\{yy})$ to $(\\{xp},\\{yp})$ in %
+\\{env\_move}\X
+\U515.
+\:\X814:Record a new maximum coefficient of type \|t\X
+\U812.
+\:\X583:Record a possible transition in column \|m\X
+\U582.
+\:\X810:Recycle a big node\X
+\U809.
+\:\X811:Recycle a dependency list\X
+\U809.
+\:\X812:Recycle an independent variable\X
+\U809.
+\:\X925:Recycle any sidestepped \\{independent} capsules\X
+\U922.
+\:\X939:Reduce comparison of big nodes to comparison of scalars\X
+\U936.
+\:\X302:Reduce to simple case of straight line and \&{return}\X
+\U285.
+\:\X301:Reduce to simple case of two givens and \&{return}\X
+\U285.
+\:\X118:Reduce to the case that $\|a,\|c\G0$, $\|b,\|d>0$\X
+\U117.
+\:\X110:Reduce to the case that $\|f\G0$ and $\|q>0$\X
+\Us109\ET112.
+\:\X339:Reflect the edge-and-weight data in $\\{sorted}(\|p)$\X
+\U337.
+\:\X338:Reflect the edge-and-weight data in $\\{unsorted}(\|p)$\X
+\U337.
+\:\X312:Remove a subproblem for \\{make\_moves} from the stack\X
+\U311.
+\:\X447:Remove dead cubics\X
+\U402.
+\:\X1007:Remove the left operand from its container, negate it, and put it into
+dependency list~\|p with constant term~\|q\X
+\U1006.
+\:\X534:Remove the line from \|p to \|q, and adjust vertex~\|q to introduce a
+new line\X
+\U531.
+\:\X282:Remove \\{open} types at the breakpoints\X
+\U278.
+\:\X712:Repeat a loop\X
+\U707.
+\:\X1122:Replace an interval of values by its midpoint\X
+\U1121.
+\:\X125:Replace \|a by an approximation to $\psqrt{a^2+b^2}$\X
+\U124.
+\:\X127:Replace \|a by an approximation to $\psqrt{a^2-b^2}$\X
+\U126.
+\:\X341:Replicate every row exactly $s$ times\X
+\U340.
+\:\X270:Report an unexpected problem during the choice-making\X
+\U269.
+\:\X34:Report overflow of the input buffer, and abort\X
+\U30.
+\:\X1004:Report redundant or inconsistent equation and \&{goto} \\{done}\X
+\U1003.
+\:\X141:Return an appropriate answer based on \|z and \\{octant}\X
+\U139.
+\:\X529:Revise the values of $\alpha$, $\beta$, $\gamma$, if necessary, so that
+degenerate lines of length zero will not be obtained\X
+\U528.
+\:\X541:Rotate the cubic between \|p and \|q; then \&{goto} \\{found} if the
+rotated cubic travels due east at some time \\{tt}; but \&{goto} \\{not\_found}
+if an entire cyclic path has been traversed\X
+\U539.
+\:\X605:Run through the dependency list for variable \|t, fixing all nodes, and
+ending with final link~\|q\X
+\U604.
+\:\X1083:Save string \\{cur\_exp} as the \\{err\_help}\X
+\U1082.
+\:\X343:Scale the $x$~coordinates of each row by $s$\X
+\U342.
+\:\X964:Scale the edges, shift them, and \&{return}\X
+\U963.
+\:\X408:Scale up \\{del1}, \\{del2}, and \\{del3} for greater accuracy; also
+set \\{del} to the first nonzero element of $(\\{del1},\\{del2},\\{del3})$\X
+\Us407, 413\ETs420.
+\:\X839:Scan a binary operation with `\&{of}' between its operands\X
+\U823.
+\:\X861:Scan a bracketed subscript and set $\\{cur\_cmd}\K\\{numeric\_token}$\X
+\U860.
+\:\X876:Scan a curl specification\X
+\U875.
+\:\X826:Scan a delimited primary\X
+\U823.
+\:\X877:Scan a given direction\X
+\U875.
+\:\X832:Scan a grouped primary\X
+\U823.
+\:\X859:Scan a mediation construction\X
+\U823.
+\:\X834:Scan a nullary operation\X
+\U823.
+\:\X869:Scan a path construction operation; but \&{return} if \|p has the wrong
+type\X
+\U868.
+\:\X837:Scan a primary that starts with a numeric token\X
+\U823.
+\:\X833:Scan a string constant\X
+\U823.
+\:\X735:Scan a suffix with optional delimiters\X
+\U733.
+\:\X835:Scan a unary operation\X
+\U823.
+\:\X844:Scan a variable primary; \&{goto} \\{restart} if it turns out to be a
+macro\X
+\U823.
+\:\X734:Scan an expression followed by `\&{of} $\langle$primary$\rangle$'\X
+\U733.
+\:\X841:Scan an internal numeric quantity\X
+\U823.
+\:\X787:Scan file name in the buffer\X
+\U786.
+\:\X846:Scan for a subscript; replace \\{cur\_cmd} by \\{numeric\_token} if
+found\X
+\U844.
+\:\X729:Scan the argument represented by $\\{info}(\|r)$\X
+\U726.
+\:\X726:Scan the delimited argument represented by $\\{info}(\|r)$\X
+\U725.
+\:\X758:Scan the loop text and put it on the loop control stack\X
+\U755.
+\:\X725:Scan the remaining arguments, if any; set \|r to the first token of the
+replacement text\X
+\U720.
+\:\X830:Scan the second of a pair of numerics\X
+\U826.
+\:\X700:Scan the token or variable to be defined; set \|n, \\{scanner\_status},
+and \\{warning\_info}\X
+\U697.
+\:\X764:Scan the values to be used in the loop\X
+\U755.
+\:\X733:Scan undelimited argument(s)\X
+\U725.
+\:\X708:Scold the user for having an extra \&{endfor}\X
+\U707.
+\:\X209:Search \\{eqtb} for equivalents equal to \|p\X
+\U185.
+\:\X1166:Send nonzero offsets to the output file\X
+\U1165.
+\:\X1179:Send the current expression as a title to the output file\X
+\U994.
+\:\X884:Set explicit control points\X
+\U881.
+\:\X882:Set explicit tensions\X
+\U881.
+\:\X21, 22, 23, 69, 72, 75, 92, 98, 131, 138, 179, 191, 199, 202, 231, 251,
+396, 428, 449, 456, 462, 570, 573, 593, 739, 753, 776, 797, 822, 1078, 1085,
+1097, 1150, 1153, 1184:Set initial values of key variables\X
+\U4.
+\:\X543:Set local variables $\\{x1},\\{x2},\\{x3}$ and $\\{y1},\\{y2},\\{y3}$
+to multiples of the control points of the rotated derivatives\X
+\U541.
+\:\X987:Set the current expression to the desired path coordinates\X
+\U985.
+\:\X295:Set up equation for a curl at $\theta_n$ and \&{goto} \\{found}\X
+\U284.
+\:\X287:Set up equation to match mock curvatures at $z_k$; then \&{goto} %
+\\{found} with $\theta_n$ adjusted to equal $\theta_0$, if a cycle has ended\X
+\U284.
+\:\X854:Set up suffixed macro call and \&{goto} \\{restart}\X
+\U852.
+\:\X1075:Set up the culling weights, or \&{goto} \\{not\_found} if the
+thresholds are bad\X
+\U1074.
+\:\X294:Set up the equation for a curl at $\theta_0$\X
+\U285.
+\:\X293:Set up the equation for a given value of $\theta_0$\X
+\U285.
+\:\X582:Set up the parameters needed for \\{paint\_row}; but \&{goto} \\{done}
+if no painting is needed after all\X
+\U578.
+\:\X421:Set up the variables $(\\{del1},\\{del2},\\{del3})$ to represent
+$x'-y'$\X
+\U420.
+\:\X853:Set up unsuffixed macro call and \&{goto} \\{restart}\X
+\U845.
+\:\X466:Set variable \|q to the node at the end of the current octant\X
+\Us465, 506\ETs506.
+\:\X142:Set variable \|z to the arg of $(x,y)$\X
+\U139.
+\:\X867:Shift the coordinates of path \|q\X
+\U866.
+\:\X965:Shift the edges by $(\\{tx},\\{ty})$, rounded\X
+\U964.
+\:\X1042:Show a numeric or string or capsule token\X
+\U1041.
+\:\X721:Show the text of the macro being expanded, and the existing arguments\X
+\U720.
+\:\X817:Show the transformed dependency\X
+\U816.
+\:\X926:Sidestep \\{independent} cases in capsule \|p\X
+\U922.
+\:\X927:Sidestep \\{independent} cases in the current expression\X
+\U922.
+\:\X614:Simplify all existing dependencies by substituting for \|x\X
+\U610.
+\:\X1174:Skip down $\\{prev\_n}-\|n$ rows\X
+\U1172.
+\:\X749:Skip to \&{elseif} or \&{else} or \&{fi}, then \&{goto} \\{done}\X
+\U748.
+\:\X1173:Skip to column $m$ in the next row and \&{goto} \\{done}, or skip zero
+rows\X
+\U1172.
+\:\X174:Sort \|p into the list starting at \\{rover} and advance \|p to $%
+\\{rlink}(\|p)$\X
+\U173.
+\:\X890:Splice independent paths together\X
+\U887.
+\:\X504:Split off another \\{rising} cubic for \\{fin\_offset\_prep}\X
+\U503.
+\:\X499:Split the cubic at $t$, and split off another cubic if the derivative
+crosses back\X
+\U497.
+\:\X494:Split the cubic between \|p and \|q, if necessary, into cubics
+associated with single offsets, after which \|q should point to the end of the
+final such cubic\X
+\U491.
+\:\X950:Squeal about division by zero\X
+\U948.
+\:\X479:Stamp all nodes with an octant code, compute the maximum offset, and
+set \\{hh} to the node that begins the first octant; \&{goto} \\{not\_found} if
+there's a problem\X
+\U477.
+\:\X1172:Start a new row at $(m,n)$\X
+\U1170.
+\:\X1170:Start black at $(m,n)$\X
+\U1169.
+\:\X829:Stash an independent \\{cur\_exp} into a big node\X
+\U827.
+\:\X1171:Stop black at $(m,n)$\X
+\U1169.
+\:\X1115:Store a list of font dimensions\X
+\U1106.
+\:\X1114:Store a list of header bytes\X
+\U1106.
+\:\X1107:Store a list of ligature/kern steps\X
+\U1106.
+\:\X1099:Store the width information for character code~\|c\X
+\U1070.
+\:\X413:Subdivide all cubics between \|p and \|q so that the results travel
+toward the first quadrant; but \&{return} or \&{goto} \\{continue} if the cubic
+from \|p to \|q was dead\X
+\U406.
+\:\X559:Subdivide for a new level of intersection\X
+\U556.
+\:\X412:Subdivide the cubic a second time with respect to $x'$\X
+\U411.
+\:\X425:Subdivide the cubic a second time with respect to $x'-y'$\X
+\U424.
+\:\X416:Subdivide the cubic a second time with respect to $y'$\X
+\U415.
+\:\X420:Subdivide the cubic between \|p and \|q so that the results travel
+toward the first octant\X
+\U419.
+\:\X407:Subdivide the cubic between \|p and \|q so that the results travel
+toward the right halfplane\X
+\U406.
+\:\X411:Subdivide the cubic with respect to $x'$, possibly twice\X
+\U407.
+\:\X424:Subdivide the cubic with respect to $x'-y'$, possibly twice\X
+\U420.
+\:\X415:Subdivide the cubic with respect to $y'$, possibly twice\X
+\U413.
+\:\X686:Substitute for \\{cur\_sym}, if it's on the \\{subst\_list}\X
+\U685.
+\:\X818:Substitute new dependencies in place of \|p\X
+\U815.
+\:\X819:Substitute new proto-dependencies in place of \|p\X
+\U815.
+\:\X147:Subtract angle \|z from $(\|x,\|y)$\X
+\U145.
+\:\X825:Supply diagnostic information, if requested\X
+\U823.
+\:\X423:Swap the \|x and \|y coordinates of the cubic between \|p and~\|q\X
+\U420.
+\:\X318:Switch to the right subinterval\X
+\U317.
+\:\X663:Tell the user what has run away and try to recover\X
+\U661.
+\:\X751:Terminate the current conditional and skip to \&{fi}\X
+\U707.
+\:\X761:The arithmetic progression has ended\X
+\U760.
+\:\X998:Trace the current assignment\X
+\U996.
+\:\X924:Trace the current binary operation\X
+\U922.
+\:\X997:Trace the current equation\X
+\U995.
+\:\X902:Trace the current unary operation\X
+\U898.
+\:\X945:Trace the fraction multiplication\X
+\U944.
+\:\X762:Trace the start of a loop\X
+\U760.
+\:\X520:Transfer moves dually from the \\{move} array to \\{env\_move}\X
+\U518.
+\:\X514:Transfer moves from the \\{move} array to \\{env\_move}\X
+\U512.
+\:\X970:Transform a known big node\X
+\U966.
+\:\X967:Transform an unknown big node and \&{return}\X
+\U966.
+\:\X973:Transform known by known\X
+\U970.
+\:\X444:Transform the skewed coordinates\X
+\U440.
+\:\X436:Transform the \|x coordinates\X
+\U433.
+\:\X439:Transform the \|y coordinates\X
+\U433.
+\:\X206:Treat special case of length 1 and \&{goto} \\{found}\X
+\U205.
+\:\X404:Truncate the values of all coordinates that exceed \\{max\_allowed},
+and stamp segment numbers in each \\{left\_type} field\X
+\U402.
+\:\X169:Try to allocate within node \|p and its physical successors, and %
+\&{goto} \\{found} if allocation was possible\X
+\U167.
+\:\X789:Try to get a different log file name\X
+\U788.
+\:\X18, 24, 37, 101, 105, 106, 156, 186, 565, 571, 627, 1151:Types in the outer
+block\X
+\U4.
+\:\X1199:Undump a few more things and the closing check word\X
+\U1187.
+\:\X1191:Undump constants for consistency check\X
+\U1187.
+\:\X1195:Undump the dynamic memory\X
+\U1187.
+\:\X1193:Undump the string pool\X
+\U1187.
+\:\X1197:Undump the table of equivalents and the hash table\X
+\U1187.
+\:\X351:Update the max/min amounts\X
+\U349.
+\:\X392:Use bisection to find the crossing point, if one exists\X
+\U391.
+\:\X584:Wind up the \\{paint\_row} parameter calculation by inserting the final
+transition; \&{goto} \\{done} if no painting is needed\X
+\U582.
+\:\X990:Worry about bad statement\X
+\U989.
+\con