From 7ee8ebab3c9490f7f4f642727bc9cb8bb29fcd59 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 8 Mar 2021 19:20:28 +0000 Subject: add knuthian glue.web and webman.tex here, for lack of a better idea git-svn-id: svn://tug.org/texlive/trunk@58229 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/ChangeLog | 6 + Build/source/texk/web2c/doc/glue.web | 421 ++++++++ Build/source/texk/web2c/doc/webman.tex | 1674 ++++++++++++++++++++++++++++++++ 3 files changed, 2101 insertions(+) create mode 100644 Build/source/texk/web2c/doc/glue.web create mode 100644 Build/source/texk/web2c/doc/webman.tex (limited to 'Build/source/texk') diff --git a/Build/source/texk/web2c/ChangeLog b/Build/source/texk/web2c/ChangeLog index cd667d3f500..ea9e3ba78b5 100644 --- a/Build/source/texk/web2c/ChangeLog +++ b/Build/source/texk/web2c/ChangeLog @@ -1,3 +1,9 @@ +2021-03-08 Karl Berry + + * doc/glue.web, + * doc/webman.tex: add these Knuth files here, since nowhere + else seems better. PDF output for them is in the knuth page. + 2021-02-25 Andreas Scherer * ctangleboot.cin, diff --git a/Build/source/texk/web2c/doc/glue.web b/Build/source/texk/web2c/doc/glue.web new file mode 100644 index 00000000000..add1903b506 --- /dev/null +++ b/Build/source/texk/web2c/doc/glue.web @@ -0,0 +1,421 @@ +% This program by D. E. Knuth is not copyrighted and can be used freely. +% It was written on 18 Dec 1981 and revised on 24 May 1991. + +% Here is TeX material that gets inserted after \input webmac +\def\PASCAL{Pascal} +\font\eightrm=cmr8 + +\def\title{GLUE} +\def\topofcontents{\null + \titlefalse % include headline on the contents page + \def\rheader{\mainfont\hfil \contentspagenumber} + \vfill + \centerline{\titlefont Fixed-Point Glue Setting} + \vfill} +\def\botofcontents{\vfill + \centerline{\hsize 6in\baselineskip9pt + \vbox{\eightrm\baselineskip9pt\noindent + The preparation of this report + was supported in part by the National Science + Foundation under grants IST-7921977 and MCS-7723728; + by Office of Naval Research grant N00014-81-K-0330; + and by the IBM Corporation. `\TeX' is a + trademark of the American Mathematical Society.}}} + +@* Introduction. +If \TeX\ is being implemented on a microcomputer that does 32-bit +addition and subtraction, but with multiplication and division restricted to +multipliers and divisors that are either powers of~2 or positive +integers less than~$2^{15}$, it can still do the computations associated +with the setting of glue in a suitable way. This program illustrates one +solution to the problem. + +Another purpose of this program is to provide the first ``short'' example +of the use of \.{WEB}. + +@ The program itself is written in standard \PASCAL. It begins with a +normal program header, most of which will be filled in with other parts of this +``web'' as we are ready to introduce them. +@^program header@> + +@p program GLUE(@!input,@!output); + type @@; + var @@; + procedure initialize; {this procedure gets things started} + var @@; + begin @; + end; + +@ Here are two macros for common programming idioms. + +@d incr(#) == #:=#+1 {increase a variable by unity} +@d decr(#) == #:=#-1 {decrease a variable by unity} + +@* The problem and a solution. +We are concerned here with the ``setting of glue'' that occurs when a +\TeX\ box is being packaged. Let $x_1$, \dots,~$x_n$ be integers whose sum +$s=x_1+\cdots+x_n$ is positive, and let $t$ be another positive integer. +These $x_i$ represent scaled amounts of glue in units of sp (scaled +points), where one sp is $2^{-16}$ of a printer's point. The other +quantity $t$ represents the total by which the glue should stretch or +shrink. Following the conventions of \TeX82, we will assume that the +integers we deal with are less than $2^{31}$ in absolute value. + +After the glue has been set, the actual amounts of incremental glue space +(in~sp) will be the integers $f(x_1)$, \dots,~$f(x_n)$, where $f$ is a +function that we wish to compute. We want $f(x)$ to be nearly proportional +to~$x$, and we also want the sum $f(x_1)+\cdots+f(x_n)$ to be nearly +equal to~$t$. If we were using floating-point arithmetic, we would simply +compute $f(x)\equiv(t/s)\cdot x$ and hope for the best; but the goal here +is to compute a suitable~$f$ using only the fixed-point arithmetic operations +of a typical ``16-bit microcomputer.'' + +The solution adopted here is to determine integers $a$, $b$, $c$ such that +$$f(x)=\bigl\lfloor 2^{-b}c\lfloor 2^{-a}x\rfloor\bigr\rfloor$$ +if $x$ is nonnegative. Thus, we take $x$ and shift it right by $a$~bits, +then multiply by~$c$ (which is $2^{15}$ or less), and shift the product +right by $b$~bits. The quantities $a$, $b$, and~$c$ are to be chosen +so that this calculation doesn't cause overflow and so that $f(x_1)+\cdots ++f(x_n)$ is reasonably close to~$t$. + +The following method is used to calculate $a$ and~$b$: +Suppose $$y=\max_{1\le i\le n}\vert x_i\vert\,.$$ +Let $d$ and $e$ be the smallest integers such that $t<2^ds$ and $y<2^e$. +Since $s$ and~$t$ are less than~$2^{31}$, we have $-30\le d\le31$ and +$1\le e\le31$. An error message is given if $d+e\ge31$; in such a case +some $x_m$ has $\vert x_m\vert\ge 2^{e-1}$ and we are trying to change +$\vert x_m\vert$ to $\vert(t/s)x_m\vert\ge2^{d+e-2}\ge2^{30}$~sp, which +\TeX\ does not permit. (Consider, for example, the ``worst case'' situation +$x_1=2^{30}+1$, $x_2=-2^{30}$, $t=2^{31}-1$; surely we need not bother +trying to accommodate such anomalous combinations of values.) On the other +hand if $d+e\le31$, we set $a=e-16$ and $b=31-d-e$. Notice that this choice +of~$a$ guarantees that $\lfloor2^{-a}\vert x_i\vert\rfloor<2^{16}$. We will +choose~$c$ to be at most~$2^{15}$, so that the product will be less +than~$2^{31}$. + +The computation of $c$ is the tricky part. +@^hairy mathematics@> +The ``ideal'' value for $c$ would be $\rho=2^{a+b}t/s$, since $f(x)$ should +be approximately $(t/s)\cdot x$. Furthermore it is better to have $c$ slightly +larger than~$\rho$, instead of slightly smaller, since the other operations +in $f(x)$ have a downward bias. Therefore we shall compute $c=\lceil\rho\rceil$. +Since $2^{a+b}t/s<2^{a+b+d}=2^{15}$, we have $c\le2^{15}$ as desired. + +We want to compute $c=\lceil\rho\rceil$ exactly in all cases. There is no +difficulty if $s<2^{15}$, since $c$ can be computed directly using the +formula $c=\bigl\lfloor(2^{a+b}t+s-1)/s\bigr\rfloor$; overflow will not +occur since $2^{a+b}t<2^{15}s<2^{30}$. + +Otherwise let $s=s_12^l+s_2$, where $2^{14}\le s_1<2^{15}$ and $0\le s_2<2^l$. +We will essentially carry out a long division. Let $t$ be ``normalized'' +so that $2^{30}\le2^ht<2^{31}$ for some~$h$. Then we form the quotient and +remainder of $2^ht$ divided by~$s_1$, +$$ 2^ht=qs_1+r_0, \qquad 0\le r_0-s$ we have +$q=\lceil2^{h+l}t/s\rceil$; otherwise we can replace $(q,r)$ by +$(q\pm1,r\mp s)$ repeatedly until $r$ is in the correct range. It is not +difficult to prove that $q$ needs to be increased at most once and decreased +at most seven times, since $2^lr_0-qs_2<2^ls_1\le s$ and since +$qs_2/s\le(2^ht/s_1)(s_2/2^ls_1)<2^{31}/s_1^2\le8$. Finally, we have +$a+b-h-l=-1$ or~$-2$, since $2^{28+l}\le2^{14}s=2^{a+b+d-1}s\le2^{a+b}t< +2^{a+b+d}s=2^{15}s<2^{30+l}$ and $2^{30}\le2^ht<2^{31}$. Hence +$c=\lceil2^{a+b-h-l}q\rceil=\lceil{1\over2}q\rceil$ or~$\lceil{1\over4}q\rceil$. + +An error analysis shows that these values of $a$, $b$, and $c$ work +satisfactorily, except in unusual cases where we wouldn't expect them to. +@^error analysis@> +When $x\ge0$ we have +$$\eqalign{f(x)&=2^{-b}(2^{a+b}t/s+\theta_0)(2^{-a}x-\theta_1)-\theta_2\cr +&=(t/s)x+\theta_02^{-a-b}x-\theta_12^at/s-2^{-b}\theta_0\theta_1-\theta_2\cr}$$ +where $0\le\theta_0,\theta_1,\theta_2<1$. Now $0\le\theta_02^{-a-b}x +<2^{e-a-b}=2^{d+e-15}$ and $0\le\theta_12^at/s<2^{a+d}=2^{d+e-16}$, and +the other two terms are negligible. Therefore $f(x_1)+\cdots+f(x_n)$ differs +from~$t$ by at most about $2^{d+e-15}n$. Since $2^{d+e}$ is larger than +$(t/s)y$, which is the largest stretching or shrinking of glue after expansion, +the error is at worst about $n/32000$ times as much as this, so it is quite +reasonable. For example, even if fill glue is being used to stretch +20 inches, the error will still be less than $1\over1600$ of an inch. + +@ To sum up: Given the positive integers $s$, $t$, and $y$ as above, we +set $$a\gets\lfloor\lg y\rfloor-15,\qquad b\gets29-\lfloor\lg y\rfloor- +\lfloor\lg t/s\rfloor,\qquad\hbox{and}\qquad c\gets\lceil2^{a+b}t/s\rceil.$$ +The implementation below shows how to do the job in \PASCAL\ without using +large numbers. + +@ \TeX\ wants to have the glue-setting information in a 32-bit data type +called |glue_ratio|. The \PASCAL\ implementation of \TeX82 has |glue_ratio +=real|, but alternative definitions of |glue_ratio| are explicitly allowed. + +For our purposes we shall let |glue_ratio| be a record that is packed with +three fields: The |a_part| will hold the positive integer |a+16|, the +|b_part| will hold the nonnegative integer~|b|, and the |c_part| will hold +the nonnegative integer~|c|. When the formulas above tell us to take +|b>30|, we might as well set |c:=0| instead, because |f(x)| will be +zero in all cases when |b>30|. Note that we have only about 25 bits of +information in all, so it should fit in 32 bits with ease. + +@= +@!glue_ratio=packed record + @!a_part: 1..31; {the quantity |e=a+16| in our derivation} + @!b_part: 0..30; {the quantity |b| in our derivation} + @!c_part: 0..@'100000; {the quantity |c| in our derivation} + end; +@!scaled = integer; {this data type is used for quantities in sp units} + +@ The real problem is to define the procedures that \TeX\ needs to +deal with such |glue_ratio| values: +(a)~Given scaled numbers |s|, |t|, and~|y| as above, to compute the +corresponding |glue_ratio|. +(b)~Given a nonnegative scaled number~|x| and a |glue_ratio|~|g|, to +compute the scaled number~|f(x)|. +(c)~Given a |glue_ratio|~|g|, to print out a decimal equivalent of +|g| for diagnostic purposes. + +The procedures below can be incorporated into \TeX82 via a change file +without great difficulty. A few modifications will be needed, because +\TeX's |glue_ratio| values can be negative in unusual cases---when the +amount of stretchability or shrinkability is less than zero. Negative +values in the |c_part| will handle such problems, if proper care is +taken. The error message below should either become a warning message +or a call to \TeX's |print_err| routine; in the latter case, an +@^error message@> +appropriate help message should be given, stating that glue cannot +stretch to more than 18~feet long, but that it's OK to proceed with +fingers crossed. + +@*Glue multiplication. +The easiest procedure of the three just mentioned is the one that is +needed most often, namely, the computation of~|f(x)|. + +\PASCAL\ doesn't have built-in binary shift commands or built-in exponentiation, +although many computers do have this capability. Therefore our arithmetic +routines use an array called `|two_to_the|', containing powers of~two. +Divisions by powers of two are never done in the programs below when the +dividend is negative, so the operations can safely be replaced by right +shifts on machines for which this is most appropriate. (Contrary to popular +opinion, the operation `|x div 2|' is not the same as shifting |x| +right one binary place, on a machine with two's complement arithmetic, +when |x| is a negative odd integer. But division +{\it is\/} equivalent to shifting when |x| is nonnegative.) + +@= +@!two_to_the: array[0..30] of integer; {$|two_to_the|[k]=2^k$} + +@ @= +@!k:1..30; {an index for initializing |two_to_the|} + +@ @= +two_to_the[0]:=1; +for k:=1 to 30 do two_to_the[k]:=two_to_the[k-1]+two_to_the[k-1]; + +@ We will use the abbreviations |ga|, |gb|, and |gc| as convenient +alternatives to \PASCAL's \&{with} statement. The glue-multiplication +function |f|, which replaces several occurrences of the `|float|' macro +in \TeX82, is now easy to state: + +@d ga==g.a_part +@d gb==g.b_part +@d gc==g.c_part + +@p function glue_mult(@!x:scaled;@!g:glue_ratio):integer; + {returns |f(x)| as above, assuming that |x>=0|} +begin if ga>16 then x:=x div two_to_the[ga-16] {right shift by |a| places} +else x:=x*two_to_the[16-ga]; {left shift by |-a| places} +glue_mult:=(x*gc) div two_to_the[gb]; {right shift by |b| places} +end; {note that |b| may be as large as 30} + +@*Glue setting. +The |glue_fix| procedure computes |a|, |b|, and |c| by the method +explained above. \TeX\ does not normally compute the quantity~|y|, but +it could be made to do so without great difficulty. + +This procedure replaces several occurrences of the `|unfloat|' macro in +\TeX82. It would be written as a function that returns a |glue_ratio|, +if \PASCAL\ would allow functions to produce records as values. + +@p procedure glue_fix(@!s,@!t,@!y:scaled; var@!g:glue_ratio); +var @!a,@!b,@!c:integer; {components of the desired ratio} +@!k,@!h:integer; {$30-\lfloor\lg s\rfloor$, $30-\lfloor\lg t\rfloor$} +@!s0:integer; {original (unnormalized) value of |s|} +@!q,@!r,@!s1:integer; {quotient, remainder, divisor} +@!w:integer; {$2^l$, where $l=16-k$} +begin @; +if t30) then + begin if b<0 then write_ln('! Excessive glue.'); {error message} +@^error message@> + b:=0; c:=0; {make |f(x)| identically zero} + end +else begin if k>=16 then {easy case, $s_0<2^{15}$} + c:=(t div two_to_the[h-a-b]+s0-1) div s0 {here |1<=h-a-b<=k-14<=16|} + else @; + end; +ga:=a+16; gb:=b; gc:=c; +end; + +@ @= +begin a:=15; k:=0; h:=0; s0:=s; +while y<@'10000000000 do {|y| is known to be positive} + begin decr(a); y:=y+y; + end; +while s<@'10000000000 do {|s| is known to be positive} + begin incr(k); s:=s+s; + end; +while t<@'10000000000 do {|t| is known to be positive} + begin incr(h); t:=t+t; + end; +end {now $2^{30}\le t=2^ht_0<2^{31}$ and $2^{30}\le s=2^ks_0<2^{31}$, + hence $d=k-h$ if $t/s<1$} + +@ @= +begin w:=two_to_the[16-k]; +s1:=s0 div w; +q:=t div s1; +r:=((t mod s1)*w)-((s0 mod w)*q); +if r>0 then + begin incr(q); r:=r-s0; + end +else while r<=-s0 do + begin decr(q); r:=r+s0; + end; +if a+b+k-h=15 then c:=(q+1) div 2 @+else c:=(q+3) div 4; +end + +@*Glue-set printing. +The last of the three procedures we need is |print_gr|, which displays a +|glue_ratio| in symbolic decimal form. Before constructing such a procedure, +we shall consider some simpler routines, copying them from an early +draft of the program \TeX82. + +@d unity==@'200000 {$2^{16}$, represents 1.0000} + +@= +@!dig:array[0..15] of 0..9; {for storing digits} + +@ An array of digits is printed out by |print_digs|. + +@p procedure print_digs(@!k:integer); {prints |dig[k-1]| \dots |dig[0]|} +begin while k>0 do + begin decr(k); write(chr(ord('0')+dig[k])); + end; +end; + +@ A nonnegative integer is printed out by |print_int|. + +@p procedure print_int(@!n:integer); {prints an integer in decimal form} +var @!k:0..12; {index to current digit; we assume that $0\le n<10^{12}$} +begin k:=0; +repeat dig[k]:=n mod 10; n:=n div 10; incr(k); +until n=0; +print_digs(k); +end; + +@ And here is a procedure to print a nonnegative |scaled| number. + +@p procedure print_scaled(s:scaled); + {prints a scaled real, truncated to four digits} +var k:0..3; {index to current digit of the fraction part} +begin print_int(s div unity); {print the integer part} +s:=((s mod unity)*10000) div unity; +for k:=0 to 3 do + begin dig[k]:=s mod 10; s:=s div 10; + end; +write('.'); print_digs(4); +end; + +@ Now we're ready to print a |glue_ratio|. Since the effective multiplier +is $2^{-a-b}c$, we will display the scaled integer $2^{16-a-b}c$, taking +care to print something special if this quantity is terribly large. + +@p procedure print_gr(@!g:glue_ratio); {prints a glue multiplier} +var @!j:-29..31; {the amount to shift |c|} +begin j:=32-ga-gb; +while j>15 do + begin write('2x'); decr(j); {indicate multiples of 2 for BIG cases} + end; +if j<0 then print_scaled(gc div two_to_the[-j]) {shift right} +else print_scaled(gc*two_to_the[j]); {shift left} +end; + +@* The driver program. +In order to test these routines, we will assume that the |input| file +contains a sequence of test cases, where each test case consists of the +integer numbers $t$, $x_1$, \dots,~$x_n$, 0. The final test case should +be followed by an additional zero. + +@= +@!x:array[1..1000] of scaled; {the $x_i$} +@!t:scaled; {the desired total} +@!m:integer; {the test case number} + +@ Each case will be processed by the following routine, which assumes +that |t| has already been read. + +@p procedure test; {processes the next data set, given |t| and~|m|} +var @!n: 0..1000; {the number of items} +k:0..1000; {runs through the items} +y:scaled; {$\max_{1\le i\le n}\vert x_i\vert$} +@!g:glue_ratio; {the computed glue multiplier} +@!s:scaled; {the sum $x_1+\cdots+x_n$} +@!ts:scaled; {the sum $f(x_1)+\cdots+f(x_n)$} +begin write_ln('Test data set number ',m:1,':'); +@; +@; +if s<=0 then write_ln('Invalid data (nonpositive sum); this set rejected.') +else begin @; + @; + end; +end; + +@ @= +begin n:=0; +repeat incr(n); read(x[n]); +until x[n]=0; +decr(n); +end + +@ @= +begin s:=0; y:=0; +for k:=1 to n do + begin s:=s+x[k]; + if y= +begin glue_fix(s,t,y,g); {set |g|, perhaps print an error message} +write(' Glue ratio is '); print_gr(g); +write_ln(' (',ga-16:1,',',gb:1,',',gc:1,')'); +end + +@ @= +begin ts:=0; +for k:=1 to n do + begin write(x[k]:20); + if x[k]>=0 then y:=glue_mult(x[k],g) + else y:=-glue_mult(-x[k],g); + write_ln(y:15); + ts:=ts+y; + end; +write_ln(' Totals',s:13,ts:15,' (versus ',t:1,')'); +end + +@ Here is the main program. +@^main program@> + +@p begin initialize; +m:=1; +read(t); +while t>0 do + begin test; + incr(m); read(t); + end; +end. + +@*Index. Here are the section numbers where various identifiers are used in the +program, and where various topics are discussed. + + + + + diff --git a/Build/source/texk/web2c/doc/webman.tex b/Build/source/texk/web2c/doc/webman.tex new file mode 100644 index 00000000000..e4781c1da77 --- /dev/null +++ b/Build/source/texk/web2c/doc/webman.tex @@ -0,0 +1,1674 @@ +% WEB user manual -- last updated by D E Knuth on 4 Dec 89 +\input webmac +\parskip 0pt plus 1pt +\def\RA{\char'31 } % right arrow +\def\hang{\hangindent 4em\ignorespaces} +\font\ninerm=cmr9 +\font\ninett=cmtt9 +\font\eighttt=cmtt8 +\let\mc=\ninerm % medium caps for names like SAIL +\def\PASCAL{Pascal} +\font\quoterm=cmssq8 +\font\quoteit=cmssqi8 +\def\pb{\.{|...|}} +\def\lpile{\def\cr{\hfill\endline}\matrix} % I only use \lpile by itself + +\outer\def\section #1.{\penalty-50\vskip 12pt plus 3pt minus 3pt + \noindent{\bf #1.}\quad\ignorespaces} + +\def\lheader{\mainfont\the\pageno\hfill\sc\runninghead\hfill} +\def\rheader{\hfill\sc\runninghead\hfill\mainfont\the\pageno} +\def\runninghead{{\tentt WEB} USER MANUAL} + +% This verbatim mode assumes that no ? appears in the text being copied. +\def\verbatim{\begingroup + \def\do##1{\catcode`##1=12 } \dospecials + \parskip 0pt \parindent 0pt + \catcode`\ =13 \catcode`\^^M=13 + \tt \catcode`\?=0 \verbatimdefs \verbatimgobble} +{\catcode`\^^M=13{\catcode`\ =13\gdef\verbatimdefs{\def^^M{\ \par}\let =\ }} % + \gdef\verbatimgobble#1^^M{}} + \centerline{\titlefont The {\ttitlefont WEB} System + of Structured Documentation} + +\vskip 15pt plus 3pt minus 3pt +\noindent This memo describes how to write programs in the +\.{WEB} language; and it also includes the full \.{WEB} documentation for +\.{WEAVE} and \.{TANGLE}, the programs that read \.{WEB} input and produce +\TeX\ and \PASCAL\ output, respectively. The philosophy behind \.{WEB} is +that an experienced system programmer, who wants to provide the best +possible documentation of software products, needs two things +simultaneously: a language like \TeX\ for formatting, and a language like +\PASCAL\ for programming. Neither type of language can provide the best +documentation by itself. But when both are appropriately combined, we +obtain a system that is much more useful than either language separately. + +The structure of a software program may be thought of as a ``web'' that is +made up of many interconnected pieces. To document such a program, we want +to explain each individual part of the web and how it relates to its +neighbors. The typographic tools provided by \TeX\ give us an opportunity +to explain the local structure of each part by making that structure +visible, and the programming tools provided by \PASCAL\ make it possible +for us to specify the algorithms formally and unambiguously. By combining +the two, we can develop a style of programming that maximizes our ability +to perceive the structure of a complex piece of software, and at the same +time the documented programs can be mechanically translated into a working +software system that matches the documentation. + +Since \.{WEB} is an experimental system developed for internal use within +the \TeX\ project at Stanford, this report is rather terse, and it assumes +that the reader is an experienced programmer who is highly motivated to +read a detailed description of \.{WEB}'s rules. Furthermore, even if a +less terse manual were to be written, the reader would have to be warned +in advance that \.{WEB} is not for beginners and it never will be: The +user of \.{WEB} must be familiar with both \TeX\ and \PASCAL. When one +writes a \.{WEB} description of a software system, it is possible to make +mistakes by breaking the rules of \.{WEB} and/or the rules of \TeX\ and/or +the rules of \PASCAL. In practice, all three types of errors will occur, +and you will get different error messages from the different language +processors. In compensation for the sophisticated expertise needed to cope +with such a variety of languages, however, experience has shown that +reliable software can be created quite rapidly by working entirely in +\.{WEB} from the beginning; and the documentation of such programs seems +to be better than the documentation obtained by any other known method. +Thus, \.{WEB} users need to be highly qualified, but they can get some +satisfaction and perhaps even a special feeling of accomplishment when +they have successfully created a software system with this method. + +To use \.{WEB}, you prepare a file called \.{COB.WEB} (say), and then you +apply a system program called \.{WEAVE} to this file, obtaining an output +file called \.{COB.TEX}. When \TeX\ processes \.{COB.TEX}, your output +will be a ``pretty printed'' version of \.{COB.WEB} that takes appropriate +care of typographic details like page layout and the use of indentation, +italics, boldface, etc.; this output will contain extensive cross-index +information that is gathered automatically. You can also submit the same +file \.{COB.WEB} to another system program called \.{TANGLE}, which will +produce a file \.{COB.PAS} that contains the \PASCAL\ code of your \.{COB} +program. The \PASCAL\ compiler will convert \.{COB.PAS} into +machine-language instructions corresponding to the algorithms that were so +nicely formatted by \.{WEAVE} and \TeX. Finally, you can (and should) +delete the files \.{COB.TEX} and \.{COB.PAS}, because \.{COB.WEB} contains +the definitive source code. Examples of the behavior of \.{WEAVE} and +\.{TANGLE} are appended to this manual. + +Besides providing a documentation tool, \.{WEB} enhances the \PASCAL\ +language by providing a rudimentary macro capability together with the +ability to permute pieces of the program text, so that a large system can +be understood entirely in terms of small modules and their local +interrelationships. The \.{TANGLE} program is so named because it takes a +given web and moves the modules from their web structure into the order +required by \PASCAL; the advantage of programming in \.{WEB} is that the +algorithms can be expressed in ``untangled'' form, with each module +explained separately. The \.{WEAVE} program is so named because it takes +a given web and intertwines the \TeX\ and \PASCAL\ portions contained in +each module, then it knits the whole fabric into a structured document. +(Get it? Wow.) Perhaps there is some deep connection here with the fact +that the German word for ``weave'' is ``{\it web\/}'', and the +corresponding Latin imperative is ``{\it texe\/}''! + +It is impossible to list all of the related work that has influenced the +design of \.{WEB}, but the key contributions should be mentioned +here.\quad (1)~Myrtle Kellington, as executive editor for ACM +publications, developed excellent typographic standards for the +typesetting of Algol programs during the 1960s, based on the original +designs of Peter Naur; the subtlety and quality of this influential work +can be appreciated only by people who have seen what happens when other +printers try to typeset Algol without the advice of ACM's copy +editors.\quad(2)~Bill McKeeman introduced a program intended to automate +some of this task [Algorithm 268, ``Algol~60 reference language editor,'' +{\sl CACM \bf8} (1965), 667--668]; and a considerable flowering of such +programs has occurred in recent years [see especially Derek Oppen, +``Prettyprinting,'' {\sl ACM TOPLAS \bf2} (1980), 465--483; G.~A. Rose and +J. Welsh, ``Formatted programming languages,'' {\sl SOFTWARE Practice +\char`\&\ Exper.\ \bf11} (1981), 651--669].\quad(3)~The top-down style of +exposition encouraged by \.{WEB} was of course chiefly influenced by Edsger +Dijkstra's essays on structured programming in the late 1960s. The less +well known work of Pierre-Arnoul de Marneffe [``Holon programming: A +survey,'' Univ.\ de Liege, Service Informatique, Liege, Belgium, 1973; 135 +pp.\null] also had a significant influence on the author as \.{WEB} was +being formulated.\quad(4)~Edwin Towster has proposed a similar style of +documentation in which the programmer is supposed to specify the relevant +data structure environment in the name of each submodule [``A convention +for explicit declaration of environments and top-down refinement of +data,'' {\sl IEEE Trans.\ on Software Eng.\ \bf SE--5} (1979), 374--386]; +this requirement seems to make the documentation a bit too verbose, +although experience with \.{WEB} has shown that any unusual control +structure or data structure should definitely be incorporated into the +module names on psychological grounds.\quad(5)~Discussions with Luis +Trabb~Pardo in the spring of 1979 were extremely helpful for setting up a +prototype version of \.{WEB} that was called \.{DOC}.\quad (6)~Ignacio +Zabala's extensive experience with \.{DOC}, in which he created a full +implementation of \TeX\ in \PASCAL\ that was successfully transported to +many different computers, was of immense value while \.{WEB} was taking +its present form.\quad(7)~David~R. Fuchs made several crucial suggestions +about how to make \.{WEB} more portable; he and Arthur~L. Samuel +coordinated the initial installations of \.{WEB} on dozens of computer +systems, making changes to the code so that it would be acceptable to +a wide variety of \PASCAL\ compilers.\quad(8)~The name \.{WEB} itself +was chosen in honor of my wife's mother, Wilda Ernestine Bates. + +The appendices to this report contain complete \.{WEB} programs for the +\.{WEAVE} and \.{TANGLE} processors. A study of these examples, together +with an attempt to write \.{WEB} programs by yourself, is the best way +to understand why \.{WEB} has come to be like it is. + \section General rules. +A \.{WEB} file is a long string of text that has been divided into +individual lines. The exact line boundaries are not terribly crucial, and +a programmer can pretty much chop up the \.{WEB} file in whatever way seems +to look best as the file is being edited; but string constants and control +texts must end on the same line on which they begin, since this convention +helps to keep errors from propagating. The end of a line means +the same thing as a blank space. + +Two kinds of material go into \.{WEB} files: \TeX\ text and \PASCAL\ text. +A programmer writing in \.{WEB} should be thinking both of the +documentation and of the \PASCAL\ program that he or she is creating; +i.e., the programmer should be instinctively aware of the different +actions that \.{WEAVE} and \.{TANGLE} will perform on the \.{WEB} file. +\TeX\ text is essentially copied without change by \.{WEAVE}, and it is +entirely deleted by \.{TANGLE}, since the \TeX\ text is ``pure +documentation.'' \PASCAL\ text, on the other hand, is formatted by +\.{WEAVE} and it is shuffled around by \.{TANGLE}, according to rules that +will become clear later. For now the important point to keep in mind is +that there are two kinds of text. Writing \.{WEB} programs is something +like writing \TeX\ documents, but with an additional ``\PASCAL\ mode'' +that is added to \TeX's horizontal mode, vertical mode, and math mode. + +A \.{WEB} file is built up from units called {\sl modules\/} that are more +or less self-contained. Each module has three parts: + +\yskip\item{1)} A \TeX\ part, containing explanatory material about what +is going on in the module. + +\item{2)} A definition part, containing macro definitions that serve as +abbreviations for \PASCAL\ constructions that would be less comprehensible +if written out in full each time. + +\item{3)} A \PASCAL\ part, containing a piece of the program that +\.{TANGLE} will produce. This \PASCAL\ code should ideally be about a +dozen lines long, so that it is easily comprehensible as a unit and so +that its structure is readily perceived. + +\yskip\noindent The three parts of each module must appear in this order; +i.e., the \TeX\ commentary must come first, then the definitions, and +finally the \PASCAL\ code. Any of the parts may be empty. + +\eject % page break inserted Dec 88 + +A module begins with the pair of symbols `\.{@\ }' or `\.{@*}', where +`\.{\ }' denotes a blank space. A module ends +at the beginning of the next module (i.e., at the next +`\.{@\ }' or `\.{@*}'), or at the end of the file, whichever comes first. +The \.{WEB} file may also contain material that is not part of any module +at all, namely the text (if any) that occurs before the first module. +Such text is said to be ``in limbo''; it is ignored by \.{TANGLE} +and copied essentially verbatim by \.{WEAVE}, so its function is to +provide any additional formatting instructions that may be desired in the +\TeX\ output. Indeed, it is customary to begin a \.{WEB} file with +\TeX\ code in limbo that loads special fonts, defines special macros, +changes the page sizes, and/or produces a title page. + +Modules are numbered consecutively, starting with 1; these numbers appear +at the beginning of each module of the \TeX\ documentation, and they appear +as bracketed comments at the beginning of the code generated by that +module in the \PASCAL\ program. + +Fortunately, you never mention these numbers yourself when you are writing +in \.{WEB}. You just say `\.{@\ }' or `\.{@*}' at the beginning of each +new module, and the numbers are supplied automatically by \.{WEAVE} and +\.{TANGLE}. As far as you are concerned, a module has a +{\sl name\/} instead of a number; such a name is specified by writing +`\.{@<}' followed by \TeX\ text followed by `\.{@>}'. When \.{WEAVE} +outputs a module name, it replaces the `\.{@<}' and `\.{@>}' by +angle brackets and inserts the module number in small type. Thus, when you +read the output of \.{WEAVE} it is easy to locate any module that is +referred to in another module. + +For expository purposes, a module name should be a good description of the +contents of that module; i.e., it should stand for the abstraction +represented by the module. Then the module can be ``plugged into'' one or +more other modules in such a way +that unimportant details of its inner workings +are suppressed. A module name therefore ought to be long enough to convey +the necessary meaning. Unfortunately, however, it is laborious to type +such long names over and over again, and it is also difficult to specify a +long name twice in exactly the same way so that \.{WEAVE} and \.{TANGLE} +will be able to match the names to the modules. To ameliorate this difficulty, +\.{WEAVE} and \.{TANGLE} let you abbreviate a module name +after its first appearance in the \.{WEB} file; you can type simply +`\.{@<$\alpha$...@>}', where $\alpha$ is any string that is a prefix of +exactly one module name appearing in the file. For example, `\.{@}' can be abbreviated to `\.{@}' if no other module +name begins with the five letters `\.{Clear}'. Module names must otherwise +match character for character, except that consecutive blank spaces and/or +tab marks are treated as equivalent to single spaces, and such spaces are +deleted at the beginning and end of the name. Thus, `\.{@< Clear { }the +arrays @>}' will also match the name in the previous example. + +We have said that a module begins with `\.{@\ }' or `\.{@*}', but we +didn't say how it gets divided up into a \TeX\ part, a definition part, +and a \PASCAL\ part. The definition part begins with the first appearance +of `\.{@d}' or `\.{@f}' in the module, and the \PASCAL\ part begins with +the first appearance of `\.{@p}' or `\.{@<}'. The latter option `\.{@<}' +stands for the beginning of a module name, which is the name of the module +itself. An equals sign (\.=) must follow the `\.{@>}' at the end of this +module name; you are saying, in effect, that the module name stands for +the \PASCAL\ text that follows, so you say `$\langle\,$module +name$\,\rangle=\null$\PASCAL\ text'. Alternatively, if the \PASCAL\ part +begins with `\.{@p}' instead of a module name, the current module is said +to be {\sl unnamed}. Note that module names cannot appear in the +definition part of a module, because the first `\.{@<}' in a module +signals the beginning of its \PASCAL\ part. But any number of module names +might appear in the \PASCAL\ part, once it has started. + +The general idea of \.{TANGLE} is to make a \PASCAL\ program out of these +modules in the following way: First all the \PASCAL\ parts of unnamed +modules are copied down, in order; this constitutes the initial +approximation $T_0$ to the text of the program. (There should be at least +one unnamed module, otherwise there will be no program.) Then all module +names that appear in the initial text $T_0$ are replaced by the \PASCAL\ +parts of the corresponding modules, and this substitution process +continues until no module names remain. Then all defined macros are +replaced by their equivalents, according to certain rules that are +explained later. The resulting \PASCAL\ code is ``sanitized'' so that it +will be acceptable to an average garden-variety \PASCAL\ compiler; i.e., +lowercase letters are converted to uppercase, long identifiers are +chopped, and the lines of the output file are constrained to be at most 72 +characters long. All comments will have been removed from this \PASCAL\ +program except for the meta-comments delimited by `\.{@\{}' and +`\.{@\}}', as explained below, and except for the module-number comments +that point to the source location where each piece of the program text +originated in the \.{WEB} file. + +If the same name has been given to more than one module, the \PASCAL\ text +for that name is obtained by putting together all of the \PASCAL\ parts in +the corresponding modules. This feature is useful, for example, in a +module named `Global variables in the outer block', since one can then +declare global variables in whatever modules those variables are +introduced. When several modules have the same name, \.{WEAVE} assigns the +first module number as the number corresponding to that name, and it +inserts a note at the bottom of that module telling the reader to `See +also sections so-and-so'; this footnote gives the numbers of all the other +modules having the same name as the present one. The \PASCAL\ text +corresponding to a module is usually formatted by \.{WEAVE} so that the +output has an equivalence sign in place of the equals sign in the \.{WEB} +file; i.e., the output says `$\langle\,$module +name$\,\rangle\equiv\null$\PASCAL\ text'. However, in the case of the second +and subsequent appearances of a module with the same name, this `$\equiv$' +sign is replaced by `$\mathrel+\equiv$', as an indication that the \PASCAL\ +text that follows is being appended to the \PASCAL\ text of another +module. + +The general idea of \.{WEAVE} is to make a \.{TEX} file from the \.{WEB} +file in the following way: The first line of the \.{TEX} file will be +`\.{\\input webmac}'; this will cause \TeX\ to read in the macros that +define \.{WEB}'s documentation conventions. The next lines of the file +will be copied from whatever \TeX\ text is in limbo before the first +module. Then comes the output for each module in turn, possibly +interspersed with end-of-page marks. Finally, \.{WEAVE} will generate a +cross-reference index that lists each module number in which each \PASCAL\ +identifier appears, and it will also generate an alphabetized list +of the module names, as well as a table of contents that +shows the page and module numbers for each ``starred'' module. + +What is a ``starred'' module, you ask? A module that begins with `\.{@*}' +instead of `\.{@\ }' is slightly special in that it denotes a new major +group of modules. The `\.{@*}' should be followed by the title of this +group, followed by a period. Such modules will always start on a new page +in the \TeX\ output, and the group title will appear as a running headline +on all subsequent pages until the next starred module. The title will also +appear in the table of contents, and in boldface type at the beginning of +its module. Caution: Do not use \TeX\ control sequences in such titles, +unless you know that the \.{webmac} macros will do the right thing with +them. The reason is that these titles are converted to uppercase when +they appear as running heads, and they are converted to boldface when they +appear at the beginning of their modules, and they are also written out to +a table-of-contents file used for temporary storage while \TeX\ is +working; whatever control sequences you use must be meaningful in all +three of these modes. + +The \TeX\ output produced by \.{WEAVE} for each module consists of +the following: First comes the module number (e.g., `\.{\\M123.}' +at the beginning of module 123, except that `\.{\\N}' appears in place of +`\.{\\M}' at the beginning of a starred module). Then comes the +\TeX\ part of the module, copied almost verbatim except as noted +below. Then comes the definition part and the \PASCAL\ part, formatted +so that there will be a little extra space between them if both are +nonempty. The definition and \PASCAL\ parts are obtained by inserting +a bunch of funny looking \TeX\ macros into the \PASCAL\ program; these +macros handle typographic details about fonts and proper math spacing, +as well as line breaks and indentation. + +When you are typing \TeX\ text, you will probably want to make frequent +reference to variables and other quantities in your \PASCAL\ code, and you +will want those variables to have the same typographic treatment +when they appear in your text as when they appear in your +program. Therefore the \.{WEB} language allows you to get the effect of +\PASCAL\ editing within \TeX\ text, if you place `\.|' marks before and +after the \PASCAL\ material. For example, suppose you want to say something +like this: +$$\hbox{The characters are placed into \\{buffer}, which is a +\&{packed} \&{array} $[1\to\|n]$ \&{of} \\{char}.}$$ +The \TeX\ text would look like this in your \.{WEB} file: +$$\.{The characters are placed into |buffer|, which is a |packed +array [1..n] of char|.}$$ +And \.{WEAVE} translates this into something you are glad you didn't have +to type: +$$\lpile{\.{The characters are placed into \\\\\{buffer\},}\cr + \.{which is a \\\&\{packed\}{ }\\\&\{array\}{ }\$ + [1\\to\\|n]\${ }\\\&\{of\}{ }\\\\\{char\}.}\cr}$$ +Incidentally, the cross-reference index that \.{WEAVE} would make, in +the presence of a comment like this, would include +the current module number as one of the index entries for \\{buffer} +\vadjust{\eject}% page break inserted Dec 88 +and \\{char}, even though \\{buffer} and \\{char} +might not appear in the \PASCAL\ part of +this module. Thus, the index covers references to identifiers in +the explanatory comments as well as in the program itself; you will +soon learn to appreciate this feature. However, the identifiers +\&{packed} and \&{array} and \|n\ and \&{of\/} would not be indexed, +because \.{WEAVE} does not make index entries for reserved words or +single-letter identifiers. Such identifiers are felt to be so ubiquitous +that it would be pointless to mention every place where they occur. + +Speaking of identifiers, the author of \.{WEB} thinks that +\\{IdentifiersSeveralWordsLong} look terribly ugly when they mix +uppercase and lowercase letters. He recommends that +\\{identifiers\_several\_words\_long} be written with underline characters +to get a much better effect. The actual identifiers sent to the \PASCAL\ +compiler by \.{TANGLE} will have such underlines removed, and \.{TANGLE} +will check to make sure that two different identifiers do not become +identical when this happens. (In fact, \.{TANGLE} even checks that +the first seven characters of identifiers are unique, when lowercase +letters have been converted to uppercase; the number seven in this +constraint is more strict than \PASCAL's eight, and it can +be changed if desired.) The \.{WEAVE} processor will properly +alphabetize identifiers that have embedded underlines +when it makes the index. + +Although a module begins with \TeX\ text and ends with \PASCAL\ text, we +have noted that the dividing line isn't sharp, since \PASCAL\ text can be +included in \TeX\ text if it is enclosed in `\pb'. Conversely, \TeX\ text +also appears frequently within \PASCAL\ text, because everything in +comments (i.e., between left and right braces) is treated as \TeX\ text. +Furthermore, a module name consists of \TeX\ text; thus, a \.{WEB} file +typically involves constructions like `\.{if} \.x \.= \.0 \.{then} +\.{@}' where we go back and forth +between \PASCAL\ and \TeX\ conventions in a natural way. + \section Macros. +A \.{WEB} programmer can define three kinds of macros to make the programs +shorter and more readable: + +\yskip\hang`\.{@d} \\{identifier} \.= \\{constant}' defines a {\sl numeric\/} +macro, allowing \.{TANGLE} to do rudimentary arithmetic. + +\yskip\hang`\.{@d} \\{identifier} \.{==} \PASCAL\ text' defines a {\sl +simple\/} macro, where the identifier will be replaced by the \PASCAL\ text +when \.{TANGLE} produces its output. + +\yskip\hang`\.{@d} \\{identifier}\.{(\#) ==} \PASCAL\ text' defines a +{\sl parametric\/} macro, where the identifier will be replaced by the \PASCAL\ +text and where occurrences of \.{\#} in that \PASCAL\ text will be +replaced by an argument. + +\yskip\noindent In all three cases, the identifier must have length greater +than one; it must not be a single letter. + +Numeric macros are subject to the following restrictions:\quad +(1)~The identifier must +be making its first appearance in the \.{WEB} file; +a numeric macro must be defined before it is used.\quad +(2)~The right-hand side of the numeric definition must be made entirely from +integer constants, numeric macros, preprocessed strings (see below), and +plus~signs or minus signs. No other operations or symbols are allowed, +not even parentheses, except that \PASCAL-like comments (enclosed in +braces) can appear. Indeed, comments are recommended, since it is usually +wise to give a brief explanation of the significance of each identifier as +it is defined.\quad +(3)~The numeric value must be less than $2^{15}=32768$ in absolute value. +(For larger values, you can use `\.{==}' in place of~`\.=', thus making use +of a simple macro instead of a numeric one. Note, however, that simple +macros sometimes have a different effect. For example, consider the three +definitions `\.{@d n1=2 @d n2=2+n1 @d n3==2+n1}'; then `\.{x-n2}' will +expand into `\.{x-4}', while `\.{x-n3}' will expand into `\.{x-2+2}' which +is quite different! It is wise to include parentheses in non-numeric +macros, e.g., `\.{@d n3==(2+n1)}', to avoid such errors.) + +When constants are connected by plus signs or minus +signs in a \PASCAL\ program, \.{TANGLE} does the arithmetic before putting +the constant into the output file. Therefore it is permissible to say, for +example, `\&{array} $[0\,.\,.\,\\{size}-1]$' if \\{size} has been declared +as a macro; note that \PASCAL\ doesn't allow this kind of compile-time +arithmetic if \\{size} is a \&{constant} quantity in the program. Another +use of \.{TANGLE}'s arithmetic is to make \&{case} statement labels such +as `$\\{flag}+1$' legitimate. Of course, it is improper to change \.{2+2} +into \.4 without looking at the surrounding context; many counterexamples +exist, such as the phrases `\.{-2+2}', `\.{x/2+2}', and `\.{2+2E5}'. The +program for \.{TANGLE}, in the appendix, gives precise details about this +conversion, which \.{TANGLE} does only when it is safe. + +The right-hand sides of simple and parametric macros +are required to have balanced parentheses, and the \PASCAL\ texts of +modules must have balanced parentheses too. Therefore when the argument +to a para\-metric macro appears in parentheses, both parentheses +will belong to the same \PASCAL\ text. + +The appendices to this report contain hundreds of typical examples of the +usefulness of \.{WEB} macros, so it is not necessary to dwell on the +subject here. However, the reader should know that \.{WEB}'s apparently +primitive macro capabilities can actually do a lot of rather surprising +things. Here is a construction that sheds further light on what is +possible: After making the definitions +$$\catcode`\#=12 +\lpile{\.{@d two\_cases(#)==case j of 1:#(1); 2:#(2); end}\cr +\.{@d reset\_file(#)==reset(input\_file@\&#)}\cr}$$ +one can write `\.{two\_cases(reset\_file)}' and the resulting \PASCAL\ +output will be +$$\.{case j of 1:reset(input\_file1); 2:reset(input\_file2); end}$$ +(but in uppercase letters and with \.\_'s removed). +The `\.{@\&}' operation used here joins together two adjacent tokens +into a single token, as explained later; otherwise the \PASCAL\ file would +contain a space between \.{input\_file} and the digit that followed it. +This trick can be used to provide the effect of an array of files, if you +are unfortunate enough to have a \PASCAL\ compiler that doesn't allow such +arrays. Incidentally, the cross-reference index made by \.{WEAVE} from +this example would contain the identifier \\{input\_file} but it would not +contain \\{input\_file1} or \\{input\_file2}. Furthermore, \.{TANGLE} +would not catch the error that \.{INPUTFILE1} and \.{INPUTFILE2} both +begin with the same nine letters; one should be more careful when using +`\.{@\&}'! But such aspects of the construction in this trick are +peripheral to our main point, which is that a parametric macro name without +arguments can be used as an argument to another parametric macro. + +Although \.{WEB}'s macros are allowed to have at most one parameter, the +following example shows that this is not as much of a restriction as it +may seem at first. Let \\{amac} and \\{bmac} be any parametric macros, and +suppose that we want to get the effect of +$$\catcode`\#=12 +\.{@d cmac(#1,#2) == amac(#1) bmac(#2)}$$ +which \.{WEB} doesn't permit. The solution is to make the definitions +$$\catcode`\#=12 +\lpile{\.{@d cmac(#) == amac(#) dmac}\cr +\.{@d dmac(#) == bmac(#)}\cr}$$ +and then to say `\.{cmac(x)(y)}'. + +There is one restriction in the generality of \.{WEB}'s parametric +macros, however: the argument to a para\-metric macro must not come from +the expansion of a macro that has not already been ``started.'' For +example, here is one of the things \.{WEB} cannot handle: +$$\catcode`\#=12 +\lpile{\.{@d arg == (p)}\cr +\.{@d identity(#) == #}\cr +\.{@p identity arg}\cr}$$ +In this case \.{TANGLE} will complain that the \.{identity} macro is not +followed by an argument in parentheses. + +The \.{WEB} language has another feature that is somewhat similar to a +numeric macro. A {\sl preprocessed string\/} is a string that is like +a \PASCAL\ string but delimited by double-quote marks (\.") instead of +single-quotes. Double-quote marks inside of such strings are indicated by +giving two double-quotes in a row. If a preprocessed string is +of length one (e.g., \.{"A"} or \.{""""}), it will be treated by \.{TANGLE} +as equivalent to the corresponding ASCII-code integer (e.g., \.{65} or +\.{34}). And if a preprocessed string is not of length one, it will be +converted into an integer equal to 256 or more. A {\sl string pool\/} +containing all such strings will be written out by the \.{TANGLE} +processor; this string pool file consists of string 256, then string 257, +etc., where each string is followed by an end-of-line and prefixed by two +decimal digits that define its length. Thus, for example, the empty string +\.{""} would be represented in the string pool file by a line containing +the two characters `\.{00}', while the string \.{"""String"""} would be +represented by `\.{08"String"}'. A given string appears at most once in +the string pool; the use of such a pool makes it easier to cope with +\PASCAL's restrictions on string manipulation. The string pool ends with +`\.{*nnnnnnnnn}', where \.{nnnnnnnnn} is a decimal number +called the {\sl string pool check sum}. If any string changes, the check +sum almost surely changes too; thus, the `\.{@\$}' feature +described below makes it possible for a program to assure itself that it +is reading its own string pool. + +Here is a simple example that combines numeric macros with preprocessed +strings of length one: +$$\lpile{\.{@d upper\_case\_Y = "Y"}\cr +\.{@d case\_difference = -"y"+upper\_case\_Y}\cr}$$ +The result is to define +$\\{upper\_case\_Y}=89$, $\\{case\_difference}=-32$. + \section Control codes. +We have seen several magic uses of `\.{@}' signs in \.{WEB} files, and it +is time to make a systematic study of +these special features. A \.{WEB} {\sl control code\/} +is a two-character combination of which the first is `\.@'. + +Here is a complete list of the legal control codes. The letters $L$, $T$, +$P$, $M$, $C$, and/or $S$ following each code indicate whether or not that +code is allowable in limbo, in \TeX\ text, in \PASCAL\ text, in module +names, in comments, and/or in strings. A bar over such a letter means +that the control code terminates the present part of the \.{WEB} file; for +example, $\overline L$ means that this control code ends the limbo material +before the first module. + +\def\@#1[#2] {\yskip\hangindent 2em\noindent\.{@#1\unskip + \spacefactor1000{ }}$[#2]$\quad} +\def\oP{\overline P} +\def\oT{\overline T\mskip1mu} + +\@@ [C,L,M,P,S,T] A double \.@ denotes the single character `\.@'. This is +the only control code that is legal in limbo, in comments, and in strings. + +\@\ [\overline L,\oP,\oT] This denotes the beginning of a new +(unstarred) module. A tab mark or end-of-line (carriage return) +is equivalent to a space when it follows an \.@ sign. + +\@* [\overline L,\oP,\oT] This denotes the beginning of a new starred +module, i.e., a module that begins a new major group. The title of the new +group should appear after the \.{@*}, followed by a period. As explained +above, \TeX\ control sequences should be avoided in such titles unless +they are quite simple. When \.{WEAVE} and \.{TANGLE} read a \.{@*}, they +print an asterisk on the terminal +followed by the current module number, so that the user +can see some indication of progress. The very first module should be starred. + +\@d [\oP,\oT] Macro definitions begin with \.{@d} (or \.{@D}), followed by +the \PASCAL\ text for one of the three kinds of macros, as explained +earlier. + +\@f [\oP,\oT] Format definitions begin with \.{@f} (or \.{@F}); they cause +\.{WEAVE} to treat identifiers in a special way when they appear in +\PASCAL\ text. The general form of a format definition is `\.{@f} \|l \.{==} +\|r', followed by an optional comment enclosed in braces, where \|l and \|r +are identifiers; \.{WEAVE} will subsequently treat identifier \|l as it +currently treats \|r. This feature allows a \.{WEB} programmer to invent +new reserved words and/or to unreserve some of \PASCAL's reserved +identifiers. The definition part of each module consists of any number of +macro definitions (beginning with \.{@d}) and format definitions (beginning +with \.{@f}), intermixed in any order. + +\@p [\oP,\oT] The \PASCAL\ part of an unnamed module begins with \.{@p} +(or \.{@P}). This causes \.{TANGLE} to append the following \PASCAL\ code +to the initial program text $T_0$ as explained above. The \.{WEAVE} +processor does not cause a `\.{@p}' to appear explicitly in the \TeX\ +output, so if you are creating a \.{WEB} file based on a \TeX-printed +\.{WEB} documentation you have to remember to insert \.{@p} in the +appropriate places of the unnamed modules. + +\@< [P,\oT] A module name begins with \.{@<} followed by \TeX\ text followed +by \.{@>}; the \TeX\ text should not contain any \.{WEB} control codes +except \.{@@}, unless these control codes appear in \PASCAL\ text that +is delimited by \pb. The module name may be abbreviated, after its first +appearance in a \.{WEB} file, by giving any unique prefix followed by \.{...}, +where the three dots immediately precede the closing \.{@>}. No module name +should be a prefix of another. Module names may not appear in \PASCAL\ +text that is enclosed in \pb, nor may they appear in the definition part +of a module (since the appearance of a module name ends the definition +part and begins the \PASCAL\ part). + +\@\' [P,T] This denotes an octal constant, to be formed from the +succeeding digits. For example, if the \.{WEB} file contains `\.{@\'100}', +the \.{TANGLE} processor will treat this an equivalent to `\.{64}'; +the constant will be formatted as ``\O{100}'' in the \TeX\ output +produced via \.{WEAVE}. You should use octal notation only for positive +constants; don't try to get, e.g., $-1$ by saying `\.{@\'777777777777}'. + +\@" [P,T] A hexadecimal constant; `\.{@"D0D0}' tangles to \.{53456} and +weaves to `\H{D0D0}'. + +\@\$ [P] This denotes the string pool check sum. + +\@\{ [P] The beginning of a ``meta comment,'' i.e., a comment +that is supposed to appear in the \PASCAL\ code, is indicated by +\.{@\{} in the \.{WEB} file. Such delimiters can be used as +isolated symbols in macros or modules, but they should be properly nested +in the final \PASCAL\ program. The \.{TANGLE} processor will convert +`\.{@\{}' into `\.\{' in the \PASCAL\ output file, unless +the output is already part of a meta-comment; in the latter case +`\.{@\{}' is converted into `\.[', since \PASCAL\ does not allow +nested comments. The \.{WEAVE} processor outputs `\.{@\{}'. +Incidentally, module numbers are automatically inserted +as meta-comments into the \PASCAL\ program, in order to help correlate the +outputs of \.{WEAVE} and \.{TANGLE} (see Appendix~C\null). Meta-comments +can be used to put conditional text into a \PASCAL\ program; this helps to +overcome one of the limitations of \.{WEB}, since the simple macro +processing routines of \.{TANGLE} do not include the dynamic evaluation of +boolean expressions. + +\@\} [P] The end of a ``meta comment'' is indicated by `\.{@\}}'; this is +converted either into `\.\}' or `\.{]}' in the \PASCAL\ output, according +to the conventions explained for \.{@\{} above. +The \.{WEAVE} processor outputs `\.{@\}}'. + +\@\& [P] The \.{@\&} operation causes whatever is on its left to be +adjacent to whatever is on its right, in the \PASCAL\ output. No spaces or +line breaks will separate these two items. However, the thing on the left +should not be a semicolon, since a line break might occur after a semicolon. + +\@\^ [P,T] The ``control text'' that follows, up to the next +`\.{@>}', will be entered into the index together with the identifiers of +the \PASCAL\ program; this text will appear in roman type. For example, to +put the phrase ``system dependencies'' into the index, you can type +`\.{@\^system dependencies@>}' in each module +that you want to index as system dependent. A control text, like a string, +must end on the same line of the \.{WEB} file as it began. Furthermore, +no \.{WEB} control codes are allowed in a control text, not even +\.{@@}. (If you need an \.{@} sign you can get around this restriction by +typing `\.{\\AT!}'.) + +\@. [P,T] The ``control text'' that follows will be entered into the index +in \.{typewriter} \.{type}; see the rules for `\.{@\^}', which is analogous. + +\@: [P,T] The ``control text'' that follows will be entered into the index +in a format controlled by the \TeX\ macro `\.{\\9}', which the user +should define as desired; see the rules for `\.{@\^}', which is analogous. + +\@t [P] The ``control text'' that follows, up to the next `\.{@>}', will +be put into a \TeX\ \.{\\hbox} and formatted along with the neighboring +\PASCAL\ program. This text is ignored by \.{TANGLE}, but it can be used +for various purposes within \.{WEAVE}. For example, you can make comments +that mix \PASCAL\ and classical mathematics, as in `$\\{size}<2^{15}$', by +typing `\.{|size < @t\$2\^\{15\}\$@>|}'. A control text must end on the +same line of the \.{WEB} file as it began, and it may not contain any +\.{WEB} control codes. + +\@= [P] The ``control text'' that follows, up to the next `\.{@>}', will +be passed verbatim to the \PASCAL\ program. + +\@\\ [P] Force end-of-line here in the \PASCAL\ program file. + +\@! [P,T] The module number in an index entry will be underlined if `\.{@!}' +immediately precedes the identifier or control text being indexed. This +convention is used to distinguish the modules where an identifier is +defined, or where it is explained in some special way, from the modules +where it is used. A~reserved word or an identifier of length one will not +be indexed except for underlined entries. An `\.{@!}' is implicitly inserted +by \.{WEAVE} just after the reserved words \&{function}, \&{procedure}, +\&{program}, and \&{var}, and just after \.{@d} and \.{@f}. But you should +insert your own `\.{@!}' before the definitions of types, constants, +variables, parameters, and components of records and enumerated types that +are not covered by this implicit convention, if you want to improve the +quality of the index that you get. + +\@? [P,T] This cancels an implicit (or explicit) `\.{@!}', so that the next +index entry will not be underlined. + +\@, [P] This control code inserts a thin space in \.{WEAVE}'s output; it is +ignored by \.{TANGLE}. Sometimes you need this extra space if you are using +macros in an unusual way, e.g., if two identifiers are adjacent. + +\@/ [P] This control code causes a line break to occur within a \PASCAL\ +program formatted by \.{WEAVE}; it is ignored by \.{TANGLE}. Line breaks +are chosen automatically by \TeX\ according to a scheme that works 99\%\ +of the time, but sometimes you will prefer to force a line break so that +the program is segmented according to logical rather than visual criteria. +Caution: `\.{@/}' should be used only after statements or clauses, not in +the middle of an expression; use \.{@|} in the middle of expressions, in +order to keep \.{WEAVE}'s parser happy. + +\@| [P] This control code specifies an optional line break in the midst of +an expression. For example, if you have a long condition between \&{if} and +\&{then}, or a long expression on the right-hand side of an assignment +statement, you can use `\.{@|}' to specify breakpoints more logical than +the ones that \TeX\ might choose on visual grounds. + +\@\# [P] This control code forces a line break, like \.{@/} does, +and it also causes a little extra white space to appear between the lines at +this break. You might use it, for example, between procedure definitions or +between groups of macro definitions that are logically separate but within +the same module. + +\@+ [P] This control code cancels a line break that might otherwise be +inserted by \.{WEAVE}, e.g., before the word `\&{else}', if you want to +put a short if-then-else construction on a single line. It is ignored by +\.{TANGLE}. + +\@; [P] This control code is treated like a semicolon, for formatting +purposes, except that it is invisible. You can use it, for example, after +a module name when the \PASCAL\ text represented by that module name ends +with a semicolon. + +\yskip\noindent +The last six control codes (namely `\.{@,}', `\.{@/}', `\.{@|}', +`\.{@\#}', `\.{@+}', and `\.{@;}') have no effect on the \PASCAL\ +program output by \.{TANGLE}; they merely help to improve the readability +of the \TeX-formatted \PASCAL\ that is output by \.{WEAVE}, in unusual +circumstances. \.{WEAVE}'s built-in formatting method is fairly good, but +it is incapable of handling all possible cases, because it must deal with +fragments of text involving macros and module names; these fragments do +not necessarily obey \PASCAL's syntax. Although \.{WEB} allows you to +override the automatic formatting, your best strategy is not to worry +about such things until you have seen what \.{WEAVE} produces automatically, +since you will probably need to make only a few corrections when you are +touching up your documentation. + +Because of the rules by which every module is broken into three parts, +the control codes `\.{@d}', `\.{@f}', and `\.{@p}' are not allowed to occur +once the \PASCAL\ part of a module has begun. + \section Additional features and caveats. + +1. The character pairs `\.{(*}', `\.{*)}', `\.{(.}', and `\.{.)}' are +converted automatically in \PASCAL\ text as though they were +`\.{@\{}', `\.{@\}}', `\.[', and `\.]', respectively, except +of course in strings. Furthermore in certain installations of \.{WEB} that +{\def\\#1#2{`{\tentex\char'#1#2}'}% +have an extended character set, the characters \\32, \\34, \\35, \\30, +\\36, \\04, \\37, \\05, and \\06} +can be typed as abbreviations for +`\.{<>}', `\.{<=}', `\.{>=}', `\.{:=}', `\.{==}', `\.{and}', `\.{or}', +`\.{not}', and `\.{in}', respectively. However, the latter abbreviations +are not used in the standard versions of \.{WEAVE.WEB} and \.{TANGLE.WEB} +that are distributed to people who are installing \.{WEB} on other +computers, and the programs are designed to produce only standard ASCII +characters as output if the input consists entirely of ASCII characters. + +2. If you have an extended character set, all of the characters listed +in Appendix C of {\sl The \TeX book\/} can be used in strings. But you should +stick to standard ASCII characters if you want to write programs that will +be useful to all the poor souls out there who don't have extended +character sets. + +3. The \TeX\ file output by \.{WEAVE} is broken into lines having at most +80 characters each. The algorithm that does this line breaking is unaware +of \TeX's convention about comments following `\.\%' signs on a line. When +\TeX\ text is being copied, the existing line breaks are copied as well, +so there is no problem with `\.\%' signs unless the original \.{WEB} file +contains a line more than eighty characters long or a line with \PASCAL\ +text in \pb\ that expands to more than eighty characters long. Such lines +should not have `\.\%' signs. + +4. \PASCAL\ text is translated by a ``bottom up'' procedure that +identifies each token as a ``part of speech'' and combines parts of speech +into larger and larger phrases as much as possible according to a special +grammar that is explained in the documentation of \.{WEAVE}. It is easy to +learn the translation scheme for simple constructions like single +identifiers and short expressions, just by looking at a few examples of +what \.{WEAVE} does, but the general mechanism is somewhat complex because +it must handle much more than \PASCAL\ itself. Furthermore the output +contains embedded codes that cause \TeX\ to indent and break lines as +necessary, depending on the fonts used and the desired page width. For +best results it is wise to adhere to the following restrictions: + +\yskip\itemitem{a)}Comments in \PASCAL\ text should appear only after +statements or clauses; i.e., after semicolons, after reserved words like +\&{then} and \&{do}, or before reserved words like \&{end} and \&{else}. +Otherwise \.{WEAVE}'s parsing method may well get mixed up. + +\itemitem{b)}Don't enclose long \PASCAL\ texts in \pb, since the +indentation and line breaking codes are omitted when the \pb\ text is +translated from \PASCAL\ to \TeX. Stick to simple expressions or +statements. + +\yskip +5. Comments and module names are not permitted in \pb\ text. After a `\.|' +signals the change from \TeX\ text to \PASCAL\ text, the next `\.|' that is +not part of a string or control text ends the \PASCAL\ text. + +6. A comment must have properly nested occurrences of left and right +braces, otherwise \.{WEAVE} and \.{TANGLE} will not know where the comment +ends. However, the character pairs `\.{\\\{}' and `\.{\\\}}' do not count +as left and right braces in comments, and the character pair `\.{\\|}' +does not count as a delimiter that begins \PASCAL\ text. (The actual rule +is that a character after `\.\\' is ignored; hence in `\.{\\\\\{}' the +left brace {\sl does\/} count.) At present, \.{TANGLE} and \.{WEAVE} treat +comments in slightly different ways, and it is necessary to satisfy both +conventions: \.{TANGLE} ignores `\.|' characters entirely, while \.{WEAVE} +uses them to switch between \TeX\ text and \PASCAL\ text. Therefore, a +comment that includes a brace in a string in \pb---e.g., `\.{\{{ }look at +this |"\{"| \}}'---will be handled correctly by \.{WEAVE}, but \.{TANGLE} +will think there is an unmatched left brace. In order to satisfy both +processors, one can write `\.{\{{ }look at this \\leftbrace\\{ }\}}', after +setting up `\.{\\def\\leftbrace\{|"\{"|\}}'. + +7. Reserved words of \PASCAL\ must appear entirely in lowercase letters +in the \.{WEB} file; otherwise their special nature will not be recognized +by \.{WEAVE}. You could, for example, have a macro named \\{END} and it +would not be confused with \PASCAL's \&{end}. + +However, you may not want to capitalize macro names just to distinguish them +from other identifiers. Here is a way to unreserve \PASCAL's reserved word +`\&{type}' and to substitute another word `\&{mtype}' in the \.{WEB} file. +$$\vbox{\halign{\tt #\hfil\cr +@d type(\char'43) == mem[\char'43].t\cr +@d mtype == t \char'100\char'46{} y \char'100\char'46{} p + \char'100\char'46{} e\cr +@f mtype == type\cr +@f type == true\cr}}$$ +In the output of \.{TANGLE}, the macro \.{mtype} now produces `\.{TYPE}' +and the macro \.{type(x)} now produces `\.{MEM[X].T}'. In the output of +\.{WEAVE}, these same inputs produce \&{mtype} and \\{type}(\|x), +respectively. + +8. The \.{@f} feature allows you to define one identifier to act like +another, and these format definitions are carried out sequentially, as the +example above indicates. However, a given identifier has only one printed format +throughout the entire document (and this format will even be used before +the \.{@f} that defines it). The reason is that \.{WEAVE} operates in two +passes; it processes \.{@f}'s and cross-references on the first pass and +it does the output on the second. + +9. You may want some \.{@f} formatting that doesn't correspond to any +existing reserved word. In that case, \.{WEAVE} could be extended in a +fairly obvious way to include new ``reserved words'' in its vocabulary. +The identifier `\&{xclause}' has in fact been included already as a +reserved word, so that it can be used to format the `\&{loop}' macro, +where `\&{loop}' is defined to be equivalent to `\&{while \\{true} do}'. + +10. Sometimes it is desirable to insert spacing into \PASCAL\ code that is +more general than the thin space provided by `\.{@,}'. The \.{@t} feature +can be used for this purpose; e.g., `\.{@t\\hskip 1in@>}' will +leave one inch of blank space. Furthermore, `\.{@t\\4@>}' can be +used to backspace by one unit of indentation, since the control sequence +\.{\\4} is defined in \.{webmac} to be such a backspace. (This +control sequence is used, for example, at the beginning of lines that +contain labeled statements, so that the label will stick out a little at +the left.) + +11. \.{WEAVE} and \.{TANGLE} are designed to work with two input files, +called \\{web\_file} and \\{change\_file}, where \\{change\_file} contains +data that overrides selected portions of \\{web\_file}. The resulting merged +text is actually what has been called the \.{WEB} file elsewhere in this +report. + +Here's how it works: The change file consists of zero or more ``changes,'' +where a change has the form `\.{@x}$\langle$old lines$\rangle$\.{@y}$\langle$% +new lines$\rangle$\.{@z}'. The special control codes \.{@x}, \.{@y}, \.{@z}, +which are allowed only in change files, must appear at the beginning of a line; +the remainder of such a line is ignored. +The $\langle$old lines$\rangle$ represent material that exactly matches +consecutive lines of the \\{web\_file}; the $\langle$new lines$\rangle$ +represent zero or more lines that are supposed to replace the old. Whenever +the first ``old line'' of a change is found to match a line in the +\\{web\_file}, all the other lines in that change must match too. + +Between changes, before the first change, and after the last change, +the change file can have any number of lines that do not begin with +`\.{@x}', `\.{@y}', or~`\.{@z}'. Such lines are bypassed and not used for +matching purposes. + +This dual-input feature is useful when working with a master \.{WEB} file +that has been received from elsewhere (e.g., \.{TANGLE.WEB} or +\.{WEAVE.WEB} or \.{TEX.WEB}), when changes are desirable to customize the +program for your local computer system. You will be able to debug your +system-dependent changes without clobbering the master web file; and once +your changes are working, you will be able to incorporate them readily +into new releases of the master web file that you might receive from time +to time. + \section Appendices. +The basic ideas of \.{WEB} can be understood most easily by looking at +examples of ``real'' programs. Appendix~A shows the \.{WEB} input that +generated modules 55--59 of the \.{WEAVE} program; Appendix~B shows the +corresponding \TeX\ code output by \.{WEAVE}; and Appendix~C shows excerpts +from the corresponding \PASCAL\ code output by \.{TANGLE}. + +The complete webs for \.{WEAVE} and \.{TANGLE} appear as the bulk of this +report, in Appendices D and~E. The reader should first compare Appendix~A +to the corresponding portion of Appendix~D; then the same material should +be compared to Appendices B and~C. Finally, if time permits, the reader may +enjoy studying the complete programs in Appendices D and~E, since \.{WEAVE} +and \.{TANGLE} contain several interesting aspects, and since an attempt +has been made in these appendices to evolve a style of programming that +makes good use of the \.{WEB} language. + +Finally, Appendix F is the `\.{webmac}' file that sets \TeX\ up to accept +the output of \.{WEAVE}; Appendix~G discusses how to use some of its macros +to vary the output formats; and Appendix~H discusses what needs to be done +when \.{WEAVE} and \.{TANGLE} are installed in a new operating environment. + \section Performance statistics. +The programs in Appendices D and E will optionally keep statistics on +how much memory they require. Here is what they once printed out when +processing themselves: + +\def\pstat#1#2#3 +#4{\yskip\noindent\.{#1} applied to \.{#2} (cpu time #3 sec)\par +\halign{\quad\tt##\hfil\cr#4}} + +\pstat{TANGLE}{TANGLE}{15} +{Memory usage statistics:\cr +456 names, 215 replacement texts;\cr +3396+3361 bytes, 6685+7329+5805 tokens.\cr} + +\pstat{TANGLE}{WEAVE}{30} +{Memory usage statistics:\cr +692 names, 339 replacement texts;\cr +4576+4294 bytes, 10184+9875+9150 tokens.\cr} + +\pstat{WEAVE}{TANGLE}{45} +{Memory usage statistics: 478 names, 2045 cross references, 4159+3729 bytes;\cr +parsing required 684 scraps, 1300 texts, 3766 tokens, 119 levels;\cr +sorting required 34 levels.\cr} + +\pstat{WEAVE}{WEAVE}{65} +{Memory usage statistics: 737 names, 3306 cross references, 4896+4962 bytes;\cr +parsing required 684 scraps, 1300 texts, 3766 tokens, 119 levels;\cr +sorting required 73 levels.\cr} + +\yskip\noindent The cpu time for \PASCAL\ to process \.{TANGLE.PAS} was +approximately 13 seconds, and \.{WEAVE.PAS} took approximately 26 seconds; +thus the tangling time was slightly more than the compiling time. The cpu +time for \TeX\ to process \.{TANGLE.TEX} was approximately 500 seconds, +and \.{WEAVE.TEX} took approximately 750 seconds (i.e., about 7 +seconds per printed page, where these pages are substantially larger than +the pages in a normal book). All cpu times quoted are for a DECsystem-10. + +\def\K{{\mc K}} +The file \.{TANGLE.WEB} is about 125\K\ characters long; \.{TANGLE} +reduces it to a file \.{TANGLE.PAS} whose size is about 42\K\ characters, +while \.{WEAVE} expands it to a file \.{TANGLE.TEX} of about 185\K\null. +The corresponding file sizes for \.{WEAVE.WEB}, \.{WEAVE.PAS}, and +\.{WEAVE.TEX} are 180\K, 89\K, and 265\K. + +The much larger file \.{TEX.WEB} led to the following numbers: + +\pstat{TANGLE}{TEX}{110} +{Memory usage statistics:\cr +3750 names, 1768 replacement texts;\cr +41895+41053 bytes, 42378+45074+41091 tokens.\cr} + +\pstat{WEAVE}{TEX}{270} +{Memory usage statistics: 3412 names, 19699 cross references, + 37900+40232 bytes;\cr +parsing required 685 scraps, 1303 texts, 3784 tokens, 104 levels;\cr +sorting required 52 levels.\cr} + +\yskip\noindent +\PASCAL\ did \.{TEX.PAS} in about 75 seconds; \TeX\ did \.{TEX.TEX} +in about 3600. + % Here is a quotation that could not really be omitted + +\vfill + +{\baselineskip9pt +\halign to\hsize{\hfil\quoteit#\tabskip 0pt plus 100pt& + \hfil\quoteit#\tabskip 0pt\cr +O, what a tangled web we weave& + O, what a tangled WEB we weave\cr +When first we practise to deceive!& + When \TeX\ we practise to conceive!\cr +\noalign{\vskip 2pt} +\quoterm ---SIR WALTER SCOTT, {\quoteit Marmion} 6:17 (1808)& + \quoterm ---RICHARD PALAIS (1982)\cr +}} +\eject + \def\runninghead{APPENDIX A --- {\tentt WEB} FILE FORMAT} +\section Appendix A. +This excerpt from \.{WEAVE.WEB} produced modules 55--59 in Appendix~D. +Note that some of the lines are indented to show the program structure. +The indentation is ignored by \.{WEAVE} and \.{TANGLE}, but users find +that \.{WEB} files are quite readable if they have some such indentation. + +\vskip 6pt +\begingroup \def\tt{\eighttt} \baselineskip9pt +% Note to myself: I had to remove SAIL characters from the file here! +% Also tabs replaced by double-space. The changes were made in WEAVE source. +\verbatim +@* Searching for identifiers. +The hash table described above is updated by the |id_lookup| procedure, +which finds a given identifier and returns a pointer to its index in +|byte_start|. The identifier is supposed to match character by character +and it is also supposed to have a given |ilk| code; the same name may be +present more than once if it is supposed to appear in the index with +different typesetting conventions. +If the identifier was not already present, it is inserted into the table. + +Because of the way \.{WEAVE}'s scanning mechanism works, it is most convenient +to let |id_lookup| search for an identifier that is present in the |buffer| +array. Two other global variables specify its position in the buffer: the +first character is |buffer[id_first]|, and the last is |buffer[id_loc-1]|. + +@= +@!id_first:0..long_buf_size; {where the current identifier begins in the buffer} +@!id_loc:0..long_buf_size; {just after the current identifier in the buffer} +@# +@!hash:array [0..hash_size] of sixteen_bits; {heads of hash lists} + +@ Initially all the hash lists are empty. + +@= +@!h:0..hash_size; {index into hash-head array} + +@ @= +for h:=0 to hash_size-1 do hash[h]:=0; + +@ Here now is the main procedure for finding identifiers (and index +entries). The parameter |t| is set to the desired |ilk| code. The +identifier must either have |ilk=t|, or we must have +|t=normal| and the identifier must be a reserved word. + +@p function id_lookup(@!t:eight_bits):name_pointer; {finds current identifier} +label found; +var i:0..long_buf_size; {index into |buffer|} +@!h:0..hash_size; {hash code} +@!k:0..max_bytes; {index into |byte_mem|} +@!w:0..ww-1; {row of |byte_mem|} +@!l:0..long_buf_size; {length of the given identifier} +@!p:name_pointer; {where the identifier is being sought} +begin l:=id_loc-id_first; {compute the length} +@; +@; +if p=name_ptr then @; +id_lookup:=p; +end; + +@ A simple hash code is used: If the sequence of +ASCII codes is $c_1c_2\ldots c_m$, its hash value will be +$$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,|hash_size|.$$ + +@= +h:=buffer[id_first]; i:=id_first+1; +while i0 DO BEGIN IF(BYTESTART[P+2]-BYTESTART[P]=L)AND((ILK[P]=T)OR((T +=0)AND(ILK[P]>3)))THEN{61:}BEGIN I:=IDFIRST;K:=BYTESTART[P];W:=P MOD 2; +WHILE(IMAXBYTES THEN BEGIN WRITELN(TERMOUT); +WRITE(TERMOUT,'! Sorry, ','byte memory',' capacity exceeded');ERROR; +HISTORY:=3;JUMPOUT;END; +IF NAMEPTR+2>MAXNAMES THEN BEGIN WRITELN(TERMOUT); +WRITE(TERMOUT,'! Sorry, ','name',' capacity exceeded');ERROR;HISTORY:=3; +JUMPOUT;END;I:=IDFIRST;K:=BYTEPTR[W]; +WHILE I}', the backslash character gets in the way, +and this entry wouldn't appear in the index with the T's. + +The solution is to use the `\.{@:}' feature, declaring a macro that +simply removes a sort key as follows: +$$\.{\\def\\9\#1\{\}}$$ +Now you can say, e.g., `\.{@:TeX\}\{\\TeX@>}' in your \.{WEB} file; \.{WEAVE} +puts it into the index alphabetically, based on the sort key, and +produces the macro call `\.{\\9\{TeX\}\{\\TeX\}}' which will ensure that +the sort key isn't printed. + +A similar idea can be used to insert hidden material into module +names so that they are alphabetized in whatever way you might wish. +Some people call these tricks ``special refinements''; others call +them ``kludges''. + +\point 12. The control sequence \.{\\modno} is set to the number of the +module being typeset. + +\point 13. If you want to list only the modules that have changed, +together with the index, put the command `\.{\\let\\maybe=\\iffalse}' in +the limbo section before the first module of your \.{WEB} file. It's +customary to make this the first change in your change file. + +\point 14. To get output in languages other than English, redefine the +macros \.{\\A}, \.{\\As}, \.{\\ET}, \.{\\ETs}, \.{\\U}, \.{\\Us}, +\.{\\ch}, \.{\\fin}, and \.{\\con}. \.{WEAVE} itself need not be changed. + +\vfill\eject + \def\runninghead{APPENDIX H --- GETTING STARTED} +\section Appendix H: Installing the \.{WEB} system. +Suppose you want to use the \.{WEB} programs on your computer, and suppose +that you can't simply borrow them from somebody else who has the same +kind of machine. Here's what to do: + +\yskip +\def\step(#1){\par\hangindent 2em\noindent\hbox to 2em{\hfil(#1) }\ignorespaces} +\step(1) Get a tape that contains the files \.{WEAVE.WEB}, \.{TANGLE.WEB}, +\.{TANGLE.PAS}, and \.{WEBMAC.TEX}. The tape will probably also contain an +example change file \.{TANGLE.CH}. +\step(2) Look at the sections of \.{TANGLE} that are listed under ``system +dependencies'' in the index of Appendix~E above, and figure out what changes +(if any) will be needed for your system. +\step(3) Make a change file \.{TANGLE.CH} that contains the changes of~(2); +do not change your copy of \.{TANGLE.WEB}, leave it intact. (The +rules for change files are explained at the end of the manual just before +the appendices; you may want to look at the example change file that +arrived with your copy of \.{TANGLE.WEB}. It's also a good idea to +define all the ``switches'' like \&{debug} and \&{gubed} to be null in your +first change files; then you can sure that your compiler will handle +all of the code.) +\step(4) Make the changes of (2) in your copy of \.{TANGLE.PAS}. (If these +changes are extensive, you might be better off finding some computer +that already has \.{TANGLE} running, and making the new \.{TANGLE.PAS} +from \.{TANGLE.WEB} and your \.{TANGLE.CH}.) +\step(5) Use your \PASCAL\ compiler to convert your copy of \.{TANGLE.PAS} +to a running program \.{TANGLE}. +\step(6) Check your changes as follows: Run \.{TANGLE} on \.{TANGLE.WEB} +and your \.{TANGLE.CH}, yielding $\.{TANGLE.PAS}'$; make a running +program $\.{TANGLE}'$ by applying \PASCAL\ to +$\.{TANGLE.PAS}'$; run $\.{TANGLE}'$ on \.{TANGLE.WEB} and +your \.{TANGLE.CH}, yielding $\.{TANGLE.PAS}''$; and check +that $\.{TANGLE.PAS}''$ is identical to +$\.{TANGLE.PAS}'$. Once this test has been passed, you have got a +working \.{TANGLE} program. +\step(7) Make a change file \.{WEAVE.CH} analogous to (3), but this time +consider the system-dependent parts of \.{WEAVE} that are listed in +the index to Appendix~D. +\step(8) Run \.{TANGLE} on \.{WEAVE.WEB} and your \.{WEAVE.CH}, obtaining +\.{WEAVE.PAS}. +\step(9) Use \PASCAL\ on \.{WEAVE.PAS} to make a running \.{WEAVE} program. +\step(10) Run \.{WEAVE} on \.{TANGLE.WEB} and \.{TANGLE.CH} to produce +\.{TANGLE.TEX}. +\step(11) Run \TeX\ on \.{TANGLE.TEX}, obtaining a listing analogous to +Appendix~E. This listing will incorporate your changes. +\step(12) Run \.{WEAVE} on \.{WEAVE.WEB} and your \.{WEAVE.CH} to produce +\.{WEAVE.TEX}. +\step(13) Run \TeX\ on \.{WEAVE.TEX}, obtaining a listing analogous to +Appendix~D that incorporates your changes. + +\yskip\noindent +This description assumes that you already have a working \TeX82 system. +But what if you don't have \TeX82? Then you start with a tape that also +contains \.{TEX.WEB} and \.{plain.tex}, and you refer to a hardcopy +listing of the \TeX82 program corresponding to \.{TEX.WEB}. Between steps +(10) and (11) you do the following: + +\yskip +\def\substep(10.#1){\par\hangindent 4em\noindent + \hbox to 4em{\hfil(10.#1) }\ignorespaces} +\substep(10.1) Make a change file \.{TEX.CH} to fix the system dependent +portions of \.{TEX.WEB}, in a manner analogous to step~(2). Since \TeX\ is +a much more complex program than \.{WEAVE} or \.{TANGLE}, there are more +system-dependent features to think about, but by now you will be good at +making such modifications. Do not make any changes to \.{TEX.WEB}. +\substep(10.2) Make an almost-copy of your \.{TEX.CH} called \.{INITEX.CH}; +this one will have the `\&{init}' and `\&{tini}' macros redefined in order +to make the initialization version of \TeX. It also might have smaller +font memory and dynamic memory areas, since \.{INITEX} doesn't need as +much memory for such things; by setting the memory smaller in \.{INITEX}, +you guarantee that the production system will have a ``cushion.'' +\substep(10.3) Run \.{TANGLE} on \.{TEX.WEB} and \.{INITEX.CH}, obtaining +\.{INITEX.PAS} and \.{TEX.POOL}. +\substep(10.4) Run \PASCAL\ on \.{INITEX.PAS}, obtaining \.{INITEX}. +\substep(10.5) Run \.{INITEX} on \.{TEX.POOL}, during which run you type +`\.{plain}' and `\.{\\dump}'. This will produce a file \.{plain.fmt} +containing the data needed to initialize \TeX's memory. +\substep(10.6) Run \.{TANGLE} on \.{TEX.WEB} and the \.{TEX.CH} of (10.1), +obtaining \.{TEX.PAS}. +\substep(10.7) Run \PASCAL\ on \.{TEX.PAS}, obtaining \.{VIRTEX}. +\substep(10.8) If your operating system supports programs whose core images +have been saved, run \.{VIRTEX}, type `\.{\&plain}', then save the core image +and call it \TeX. Otherwise, \.{VIRTEX} will be your \TeX, and it will +read `\.{plain.fmt}' (or some other \.{fmt} file) each time you run. + +\yskip +This 21-step process may seem long, but it is actually an oversimplification, +since you also need fonts and a way to print the device-independent files +that \TeX\ spews out. On the other hand, the total number of steps is not +quite so large when you consider that \.{TANGLE}-followed-by-\PASCAL\ and +\.{WEAVE}-followed-by-\TeX\ may be regarded as single operations. + +If you have only the present report, not a tape, you will have to prepare +files \.{WEAVE.WEB} and \.{TANGLE.WEB} by hand, typing them into the +computer by following Appendices D and E. Then you have to simulate the +behavior of \.{TANGLE} by converting \.{TANGLE.WEB} manually into +\.{TANGLE.PAS}; with a good text editor this takes about six hours. Then +you have to correct errors that were made in all this hand work; but still +the whole project is not impossibly difficult, because in fact the entire +development of \.{WEAVE} and \.{TANGLE} (including the writing of the +programs and this manual) took less than two months of work. + \vfill\end -- cgit v1.2.3