124  INTRODUCTION  TANGLE changes C §1

1* . Introduction. This program converts a file to a Pascal file. It was written by D. E. Knuth in September, 1981; a somewhat similar SAIL program had been developed in March, 1979. Since this program describes itself, a bootstrapping process involving hand-translation had to be used to get started.

For large files one should have a large memory, since keeps all the Pascal text in memory (in an abbreviated form). The program 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.

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, the Pascal output goes to file Pascal file, and the string pool output goes to file pool .

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 TANGLE .

define end of TANGLE = 9999 { go here to wrap it up } program TANGLE ;

label end of TANGLE ; { 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 ⟩ ⟨ Declaration of scan args 190* ⟩

procedure initialize; var ⟨ Local variables for initialization 16 ⟩ begin ⟨ 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. ⟨ Compiler directives 4* ⟩ ≡

\underline{\overline{$}} \{ no range check \} debug \underline{\overline{$}} gubed \{ but turn everything on when debugging \}

§8  TANGLE changes C  INTRODUCTION 125

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* ⟩ ≡

buf size = 100; { maximum length of input line } max bytes = 45000; { 1/ww times the number of bytes in identifiers, strings, and module names; must

be less than 65536 } max toks = 50000;

{ 1/zz times the number of bytes in compressed Pascal code; must be less than 65536 } max names = 4000; { number of identifiers, strings, module names; must be less than 10240 } max texts = 2000; { number of replacement texts, must be less than 10240 } hash size = 353; { should be prime } longest name = 400; { module names shouldn’t be longer than this } line length = 72; { lines of Pascal output have at most this many characters } out buf size = 144; { length of output buffer, should be twice line length } stack size = 100; { number of simultaneous levels of macro expansion } max id length = 50; { long identifiers are chopped to this length, which must not exceed line length } unambig length = 20; { identifiers must be unique if chopped to this length }

This code is used in section 2*.

126  THE CHARACTER SET  TANGLE changes C §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 ≡ ASCII code { 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 = 255 { ordinal number of the largest element of text char } ⟨ Types in the outer block 11 ⟩ +≡

text file = packed file of text char ;

17* . Here now is the system-dependent part of the character set. If is being implemented on a gardenvariety Pascal for which only standard ASCII codes will appear in the input and output files, you don’t need to make any changes here. But if you have, for example, an extended character set like the one in Appendix C of The TEXbook, the first line of code in this module should be changed to

for i ← 1 to ´ 37 do xchr [i] ← chr (i);

’s character set is essentially identical to TEX’s, even with respect to characters less than ´ 40 .

Changes to the present module will make more friendly on computers that have an extended character set, so that one can type things like instead of . If you have an extended set of characters that are easily incorporated into text files, you can assign codes arbitrarily here, giving an xchr equivalent to whatever characters the users of are allowed to have in their input files, provided that unsuitable characters do not correspond to special codes like carriage return that are listed above.

(The present file does not contain any of the non-ASCII characters, because it is intended to be used with all implementations of . It was originally created on a Stanford system that has a convenient extended character set, then “sanitized” by applying another program that transliterated all of the non-standard characters into standard equivalents.) ⟨ Set initial values 10 ⟩ +≡

for i ← 1 to ´ 37 do xchr [i] ← chr (i);

for i ← ´ 200 to ´ 377 do xchr [i] ← chr (i);

§19  TANGLE changes C  INPUT AND OUTPUT 127

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

define term out ≡ stdout

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

begin new line; print (#); end

21* . Different systems have different ways of specifying that the output on a certain file will appear on the user’s terminal. ⟨ Set initial values 10 ⟩ +≡

{ Nothing need be done for C. }

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 ≡ flush(term out ) { empty the terminal output buffer }

24* . The following code opens the input files. This happens after the initialize procedure has executed. That will have called the scan args procedure to set up the global variables web file name and change file name to the appropriate file names. These globals, and the scan args procedure will be defined at the end where they won’t disturb the module numbering. procedure open input ; { prepare to read web file and change file }

begin reset (web file, web file name); reset (change file, change file name); end;

26* . The following code opens Pascal file and pool . Use the scan args procedure to fill the global file names, according to the names given on the command line. ⟨ Set initial values 10 ⟩ +≡

scan args ; rewrite(Pascal file, pascal file name);

128  INPUT AND OUTPUT  TANGLE changes C §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. function input ln(var f : text file): boolean; { inputs a line or returns false }

var final limit : 0 . . buf size; { limit without trailing blanks }

begin limit ← 0; final limit ← 0;

if eof (f) then input ln ← false

else begin while ¬eoln(f) do begin buffer [limit ] ← xord [getc(f)]; incr (limit ); if buffer [limit − 1] ≠ ␣ then final limit ← limit ; if limit = buf size then

begin while ¬eoln(f) do vgetc(f);

decr (limit ); { keep buffer [buf size] empty } if final limit > limit then final limit ← limit ; print nl (´ ␣ ␣ ␣ ␣ ´ ); loc ← 0; error ; end; end;

read ln(f); limit ← final limit ; input ln ← true; end;

end;

§29  TANGLE changes C  REPORTING ERRORS TO THE USER 129

34* . The jump out procedure just cuts across all active procedure levels and jumps out of the program. This is the only non-local goto statement in . It is used when no recovery from a particular error has been provided.

Some Pascal compilers do not implement non-local goto statements. In such cases the code that appears at label end of TANGLE should be copied into the jump out procedure, followed by a call to a system procedure that terminates the program.

define jump out ≡ uexit (1)

define fatal error (#) ≡ begin new line; print (#); error ; mark fatal ; uexit (1); end

130  DATA STRUCTURES  TANGLE changes C §37

38* . has been designed to avoid the need for indices that are more than sixteen bits wide, so that it can be used on most computers. But there are programs that need more than 65536 tokens, and some programs even need more than 65536 bytes; TEX is one of these. To get around this problem, a slight complication has been added to the data structures: byte mem and tok mem are two-dimensional arrays, whose first index is either 0 or 1. (For generality, the first index is actually allowed to run between 0 and ww − 1 in byte mem, or between 0 and zz − 1 in tok mem, where ww and zz are set to 2 and 3; the program will work for any positive values of ww and zz , and it can be simplified in obvious ways if ww = 1 or zz = 1.)

define ww = 3 { we multiply the byte capacity by approximately this amount } define zz = 4 { we multiply the token capacity by approximately this amount }

⟨ Globals in the outer block 9 ⟩ +≡ byte mem: packed array [0 . . ww − 1, 0 . . max bytes ] of ASCII code; { characters of names } tok mem: packed array [0 . . zz − 1, 0 . . max toks ] of eight bits ; { tokens } byte start : array [0 . . max names ] of sixteen bits ; { directory into byte mem } tok start : array [0 . . max texts ] of sixteen bits ; { directory into tok mem } link : array [0 . . max names ] of sixteen bits ; { hash table or tree links } ilk : array [0 . . max names ] of sixteen bits ; { type codes or tree links } equiv : array [0 . . max names ] of sixteen bits ; { info corresponding to names } text link : array [0 . . max texts ] of sixteen bits ; { relates replacement texts }

§50  TANGLE changes C  SEARCHING FOR IDENTIFIERS 131

63* . ⟨ Check if q conflicts with p 63* ⟩ ≡ begin k ← byte start [q]; s ← 0; w ← q mod ww ; while (k < byte start [q + ww ]) ∧ (s < unambig length) do

begin c ← byte mem[w, k]; if c ≠ then

begin if chopped id [s] ≠ c then goto not found ;

incr (s);

end; incr (k); end;

if (k = byte start [q + ww ]) ∧ (chopped id [s] ≠ 0) then goto not found ; print nl (´ ␣ ␣ ␣ ␣´ ); for k ← byte start [q] to byte start [q + ww ] − 1 do print (xchr [byte mem[w, k]]); error ; q ← 0; { only one conflict will be printed, since equiv [0] = 0 }

not found : end

This code is used in section 62.

64* . We compute the string pool check sum by working modulo a prime number that is large but not so large that overflow might occur.

define check sum prime ≡ ´ 3777777667 { 2^{29} − 73 } ⟨ Define and output a new string of the pool 64* ⟩ ≡

begin ilk [p] ← numeric; { strings are like numeric macros } if l − double chars = 2 then { this string is for a single character }

equiv [p] ← buffer [id first + 1] + ´ 100000 else begin if string ptr = 256 then rewrite(pool , pool file name);

equiv [p] ← string ptr + ´ 100000 ; l ← l − double chars − 1; if l > 99 then err print (´ ␣ ␣ ␣ ␣ ␣ ´ ); incr (string ptr ); write(pool , xchr [ + l div 10], xchr [ + l mod 10]); { output the length } pool check sum ← pool check sum + pool check sum + l; while pool check sum > check sum prime do pool check sum ← pool check sum − check sum prime; i ← id first + 1; while i < id loc do

begin write(pool , xchr [buffer [i]]); { output characters of string }

pool check sum ← pool check sum + pool check sum + buffer [i];

while pool check sum > check sum prime do pool check sum ← pool check sum − check sum prime; if (buffer [i] = ) ∨ (buffer [i] = ) then i ← i + 2

{ omit second appearance of doubled character } else incr (i); end;

write ln(pool ); end;

end

This code is used in section 61.

132  PRODUCING THE OUTPUT  TANGLE changes C §65
105* . ⟨ Contribution is or or  or  105* ⟩ ≡

((t = ident ) ∧ (v = 3) ∧ (((out contrib[1] = ) ∧ (out contrib[2] = ) ∧ (out contrib[3] = )) ∨ ((out contrib[1] = ) ∧ (out contrib[2] = ) ∧ (out contrib[3] = )) ∨ ((out contrib[1] = ) ∧ (out contrib[2] = ) ∧ (out contrib[3] = )) ∨ ((out contrib[1] = ) ∧ (out contrib[2] = ) ∧ (out contrib[3] = )))) ∨ ((t = misc) ∧ ((v = ) ∨ (v = )))

This code is used in section 104.

110* . ⟨ If previous output was or , goto bad case 110* ⟩ ≡

if (out ptr = break ptr + 3) ∨ ((out ptr = break ptr + 4) ∧ (out buf [break ptr ] = ␣ )) then if ((out buf [out ptr − 3] = ) ∧ (out buf [out ptr − 2] = ) ∧ (out buf [out ptr − 1] = ))∨ ((out buf [out ptr − 3] = ) ∧ (out buf [out ptr − 2] = ) ∧ (out buf [out ptr − 1] = ))∨ ((out buf [out ptr − 3] = ) ∧ (out buf [out ptr − 2] = ) ∧ (out buf [out ptr − 1] = ))∨ ((out buf [out ptr − 3] = ) ∧ (out buf [out ptr − 2] = ) ∧ (out buf [out ptr − 1] = )) then

goto bad case

This code is used in section 107.

§112  TANGLE changes C  THE BIG OUTPUT SWITCH 133

114* . ⟨ Cases like and 114* ⟩ ≡ and sign: begin out contrib[1] ← ; out contrib[2] ← ; out contrib[3] ← ; send out (ident , 3);

end; not sign: begin out contrib[1] ← ; out contrib[2] ← ; out contrib[3] ← ; send out (ident , 3);

end; set element sign: begin out contrib[1] ← ; out contrib[2] ← ; send out (ident , 2);

end; or sign: begin out contrib[1] ← ; out contrib[2] ← ; send out (ident , 2);

end; left arrow : begin out contrib[1] ← ; out contrib[2] ← ; send out (str , 2);

end; not equal : begin out contrib[1] ← ; out contrib[2] ← ; send out (str , 2);

end; less or equal : begin out contrib[1] ← ; out contrib[2] ← ; send out (str , 2);

end; greater or equal : begin out contrib[1] ← ; out contrib[2] ← ; send out (str , 2);

end; equivalence sign: begin out contrib[1] ← ; out contrib[2] ← ; send out (str , 2);

end; double dot : begin out contrib[1] ← ; out contrib[2] ← ; send out (str , 2);

end;

This code is used in section 113.

116* . Single-character identifiers represent themselves, while longer ones appear in byte mem. All must be converted to lowercase, with underlines removed. Extremely long identifiers must be chopped.

define up to(#) ≡ # − 24, # − 23, # − 22, # − 21, # − 20, # − 19, # − 18, # − 17, # − 16, # − 15, # − 14, # − 13,

# − 12, # − 11, # − 10, # − 9, # − 8, # − 7, # − 6, # − 5, # − 4, # − 3, # − 2, # − 1, #

⟨ Cases related to identifiers 116* ⟩ ≡ , up to( ), , up to( ): begin out contrib[1] ← cur char ; send out (ident , 1);

end; identifier : begin k ← 0; j ← byte start [cur val ]; w ← cur val mod ww ;

while (k < max id length) ∧ (j < byte start [cur val + ww ]) do begin incr (k); out contrib[k] ← byte mem[w, j]; incr (j); if out contrib[k] = then decr (k); end;

send out (ident , k);

end;

This code is used in section 113.

134  SCANNING A NUMERIC DEFINITION  TANGLE changes C §123

157* . The evaluation of a numeric expression makes use of two variables called the accumulator and the next sign. At the beginning, accumulator is zero and next sign is +1. When a or is scanned, next sign is multiplied by the value of that sign. When a numeric value is scanned, it is multiplied by next sign and added to the accumulator , then next sign is reset to +1.

define add in(#) ≡ begin accumulator ← accumulator + next sign ∗ toint (#); next sign ← +1; end

procedure scan numeric(p : name pointer ); { defines numeric macros } label reswitch, done; var accumulator : integer ; { accumulates sums }

next sign: −1 . . +1; { sign to attach to next value }

q: name pointer ; { points to identifiers being evaluated }

val : integer ; { constants being evaluated } begin ⟨ Set accumulator to the value of the right-hand side 158 ⟩; if abs (accumulator ) ≥ ´ 100000 then

begin err print (´ ␣ ␣ ␣ ␣´ , accumulator : 1); accumulator ← 0; end;

equiv [p] ← accumulator + ´ 100000 ; { name p now is defined to equal accumulator } end;

§163  TANGLE changes C  DEBUGGING 135

179* . 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.

define term in ≡ stdin ⟨ 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

180* . The debugging routine needs to read from the user’s terminal. ⟨ Set initial values 10 ⟩ +≡

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

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

gubed

136  THE MAIN PROGRAM  TANGLE changes C §182

182* . The main program. We have defined plenty of procedures, and it is time to put the last pieces of the puzzle in place. Here is where starts, and where it ends.

begin initialize; ⟨ Initialize the input system 134 ⟩; print ln(banner ); { print a “banner line” } ⟨ Phase I: Read all the user’s text and compress it into tok mem 183 ⟩; stat for ii ← 0 to zz − 1 do max tok ptr [ii ] ← tok ptr [ii ]; tats ⟨ Phase II: Output the contents of the compressed tables 112 ⟩;

end of TANGLE : if string ptr > 256 then ⟨ Finish off the string pool file 184 ⟩;

stat ⟨ Print statistics about memory usage 186 ⟩; tats { here files should be closed if the operating system requires it }

⟨ Print the job history 187 ⟩; new line; if (history ≠ spotless ) ∧ (history ≠ harmless message) then uexit (1) else uexit (0); end.

§188  TANGLE changes C  SYSTEM-DEPENDENT CHANGES 137

188* . System-dependent changes. This module should be replaced, if necessary, by changes to the program that are necessary to make work at a particular installation. It is usually best to design your change file so that all changes to previous modules preserve the module numbering; then everybody’s version will be consistent with the printed program. More extensive changes, which introduce new modules, can be inserted here; then only the index itself will get a new module number.

189* . The user calls with arguments on the command line. These are either file names or flags (beginning with ‘ ’). The following globals are for communicating the user’s desires to the rest of the program. The various file name variables contain strings with the full names of those files, as UNIX knows them.

There are no flags that affect at the moment.

define max file name length ≡ FILENAMESIZE ⟨ Globals in the outer block 9 ⟩ +≡ web file name, change file name, pascal file name, pool file name: array [1 . . max file name length] of

char ;

190* . The scan args procedure looks at the command line arguments and sets the file name variables accordingly. At least one file name must be present: the file. It may have an extension, or it may omit it to get ´ ´ added. The Pascal output file name is formed by replacing the file name extension by ´´ . Similarly, the pool file name is formed using a ´ ´ extension.

If there is another file name present among the arguments, it is the change file, again either with an extension or without one to get ´ ´ An omitted change file argument means that ´ ´ should be used, when no changes are desired. ⟨ Declaration of scan args 190* ⟩ ≡ procedure scan args ;

var dot pos , slash pos , i, a: integer ; { indices } c: char ; fname: array [1 . . max file name length] of char ; { temporary argument holder } found web, found change: boolean; { true when those file names have been seen }

begin found web ← false; found change ← false;

for a ← 1 to argc − 1 do begin argv (a, fname); { put argument number a into fname } if fname[1] ≠ ´ ´ then

begin if ¬found web then

⟨ Get web file name, pascal file name, and pool file name variables from fname 191* ⟩ else if ¬found change then ⟨ Get change file name from fname 192* ⟩

else ⟨ Print usage error message and quit 195* ⟩; end

else ⟨ Handle flag argument in fname 194* ⟩;

end; if ¬found web then ⟨ Print usage error message and quit 195* ⟩; if ¬found change then ⟨ Set up null change file 193* ⟩; end;

This code is used in section 2*.

138  SYSTEM-DEPENDENT CHANGES  TANGLE changes C §191

191* . Use all of fname for the web file name if there is a ´ ´ in it, otherwise add ´ ´ . The other file names come from adding things after the dot. The argv procedure won’t put more than max file name length −5 characters into fname, and this leaves enough room in the file name variables to add the extensions.

The end of a file name is marked with a ´ ␣´ , the convention assumed by the reset and rewrite procedures. ⟨ Get web file name, pascal file name, and pool file name variables from fname 191* ⟩ ≡

begin dot pos ← −1; slash pos ← −1; i ← 1; while (fname[i] ≠ ´ ␣´ ) ∧ (i ≤ max file name length − 5) do

begin web file name[i] ← fname[i];

if fname[i] = ´ ´ then dot pos ← i;

if fname[i] = ´ ´ then slash pos ← i;

incr (i);

end; web file name[i] ← ´ ␣´ ; if (dot pos = −1) ∨ (dot pos < slash pos ) then

begin dot pos ← i; web file name[dot pos ] ← ´ ´ ; web file name[dot pos + 1] ← ´ ´ ; web file name[dot pos + 2] ← ´ ´ ; web file name[dot pos + 3] ← ´ ´ ; web file name[dot pos + 4] ← ´ ␣´ ; end;

for i ← 1 to dot pos do begin c ← web file name[i]; pascal file name[i] ← c; pool file name[i] ← c; end;

pascal file name[dot pos + 1] ← ´ ´ ; pascal file name[dot pos + 2] ← ´ ␣´ ; pool file name[dot pos + 1] ← ´ ´ ; pool file name[dot pos + 2] ← ´ ´ ; pool file name[dot pos + 3] ← ´ ´ ; pool file name[dot pos + 4] ← ´ ´ ; pool file name[dot pos + 5] ← ´ ␣´ ; found web ← true; end

This code is used in section 190*.

192* . ⟨ Get change file name from fname 192* ⟩ ≡ begin dot pos ← −1; slash pos ← −1; i ← 1; while (fname[i] ≠ ´ ␣´ ) ∧ (i ≤ max file name length − 5) do

begin change file name[i] ← fname[i];

if fname[i] = ´ ´ then dot pos ← i;

if fname[i] = ´ ´ then slash pos ← i;

incr (i);

end; change file name[i] ← ´ ␣´ ; if (dot pos = −1) ∨ (dot pos < slash pos ) then

begin dot pos ← i; change file name[dot pos ] ← ´ ´ ; change file name[dot pos + 1] ← ´ ´ ; change file name[dot pos + 2] ← ´ ´ ; change file name[dot pos + 3] ← ´ ␣´ ; end;

found change ← true; end

This code is used in section 190*.

193* . ⟨ Set up null change file 193* ⟩ ≡ begin change file name[1] ← ´ ´ ; change file name[2] ← ´ ´ ; change file name[3] ← ´ ´ ; change file name[4] ← ´ ´ ; change file name[5] ← ´ ´ ; change file name[6] ← ´ ´ ; change file name[7] ← ´ ´ ; change file name[8] ← ´ ´ ; change file name[9] ← ´ ´ ; change file name[10] ← ´ ␣´ ; end

This code is used in section 190*.

194* . There are no flags currently used by , but this module can be used as a hook to introduce flags. ⟨ Handle flag argument in fname 194* ⟩ ≡

begin ⟨ Print usage error message and quit 195* ⟩;

end

This code is used in section 190*.

195* . ⟨ Print usage error message and quit 195* ⟩ ≡ begin print ln(´ ␣ ␣ ␣ ´ ); uexit (1); end

This code is used in sections 190*, 190*, and 194*.

140  INDEX  TANGLE changes C §196

196* . Index. Here is a cross-reference table for the processor. 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 and a few other things like “ASCII code” are indexed here too.

The following sections were changed by the change file: 1, 2, 4, 8, 12, 17, 20, 21, 22, 24, 26, 28, 34, 38, 63, 64, 105, 110, 114, 116, 157, 179, 180, 182, 188, 189, 190, 191, 192, 193, 194, 195, 196.

: 167. : 167. : 167. a: \underline{74}, \underline{87}, \underline{165}. abs : 103, 157* . accumulator : \underline{157*} , 158, 159. add in: \underline{157*} , 158. : 69. and sign: \underline{15}, 114* . app: \underline{99}, 101, 102, 103, 111. app repl : \underline{93}, 165, 166, 167, 168, 169. app val : \underline{99}, 103, 111. argc: 190* . argv : 190* , 191* . ASCII code: 11, 72. ASCII code: \underline{11}, 12* , 13, 27, 28* , 38* , 50, 65, 94,

95, 100, 126, 139, 141, 165. b: \underline{87}, \underline{97}, \underline{165}. bad case: \underline{107}, 109, 110* . bal : \underline{87}, 93, \underline{141}, 142, \underline{165}, 166. banner : \underline{1*} , 182* . begin: 3. begin comment : \underline{72}, 76, 121, 139, 147. begin Pascal : \underline{139}, 156, 158, 167, 175. boolean: 28* , 29, 124, 127, 143, 179* , 190* . brace level : \underline{82}, 83, 98, 121. break ptr : \underline{94}, 95, 96, 97, 98, 101, 102, 106, 107,

109, 110* , 111, 122. breakpoint : 179* , \underline{181}. buf size: \underline{8*} , 27, 28* , 31, 50, 53, 124, 126, 127,

128, 132. buffer : \underline{27}, 28* , 31, 32, 50, 53, 54, 56, 57, 58, 61,

64* , 127, 129, 131, 132, 133, 134, 135, 136, 137, 138, 140, 141, 142, 145, 147, 148, 149, 150, 153, 154, 167, 168, 169, 181.

byte field : \underline{78}, 79. byte mem: 37, \underline{38*} , 39, 40, 41, 48, 49, 53, 56, 61,

63* , 66, 67, 68, 69, 75, 87, 90, 113, 116* . byte ptr : 39, \underline{40}, 42, 61, 67, 90, 91, 186. byte start : 37, \underline{38*} , 39, 40, 42, 49, 50, 56, 61, 63* ,

67, 68, 75, 78, 81, 90, 116* , 143. c: \underline{53}, \underline{66}, \underline{69}, \underline{139}, \underline{140}, \underline{141}, \underline{145}. : 113. carriage return: \underline{15}, 17* , 28* . : 130, 132, 137.

: 138. change buffer : \underline{126}, 127, 128, 131, 132, 136, 138. change changing : \underline{125}, 132, 134, 137. change file: 2* , \underline{23}, 24* , 32, 124, 126, 129, 130,

132, 137. change file name: 24* , \underline{189*} , 192* , 193* . change limit : \underline{126}, 127, 128, 131, 132, 136, 138. changing : 32, \underline{124}, 125, 126, 128, 132, 134,

135, 138. char : 12* , 14, 189* , 190* . check break : \underline{97}, 101, 102, 103, 111. check change: \underline{132}, 136. check sum: \underline{72}, 76, 119, 139. check sum prime: \underline{64*} . chop hash: \underline{50}, 52, 60, 62. chopped id : \underline{50}, 53, 58, 63* . chr : 12* , 13, 17* , 18. compress : \underline{147}. confusion: \underline{35}, 89. : 119. continue: \underline{5}, 113, 128, 129, 165, 167, 172, 173, 174. control code: \underline{139}, 140, 143, 150. control text : \underline{139}, 150. count : \underline{69}. cur byte: 78, \underline{79}, 83, 84, 85, 87, 90, 93. cur char : \underline{113}, 116* , 117, 119, 120. cur end : 78, \underline{79}, 83, 84, 85, 87, 90. cur mod : 78, \underline{79}, 83, 84, 87. cur module: \underline{143}, 151, 167, 175. cur name: 78, \underline{79}, 83, 84, 85. cur repl : 78, \underline{79}, 80, 83, 84, 85. cur repl text : \underline{164}, 165, 170, 175, 178. cur state: \underline{79}, 84, 85. cur val : \underline{86}, 87, 89, 116* , 119, 121. d: \underline{145}. dd : \underline{179*} , 181. ddt : \underline{179*} , 181. debug: \underline{3}, \underline{4*} , \underline{30}, \underline{31}, \underline{74}, \underline{87}, \underline{90}, \underline{91}, \underline{145}, \underline{179*} ,

\underline{180*} , \underline{181}. debug cycle: \underline{179*} , 180* , 181. debug help: \underline{30}, 31, 87, 145, 179* , \underline{181}. debug skipped : \underline{179*} , 180* , 181. decr : \underline{6}, 28* , 85, 91, 93, 99, 116* , 121, 142, 148,

§196  TANGLE changes C  INDEX 141

153, 165, 166. define macro: \underline{170}, 173, 174. definition: \underline{139}, 156, 158, 167, 173. : 173. digits : \underline{119}, 158. do nothing : \underline{6}, 93, 102, 113, 145, 158, 165. done: \underline{5}, 87, 93, 128, 129, 140, 145, 153, 154, 157* ,

158, 159, 165, 167, 172, 173. dot pos : \underline{190*} , 191* , 192* . : 149. double chars : \underline{50}, 64* , 143, 149. double dot : \underline{72}, 114* , 147. EBCDIC: 115. eight bits : \underline{37}, 38* , 53, 82, 87, 95, 101, 113, 139,

140, 141, 145, 156, 165, 170. else: 7. end: 3, 7. end comment : \underline{72}, 76, 121, 139, 147. end field : \underline{78}, 79. end of definition: \underline{156}, 159. end of TANGLE : \underline{2*} , 34* , 182* . endcases: \underline{7}. eof : 28* . eoln: 28* . equal : \underline{66}, 67, 68. equiv : 37, \underline{38*} , 47, 48, 50, 60, 62, 63* , 64* , 67, 84,

88, 89, 90, 157* , 158, 170, 178. equivalence sign: \underline{15}, 114* , 147, 173, 174, 176. err print : \underline{31}, 59, 64* , 66, 69, 97, 98, 108, 113, 117,

118, 119, 120, 121, 125, 129, 130, 132, 133, 137, 138, 141, 142, 149, 150, 153, 154, 157* , 158, 159, 165, 166, 167, 168, 169, 173, 174, 176.

error : 28* , \underline{31}, 34* , 63* , 88, 90. error message: \underline{9}, 187. exit : \underline{5}, 6, 85, 107, 127, 128, 132, 141, 172, 181. extension: \underline{66}, 68, 69. : 165. : 121. f: \underline{28*} . false: 28* , 29, 125, 126, 127, 132, 134, 144, 146,

180* , 183, 190* . fatal error : \underline{34*} , 35, 36. fatal message: \underline{9}, 187. file name: 189* , 190* , 191* . FILENAMESIZE : 189* . final limit : \underline{28*} . first text char : \underline{12*} , 18. flush: 22* . flush buffer : \underline{97}, 98, 122. fname: \underline{190*} , 191* , 192* . force line: \underline{72}, 76, 113, 139. form feed : \underline{15}, 28* . format : \underline{139}, 156, 158, 167, 173. forward : 30. found : \underline{5}, 53, 55, 56, 66, 87, 89, 145, 146, 165, 168. found change: \underline{190*} , 192* . found web: \underline{190*} , 191* . frac: \underline{100}, 101, 102, 104, 113, 120. : 120. get fraction: \underline{113}, 119, 120. get line: 124, \underline{135}, 140, 141, 145, 153. get next : 143, \underline{145}, 156, 158, 159, 160, 161, 162,

165, 173, 174, 176. get output : 86, \underline{87}, 94, 112, 113, 117, 118, 119, 120. getc: 28* . greater : \underline{66}, 68, 69. greater or equal : \underline{15}, 114* , 147. gubed: \underline{3}. h: \underline{51}, \underline{53}. harmless message: \underline{9}, 182* , 187. hash: 39, \underline{50}, 52, 55. hash size: \underline{8*} , 50, 51, 52, 53, 54, 58. hex : \underline{72}, 76, 119, 139, 150, 158. history : \underline{9}, 10, 182* , 187. : 133. i: \underline{16}, \underline{53}. id first : \underline{50}, 53, 54, 56, 57, 58, 61, 64* , 143, 148, 149. id loc: \underline{50}, 53, 54, 56, 58, 61, 64* , 143, 148, 149. id lookup: 50, \underline{53}, 143, 158, 167, 170, 173. ident : \underline{100}, 101, 102, 105* , 114* , 116* . identifier : \underline{86}, 89, 116* , 143, 148, 149, 158, 167, 173. : 63* . ignore: \underline{139}, 140, 150. ii : \underline{124}, 138, 182* , 184, 186. ilk : 37, \underline{38*} , 47, 48, 50, 57, 59, 60, 61, 64* , 85,

89, 90, 158. : 150. : 159. : 66. incr : \underline{6}, 28* , 54, 56, 58, 61, 63* , 64* , 67, 68, 69,

74, 75, 84, 87, 90, 93, 97, 99, 116* , 117, 118, 120, 121, 129, 130, 132, 136, 137, 140, 141, 142, 145, 147, 148, 149, 150, 153, 154, 165, 168, 169, 172, 181, 191* , 192* .

initialize: \underline{2*} , 24* , 182* .

: 141. : 153. : 28* . input has ended : \underline{124}, 132, 134, 136, 140, 141,

145, 153, 183. input ln: \underline{28*} , 129, 130, 132, 136, 137. integer : 14, 40, 86, 95, 99, 106, 107, 113, 124,

132, 157* , 179* , 181, 190* . j: \underline{31}, \underline{66}, \underline{69}, \underline{113}, \underline{145}.

join: \underline{72}, 101, 113, 139.
jump out : 2* , 31, \underline{34*} .

k: \underline{31}, \underline{49}, \underline{53}, \underline{66}, \underline{69}, \underline{74}, \underline{87}, \underline{97}, \underline{99}, \underline{101}, \underline{113},

\underline{127}, \underline{128}, \underline{132}, \underline{145}, \underline{181}. l: \underline{31}, \underline{53}, \underline{66}, \underline{69}. last sign: \underline{95}, 103, 106, 107. last text char : \underline{12*} , 18. last unnamed : \underline{70}, 71, 178. left arrow : \underline{15}, 114* , 147. length: \underline{39}, 55. less : \underline{66}, 67, 68, 69. less or equal : \underline{15}, 114* , 147. limit : 28* , 32, \underline{124}, 127, 129, 130, 131, 133, 134,

135, 136, 137, 138, 140, 141, 145, 147, 149, 153, 168, 169.

line: 32, 33, 96, 97, \underline{124}, 125, 129, 130, 132,

134, 136, 137, 138. line feed : \underline{15}, 28* . line length: \underline{8*} , 94, 97, 100, 101, 113, 117, 118,

120, 122. lines dont match: \underline{127}, 132. link : 37, \underline{38*} , 39, 48, 50, 55. llink : \underline{48}, 66, 67, 69. loc: 28* , 32, \underline{124}, 129, 133, 134, 135, 137, 138,

140, 141, 142, 145, 147, 148, 149, 150, 153, 154, 159, 167, 168, 169, 173.

: 97. longest name: \underline{8*} , 65, 66, 69, 145, 153, 155. loop: \underline{6}. mark error : \underline{9}, 31. mark fatal : \underline{9}, 34* . mark harmless : \underline{9}, 112, 155. max bytes : \underline{8*} , 38* , 40, 49, 53, 61, 66, 67, 69,

87, 90, 113. max file name length: \underline{189*} , 190* , 191* , 192* . max id length: \underline{8*} , 116* . max names : \underline{8*} , 38* , 39, 61, 67, 69, 90. max texts : \underline{8*} , 38* , 43, 70, 90, 165. max tok ptr : \underline{44}, 91, 182* , 186. max toks : \underline{8*} , 38* , 44, 73, 74, 93. misc: \underline{95}, 96, 100, 101, 102, 105* , 107, 111, 113,

119, 121, 122. : 166. mod: 94. mod field : \underline{78}, 79. mod lookup: 65, \underline{66}, 151, 152. mod text : \underline{65}, 66, 67, 68, 69, 145, 151, 152, 153,

154, 155, 181. module count : 139, \underline{171}, 172, 177, 183. module flag : \underline{70}, 85, 178. module name: \underline{139}, 143, 150, 156, 158, 159, 164,

167, 173, 175. module number : \underline{86}, 87, 121. n: \underline{113}, \underline{132}.

: 69. name field : \underline{78}, 79. name pointer : \underline{39}, 40, 49, 53, 66, 69, 78, 84,

143, 157* , 170, 172. name ptr : 39, \underline{40}, 42, 49, 53, 55, 57, 59, 61, 67,

90, 91, 92, 93, 186. new line: \underline{20*} , 31, 32, 34* , 182* . new module: \underline{139}, 140, 145, 156, 158, 167, 176, 183. next control : \underline{156}, 158, 159, 160, 161, 162, 164,

165, 173, 174, 175, 176, 183. next sign: \underline{157*} , 158. nil: 6. : 112. : 90. normal : \underline{47}, 50, 53, 57, 59, 60, 61, 89, 158, 167. : 88. not equal : \underline{15}, 114* , 147. not found : \underline{5}, 53, 63* . not sign: \underline{15}, 114* . num or id : \underline{95}, 101, 102, 107, 111. number : \underline{86}, 89, 119. numeric: \underline{47}, 53, 59, 64* , 89, 158, 173. octal : \underline{72}, 76, 119, 139, 158. : 158. open input : \underline{24*} , 134. or sign: \underline{15}, 114* . ord : 13. other line: \underline{124}, 125, 134, 138. othercases: \underline{7}. others : 7. out app: \underline{95}, 102, 104, 106, 108. out buf : 31, 33, \underline{94}, 95, 96, 97, 99, 100, 109,

110* , 181, 184. out buf size: \underline{8*} , 31, 94, 97, 99. out contrib: \underline{100}, 101, 105* , 113, 114* , 116* , 117,

118, 119, 120, 121, 181. out ptr : 33, \underline{94}, 95, 96, 97, 98, 99, 101, 102, 106,

107, 109, 110* , 111, 122, 181. out sign: \underline{95}, 103, 104, 107, 108. out state: \underline{95}, 96, 101, 102, 104, 106, 107, 108,

111, 113, 117, 122. out val : \underline{95}, 103, 104, 106, 107, 108. output state: \underline{78}, 79. overflow : \underline{36}, 61, 67, 73, 84, 90, 93, 165. p: \underline{49}, \underline{53}, \underline{66}, \underline{69}, \underline{74}, \underline{84}, \underline{157*} , \underline{170}, \underline{172}. pack : 61. param: \underline{72}, 76, 87, 93, 165. parametric: \underline{47}, 53, 85, 89, 164, 165, 174. : 176. Pascal file: 2* , \underline{25}, 26* , 97. pascal file name: 26* , \underline{189*} , 191* . phase one: \underline{29}, 31, 183. pool : 2* , \underline{25}, 26* , 64* , 184. pool check sum: \underline{40}, 42, 64* , 119, 184. pool file name: 64* , \underline{189*} , 191* . pop level : \underline{85}, 87, 90, 91. prefix : \underline{66}, 68. prefix lookup: \underline{69}, 151. : 64* . preprocessed strings: 64* , 149. prime the change buffer : \underline{128}, 134, 137. print : \underline{20*} , 31, 32, 33, 34* , 49, 63* , 74, 75, 76, 88,

93, 97, 139, 155, 181, 186. print id : \underline{49}, 75, 88, 90, 181. print ln: \underline{20*} , 32, 33, 182* , 195* . print nl : \underline{20*} , 28* , 63* , 88, 90, 112, 155, 184, 186, 187. print repl : \underline{74}, 181. : 98. push level : \underline{84}, 88, 89, 92. q: \underline{53}, \underline{66}, \underline{69}, \underline{157*} . r: \underline{69}. read : 181. read ln: 28* . repl field : \underline{78}, 79. reset : 24* , 191* . restart : \underline{5}, 87, 88, 89, 90, 92, 101, 102, 104,

135, 145, 150. reswitch: \underline{5}, 113, 117, 119, 120, 157* , 158. return: 5, \underline{6}. rewrite: 26* , 64* , 191* . rlink : \underline{48}, 66, 67, 69. s: \underline{53}. scan args : 24* , 26* , \underline{190*} . scan module: 171, \underline{172}, 183. scan numeric: 156, \underline{157*} , 173. scan repl : 164, \underline{165}, 170, 175. scanning hex : \underline{143}, 144, 145, 146, 150. : 142. : 154. : 155. semi ptr : \underline{94}, 96, 97, 98, 101. send out : 100, \underline{101}, 112, 113, 114* , 116* , 117, 118,

119, 120, 121, 122. send sign: 100, \underline{106}, 112, 113. send the output : 112, \underline{113}. send val : 100, \underline{107}, 112, 119, 121. set element sign: \underline{15}, 114* . sign: \underline{95}, 102, 106, 108. sign val : \underline{95}, 102, 104, 106, 107, 108. sign val sign: \underline{95}, 102, 106, 108. sign val val : \underline{95}, 102, 106, 108. simple: \underline{47}, 53, 89, 90, 164, 173. sixteen bits : \underline{37}, 38* , 50, 66, 69, 73, 74, 78, 87,

101, 165. skip ahead : \underline{140}, 150, 159, 173, 176, 183. skip comment : \underline{141}, 145. slash pos : 190* , 191* , 192* . : 36. spotless : \underline{9}, 10, 182* , 187. stack : 78, \underline{79}, 84, 85. stack ptr : 78, \underline{79}, 83, 84, 85, 87, 90, 113, 117, 118. stack size: \underline{8*} , 79, 84. stat: \underline{3}. stdin: 179* . stdout : 20* . store two bytes : \underline{73}, 93, 177. str : \underline{100}, 101, 114* , 117, 118, 119, 121, 122. : 149. : 168. : 117. string ptr : 39, \underline{40}, 42, 64* , 182* , 184. system dependencies: \underline{1*} , 2* , 4* , 7, 12* , 17* , 20* , 21* , 22* , 24* , 26* , 28* , 32, 34* , 115, 116* , 121, 180* , 181, 182* , 187, 188* .

t: \underline{53}, \underline{101}, \underline{165}, \underline{170}.

tab mark : \underline{15}, 32, 139, 142, 145, 153, 154.
TANGLE : \underline{2*} .
tats: \underline{3}.
temp line: \underline{124}, 125.
term in: \underline{179*} , 181.
term out : \underline{20*} , 22* , 181.
text char : \underline{12*} , 13, 20* .
text file: \underline{12*} , 23, 25, 28* .

text link : 37, \underline{38*} , 43, 70, 71, 83, 85, 90, 112,

170, 178. text pointer : \underline{43}, 44, 70, 74, 78, 164. text ptr : 43, \underline{44}, 46, 74, 81, 90, 91, 165, 186. : 35. : 59. : 59. toint : 157* . tok mem: 37, \underline{38*} , 43, 44, 45, 70, 73, 74, 75, 78,

79, 80, 81, 87, 90, 93, 165. tok ptr : 43, \underline{44}, 46, 73, 81, 90, 91, 93, 165, 182* . tok start : 37, \underline{38*} , 43, 44, 46, 70, 74, 78, 83, 84,

85, 90, 91, 165. trouble shooting : 87, 145, \underline{179*} , 180* . true: 6, 28* , 29, 124, 125, 127, 132, 134, 136, 138, 143, 150, 179* , 180* , 183, 190* , 191* , 192* .

: 108.

uexit : 34* , 182* , 195* .

unambig length: \underline{8*} , 47, 50, 53, 58, 63* .

unbreakable: \underline{95}, 102, 113, 117.

up to: \underline{116*} , 145.

update terminal : \underline{22*} , 31, 97, 112, 139, 181.

uppercase: 119, 120.

: 174. v: \underline{99}, \underline{101}, \underline{106}, \underline{107}. val : \underline{157*} , 158, 160, 161, 162. : 157* . verbatim: \underline{72}, 76, 113, 118, 139, 167, 169. : 169. : 118. vgetc: 28* . w: \underline{49}, \underline{53}, \underline{66}, \underline{69}, \underline{87}, \underline{113}. : 132. web file: 2* , \underline{23}, 24* , 32, 124, 126, 132, 136, 138. web file name: 24* , \underline{189*} , 191* . : 129, 133, 137. wi : \underline{41}, 42. wo: \underline{185}, 186. write: 20* , 64* , 97, 181, 184. write ln: 20* , 64* , 97, 184. ww : 8* , \underline{38*} , 39, 40, 41, 42, 49, 53, 56, 61, 63* , 66,

67, 68, 69, 75, 87, 90, 91, 113, 116* , 185, 186. x: \underline{73}. xchr : \underline{13}, 14, 16, 17* , 18, 32, 33, 49, 63* , 64* , 75,

76, 97, 155, 167, 181, 184. xclause: 6. xord : \underline{13}, 16, 18, 28* . : 168, 169. z: \underline{44}. zi : \underline{45}, 46. zo: \underline{80}, 83, 84, 85, 87, 90, 93. zp: \underline{74}, 75. zz : 8* , \underline{38*} , 43, 44, 45, 46, 74, 80, 83, 84, 85, 90,

91, 165, 182* , 186.

§196  TANGLE changes C  NAMES OF THE SECTIONS 145

⟨ Append out val to buffer 103 ⟩ Used in sections 102 and 104.

⟨ Append the decimal value of v, with parentheses if negative 111 ⟩ Used in section 107.

⟨ Cases involving and 121 ⟩ Used in section 113. ⟨ Cases like and 114* ⟩ Used in section 113.

⟨ Cases related to constants, possibly leading to get fraction or reswitch 119 ⟩ Used in section 113. ⟨ Cases related to identifiers 116* ⟩ Used in section 113. ⟨ Check for ambiguity and update secondary hash 62 ⟩ Used in section 61. ⟨ Check for overlong name 155 ⟩ Used in section 153. ⟨ Check if q conflicts with p 63* ⟩ Used in section 62. ⟨ Check that all changes have been read 138 ⟩ Used in section 183. ⟨ Check that = or ≡ follows this module name, otherwise return 176 ⟩ Used in section 175. ⟨ Compare name p with current identifier, goto found if equal 56 ⟩ Used in section 55. ⟨ Compiler directives 4* ⟩ ⟨ Compress two-symbol combinations like ‘ ’ 147 ⟩ Used in section 145. ⟨ Compute the hash code h 54 ⟩ Used in section 53. ⟨ Compute the name location p 55 ⟩ Used in section 53. ⟨ Compute the secondary hash code h and put the first characters into the auxiliary array chopped id 58 ⟩

Used in section 57.

⟨ Constants in the outer block 8* ⟩ Used in section 2*. ⟨ Contribution is or or or 105* ⟩ Used in section 104. ⟨ Copy a string from the buffer to tok mem 168 ⟩ Used in section 165. ⟨ Copy the parameter into tok mem 93 ⟩ Used in section 90. ⟨ Copy verbatim string from the buffer to tok mem 169 ⟩ Used in section 167.

⟨ Declaration of scan args 190* ⟩ Used in section 2*.

⟨ Define and output a new string of the pool 64* ⟩ Used in section 61. ⟨ Display one-byte token a 76 ⟩ Used in section 74. ⟨ Display two-byte token starting with a 75 ⟩ Used in section 74. ⟨ Do special things when c = , , , ; return at end 142 ⟩ Used in section 141. ⟨ Empty the last line from the buffer 98 ⟩ Used in section 112. ⟨ Enter a new identifier into the table at position p 61 ⟩ Used in section 57. ⟨ Enter a new module name into the tree 67 ⟩ Used in section 66. ⟨ Error handling procedures 30, 31 ⟩ Used in section 2*. ⟨ Expand macro a and goto found , or goto restart if no output found 89 ⟩ Used in section 87.

⟨ Expand module a − ´ 24000 , goto restart 88 ⟩ Used in section 87.

⟨ Finish off the string pool file 184 ⟩ Used in section 182*.

⟨ Force a line break 122 ⟩ Used in section 113.

⟨ Get a preprocessed string 149 ⟩ Used in section 145.

⟨ Get an identifier 148 ⟩ Used in section 145.

⟨ Get control code and possible module name 150 ⟩ Used in section 145. ⟨ Get the buffer ready for appending the new information 102 ⟩ Used in section 101.

⟨ Get change file name from fname 192* ⟩ Used in section 190*.

⟨ Get web file name, pascal file name, and pool file name variables from fname 191* ⟩ Used in section 190*. ⟨ Give double-definition error, if necessary, and change p to type t 59 ⟩ Used in section 57.

⟨ Globals in the outer block 9, 13, 23, 25, 27, 29, 38*, 40, 44, 50, 65, 70, 79, 80, 82, 86, 94, 95, 100, 124, 126, 143, 156,

164, 171, 179*, 185, 189* ⟩ Used in section 2*.

⟨ Go to found if c is a hexadecimal digit, otherwise set scanning hex ← false 146 ⟩ Used in section 145. ⟨ Handle cases of send val when out state contains a sign 108 ⟩ Used in section 107.

⟨ Handle flag argument in fname 194* ⟩ Used in section 190*. ⟨ If end of name, goto done 154 ⟩ Used in section 153.

⟨ If previous output was or , goto bad case 109 ⟩ Used in section 107. ⟨ If previous output was or , goto bad case 110* ⟩ Used in section 107. ⟨ If the current line starts with , report any discrepancies and return 133 ⟩ Used in section 132.

146  NAMES OF THE SECTIONS  TANGLE changes C §196

⟨ If the next text is ‘(#) ≡’, call define macro and goto continue 174 ⟩ Used in section 173. ⟨ In cases that a is a non-ASCII token (identifier , module name, etc.), either process it and change a to a

byte that should be stored, or goto continue if a should be ignored, or goto done if a signals the end of this replacement text 167 ⟩ Used in section 165.

⟨ Initialize the input system 134 ⟩ Used in section 182*. ⟨ Initialize the output buffer 96 ⟩ Used in section 112. ⟨ Initialize the output stacks 83 ⟩ Used in section 112. ⟨ Insert the module number into tok mem 177 ⟩ Used in section 175. ⟨ Local variables for initialization 16, 41, 45, 51 ⟩ Used in section 2*. ⟨ Make sure the parentheses balance 166 ⟩ Used in section 165.

⟨ Move buffer and limit to change buffer and change limit 131 ⟩ Used in sections 128 and 132.

⟨ Other printable characters 115 ⟩ Used in section 113. ⟨ Phase I: Read all the user’s text and compress it into tok mem 183 ⟩ Used in section 182*. ⟨ Phase II: Output the contents of the compressed tables 112 ⟩ Used in section 182*. ⟨ Print error location based on input buffer 32 ⟩ Used in section 31. ⟨ Print error location based on output buffer 33 ⟩ Used in section 31. ⟨ Print statistics about memory usage 186 ⟩ Used in section 182*.

⟨ Print the job history 187 ⟩ Used in section 182*. ⟨ Print usage error message and quit 195* ⟩ Used in sections 190*, 190*, and 194*.

⟨ Put a parameter on the parameter stack, or goto restart if error occurs 90 ⟩ Used in section 89. ⟨ Put module name into mod text [1 . . k] 153 ⟩ Used in section 151. ⟨ Read from change file and maybe turn off changing 137 ⟩ Used in section 135. ⟨ Read from web file and maybe turn on changing 136 ⟩ Used in section 135.

⟨ Reduce sign val val to sign val and goto restart 104 ⟩ Used in section 102.

⟨ Remove a parameter from the parameter stack 91 ⟩ Used in section 85. ⟨ Remove p from secondary hash table 60 ⟩ Used in section 59. ⟨ Scan the definition part of the current module 173 ⟩ Used in section 172. ⟨ Scan the module name and make cur module point to it 151 ⟩ Used in section 150. ⟨ Scan the Pascal part of the current module 175 ⟩ Used in section 172.

⟨ Send a string, goto reswitch 117 ⟩ Used in section 113.

⟨ Send verbatim string 118 ⟩ Used in section 113. ⟨ Set accumulator to the value of the right-hand side 158 ⟩ Used in section 157*. ⟨ Set c to the result of comparing the given name to name p 68 ⟩ Used in sections 66 and 69.

⟨ Set initial values 10, 14, 17*, 18, 21*, 26*, 42, 46, 48, 52, 71, 144, 152, 180* ⟩ Used in section 2*. ⟨ Set up null change file 193* ⟩ Used in section 190*.

⟨ Set val to value of decimal constant, and set next control to the following token 160 ⟩ Used in section 158. ⟨ Set val to value of hexadecimal constant, and set next control to the following token 162 ⟩

Used in section 158.

⟨ Set val to value of octal constant, and set next control to the following token 161 ⟩ Used in section 158. ⟨ Signal error, flush rest of the definition 159 ⟩ Used in section 158. ⟨ Skip over comment lines in the change file; return if end of file 129 ⟩ Used in section 128. ⟨ Skip to the next nonblank line; return if end of file 130 ⟩ Used in section 128. ⟨ Special code to finish real constants 120 ⟩ Used in section 113. ⟨ Start scanning current macro parameter, goto restart 92 ⟩ Used in section 87.

⟨ Types in the outer block 11, 12*, 37, 39, 43, 78 ⟩ Used in section 2*.

⟨ Update the data structure so that the replacement text is accessible 178 ⟩ Used in section 175. ⟨ Update the tables and check for possible errors 57 ⟩ Used in section 53.

The TANGLE processor

(Version 4.1)

Section Page

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 124 The character set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 126 Input and output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 127 Reporting errors to the user . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 129 Data structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 130 Searching for identifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 131 Searching for module names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 132 Tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 132 Stacks for output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 132 Producing the output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 132 The big output switch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 133 Introduction to the input phase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 134 Inputting the next token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 134 Scanning a numeric definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 134 Scanning a macro definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 135 Scanning a module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 135 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 135 The main program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 136 System-dependent changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 137 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 140