2  INTRODUCTION  WEAVE changes for Vax/VMS §1

1* . Introduction. This program converts a file to a TEX file. It was written by D. E. Knuth in October, 1981; a somewhat similar SAIL program had been developed in March, 1979, although the earlier program used a top-down parsing method that is quite different from the present scheme.

The code uses a few features of the local Pascal compiler that may need to be changed in other installations:

1) Case statements have a default.

2) Input-output routines may need to be adapted for use with a particular character set and/or for printing messages on the user’s terminal.

These features are also present in the Pascal version of TEX, where they are used in a similar (but more complex) way. System-dependent portions of can be identified by looking at the entries for ‘system dependencies’ in the index below.

The “banner line” defined here should be changed whenever is modified.

For the VAX/VMS version of , we add a second decimal point and number to the main version number, so we can differentiate between changes to the standard and changes local to the VAX/VMS version of .

define banner ≡ ´ ␣ ␣ ␣ ␣ ␣ ´

2* . The program begins with a fairly normal header, made up of pieces that will mostly be filled in later. The input comes from files web file and change file, and the TEX output goes to file tex file. VMS requires us to mention input and output in the program header, too. They are used for terminal input and output.

If it is necessary to abort the job because of a fatal error, the program calls the ‘jump out ’ procedure, which goes to the label end of WEAVE .

define end of WEAVE = 9999 { go here to wrap it up } ⟨ Compiler directives 4* ⟩ program WEAVE (input , output , web file, change file, tex file);

label end of WEAVE ; { go here to finish }

const ⟨ Constants in the outer block 8* ⟩

type ⟨ Types in the outer block 11 ⟩

var ⟨ Globals in the outer block 9 ⟩

⟨ Error handling procedures 30 ⟩ procedure initialize;

var ⟨ Local variables for initialization 16 ⟩ begin ⟨ Preset initial values 269* ⟩ ⟨ Set initial values 10 ⟩ end;

4* . The Pascal compiler used to develop this system has “compiler directives” that can appear in comments whose first character is a dollar sign. In production versions of these directives tell the compiler that it is safe to avoid range checks and to leave out the extra code it inserts for the Pascal debugger’s benefit, although interrupts will occur if there is arithmetic overflow.

On Vax/VMS, things are a bit different. ⟨ Compiler directives 4* ⟩ ≡

\underline{\overline{}}\{ no debug overhead, but... \}

debug \underline{\overline{}}

gubed { turn everything on when debugging }

This code is used in section 2*.

§7  WEAVE changes for Vax/VMS  INTRODUCTION 3

7* . We assume that case statements may include a default case that applies if no matching label is found. Thus, we shall use constructions like

case x of

1: ⟨ code for x = 1 ⟩; 3: ⟨ code for x = 3 ⟩; othercases ⟨ code for x ≠ 1 and x ≠ 3 ⟩ endcases

since most Pascal compilers have plugged this hole in the language by incorporating some sort of default mechanism. For example, the compiler used to develop and TEX allows ‘others :’ as a default label, and other Pascals allow syntaxes like ‘else’ or ‘otherwise’ or ‘otherwise:’, etc. The definitions of othercases and endcases should be changed to agree with local conventions. (Of course, if no default mechanism is available, the case statements of this program must be extended by listing all remaining cases.)

define othercases ≡ otherwise { Vax/VMS default for cases not listed explicitly } define endcases ≡ end { follows the default case in an extended case statement } format othercases ≡ else format endcases ≡ end

8* . The following parameters are set big enough to handle TEX, so they should be sufficient for most applications of . ⟨ Constants in the outer block 8* ⟩ ≡

max bytes = 45000; { 1/ww times the number of bytes in identifiers, index entries, and module names;

must be less than 65536 } max names = 5000; { number of identifiers, index entries, and module names; must be less than 10240 } max modules = 2000; { greater than the total number of modules } hash size = 353; { should be prime } buf size = 100; { maximum length of input line } longest name = 400; { module names shouldn’t be longer than this } long buf size = 500; { buf size + longest name } line length = 80; { lines of TEX output have at most this many characters, should be less than 256 } max refs = 30000; { number of cross references; must be less than 65536 } max toks = 30000; { number of symbols in Pascal texts being parsed; must be less than 65536 } max texts = 2000; { number of phrases in Pascal texts being parsed; must be less than 10240 } max scraps = 1000; { number of tokens in Pascal texts being parsed } stack size = 200; { number of simultaneous output levels }

This code is used in section 2*.

4  THE CHARACTER SET  WEAVE changes for Vax/VMS §11

12* . 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, so assumes that it is being used with a Pascal whose character set contains at least the characters of standard ASCII as listed above. Some Pascal compilers use the original name char for the data type associated with the characters in text files, while other Pascals 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 in the input and output files. 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.

define text char ≡ char { the data type of characters in text files }

define first text char = 0 { ordinal number of the smallest element of text char }

define last text char = 127 { ordinal number of the largest element of text char } ⟨ Types in the outer block 11 ⟩ +≡

text file = text ;

§19  WEAVE changes for Vax/VMS  INPUT AND OUTPUT 5

20* . Terminal output is done by writing on file term out , which is assumed to consist of characters of type text char :

define print (#) ≡ write(term out , #) { ‘print ’ means write on the terminal }

define print ln(#) ≡ write ln(term out , #, chr (13), chr (10)) { ‘print ’ and then start new line } define new line ≡ write ln(term out , chr (13), chr (10)) { start new line } define print nl (#) ≡ { print information starting on a new line }

begin new line; print (#); end

⟨ Globals in the outer block 9 ⟩ +≡ term out : text file; { the terminal as an output file }

21* . Different systems have different ways of specifying that the output on a certain file will appear on the user’s terminal. Here is one way to do this on the Pascal system that was used in ’s initial development: ⟨ Set initial values 10 ⟩ +≡

\underline{\overline{␣}} (term out , ´ $ ´ , \underline{\overline{}}); rewrite(term out );

22* . The update terminal procedure 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.

define update terminal ≡ write ln(term out ) { empty the terminal output buffer }

26* . The following code opens tex file. Actually, on Vax/VMS this task is put off until later.

27* . Input goes into an array called buffer . Actually, it is first read into temp buffer . ⟨ Globals in the outer block 9 ⟩ +≡ buffer : array [0 . . long buf size] of ASCII code; temp buffer : varying [buf size] of char ;

6  INPUT AND OUTPUT  WEAVE changes for Vax/VMS §28

28* . The input ln procedure brings the next line of input from the specified file into the buffer array and returns the value true, unless the file has already been entirely read, in which case it returns false. The conventions of TEX are followed; i.e., ASCII code numbers representing the next line of the file are input into buffer [0], buffer [1], …, buffer [limit − 1]; trailing blanks are ignored; and the global variable limit is set to the length of the line. The value of limit must be strictly less than buf size.

We assume that none of the ASCII code values of buffer [j] for 0 ≤ j < limit is equal to 0, ´ 177 , line feed , form feed , or carriage return. Since buf size is strictly less than long buf size, some of ’s routines use the fact that it is safe to refer to buffer [limit + 2] without overstepping the bounds of the array.

On Vax/VMS we first read a line into temp buffer , since that’s faster. function input ln(var f : text file): boolean; { inputs a line or returns false }

var i, l: 0 . . buf size;

begin limit ← 0;

if eof (f) then input ln ← false

else begin read (f, temp buffer ); l ← temp buffer . \underline{\overline{}};

for i ← 1 to l do begin buffer [i − 1] ← xord [temp buffer [i]]; if buffer [i − 1] ≠ ␣ then limit ← i; end;

if ¬eoln(f) then begin print nl (´ ␣ ␣ ␣ ␣ ´ ); error ; end

else read ln(f); input ln ← true; end;

end;

§29  WEAVE changes for Vax/VMS  DATA STRUCTURES 7

42* . Several types of identifiers are distinguished by their ilk :

normal identifiers are part of the Pascal program and will appear in italic type. roman identifiers are index entries that appear after in the file. wildcard identifiers are index entries that appear after in the file. typewriter identifiers are index entries that appear after in the file. array like, begin like, …, var like identifiers are Pascal reserved words whose ilk explains how they are

to be treated when Pascal code is being formatted. Finally, if c is an ASCII code, an ilk equal to char like + c denotes a reserved word that will be converted

to character c. define normal = 0 { ordinary identifiers have normal ilk } define roman = 1 { normal index entries have roman ilk } define wildcard = 2 { user-formatted index entries have wildcard ilk } define typewriter = 3 { ‘typewriter type’ entries have typewriter ilk } define reserved (#) ≡ (ilk [#] > typewriter ) { tells if a name is a reserved word } define array like = 4 { array, file, set } define begin like = 5 { begin } define case like = 6 { case } define const like = 7 { const, label, type } define div like = 8 { div, mod } define do like = 9 { do, then } define else like = 10 { else } define end like = 11 { end } define for like = 12 { for, if, while, with } define goto like = 13 { implementation, definition, packed } define if like = 14 { not used for — see for like } define in like = 15 { in } define nil like = 16 { nil } define proc like = 17 { procedure, module } define record like = 18 { record } define repeat like = 19 { repeat } define to like = 20 { to } define until like = 21 { until, end } define var like = 22 { var } define loop like = 23 { loop } define elsif like = 24 { elsif } define of like = 25 { of } define char like = 26 { and, or, not, in }

8  INITIALIZING THE TABLE OF RESERVED WORDS  WEAVE changes for Vax/VMS §55

63* . Initializing the table of reserved words. We have to get Modula-2’s reserved words into the hash table, and the simplest way to do this is to insert them every time is run. A few macros permit us to do the initialization with a compact program.

define sid14 (#) ≡ buffer [14] ← #; cur name ← id lookup define sid13 (#) ≡ buffer [13] ← #; sid14 define sid12 (#) ≡ buffer [12] ← #; sid13 define sid11 (#) ≡ buffer [11] ← #; sid12 define sid10 (#) ≡ buffer [10] ← #; sid11 define sid9 (#) ≡ buffer [9] ← #; sid10 define sid8 (#) ≡ buffer [8] ← #; sid9 define sid7 (#) ≡ buffer [7] ← #; sid8 define sid6 (#) ≡ buffer [6] ← #; sid7 define sid5 (#) ≡ buffer [5] ← #; sid6 define sid4 (#) ≡ buffer [4] ← #; sid5 define sid3 (#) ≡ buffer [3] ← #; sid4 define sid2 (#) ≡ buffer [2] ← #; sid3 define sid1 (#) ≡ buffer [1] ← #; sid2 define id2 ≡ id first ← 13; sid13 define id3 ≡ id first ← 12; sid12 define id4 ≡ id first ← 11; sid11 define id5 ≡ id first ← 10; sid10 define id6 ≡ id first ← 9; sid9 define id7 ≡ id first ← 8; sid8 define id8 ≡ id first ← 7; sid7 define id9 ≡ id first ← 6; sid6 define id10 ≡ id first ← 5; sid5 define id11 ≡ id first ← 4; sid4 define id12 ≡ id first ← 3; sid3 define id13 ≡ id first ← 2; sid2 define id14 ≡ id first ← 1; sid1

⟨ Globals in the outer block 9 ⟩ +≡ cur name: name pointer ; { points to the identifier just inserted }

§64  WEAVE changes for Vax/VMS  INITIALIZING THE TABLE OF RESERVED WORDS 9

64* . The intended use of the macros above might not be immediately obvious, but the riddle is answered by the following: ⟨ Store all the reserved words 64* ⟩ ≡

id loc ← 15; id3 ( )( )( )(char like + and sign); id5 ( )( )( )( )( )(array like); id5 ( )( )( )( )( )(begin like); id2 ( )( )(to like); id4 ( )( )( )( )(case like); id5 ( )( )( )( )( )(const like); id3 ( )( )( )(div like); id2 ( )( )(do like); id10 ( )( )( )( )( )( )( )( )( )( )(goto like); id4 ( )( )( )( )(else like); id5 ( )( )( )( )( )(elsif like); id3 ( )( )( )(end like); id4 ( )( )( )( )(goto like); id6 ( )( )( )( )( )( )(goto like); id3 ( )( )( )(for like); id4 ( )( )( )( )(goto like); id2 ( )( )(for like); id14 ( )( )( )( )( )( )( )( )( )( )( )( )( )( )(goto like); id6 ( )( )( )( )( )( )(goto like); id2 ( )( )(char like + set element sign); id5 ( )( )( )( )( )(const like); id4 ( )( )( )( )(loop like); id6 ( )( )( )( )( )( )(proc like); id3 ( )( )( )(div like); id3 ( )( )( )(nil like); id3 ( )( )( )(char like + not sign); id2 ( )( )(of like); id2 ( )( )(char like + or sign); id7 ( )( )( )( )( )( )( )(goto like); id9 ( )( )( )( )( )( )( )( )( )(proc like); id9 ( )( )( )( )( )( )( )( )( )(goto like); id6 ( )( )( )( )( )( )(record like); id6 ( )( )( )( )( )( )(repeat like); id6 ( )( )( )( )( )( )(goto like); id3 ( )( )( )(array like); id4 ( )( )( )( )(do like); id2 ( )( )(to like); id4 ( )( )( )( )(const like); id5 ( )( )( )( )( )(until like); id3 ( )( )( )(var like); id5 ( )( )( )( )( )(for like); id4 ( )( )( )( )(for like);

This code is used in section 261*.

10  LEXICAL SCANNING  WEAVE changes for Vax/VMS §65

86* . Control codes in , which begin with ‘ ’, are converted into a numeric code designed to simplify ’s logic; for example, larger numbers are given to the control codes that denote more significant milestones, and the code of new module should be the largest of all. Some of these numeric control codes take the place of ASCII control codes that will not otherwise appear in the output of the scanning routines.

define ignore = 0 { control code of no interest to } define verbatim = ´ 2 { extended ASCII alpha will not appear } define force line = ´ 3 { extended ASCII beta will not appear } define vertical bar = 15 { control code for vertical bar character } define begin regular comment = 16 { control code for beginning of comments } define end regular comment = 17 { control code for ending of comments } define begin comment = ´ 11 { ASCII tab mark will not appear } define end comment = ´ 12 { ASCII line feed will not appear } define octal = ´ 14 { ASCII form feed will not appear } define hex = ´ 15 { ASCII carriage return will not appear } define double dot = ´ 40 { ASCII space will not appear except in strings } define no underline = ´ 175 { this code will be intercepted without confusion } define underline = ´ 176 { this code will be intercepted without confusion } define param = ´ 177 { ASCII delete will not appear } define xref roman = ´ 203 { control code for ‘ ’ } define xref wildcard = ´ 204 { control code for ‘ ’ } define xref typewriter = ´ 205 { control code for ‘ ’ } define TeX string = ´ 206 { control code for ‘ ’ } define check sum = ´ 207 { control code for ‘ $’ } define join = ´ 210 { control code for ‘ ’ } define thin space = ´ 211 { control code for ‘ ’ } define math break = ´ 212 { control code for ‘ ’ } define line break = ´ 213 { control code for ‘ ’ } define big line break = ´ 214 { control code for ‘ #’ } define no line break = ´ 215 { control code for ‘ ’ } define pseudo semi = ´ 216 { control code for ‘ ’ } define format = ´ 217 { control code for ‘ ’ } define definition = ´ 220 { control code for ‘ ’ } define begin Pascal = ´ 221 { control code for ‘ ’ } define module name = ´ 222 { control code for ‘ ’ } define new module = ´ 223 { control code for ‘ ␣’ and ‘ ’ }

§92  WEAVE changes for Vax/VMS  LEXICAL SCANNING 11

92* . ⟨ Do special things when c = , , , ; goto done at end 92* ⟩ ≡

if c = then begin c ← buffer [loc]; if (c ≠ ␣ ) ∧ (c ≠ tab mark ) ∧ (c ≠ ) then incr (loc) else begin decr (loc); bal ← 0; goto done;

end { an error message will occur in phase two } end

else if (c = ) ∧ (buffer [loc] ≠ ) then incr (loc)

else if c = begin regular comment then incr (bal )

else if c = end regular comment then begin decr (bal ); if bal = 0 then goto done; end

else if (c = ) ∧ (buffer [loc] = ) then begin incr (bal ); incr (loc); end

else if (c = ) ∧ (buffer [loc] = ) then begin decr (bal ); incr (loc); c ← end regular comment ; if bal = 0 then goto done; end

This code is used in section 91.

12  INPUTTING THE NEXT TOKEN  WEAVE changes for Vax/VMS §93

97* . Note that the following code converts ‘ ’ and ‘ ’ to internal characters which are converted back to ASCII when output. Adjacent vertical bar characters (´ ´ ), which represent the Modula-2 usage of that character rather than that of WEB, are handled the same way.

define compress (#) ≡

begin if loc ≤ limit then begin c ← #; incr (loc); end; end

⟨ Compress two-symbol combinations like ‘ ’ 97* ⟩ ≡ : if buffer [loc] = then compress (double dot )

else if buffer [loc] = then compress ( ); : if buffer [loc] = then compress (left arrow ); : if buffer [loc] = then compress (equivalence sign); : if buffer [loc] = then compress (greater or equal ); : if buffer [loc] = then compress (less or equal )

else if buffer [loc] = then compress (not equal ); : if buffer [loc] = then compress (begin regular comment )

else if buffer [loc] = then compress ( ); : if buffer [loc] = then compress (end regular comment ); : if buffer [loc] = then compress (vertical bar );

This code is used in section 95.

§108  WEAVE changes for Vax/VMS  PHASE ONE PROCESSING 13

111* . The Pascal xref subroutine stores references to identifiers in Pascal text material beginning with the current value of next control and continuing until next control is ‘ ’ or ‘ ’, or until the next “milestone” is passed (i.e., next control ≥ format ). If next control ≥ format when Pascal xref is called, nothing will happen; but if next control = upon entry, the procedure assumes that this is the ‘ ’ preceding Pascal text that is to be processed.

The program uses the fact that our internal code numbers satisfy the relations xref roman = identifier + roman and xref wildcard = identifier +wildcard and xref typewriter = identifier +typewriter and normal = 0. An implied ‘ ’ is inserted after function, procedure, program, and var. procedure Pascal xref ; { makes cross references for Pascal identifiers }

label exit ;

var p: name pointer ; { a referenced name }

begin while next control < format do

begin if (next control ≥ identifier ) ∧ (next control ≤ xref typewriter ) then begin p ← id lookup(next control − identifier ); new xref (p); if (ilk [p] = proc like) ∨ (ilk [p] = var like) then xref switch ← def flag ; { implied ‘ ’ } end;

next control ← get next ;

if (next control = ) ∨ (next control = begin regular comment ) then return; end;

exit : end;

112* . The outer xref subroutine is like Pascal xref but it begins with next control ≠ and ends with next control ≥ format . Thus, it handles Pascal text with embedded comments. procedure outer xref ; { extension of Pascal xref }

var bal : eight bits ; { brace level in comment }

begin while next control < format do if next control ≠ begin regular comment then Pascal xref else begin bal ← skip comment (1); next control ← ;

while bal > 0 do begin Pascal xref ; if next control = then bal ← skip comment (bal ) else bal ← 0; { an error will be reported in phase two } end; end;

end;

14  LOW-LEVEL OUTPUT ROUTINES  WEAVE changes for Vax/VMS §121

122* . The flush buffer routine empties the buffer up to a given breakpoint, and moves any remaining characters to the beginning of the next line. If the per cent parameter is true, a % is appended to the line that is being output; in this case the breakpoint b should be strictly less than line length. If the per cent parameter is false, trailing blanks are suppressed. The characters emptied from the buffer form a new line of output. procedure flush buffer (b : eight bits ; per cent : boolean); { outputs out buf [1 . . b], where b ≤ out ptr }

label done; var j, k: 0 . . line length; begin j ← b; if ¬per cent then { remove trailing blanks }

loop begin if j = 0 then goto done; if out buf [j] ≠ ␣ then goto done; decr (j); end;

done: for k ← 1 to j do out temp buffer [k] ← xchr [out buf [k]]; k ← j;

if per cent then

begin incr (k); out temp buffer [k] ← xchr [ % ];

end; write ln(tex file, substr (out temp buffer , 1, k)); incr (out line); if b < out ptr then

for k ← b + 1 to out ptr do out buf [k − b] ← out buf [k]; out ptr ← out ptr − b; end;

124* . In particular, the finish line procedure is called near the very beginning of phase two. We initialize the output variables in a slightly tricky way so that the first line of the output file will be ‘ ’. ⟨ Set initial values 10 ⟩ +≡

out ptr ← 1; out line ← 1; out buf [1] ← ; write(tex file, ´ ␣ ´ );

§132  WEAVE changes for Vax/VMS  ROUTINES THAT COPY TEX MATERIAL 15

136* . The copy comment uses and returns a brace-balance value, following the conventions of skip comment above. Instead of copying the TEX material into the output buffer, this procedure copies it into the token memory. The abbreviation app tok (t) is used to append token t to the current token list, and it also makes sure that it is possible to append at least one further token without overflow.

define app tok (#) ≡ begin if tok ptr + 2 > max toks then overflow (´ ´ ); tok mem[tok ptr ] ← #; incr (tok ptr ); end

function copy comment (bal : eight bits ): eight bits ; { copies TEX code in comments } label done; var c: ASCII code; { current character being copied }

begin loop

begin if loc > limit then begin get line;

if input has ended then

begin err print (´ ␣ ␣ ␣ ␣ ´ ); loc ← 1; ⟨ Clear bal and goto done 138* ⟩; end;

end; c ← buffer [loc]; incr (loc); if c = then goto done; if (c = ) ∧ (buffer [loc] = ) then

begin incr (loc); c ← end regular comment ; app tok ( ); end

else begin app tok (c);

end; ⟨ Copy special things when c = , , , ; goto done at end 137* ⟩; end;

done: copy comment ← bal ; end;

137* . ⟨ Copy special things when c = , , , ; goto done at end 137* ⟩ ≡

if c = then begin incr (loc); if buffer [loc − 1] ≠ then

begin err print (´ ␣ ␣ ␣ ␣ ␣ ␣ ´ ); loc ← loc − 2; decr (tok ptr ); ⟨ Clear bal and goto done 138* ⟩; end;

end else if (c = ) ∧ (buffer [loc] ≠ ) then

begin app tok (buffer [loc]); incr (loc); end

else if c = begin regular comment then incr (bal )

else if c = end regular comment then begin decr (bal ); if bal = 0 then goto done; end

else if (c = ) ∧ (buffer [loc] = ) then begin incr (bal ); incr (loc); end

This code is used in section 136*.

16  ROUTINES THAT COPY TEX MATERIAL  WEAVE changes for Vax/VMS §138

138* . When the comment has terminated abruptly due to an error, we output enough right braces to keep TEX happy. ⟨ Clear bal and goto done 138* ⟩ ≡

app tok ( ␣ ); { this is done in case the previous character was ‘ ’ } repeat app tok (end regular comment ); decr (bal ); until bal = 0; goto done;

This code is used in sections 136* and 137*.

§139  WEAVE changes for Vax/VMS  INITIALIZING THE SCRAPS 17

183* . Initializing the scraps. If we are going to use the powerful production mechanism just developed, we must get the scraps set up in the first place, given a Pascal text. A table of the initial scraps corresponding to Pascal tokens appeared above in the section on parsing; our goal now is to implement that table. We shall do this by implementing a subroutine called Pascal parse that is analogous to the Pascal xref routine used during phase one.

Like Pascal xref , the Pascal parse procedure starts with the current value of next control and it uses the operation next control ← get next repeatedly to read Pascal text until encountering the next ‘ ’ or ‘ ’, or until next control ≥ format . The scraps corresponding to what it reads are appended into the cat and trans arrays, and scrap ptr is advanced.

Like prod , this procedure has to split into pieces so that each part is short enough to be handled by Pascal compilers that discriminate against long subroutines. This time there are two split-off routines, called easy cases and sub cases .

After studying Pascal parse, we will look at the sub-procedures app comment , app octal , and app hex that are used in some of its branches.

⟨ Declaration of the app comment procedure 195 ⟩

⟨ Declaration of the app octal and app hex procedures 196 ⟩

⟨ Declaration of the easy cases procedure 186* ⟩

⟨ Declaration of the sub cases procedure 192* ⟩ procedure Pascal parse; { creates scraps from Pascal tokens }

label reswitch, exit ;

var j: 0 . . long buf size; { index into buffer }

p: name pointer ; { identifier designator } begin while next control < format do

begin ⟨ Append the scrap appropriate to next control 185 ⟩;

next control ← get next ;

if (next control = ) ∨ (next control = begin regular comment ) then return; end;

18  INITIALIZING THE SCRAPS  WEAVE changes for Vax/VMS §186

exit : end; 186* . The easy cases each result in straightforward scraps. ⟨ Declaration of the easy cases procedure 186* ⟩ ≡ procedure easy cases ; { a subprocedure of Pascal parse }

begin case next control of

set element sign: sc3 ( )( )( )(math); double dot : sc3 ( )( )( )(math); $ , % , , : sc2 ( )(next control )(math); # : if in def part then

begin pound found ← true; sc2 ( )( # )(math); end

else sc2 ( )( )(math); : sc2 ( )( )(math); : sc2 ( )( )(math); ignore, xref roman, xref wildcard , xref typewriter : do nothing ; , : sc1 (next control )(open); , : sc1 (next control )(close); : sc4 ( )( )( )( )(math); : sc3 ( )(opt )( )(math); , , , , , , , , , , : sc1 (next control )(simp); : sc1 ( )(semi ); : sc2 ( )( )(open); : sc2 ( )( )(close); , vertical bar : sc4 ( )( )( )(force)(semi ); : sc1 ( )(colon); ⟨ Cases involving nonstandard ASCII characters 188* ⟩ exponent : sc3 ( )( )( )(exp); begin comment : sc2 ( )( )(math); end comment : sc2 ( )( )(math); octal : app octal ; hex : app hex ; check sum: sc2 ( )( )(simp); force line: sc2 ( )( )(simp); thin space: sc2 ( )( )(math); math break : sc2 (opt )( )(simp); line break : comment scrap(force); big line break : comment scrap(big force); no line break : begin app(big cancel ); app( ); app( ␣ ); comment scrap(big cancel );

end; pseudo semi : sc0 (semi ); join: sc2 ( )( )(math); othercases sc1 (next control )(math) endcases; end;

This code is used in section 183*.

188* . Some nonstandard ASCII characters may have entered by means of standard ones. They are converted to TEX control sequences so that it is possible to keep from stepping beyond standard ASCII. ⟨ Cases involving nonstandard ASCII characters 188* ⟩ ≡ not equal : sc2 ( )( )(math); less or equal : sc2 ( )( )(math); greater or equal : sc2 ( )( )(math); equivalence sign: begin sc2 ( )( )(math);

if ¬pound found then in def part ← false; end;

and sign: sc2 ( )( )(math); or sign: sc2 ( )( )(math); not sign: sc2 ( )( )(math); left arrow : sc2 ( )( )(math);

This code is used in section 186*.

191* . ⟨ Append an identifier scrap 191* ⟩ ≡ begin p ← id lookup(normal ); case ilk [p] of normal , array like, const like, div like, of like, for like, goto like, nil like, to like: sub cases (p); ⟨ Cases that generate more than one scrap 193* ⟩ othercases begin next control ← ilk [p] − char like; goto reswitch;

end { and, in, not, or } endcases; end

This code is used in section 185.

192* . The sub cases also result in straightforward scraps. ⟨ Declaration of the sub cases procedure 192* ⟩ ≡ procedure sub cases (p : name pointer ); { a subprocedure of Pascal parse }

begin case ilk [p] of normal : sc1 (id flag + p)(simp); { not a reserved word } array like: sc1 (res flag + p)(alpha); { array, file, set } const like: sc3 (force)(backup)(res flag + p)(intro); { const, label, type } div like: sc3 (math bin)(res flag + p)( )(math); { div, mod } for like: sc2 (force)(res flag + p)(alpha); { for, if, while, with } goto like: sc1 (res flag + p)(intro); { packed } nil like: sc1 (res flag + p)(simp); { nil } of like: sc1 (res flag + p)(omega); { of } to like: sc3 (math rel )(res flag + p)( )(math); { to } end; end;

This code is used in section 183*.

193* . ⟨ Cases that generate more than one scrap 193* ⟩ ≡ begin like: begin sc4 (force)(backup)(res flag + p)(force)(beginning ); sc0 (intro);

end; { begin } case like: begin sc0 (casey ); sc2 (force)(res flag + p)(alpha);

end; { case } do like: begin sc2 (res flag + p)(force)(omega); sc0 (beginning ); sc0 (intro);

end; { do, then } elsif like: begin ⟨ Append terminator if not already present 194 ⟩;

sc0 (close); sc0 (terminator ); sc1 (res flag + p)(alpha); end;

else like: begin sc4 (force)(backup)(res flag + p)(force)(terminator );

end; { else } end like: begin ⟨ Append terminator if not already present 194 ⟩;

sc4 (force)(backup)(res flag + p)(break space)(close); end; { end }

loop like: begin sc1 (force)(alpha); sc2 (res flag + p)(force)(omega); sc0 (beginning ); sc0 (intro);

end; { loop } proc like: begin sc4 (force)(backup)(res flag + p)(cancel )(proc); sc3 (indent )( )( ␣ )(intro);

end; { function, procedure, program } record like: begin sc1 (res flag + p)(alpha); sc0 (omega); sc0 (beginning );

end; { record } repeat like: begin sc4 (force)(indent )(res flag + p)(force)(beginning ); sc0 (intro);

end; { repeat } until like: begin ⟨ Append terminator if not already present 194 ⟩;

sc3 (force)(backup)(res flag + p)(close); sc0 (clause); end; { until }

var like: begin sc4 (force)(backup)(res flag + p)(cancel )(var head ); sc0 (intro);

end; { var }

This code is used in section 191*.

198* . The outer parse routine is to Pascal parse as outer xref is to Pascal xref : It constructs a sequence of scraps for Pascal text until next control ≥ format . Thus, it takes care of embedded comments. procedure outer parse; { makes scraps from Pascal tokens and comments }

var bal : eight bits ; { brace level in comment }

p, q: text pointer ; { partial comments } begin while next control < format do

if next control ≠ begin regular comment then Pascal parse

else begin ⟨ Make sure that there is room for at least seven more tokens, three more texts, and one

more scrap 199 ⟩; app( ); app( ); app( ); bal ← copy comment (1); next control ← ignore; while bal > 0 do

begin p ← text ptr ; freeze text ; q ← Pascal translate; { at this point we have tok ptr + 6 ≤ max toks }

app(tok flag + p); app(inner tok flag + q);

if next control = then begin next control ← ignore; bal ← copy comment (bal ); end

else bal ← 0; { an error has been reported }

end; app(force); app comment ; { the full comment becomes a scrap } end;

end;

§200  WEAVE changes for Vax/VMS  OUTPUT OF TOKENS 21

207* . The real work associated with token output is done by make output . This procedure appends an end translation token to the current token list, and then it repeatedly calls get output and feeds characters to the output buffer until reaching the end translation sentinel. It is possible for make output to be called recursively, since a module name may include embedded Pascal text; however, the depth of recursion never exceeds one level, since module names cannot be inside of module names.

A procedure called output Pascal does the scanning, translation, and output of Pascal text within ‘ … ’ brackets, and this procedure uses make output to output the current token list. Thus, the recursive call of make output actually occurs when make output calls output Pascal while outputting the name of a module. procedure make output ; forward ; procedure output Pascal ; { outputs the current token list }

var save tok ptr , save text ptr , save next control : sixteen bits ; { values to be restored }

p: text pointer ; { translation of the Pascal text } begin save tok ptr ← tok ptr ; save text ptr ← text ptr ; save next control ← next control ; next control ← ignore; p ← Pascal translate; app(p + inner tok flag ); make output ; { output the list } stat if text ptr > max txt ptr then max txt ptr ← text ptr ; if tok ptr > max tok ptr then max tok ptr ← tok ptr ; tats text ptr ← save text ptr ; tok ptr ← save tok ptr ; { forget the tokens } next control ← save next control ; { restore next control to original state } end;

22  PHASE TWO PROCESSING  WEAVE changes for Vax/VMS §218

222* . In the TEX part of a module, we simply copy the source text, except that index entries are not copied and Pascal text within … is translated. ⟨ Translate the TEX part of the current module 222* ⟩ ≡

in def part ← false; repeat next control ← copy TeX ;

case next control of

: begin next control ← ignore; init stack ; output Pascal ;

end; : out ( ); octal : ⟨ Translate an octal constant appearing in TEX text 223 ⟩; hex : ⟨ Translate a hexadecimal constant appearing in TEX text 224 ⟩; TeX string , xref roman, xref wildcard , xref typewriter , module name: begin loc ← loc − 2;

next control ← get next ; { skip to }

if next control = TeX string then err print (´ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ´ ); end;

begin comment , end comment , check sum, thin space, math break , line break , big line break ,

no line break , join, pseudo semi : err print (´ ␣ ␣ ´ ´ ␣ ␣ ␣ ␣ ␣ ´ );

othercases do nothing

endcases; until next control ≥ format

This code is used in section 220.

227* . ⟨ Start a macro definition 227* ⟩ ≡ begin sc2 ( )( )(intro); { this will produce ‘define ’ } in def part ← true; pound found ← false; next control ← get next ; if next control ≠ identifier then err print (´ ␣ ␣ ␣ ´ ) else sc1 (id flag + id lookup(normal ))(math); next control ← get next ; end

This code is used in section 225.

229* . Finally, when the TEX and definition parts have been treated, we have next control ≥ begin Pascal . We will make the global variable this module point to the current module name, if it has a name. ⟨ Globals in the outer block 9 ⟩ +≡ this module: name pointer ; { the current module name, or zero } in def part , pound found : boolean; { flags to determine context of use of pound sign and vertical bar }

230* . ⟨ Translate the Pascal part of the current module 230* ⟩ ≡ this module ← 0; in def part ← false; if next control ≤ module name then

begin emit space if needed ; init stack ; if next control = begin Pascal then next control ← get next else begin this module ← cur module; ⟨ Check that = or ≡ follows this module name, and emit the

scraps to start the module definition 231 ⟩; end;

while next control ≤ module name do begin outer parse; ⟨ Emit the scrap for a module name if present 232 ⟩; end;

finish Pascal ; end

This code is used in section 220.

§239  WEAVE changes for Vax/VMS  DEBUGGING 23

258* . Debugging. The Pascal debugger with which was developed allows breakpoints to be set, and variables can be read and changed, but procedures cannot be executed. Therefore a ‘debug help’ procedure has been inserted in the main loops of each phase of the program; when ddt and dd are set to appropriate values, symbolic printouts of various tables will appear.

The idea is to set a breakpoint inside the debug help routine, at the place of ‘breakpoint :’ below. Then when debug help is to be activated, set trouble shooting equal to true. The debug help routine will prompt you for values of ddt and dd , discontinuing this when ddt ≤ 0; thus you type 2n + 1 integers, ending with zero or a negative number. Then control either passes to the breakpoint, allowing you to look at and/or change variables (if you typed zero), or to exit the routine (if you typed a negative value).

Another global variable, debug cycle, can be used to skip silently past calls on debug help. If you set debug cycle > 1, the program stops only every debug cycle times debug help is called; however, any error stop will set debug cycle to zero. ⟨ Globals in the outer block 9 ⟩ +≡

debug trouble shooting : boolean; { is debug help wanted? } ddt : integer ; { operation code for the debug help routine } dd : integer ; { operand in procedures performed by debug help } debug cycle: integer ; { threshold for debug help stopping } debug skipped : integer ; { we have skipped this many debug help calls }

gubed

259* . The debugging routine needs to read from the user’s terminal.

define term in ≡ input ⟨ Set initial values 10 ⟩ +≡

debug trouble shooting ← true; debug cycle ← 1; debug skipped ← 0; tracing ← 0;

trouble shooting ← false; debug cycle ← 99999; { use these when it almost works }

gubed

24  THE MAIN PROGRAM  WEAVE changes for Vax/VMS §261

261* . The main program. Let’s put it all together now: starts and ends here.

The main procedure has been split into three sub-procedures in order to keep certain Pascal compilers from overflowing their capacity. procedure Phase I ;

begin ⟨ Phase I: Read all the user’s text and store the cross references 109 ⟩; end;

procedure Phase II ; begin ⟨ Phase II: Read all the text again and translate it to TEX form 218 ⟩; end; begin initialize; { beginning of the main program } print ln(banner ); { print a “banner line” } ⟨ Store all the reserved words 64* ⟩; Phase I ; Phase II ; ⟨ Phase III: Output the cross-reference index 239 ⟩; ⟨ Check that all changes have been read 85 ⟩;

end of WEAVE : stat ⟨ Print statistics about memory usage 262 ⟩; tats if history < fatal message then \underline{\overline{␣}} (tex file, \underline{\overline{}}, \underline{\overline{}}); ⟨ Print the job history 263 ⟩; end.

§264  WEAVE changes for Vax/VMS  SYSTEM-DEPENDENT CHANGES 25

264* . System-dependent changes. Here are the remaining changes to the program that are necessary to make work on Vax/VMS.

265* . This variable is for speeding up the output routine. ⟨ Globals in the outer block 9 ⟩ +≡ out temp buffer : packed array [1 . . line length + 1] of char ;

266* . On Vax/VMS we need the following special definitions, types, variables and procedures to be able to get the file name from the command line, or to prompt for them.

define VAX volatile ≡ \underline{\overline{}}

define VAX immed ≡ \underline{\overline{% ␣}}

define VAX external ≡ \underline{\overline{}}

define VAX stdescr ≡ \underline{\overline{% ␣}}

define VAX lib get foreign ≡ \underline{\overline{␣ $}}

define VAX length ≡ \underline{\overline{␣}}

267* . ⟨ Local variables for initialization 16 ⟩ +≡ command line: packed array [1 . . 300] of char ; cmd len: sixteen bits ; cmd i : integer ; file name, default file name: varying [300] of char ; ask , got file name: boolean;

268* . Here is the library procedure that gets the user’s command line. ⟨ Error handling procedures 30 ⟩ +≡

[VAX external ] function VAX lib get foreign ( VAX stdescr cmdlin : [VAX volatile]

packed array [$l1 . . $u1 : integer ] of char ← VAX immed 0; VAX stdescr prompt : [VAX volatile] packed array [$l2 . . $u2 : integer ] of char ← VAX immed 0; var len: [VAX volatile]sixteen bits ← VAX immed 0; var flag : [VAX volatile]integer ← VAX immed 0 ) : integer ; extern;

26  SYSTEM-DEPENDENT CHANGES  WEAVE changes for Vax/VMS §269

269* . We get the external file names, and then call open to associate an external file with each file variable.

define VAX open ≡ \underline{\overline{␣}} ⟨ Preset initial values 269* ⟩ ≡

cmd i ← 0; VAX lib get foreign(command line, , cmd len, cmd i ); cmd i ← 1; while (cmd i ≤ cmd len) ∧ (command line[cmd i ] = ´ ␣´ ) do incr (cmd i ); got file name ← cmd i ≤ cmd len; if got file name then default file name ← substr (command line, cmd i , cmd len − cmd i + 1);

if got file name then

begin file name ← default file name + ´ ´ ; VAX open(web file, file name, \underline{\overline{}}, \underline{\overline{}}); ask ← status (web file) ≠ 0; if ask then write ln(´ ´ ´ ␣ ␣´ , file name); end

else ask ← true;

while ask do

begin got file name ← false; write(´ ␣ ␣´ );

if eof then

begin mark fatal ; jump out ;

end; read ln(file name); VAX open(web file, file name, \underline{\overline{}}, \underline{\overline{}}); ask ← status (web file) ≠ 0; if ask then write ln(´ ´ ´ ␣ ␣´ , file name); end;

if got file name then

begin file name ← default file name + ´ ´ ; VAX open(change file, file name, \underline{\overline{}}, \underline{\overline{}}); ask ← status (change file) > 0;

{ can be empty } if ask then write ln(´ ´ ´ ␣ ␣´ , file name); end

else ask ← true;

while ask do

begin write(´ ␣ ␣´ );

if eof then

begin mark fatal ; jump out ;

end; read ln(file name); if file name.VAX length = 0 then file name ← ´ ´ ; VAX open(change file, file name, \underline{\overline{}}, \underline{\overline{}}); ask ← status (change file) > 0; if ask then write ln(´ ´ ´ ␣ ␣´ , file name); end;

if got file name then

begin cmd i ← 1; for cmd len ← 1 to default file name.VAX length do

if (default file name[cmd len] = ´ ´ ) ∨ (default file name[cmd len] = ´ ´ ) then

cmd i ← cmd len + 1; if cmd i ≤ default file name.VAX length then

default file name ← substr (default file name, cmd i , default file name.VAX length − cmd i + 1); file name ← default file name + ´ ´ ; VAX open(tex file, file name, \underline{\overline{}}, \underline{\overline{}}); ask ← status (tex file) > 0; if ask then write ln(´ ´ ´ ␣ ␣´ , file name); end

else ask ← true;

while ask do

begin write(´ ␣ ␣´ );

if eof then

begin mark fatal ; jump out ; end;

read ln(file name); VAX open(tex file, file name, \underline{\overline{}}, \underline{\overline{}}); ask ← status (tex file) > 0; if ask then write ln(´ ´ ´ ␣ ␣´ , file name); end;

rewrite(tex file);

This code is used in section 2*.

28  INDEX  WEAVE changes for Vax/VMS §270

270* . Index. If you have read and understood the code for Phase III above, you know what is in this index and how it got here. All modules in which an identifier is used are listed with that identifier, except that reserved words are indexed only when they appear in format definitions, and the appearances of identifiers in module names are not indexed. Underlined entries correspond to where the identifier was declared. Error messages, control sequences put into the output, and a few other things like “recursion” are indexed here too.

The following sections were changed by the change file: 1, 2, 4, 7, 8, 12, 20, 21, 22, 26, 27, 28, 42, 63, 64, 86, 92, 97, 111, 112, 122, 124, 136, 137, 138, 183, 186, 188, 191, 192, 193, 198, 207, 222, 227, 229, 230, 258, 259, 261, 264, 265, 266, 267, 268, 269, 270.

: 186* . : 130. : 162, 163, 186* . : 189, 253. : 252, 256. : 189. : 254. ␣ : 186* , 189, 193* . # : 186* , 189. $ : 186* , 189. % : 186* , 189. : 189, 209, 253. ´ : 189. : 189, 209, 253. : 186* , 189. ` : 189. : 189. : 189. : 189, 193* . : 186* . : 209, 253. : 131, 189. : 236. : 186* . : 186* . : 198* . : 239. : 227* . : 186* . : 228. : 238. : 239. : 188* . : 196, 224. : 188* . : 186* . : 239. : 186* . : 188* . : 188* . : 221. : 221. : 196, 223.

: 212, 226. : 188* . : 188* , 228, 231. : 186* . : 186* . : 236. : 188* . : 188* . : 213. : 212, 219, 226, 231. : 211, 212. : 211, 212. : 211, 212. : 211, 212. : 211, 212. : 211, 212, 226. : 211, 212, 226. : 253. : 88, 177. : 88, 177. a: \underline{130}, \underline{206}, \underline{208}. alpha: \underline{140}, 142, 143, 149, 192* , 193* . alpha cases : 149, \underline{150}. : 69. and sign: \underline{15}, 64* , 188* . app: \underline{148}, 151, 152, 153, 155, 156, 158, 159,

160, 161, 162, 163, 164, 165, 167, 168, 170, 180, 184, 186* , 189, 190, 195, 196, 198* , 207* , 208, 226, 231, 256.

app comment : 183* , 184, \underline{195}, 197, 198* , 226. app hex : 183* , 186* , \underline{196}. app octal : 183* , 186* , \underline{196}. app tok : \underline{136*} , 137* , 138* , 148, 189, 190, 196,

197, 226. append xref : \underline{50}, 51. app1 : \underline{148}, 151, 152, 153, 155, 156, 159, 160, 162,

163, 164, 165, 168, 170, 174, 180, 195. app2 : \underline{148}, 153, 156, 158, 161, 163, 165, 167. app3 : \underline{148}, 158, 164. array like: \underline{42*} , 64* , 191* , 192* . ASCII code: 11, 86* . ASCII code: \underline{11}, 13, 27* , 28* , 37, 65, 73, 87, 89, 91,

§270  WEAVE changes for Vax/VMS  INDEX 29

121, 127, 132, 136* , 208, 242, 246, 247, 249. ask : \underline{267*} , 269* . b: \underline{122*} , \underline{208}. backup: \underline{141}, 142, 143, 147, 160, 167, 192* , 193* ,

208, 231. bal : \underline{91}, 92* , \underline{112*} , \underline{136*} , 137* , 138* , \underline{198*} . banner : \underline{1*} , 261* . begin: 3. begin comment : \underline{86*} , 87, 186* , 222* . begin like: \underline{42*} , 64* , 193* . begin Pascal : \underline{86*} , 87, 117, 229* , 230* . begin regular comment : \underline{86*} , 92* , 97* , 111* , 112* ,

137* , 183* , 198* . beginning : \underline{140}, 142, 143, 150, 152, 164, 170, 193* . big cancel : \underline{141}, 142, 147, 186* , 208, 212. big force: \underline{141}, 142, 147, 186* , 208, 212, 226. big line break : \underline{86*} , 87, 186* , 222* . blink : \underline{242}, 243, 250, 251, 252. boolean: 28* , 29, 45, 71, 74, 93, 122* , 143, 229* ,

258* , 267* . break out : 125, 126, \underline{127}. break space: \underline{141}, 143, 147, 152, 155, 156, 160,

164, 168, 170, 193* , 200, 208, 211, 212. breakpoint : 258* , \underline{260}. bucket : \underline{242}, 243, 249, 251. buf size: \underline{8*} , 27* , 28* , 73, 74, 75, 79, 123. buffer : \underline{27*} , 28* , 31, 32, 55, 58, 59, 61, 62, 63* , 74, 76,

78, 79, 80, 81, 82, 83, 84, 85, 89, 90, 91, 92* , 93, 95, 97* , 98, 99, 100, 103, 104, 106, 107, 110, 123, 132, 133, 134, 135, 136* , 137* , 179, 182, 183* , 189, 190, 196, 208, 214, 216, 217, 221, 223, 224, 260.

byte mem: 36, \underline{37}, 38, 39, 40, 43, 44, 52, 58, 61, 62, 66, 67, 68, 69, 131, 208, 209, 214, 215, 216, 217, 243, 244, 251.

byte ptr : 38, \underline{39}, 41, 62, 67, 262. byte start : 36, \underline{37}, 38, 39, 41, 44, 50, 55, 61, 62,

67, 68, 93, 114, 131, 209, 214, 243, 251. c: \underline{66}, \underline{69}, \underline{87}, \underline{89}, \underline{90}, \underline{91}, \underline{95}, \underline{127}, \underline{132}, \underline{134}, \underline{136*} ,

\underline{140}, \underline{172}, \underline{174}, \underline{242}, \underline{247}, \underline{249}. cancel : \underline{141}, 142, 143, 147, 153, 155, 156, 159, 160,

162, 163, 164, 165, 193* , 197, 200, 208, 211, 212. carriage return: \underline{15}, 17, 28* . case head : \underline{140}, 143, 149, 153, 154, 162, 163, 165. case like: \underline{42*} , 64* , 193* . casey : \underline{140}, 142, 143, 149, 153, 165, 193* . cat : \underline{144}, 149, 150, 151, 152, 153, 154, 155, 156,

158, 159, 160, 161, 162, 163, 164, 165, 167, 168, 170, 172, 174, 176, 178, 179, 180, 181, 183* , 184, 194, 195, 197, 244, 250, 260.

: 77, 79, 84. : 85. change buffer : \underline{73}, 74, 75, 78, 79, 83, 85. change changing : \underline{72}, 79, 81, 84. change exists : \underline{45}, 109, 110, 239. change file: \underline{2*} , \underline{23}, 24, 32, 71, 73, 76, 77, 79,

84, 269* . change limit : \underline{73}, 74, 75, 78, 79, 83, 85. changed module: \underline{45}, 82, 109, 110, 130, 241. changing : 32, \underline{71}, 72, 73, 75, 79, 81, 82, 85. char : 12* , 14, 27* , 265* , 267* , 268* . char like: \underline{42*} , 64* , 191* . check change: \underline{79}, 83. check sum: \underline{86*} , 87, 186* , 222* . chr : 12* , 13, 17, 18, 20* . clause: \underline{140}, 142, 143, 149, 151, 153, 154, 156, 193* . close: \underline{140}, 142, 143, 152, 153, 160, 162, 163,

164, 167, 186* , 193* . cmd i : \underline{267*} , 269* . cmd len: \underline{267*} , 269* . cmdlin: 268* . collate: \underline{246}, 247, 248, 249. colon: \underline{140}, 142, 143, 148, 151, 160, 163, 167,

170, 186* . command line: \underline{267*} , 269* . comment : \underline{142}. comment scrap: \underline{184}, 186* . compress : \underline{97*} . cond : \underline{140}, 142, 143, 149. confusion: \underline{34}. const like: \underline{42*} , 64* , 191* , 192* . continue: \underline{5}, 75, 76. : 106. : 106. control code: \underline{87}, 88, 90, 93, 100, 135. copy comment : 132, \underline{136*} , 198* . copy limbo: \underline{132}, 218. copy TeX : 132, \underline{134}, 222* . count : \underline{69}. cur bank : \underline{244}, 251, 262. cur byte: \underline{244}, 251. cur depth: \underline{244}, 250, 251. cur end : 201, \underline{202}, 204, 205, 206. cur mod name: \underline{208}, 214, 215, 216. cur mode: 201, \underline{202}, 204, 206, 208, 211, 212. cur module: \underline{93}, 101, 117, 230* , 232. cur name: \underline{63*} , 206, 209, 213, 214, 242, 243,

251, 252, 253, 255. cur state: \underline{202}, 204, 205. cur tok : 201, \underline{202}, 204, 205, 206. cur val : \underline{244}, 254. cur xref : \underline{118}, 119, 213, 231, 234, 235, 236, 237,

254, 255, 256. d: \underline{95}, \underline{127}, \underline{172}, \underline{174}, \underline{249}. dd : \underline{258*} , 260. ddt : \underline{258*} , 260. debug: \underline{3}, \underline{30}, \underline{31}, \underline{88}, \underline{95}, \underline{140}, \underline{146}, \underline{148}, \underline{177}, \underline{178},

\underline{181}, \underline{182}, \underline{206}, \underline{252}, \underline{258*} , \underline{259*} , \underline{260}. debug cycle: 31, \underline{258*} , 259* , 260. debug help: \underline{30}, 31, 95, 206, 252, 258* , \underline{260}. debug skipped : 31, \underline{258*} , 259* , 260. decr : \underline{6}, 92* , 98, 103, 122* , 127, 130, 135, 137* ,

138* , 205, 251, 252. def flag : \underline{46}, 48, 50, 51, 93, 100, 111* , 113, 115,

117, 119, 130, 213, 231, 233, 235, 236, 254. default file name: \underline{267*} , 269* . definition: \underline{86*} , 87, 115, 225. depth: \underline{244}, 249. dig : \underline{129}, 130. div like: \underline{42*} , 64* , 191* , 192* . do like: \underline{42*} , 64* , 193* . do nothing : \underline{6}, 95, 113, 149, 150, 186* , 189,

222* , 253. done: \underline{5}, 75, 76, 90, 91, 92* , 95, 103, 104, 122* , 134,

135, 136* , 137* , 138* , 175, 179, 236, 237. : 133. : 189. double dot : \underline{86*} , 97* , 186* . easy cases : 183* , 185, \underline{186*} . eight bits : \underline{36}, 58, 87, 90, 91, 95, 108, 112* , 122* ,

134, 136* , 140, 144, 172, 174, 178, 198* , 206, 208, 244, 249.

else: 7* . else like: \underline{42*} , 64* , 193* . elsie: \underline{140}, 142, 143, 149, 156. elsif like: \underline{42*} , 64* , 193* . emit space if needed : \underline{219}, 225, 230* . end: 3, 7* . end comment : \underline{86*} , 87, 186* , 222* . end field : \underline{201}, 202. end like: \underline{42*} , 64* , 193* . end of WEAVE : \underline{2*} , 33, 261* . end regular comment : \underline{86*} , 92* , 97* , 136* , 137* , 138* . end translation: \underline{141}, 147, 201, 207* , 208, 212. endcases: \underline{7*} . eof : 28* , 269* . eoln: 28* . equal : \underline{66}, 67, 68. equivalence sign: \underline{15}, 97* , 116, 188* , 228, 231. err print : \underline{31}, 66, 69, 72, 76, 77, 79, 80, 84, 85,

87, 99, 103, 104, 106, 107, 133, 136* , 137* , 189, 197, 222* , 227* , 228, 231, 232.

error : 28* , \underline{31}, 33. error message: \underline{9}, 263. exit : \underline{5}, 6, 50, 74, 75, 79, 89, 111* , 123, 127, 132,

183* , 208, 236, 260. exp: \underline{140}, 142, 143, 149, 186* . exponent : \underline{93}, 98, 186* . extension: \underline{66}, 68, 69. extern: 268* . : 87. f: \underline{28*} . false: 28* , 29, 72, 73, 74, 79, 81, 94, 96, 109,

110, 122* , 123, 127, 188* , 218, 222* , 227* , 230* , 238, 259* , 269* . fatal error : \underline{33}, 34, 35.

fatal message: \underline{9}, 261* , 263.
file name: \underline{267*} , 269* .

finish line: \underline{123}, 124* , 132, 134, 135, 212, 218, 226,

236, 238, 239, 254, 256. finish Pascal : 225, \underline{226}, 230* .

first text char : \underline{12*} , 18.
first xref : \underline{234}, 235.
five cases : 149, \underline{150}.
flag : \underline{236}, 237, \underline{268*} .
flush buffer : \underline{122*} , 123, 127, 128, 218, 238.
footnote: 233, \underline{236}, 256.
for like: \underline{42*} , 64* , 191* , 192* .

force: \underline{141}, 142, 143, 146, 147, 153, 155, 156, 160, 161, 167, 186* , 192* , 193* , 198* , 200, 208, 212, 226, 231. force line: \underline{86*} , 87, 186* .

form feed : \underline{15}, 28* .

format : \underline{86*} , 87, 111* , 112* , 113, 115, 183* , 198* ,

222* , 225. forward : 30, 207* . found : \underline{5}, 58, 60, 61, 66, 95, 96, 148, 149, 150,

151, 175, 179, 208, 216. freeze text : \underline{171}, 172, 180, 184, 195, 198* , 208. get line: 71, \underline{82}, 89, 90, 91, 95, 103, 123, 132,

134, 136* . get next : 93, \underline{95}, 108, 111* , 113, 115, 116, 117, 183* ,

222* , 227* , 228, 230* , 231, 232. get output : \underline{206}, 207* , 208, 211, 212. got file name: \underline{267*} , 269* . goto like: \underline{42*} , 64* , 191* , 192* . greater : \underline{66}, 68, 69. greater or equal : \underline{15}, 97* , 188* . gubed: \underline{3}. h: \underline{56}, \underline{58}, \underline{242}. harmless message: \underline{9}, 263. hash: 38, \underline{55}, 57, 60, 242, 243. hash size: \underline{8*} , 55, 56, 57, 58, 59, 242, 243. head : \underline{244}, 249, 250, 251, 252. hex : \underline{86*} , 87, 100, 186* , 222* . hi ptr : \underline{144}, 176, 178, 179. history : \underline{9}, 10, 261* , 263. : 80. i: \underline{16}, \underline{28*} , \underline{58}, \underline{172}, \underline{174}, \underline{179}. id first : \underline{55}, 58, 59, 61, 62, 63* , 93, 98, 99, 106,

107, 189, 190. id flag : \underline{146}, 192* , 206, 227* , 228. id loc: \underline{55}, 58, 59, 61, 62, 64* , 93, 98, 99, 106,

107, 189, 190. id lookup: 55, \underline{58}, 63* , 93, 111* , 113, 116, 191* ,

227* , 228. identifier : \underline{93}, 98, 111* , 113, 116, 185, 206, 208,

209, 227* , 228. id10 : \underline{63*} , 64* . id11 : \underline{63*} . id12 : \underline{63*} . id13 : \underline{63*} . id14 : \underline{63*} , 64* . id2 : \underline{63*} , 64* . id3 : \underline{63*} , 64* . id4 : \underline{63*} , 64* . id5 : \underline{63*} , 64* . id6 : \underline{63*} , 64* . id7 : \underline{63*} , 64* . id8 : \underline{63*} . id9 : \underline{63*} , 64* . if like: \underline{42*} . ignore: \underline{86*} , 87, 88, 186* , 198* , 207* , 222* . ilk : 36, \underline{37}, 42* , 43, 55, 58, 60, 62, 111* , 116,

191* , 192* , 253. : 215. : 137* . : 228. : 227* . in def part : 186* , 188* , 222* , 227* , 229* , 230* . in like: \underline{42*} . : 66. incr : \underline{6}, 50, 59, 61, 62, 67, 68, 69, 76, 77, 79, 83,

84, 89, 90, 91, 92* , 95, 97* , 98, 99, 100, 103, 104, 106, 107, 110, 122* , 125, 130, 133, 135, 136* , 137* , 148, 149, 150, 171, 176, 184, 189, 196, 204, 206, 214, 215, 216, 217, 220, 223, 224, 241, 249, 260, 269* .

indent : \underline{141}, 142, 143, 147, 151, 160, 165, 193* , 208. infinity : \underline{249}, 250. init stack : \underline{202}, 222* , 225, 230* , 256. initialize: \underline{2*} , 261* . inner : 200, \underline{201}, 206, 212. inner tok flag : \underline{146}, 198* , 206, 207* . input : \underline{2*} , 259* . : 136* . : 103. : 28* . input has ended : \underline{71}, 79, 81, 83, 89, 90, 91, 95,

103, 109, 132, 134, 136* , 218. input ln: \underline{28*} , 76, 77, 79, 83, 84. integer : 14, 71, 79, 121, 130, 172, 174, 219,

258* , 260, 267* , 268* . intro: \underline{140}, 142, 143, 148, 150, 157, 160, 162, 163,

165, 167, 170, 192* , 193* , 227* , 228. j: \underline{66}, \underline{69}, \underline{95}, \underline{122*} , \underline{146}, \underline{172}, \underline{174}, \underline{179}, \underline{183*} , \underline{208}.

join: \underline{86*} , 87, 186* , 222* .
jump out : 2* , \underline{33}, 269* .

k: \underline{31}, \underline{44}, \underline{58}, \underline{66}, \underline{69}, \underline{74}, \underline{75}, \underline{79}, \underline{95}, \underline{122*} , \underline{123}, \underline{127}, \underline{130}, \underline{131}, \underline{172}, \underline{174}, \underline{178}, \underline{179}, \underline{208}, \underline{260}.

k limit : \underline{208}, 214, 216.
k module: \underline{240}, 241.
l: \underline{28*} , \underline{31}, \underline{58}, \underline{66}, \underline{69}.
last text char : \underline{12*} , 16, 18.
lbrace: \underline{146}, 147.
left arrow : \underline{15}, 97* , 188* .
len: \underline{268*} .
length: \underline{38}, 60, 209, 253.
less : \underline{66}, 67, 68, 69.
less or equal : \underline{15}, 97* , 188* .
lhs : \underline{114}, 116.

limit : 28* , 32, \underline{71}, 74, 76, 77, 78, 80, 81, 82, 83, 84, 85, 89, 90, 91, 95, 97* , 99, 103, 106, 107, 123, 132, 133, 134, 135, 136* , 208, 214, 216, 223. line: 32, \underline{71}, 72, 76, 77, 79, 81, 83, 84, 85, 182. : 128. line break : \underline{86*} , 87, 186* , 222* . line feed : \underline{15}, 28* . line length: \underline{8*} , 121, 122* , 125, 127, 265* . lines dont match: \underline{74}, 79. link : 36, \underline{37}, 38, 43, 60, 243. llink : \underline{43}, 66, 67, 69, 119, 256. lo ptr : \underline{144}, 172, 175, 176, 178, 179, 180, 181. loc: 32, \underline{71}, 76, 80, 81, 82, 84, 85, 89, 90, 91, 92* , 95, 97* , 98, 99, 100, 103, 104, 106, 107, 110, 113, 132, 133, 134, 135, 136* , 137* , 182, 196, 208, 214, 221, 222* , 223, 224.

long buf size: \underline{8*} , 27* , 28* , 31, 55, 58, 71, 179,

183* , 208, 216, 217. longest name: \underline{8*} , 65, 66, 69, 95, 103, 105. loop: \underline{6}. loop like: \underline{42*} , 64* , 193* . l1 : 268* . l2 : 268* . m: \underline{50}, \underline{130}. make output : \underline{207*} , \underline{208}, 213, 226, 256. mark error : \underline{9}, 31, 215, 216. mark fatal : \underline{9}, 33, 269* . mark harmless : \underline{9}, 105, 119, 128, 181, 182. math: 139, \underline{140}, 142, 143, 148, 150, 151, 158, 160, 162, 163, 167, 170, 179, 180, 186* , 188* , 192* , 227* , 228, 231.

math bin: \underline{141}, 142, 147, 192* , 208, 210. math break : \underline{86*} , 87, 186* , 222* . math op: \underline{141}, 143, 147, 162, 163, 208. math rel : \underline{141}, 142, 146, 147, 192* , 208, 210, 231. max bytes : \underline{8*} , 37, 39, 44, 58, 62, 66, 67, 69,

131, 208, 244. max modules : \underline{8*} , 45, 46, 110, 240. max names : \underline{8*} , 37, 38, 62, 67, 69, 242. max refs : \underline{8*} , 47, 50. max scr ptr : \underline{144}, 145, 187, 197, 199, 226, 262. max scraps : \underline{8*} , 144, 172, 174, 178, 179, 187,

197, 199, 244. max sort ptr : \underline{244}, 245, 249, 262. max sorts : \underline{244}, 249. max stack ptr : \underline{202}, 203, 204, 262. max texts : \underline{8*} , 52, 175, 179, 187, 199. max tok ptr : \underline{53}, 54, 175, 187, 199, 207* , 226, 262. max toks : \underline{8*} , 53, 136* , 146, 175, 179, 180, 187,

189, 198* , 199. max txt ptr : \underline{53}, 54, 175, 187, 199, 207* , 226, 262. mid xref : \underline{234}, 235. : 197. mod check : \underline{119}, 120. mod flag : \underline{146}, 206, 231, 232, 256. mod lookup: 65, \underline{66}, 101, 102. mod name: \underline{206}, 208. mod print : \underline{256}, 257. mod scrap: \underline{140}, 142, 143, 149, 167, 231, 232. mod text : \underline{65}, 66, 67, 68, 69, 95, 101, 102, 103,

104, 105, 260. mod xref switch: 46, \underline{48}, 49, 51, 117. mode: \underline{201}, 208. mode field : \underline{201}, 202. module count : \underline{45}, 50, 51, 82, 109, 110, 181, 218,

220, 221, 231, 241. module name: \underline{86*} , 87, 93, 100, 113, 117, 222* ,

230* , 232. n: \underline{50}, \underline{79}, \underline{178}. : 69. name pointer : \underline{38}, 39, 44, 50, 51, 58, 63* , 66,

69, 93, 111* , 114, 119, 131, 144, 183* , 192* , 208, 229* , 242, 256.

name ptr : 38, \underline{39}, 41, 44, 58, 60, 62, 67, 262. : 119. : 119. new line: \underline{20*} , 31, 32, 33, 128. new mod xref : \underline{51}, 117. new module: \underline{86*} , 87, 90, 95, 134. new xref : \underline{50}, 111* , 113, 116. next control : \underline{108}, 111* , 112* , 113, 115, 116, 117,

183* , 185, 186* , 189, 191* , 197, 198* , 207* , 222* , 225, 227* , 228, 229* , 230* , 231, 232.

next name: \underline{242}, 243, 251. next xref : \underline{234}, 235, 255. nil: 6. nil like: \underline{42*} , 64* , 191* , 192* . no line break : \underline{86*} , 87, 186* , 222* . no underline: \underline{86*} , 87, 100, 113. normal : \underline{42*} , 58, 60, 111* , 116, 191* , 192* , 227* ,

228, 253. not equal : \underline{15}, 97* , 188* . not found : \underline{5}. not sign: \underline{15}, 64* , 188* . num: \underline{46}, 49, 50, 51, 119, 213, 231, 235, 236,

237, 254. num field : 46, \underline{48}. octal : \underline{86*} , 87, 186* , 222* . of like: \underline{42*} , 64* , 191* , 192* . omega: \underline{140}, 142, 143, 151, 192* , 193* , 195. oot : \underline{125}. oot1 : \underline{125}. oot2 : \underline{125}. oot3 : \underline{125}. oot4 : \underline{125}. oot5 : \underline{125}. open: 139, \underline{140}, 142, \underline{143}, 150, 186* , 269* . open input : \underline{24}, 81. opt : 139, \underline{141}, 142, 143, 147, 159, 163, 186* ,

208, 211. or sign: \underline{15}, 64* , 188* . ord : 13. other line: \underline{71}, 72, 81, 85. othercases: \underline{7*} . others : 7* . otherwise: 7* . out : \underline{125}, 130, 131, 133, 135, 208, 209, 210,

211, 212, 213, 214, 221, 222* , 223, 224, 236, 237, 241, 254.

out buf : \underline{121}, 122* , 124* , 125, 126, 127, 128, 212,

226, 231, 260. out line: \underline{121}, 122* , 124* , 128, 219. out mod : \underline{130}, 213, 221, 237, 241, 254. out name: \underline{131}, 209, 253. out ptr : \underline{121}, 122* , 123, 124* , 125, 127, 128, 135,

212, 219, 226, 231, 260. out temp buffer : 122* , \underline{265*} . outdent : \underline{141}, 143, 147, 153, 155, 156, 160, 162,

163, 164, 208. outer : 200, \underline{201}, 202, 211, 212. outer parse: \underline{198*} , 225, 230* . outer xref : \underline{112*} , 115, 117, 198* . output : \underline{2*} . output Pascal : \underline{207*} , 214, 222* . output state: \underline{201}, 202. out2 : \underline{125}, 130, 210, 211, 212, 213, 219, 221, 226,

241, 252, 253, 254, 256. out3 : \underline{125}, 210, 223, 224, 238. out4 : \underline{125}, 226, 236, 237, 239, 241. out5 : \underline{125}, 210. overflow : \underline{35}, 50, 62, 67, 110, 136* , 175, 180, 187,

199, 204, 216, 217, 249. p: \underline{44}, \underline{50}, \underline{51}, \underline{58}, \underline{66}, \underline{69}, \underline{111*} , \underline{119}, \underline{131}, \underline{146}, \underline{183*} ,

\underline{192*} , \underline{197}, \underline{198*} , \underline{204}, \underline{226}. param: \underline{86*} . : 216. Pascal parse: \underline{183*} , 186* , 192* , 196, 197, 198* . Pascal translate: \underline{197}, 198* , 207* . Pascal xref : \underline{111*} , 112* , 113, 183* , 198* . per cent : \underline{122*} . Phase I : \underline{261*} . Phase II : \underline{261*} . phase one: \underline{29}, 31, 109. phase three: \underline{29}, 109, 213, 239. pop level : \underline{205}, 206. pound found : 186* , 188* , 227* , 229* . pp: \underline{144}, 148, 149, 150, 151, 152, 153, 154, 155,

156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 173, 175, 176, 178, 179.

prefix : \underline{66}, 68. prefix lookup: \underline{69}, 101. prime the change buffer : \underline{75}, 81, 84. print : \underline{20*} , 31, 32, 33, 44, 105, 110, 119, 128,

140, 146, 147, 178, 181, 182, 215, 216, 221, 239, 260, 262.

print cat : \underline{140}, 178, 181, 260. print id : \underline{44}, 119, 146, 215, 216, 260. print ln: \underline{20*} , 32, 128, 181, 261* . print nl : \underline{20*} , 28* , 105, 119, 128, 178, 181, 182,

215, 216, 218, 239, 262, 263. print text : \underline{146}, 260. proc: \underline{140}, 142, \underline{143}, 149, 162, 163, 164, 193* . proc like: \underline{42*} , 64* , 111* , 193* . prod : 148, \underline{178}, 183* . production: \underline{148}. production end : \underline{148}. productions, table of: 143. prompt : 268* . pseudo semi : \underline{86*} , 87, 186* , 222* . push level : \underline{204}, 206, 208. q: \underline{50}, \underline{51}, \underline{66}, \underline{69}, \underline{198*} , \underline{236}. r: \underline{51}, \underline{69}, \underline{146}. rbrace: \underline{146}. read : 28* , 260. read ln: 28* , 269* . record head : \underline{140}, 142, 143, 149. record like: \underline{42*} , 64* , 193* . recursion: 119, 207* , 256. red : 148, \underline{172}, 174. reduce: \underline{148}, 151, 152, 153, 155, 156, 158, 159, 160,

161, 162, 163, 164, 165, 167, 168, 170, 172, 178. repeat like: \underline{42*} , 64* , 193* . res flag : \underline{146}, 192* , 193* , 206. res word : \underline{206}, 208, 209. reserved : \underline{42*} , 50, 60. reset : 24. reset input : \underline{81}, 109, 218. restart : \underline{5}, 82, 95, 100, 206. reswitch: \underline{5}, 183* , 185, 191* , 208, 212. return: 5, \underline{6}. rewrite: 21* , 269* . rhs : \underline{114}, 116. rlink : \underline{43}, 66, 67, 69, 119, 256. roman: \underline{42*} , 111* , 253. root : \underline{43}, 66, 69, 120, 257. save base: \underline{197}. save limit : \underline{208}, 214. save line: \underline{219}. save loc: \underline{208}, 214. save mode: \underline{208}, 212. save next control : \underline{207*} . save place: \underline{219}. save position: \underline{219}, 220, 225. save text ptr : \underline{207*} . save tok ptr : \underline{207*} . scanning hex : \underline{93}, 94, 95, 96, 100. scrap base: \underline{144}, 145, 173, 178, 179, 180, 181,

194, 195, 197. scrap ptr : \underline{144}, 145, 176, 178, 179, 183* , 184, 187,

194, 195, 197, 199, 226, 228, 244, 256. sc0 : \underline{184}, 186* , 193* , 194, 195, 228. sc1 : \underline{184}, 186* , 189, 190, 192* , 193* , 196, 227* ,

228, 231, 232. sc2 : \underline{184}, 186* , 188* , 192* , 193* , 227* , 228, 231. sc3 : \underline{184}, 186* , 192* , 193* , 231. sc4 : \underline{184}, 186* , 193* . : 104. : 105. semi : 139, \underline{140}, 142, 143, 149, 161, 163, 186* ,

194, 195, 228, 231. set element sign: \underline{15}, 64* , 186* . sid1 : \underline{63*} . sid10 : \underline{63*} . sid11 : \underline{63*} . sid12 : \underline{63*} . sid13 : \underline{63*} . sid14 : \underline{63*} . sid2 : \underline{63*} . sid3 : \underline{63*} . sid4 : \underline{63*} . sid5 : \underline{63*} . sid6 : \underline{63*} . sid7 : \underline{63*} . sid8 : \underline{63*} . sid9 : \underline{63*} . simp: \underline{140}, 142, 143, 148, 150, 151, 158, 160, 161,

162, 167, 170, 186* , 189, 190, 192* , 196. sixteen bits : \underline{36}, 37, 48, 50, 53, 55, 66, 69, 172,

174, 201, 206, 207* , 219, 236, 242, 244, 267* , 268* . skip comment : \underline{91}, 112* , 132, 136* . skip limbo: \underline{89}, 109, 132. skip TeX : \underline{90}, 113, 132. : 35. sort ptr : \underline{244}, 249, 250, 251, 252. special string characters: 189. split procedures: 149, 183* , 261* . spotless : \underline{9}, 10, 263. sq : 148, \underline{174}. squash: \underline{148}, 151, 152, 154, 157, 160, 161, 162,

163, 166, 167, 169, 170, 174, 178. stack : 201, \underline{202}, 204, 205. stack ptr : 201, \underline{202}, 204, 205. stack size: \underline{8*} , 202, 204. stat: \underline{3}. status : 269* . stmt : \underline{140}, 143, 149, 152, 153, 155, 156, 159, 160,

161, 162, 164, 167, 168, 169, 170. string : \underline{93}, 99, 185. : 99. string delimiter : \underline{208}, 216. sub cases : 183* , 191* , \underline{192*} . substr : 122* , 269* . system dependencies: \underline{1*} , 2* , 4* , 7* , 12* , 17, 20* , 21* , 22* ,

24, 26* , 28* , 32, 33, 259* , 260, 261* , 263, 269* . s0 : \underline{184}. s1 : \underline{184}. s2 : \underline{184}. s3 : \underline{184}. s4 : \underline{184}. t: \underline{58}. tab mark : \underline{15}, 32, 87, 89, 92* , 95, 103, 104,

123, 133, 135. tats: \underline{3}. temp buffer : \underline{27*} , 28* . temp line: \underline{71}, 72. term in: \underline{259*} , 260. term out : \underline{20*} , 21* , 22* , 260. terminator : 139, \underline{140}, 142, 143, 149, 152, 153, 160,

161, 164, 166, 167, 179, 193* , 194, 195. : 222* . tex file: \underline{2*} , \underline{25}, 26* , 122* , 124* , 261* , 269* .

TeX string : \underline{86*} , 87, 93, 100, 185, 222* .

text : 12* .

text char : \underline{12*} , 13, 20* .

text file: \underline{12*} , 20* , 23, 25, 28* .

text pointer : \underline{52}, 53, 144, 146, 179, 197, 198* ,

204, 207* , 226. text ptr : \underline{53}, 54, 146, 171, 172, 175, 179, 180, 184, 187, 195, 198* , 199, 207* , 208, 226, 256.

thin space: \underline{86*} , 87, 186* , 222* . : 34. this module: \underline{229*} , 230* , 231, 233, 235. this xref : \underline{234}, 235, 255. to like: \underline{42*} , 64* , 191* , 192* . tok field : \underline{201}, 202. tok flag : \underline{146}, 148, 195, 198* , 206, 226. tok mem: \underline{53}, 136* , \underline{146}, 148, 201, 202, 206, 213. tok ptr : \underline{53}, 54, 136* , 137* , 148, 171, 175, 179, 180,

187, 189, 198* , 199, 207* , 226, 256. tok start : 52, \underline{53}, 54, 144, 146, 171, 204.

tracing : 88, \underline{177}, 178, 181, 182, 259* .

trans : \underline{144}, 148, 172, 176, 179, 183* , 184, 195,

197, 244. translate: 149, \underline{179}, 180, 197, 226. trouble shooting : 95, 206, 252, \underline{258*} , 259* . true: 6, 28* , 29, 71, 72, 74, 79, 81, 82, 83, 85, 93, 100, 109, 110, 122* , 127, 128, 186* , 227* , 239, 258* , 259* , 269* . typewriter : \underline{42*} , 111* , 253. unbucket : \underline{249}, 250, 251. underline: \underline{86*} , 87, 100, 113. : 87. until like: \underline{42*} , 64* , 193* . up to: \underline{95}. update terminal : \underline{22*} , 31, 110, 221, 260. u1 : 268* . u2 : 268* . var head : \underline{140}, 142, 143, 148, 149, 162, 163,

170, 193* . var like: \underline{42*} , 64* , 111* , 193* . varying : 27* , 267* . VAX external : \underline{266*} , 268* . VAX immed : \underline{266*} , 268* . VAX length: \underline{266*} , 269* . VAX lib get foreign: \underline{266*} , \underline{268*} , 269* . VAX open: \underline{269*} . VAX stdescr : \underline{266*} , 268* . VAX volatile: \underline{266*} , 268* . verbatim: \underline{86*} , 87, 100, 107, 185, 189. : 107. vertical bar : \underline{86*} , 97* , 186* . w: \underline{44}, \underline{58}, \underline{66}, \underline{69}, \underline{131}, \underline{208}. WEAVE : \underline{2*} .

: 79. web file: \underline{2*} , \underline{23}, 24, 32, 71, 73, 79, 83, 85, 269* . : 76, 80, 84. wi : \underline{40}, 41. wildcard : \underline{42*} , 111* , 253. write: 20* , 124* , 260, 269* . write ln: 20* , 22* , 122* , 269* . ww : 8* , \underline{37}, 38, 39, 40, 41, 44, 50, 58, 61, 62, 66, 67,

68, 69, 131, 208, 209, 214, 243, 244, 251, 262. xchr : \underline{13}, 14, 16, 17, 18, 32, 44, 105, 122* , 128,

146, 147, 182, 260. xclause: 6. xlink : \underline{46}, 50, 51, 119, 213, 235, 237, 254, 255. xlink field : 46, \underline{48}. xmem: 46, \underline{48}. xord : \underline{13}, 16, 18, 28* . xref : 36, \underline{37}, 46, 49, 50, 51, 62, 67, 119, 213,

231, 235, 243, 255. xref number : \underline{47}, 48, 50, 51, 118, 234, 236. xref ptr : 46, \underline{48}, 49, 50, 51, 262. xref roman: \underline{86*} , 87, 93, 100, 111* , 113, 186* , 222* . xref switch: 46, \underline{48}, 49, 50, 93, 100, 101, 111* ,

113, 115. xref typewriter : \underline{86*} , 87, 93, 111* , 113, 186* , 222* . xref wildcard : \underline{86*} , 87, 93, 111* , 113, 186* , 222* . : 222* , 232.

36  NAMES OF THE SECTIONS  WEAVE changes for Vax/VMS §270

⟨ Append a string scrap 189 ⟩ Used in section 185. ⟨ Append a TEX string scrap 190 ⟩ Used in section 185. ⟨ Append an identifier scrap 191* ⟩ Used in section 185. ⟨ Append the scrap appropriate to next control 185 ⟩ Used in section 183*.

⟨ Append terminator if not already present 194 ⟩ Used in sections 193*, 193*, and 193*. ⟨ Cases for alpha 151 ⟩ Used in section 150. ⟨ Cases for beginning 152 ⟩ Used in section 150. ⟨ Cases for case head 153 ⟩ Used in section 149. ⟨ Cases for casey 154 ⟩ Used in section 149. ⟨ Cases for clause 155 ⟩ Used in section 149. ⟨ Cases for cond 156 ⟩ Used in section 149. ⟨ Cases for elsie 157 ⟩ Used in section 149. ⟨ Cases for exp 158 ⟩ Used in section 149. ⟨ Cases for intro 159 ⟩ Used in section 150. ⟨ Cases for math 160 ⟩ Used in section 150. ⟨ Cases for mod scrap 161 ⟩ Used in section 149. ⟨ Cases for open math 163 ⟩ Used in section 162. ⟨ Cases for open 162 ⟩ Used in section 150. ⟨ Cases for proc 164 ⟩ Used in section 149. ⟨ Cases for record head 165 ⟩ Used in section 149. ⟨ Cases for semi 166 ⟩ Used in section 149. ⟨ Cases for simp 167 ⟩ Used in section 150. ⟨ Cases for stmt 168 ⟩ Used in section 149. ⟨ Cases for terminator 169 ⟩ Used in section 149. ⟨ Cases for var head 170 ⟩ Used in section 149.

⟨ Cases involving nonstandard ASCII characters 188* ⟩ Used in section 186*. ⟨ Cases that generate more than one scrap 193* ⟩ Used in section 191*.

⟨ Change pp to max(scrap base,pp+d) 173 ⟩ Used in sections 172 and 174.

⟨ Check for overlong name 105 ⟩ Used in section 103. ⟨ Check that all changes have been read 85 ⟩ Used in section 261*. ⟨ Check that = or ≡ follows this module name, and emit the scraps to start the module definition 231 ⟩

Used in section 230*. ⟨ Clear bal and goto done 138* ⟩ Used in sections 136* and 137*.

⟨ Combine the irreducible scraps that remain 180 ⟩ Used in section 179. ⟨ Compare name p with current identifier, goto found if equal 61 ⟩ Used in section 60. ⟨ Compiler directives 4* ⟩ Used in section 2*. ⟨ Compress two-symbol combinations like ‘ ’ 97* ⟩ Used in section 95. ⟨ Compute the hash code h 59 ⟩ Used in section 58. ⟨ Compute the name location p 60 ⟩ Used in section 58. ⟨ Constants in the outer block 8* ⟩ Used in section 2*. ⟨ Copy a control code into the buffer 217 ⟩ Used in section 216. ⟨ Copy special things when c = , , , ; goto done at end 137* ⟩ Used in section 136*. ⟨ Copy the Pascal text into buffer [(limit + 1) . . j] 216 ⟩ Used in section 214. ⟨ Copy up to ‘ ’ or control code, goto done if finished 135 ⟩ Used in section 134. ⟨ Copy up to control code, return if finished 133 ⟩ Used in section 132. ⟨ Declaration of subprocedures for translate 150 ⟩ Used in section 179. ⟨ Declaration of the app comment procedure 195 ⟩ Used in section 183*. ⟨ Declaration of the app octal and app hex procedures 196 ⟩ Used in section 183*. ⟨ Declaration of the easy cases procedure 186* ⟩ Used in section 183*. ⟨ Declaration of the sub cases procedure 192* ⟩ Used in section 183*. ⟨ Do special things when c = , , , ; goto done at end 92* ⟩ Used in section 91. ⟨ Do the first pass of sorting 243 ⟩ Used in section 239.

§270  WEAVE changes for Vax/VMS  NAMES OF THE SECTIONS 37

⟨ Emit the scrap for a module name if present 232 ⟩ Used in section 230*. ⟨ Enter a new module name into the tree 67 ⟩ Used in section 66. ⟨ Enter a new name into the table at position p 62 ⟩ Used in section 58.

⟨ Error handling procedures 30, 31, 33, 268* ⟩ Used in section 2*. ⟨ Get a string 99 ⟩ Used in section 95. ⟨ Get an identifier 98 ⟩ Used in section 95.

⟨ Get control code and possible module name 100 ⟩ Used in section 95.

⟨ Globals in the outer block 9, 13, 20*, 23, 25, 27*, 29, 37, 39, 45, 48, 53, 55, 63*, 65, 71, 73, 93, 108, 114, 118, 121, 129,

144, 177, 202, 219, 229*, 234, 240, 242, 244, 246, 258*, 265* ⟩ Used in section 2*.

⟨ Go to found if c is a hexadecimal digit, otherwise set scanning hex ← false 96 ⟩ Used in section 95.

⟨ If end of name, goto done 104 ⟩ Used in section 103.

⟨ If semi-tracing, show the irreducible scraps 181 ⟩ Used in section 180. ⟨ If the current line starts with , report any discrepancies and return 80 ⟩ Used in section 79. ⟨ If tracing, print an indication of where we are 182 ⟩ Used in section 179. ⟨ Invert the cross-reference list at cur name, making cur xref the head 255 ⟩ Used in section 254. ⟨ Local variables for initialization 16, 40, 56, 247, 267* ⟩ Used in section 2*. ⟨ Look ahead for strongest line break, goto reswitch 212 ⟩ Used in section 211. ⟨ Make sure that there is room for at least four more scraps, six more tokens, and four more texts 187 ⟩

Used in section 185.

⟨ Make sure that there is room for at least seven more tokens, three more texts, and one more scrap 199 ⟩

Used in section 198*.

⟨ Make sure the entries cat [pp . . (pp + 3)] are defined 176 ⟩ Used in section 175. ⟨ Match a production at pp, or increase pp if there is no match 149 ⟩ Used in section 175.

⟨ Move buffer and limit to change buffer and change limit 78 ⟩ Used in sections 75 and 79.

⟨ Output a control, look ahead in case of line breaks, possibly goto reswitch 211 ⟩ Used in section 208.

⟨ Output a operator 210 ⟩ Used in section 208. ⟨ Output a module name 213 ⟩ Used in section 208.

⟨ Output all the module names 257 ⟩ Used in section 239. ⟨ Output all the module numbers on the reference list cur xref 237 ⟩ Used in section 236.

⟨ Output an identifier 209 ⟩ Used in section 208.

⟨ Output index entries for the list at sort ptr 252 ⟩ Used in section 250. ⟨ Output the code for the beginning of a new module 221 ⟩ Used in section 220. ⟨ Output the code for the end of a module 238 ⟩ Used in section 220. ⟨ Output the cross-references at cur name 254 ⟩ Used in section 252.

⟨ Output the name at cur name 253 ⟩ Used in section 252.

⟨ Output the text of the module name 214 ⟩ Used in section 213. ⟨ Phase I: Read all the user’s text and store the cross references 109 ⟩ Used in section 261*. ⟨ Phase II: Read all the text again and translate it to TEX form 218 ⟩ Used in section 261*. ⟨ Phase III: Output the cross-reference index 239 ⟩ Used in section 261*. ⟨ Preset initial values 269* ⟩ Used in section 2*. ⟨ Print error location based on input buffer 32 ⟩ Used in section 31. ⟨ Print error messages about unused or undefined module names 120 ⟩ Used in section 109. ⟨ Print statistics about memory usage 262 ⟩ Used in section 261*.

⟨ Print the job history 263 ⟩ Used in section 261*.

⟨ Print token r in symbolic form 147 ⟩ Used in section 146. ⟨ Print warning message, break the line, return 128 ⟩ Used in section 127. ⟨ Process a format definition 116 ⟩ Used in section 115. ⟨ Put module name into mod text [1 . . k] 103 ⟩ Used in section 101. ⟨ Read from change file and maybe turn off changing 84 ⟩ Used in section 82. ⟨ Read from web file and maybe turn on changing 83 ⟩ Used in section 82. ⟨ Rearrange the list pointed to by cur xref 235 ⟩ Used in section 233. ⟨ Reduce the scraps using the productions until no more rules apply 175 ⟩ Used in section 179.

⟨ Scan a verbatim string 107 ⟩ Used in section 100. ⟨ Scan the module name and make cur module point to it 101 ⟩ Used in section 100.

⟨ Scan to the next 106 ⟩ Used in section 100. ⟨ Set initial values 10, 14, 17, 18, 21*, 41, 43, 49, 54, 57, 94, 102, 124*, 126, 145, 203, 245, 248, 259* ⟩ Used in section 2*.

⟨ Set variable c to the result of comparing the given name to name p 68 ⟩ Used in sections 66 and 69. ⟨ Show cross references to this module 233 ⟩ Used in section 220. ⟨ Skip next character, give error if not ‘ ’ 215 ⟩ Used in section 214. ⟨ Skip over comment lines in the change file; return if end of file 76 ⟩ Used in section 75. ⟨ Skip to the next nonblank line; return if end of file 77 ⟩ Used in section 75. ⟨ Sort and output the index 250 ⟩ Used in section 239. ⟨ Special control codes allowed only when debugging 88 ⟩ Used in section 87. ⟨ Split the list at sort ptr into further lists 251 ⟩ Used in section 250. ⟨ Start a format definition 228 ⟩ Used in section 225. ⟨ Start a macro definition 227* ⟩ Used in section 225. ⟨ Store all the reserved words 64* ⟩ Used in section 261*. ⟨ Store cross reference data for the current module 110 ⟩ Used in section 109. ⟨ Store cross references in the definition part of a module 115 ⟩ Used in section 110. ⟨ Store cross references in the Pascal part of a module 117 ⟩ Used in section 110. ⟨ Store cross references in the TEX part of a module 113 ⟩ Used in section 110. ⟨ Tell about changed modules 241 ⟩ Used in section 239. ⟨ Translate a hexadecimal constant appearing in TEX text 224 ⟩ Used in section 222*. ⟨ Translate an octal constant appearing in TEX text 223 ⟩ Used in section 222*. ⟨ Translate the current module 220 ⟩ Used in section 218. ⟨ Translate the definition part of the current module 225 ⟩ Used in section 220. ⟨ Translate the Pascal part of the current module 230* ⟩ Used in section 220. ⟨ Translate the TEX part of the current module 222* ⟩ Used in section 220.

⟨ Types in the outer block 11, 12*, 36, 38, 47, 52, 201 ⟩ Used in section 2*.

The WEAVE processor

(Version 2.8)

Section Page

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 The character set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 4 Input and output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 5 Reporting errors to the user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 7 Data structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 7 Searching for identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 8 Initializing the table of reserved words . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 8 Searching for module names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 10 Lexical scanning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 10 Inputting the next token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 12 Phase one processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 13 Low-level output routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 14 Routines that copy TEX material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 15 Parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139 17 Implementing the productions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 17 Initializing the scraps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 17 Output of tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 21 Phase two processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 22 Phase three processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 23 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 23 The main program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 24 System-dependent changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264 25 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 28