§1 TABLE TEST PROGRAM 1

1. Table Test program. This is a sample client module for the Table Handler symbol table library module. It performs no useful function, except to exercise the procedures of the table module. module table test ; ⟨ Import List 2 ⟩

const ⟨ Constants in the outer block 23 ⟩ var ⟨ Declare some variables 4 ⟩

2. In order to keep this module reasonably free of notations that are uniquely PASCALesque, a few macro definitions for low-level output instructions are introduced here. All of the output-oriented commands in the remainder of the module will be stated in terms of simple primitives.

define pr char ≡ \underline{\overline{␣ ␣}} (∗ put a given character into the output file ∗) define pr string ≡ \underline{\overline{␣ ␣}} (∗ put a given string into the output file ∗) define rd string ≡ \underline{\overline{␣ ␣}} (∗ library procedure to input a string ∗) define pr card ≡ \underline{\overline{␣ ␣}} (∗ put a given cardinal into the output file, in decimal notation, using

only as many digit positions as necessary ∗)

define new ln ≡ \underline{\overline{␣ ␣}} (∗ advance to a new line in the output file ∗) define print string (#) ≡ pr string (#) (∗ put a given string into the output file ∗) define print cardinal (#) ≡ pr card (#, 1) (∗ put a given cardinal into the output file, in decimal notation,

using only as many digit positions as necessary ∗)

define read string (#) ≡ rd string (#) (∗ read a given string from the terminal ∗) define new line ≡ new ln (∗ advance to a new line in the output file ∗) define print ln(#) ≡ pr string (#); new line;

(∗ put a given string to the terminal, followed by a new line ∗)

⟨ Import List 2 ⟩ ≡

from \underline{\overline{␣ ␣}} import pr string , rd string , pr char , pr card , new ln;

See also sections 3 and 18. This code is used in section 1.

3. We need to import some things from table handler , since that is the whole purpose of this program. ⟨ Import List 2 ⟩ +≡

from table handler import get value of symbol , set value of symbol , search symbol table, table proc, undefined symbols in table, create symbol table, set error handler , error proc, symbol table error code, symbol is defined , symbol table, delete symbol table, symbol string ptr ;

4. We define more than one table since we want to demonstrate handling of multiple tables simultaneously. ⟨ Declare some variables 4 ⟩ ≡ the table: symbol table; second table: symbol table;

See also sections 12, 24, and 29. This code is used in section 1.

2  STATIC TEST  §5

5. Static test. Here we perform a test of the symbol table module using static values. ⟨ Do static test 5 ⟩ ≡

⟨ Create the tables 6 ⟩; ⟨ Store some stuff into the tables 7 ⟩; ⟨ Display the contents of the tables 8 ⟩; ⟨ Change the value of one of the entries and redisplay 9 ⟩; ⟨ Check for undefined symbols 10 ⟩; ⟨ Delete the tables 11 ⟩;

This code is used in section 28.

6. Here we create the static symbol tables. We make the first one case-sensitive and the second one not. define case sens ≡ true define not case sens ≡ false

⟨ Create the tables 6 ⟩ ≡ create symbol table(the table, case sens , my error proc); create symbol table(second table, not case sens , my error proc);

This code is used in section 5.

7. Here we store a bunch of canned symbols into the tables. Since the first table is case-sensitive, we test that by inserting the same symbol in upper and lower case. We do the same for the second table, which should cause a duplicate symbol error. get value of symbol is a function procedure which returns the cardinal value store in the table entry, but we ignore the value since we only want to create the entry. We indicate symbol definition on all of the entries except one in each table, so that ‘undefined symbol’ errors will occur.

define this is def ≡ true define not def ≡ false

⟨ Store some stuff into the tables 7 ⟩ ≡ n ← get value of symbol (the table, ´ ´ , this is def , strad ); n ← get value of symbol (the table, ´ ´ , this is def , strad ); n ← get value of symbol (the table, ´ ´ , this is def , strad ); n ← get value of symbol (the table, ´ ´ , this is def , strad ); n ← get value of symbol (the table, ´ ´ , this is def , strad ); n ← get value of symbol (the table, ´ ´ , this is def , strad ); n ← get value of symbol (the table, ´ ´ , this is def , strad ); n ← get value of symbol (the table, ´ ´ , not def , strad ); n ← get value of symbol (second table, ´ ´ , not def , strad ); n ← get value of symbol (second table, ´ ´ , this is def , strad ); n ← get value of symbol (second table, ´ ´ , this is def , strad ); n ← get value of symbol (second table, ´ ´ , this is def , strad ); n ← get value of symbol (second table, ´ ´ , this is def , strad ); n ← get value of symbol (second table, ´ ´ , this is def , strad ); n ← get value of symbol (second table, ´ ´ , this is def , strad ); n ← get value of symbol (second table, ´ ´ , this is def , strad ); n ← get value of symbol (second table, ´ ´ , this is def , strad ); set value of symbol (second table, ´ ´ , this is def , strad , 447);

This code is used in section 5.

§8 STATIC TEST 3

8. This code displays the contents of the two symbol tables by calling the procedure search symbol table. As its name implies, this procedure searches the entire table and will called the user-supplied procedure (in this case my proc) for each entry in the table. my proc will simply print the symbol and its value to the terminal. The symbols will be processed alphabetically. ⟨ Display the contents of the tables 8 ⟩ ≡

print string (´ ␣ ␣ ␣ ´ ); new line; search symbol table(the table, my proc); print string (´ ␣ ␣ ␣ ´ ); new line; search symbol table(second table, my proc);

This code is used in section 5.

9. ⟨ Change the value of one of the entries and redisplay 9 ⟩ ≡

set value of symbol (second table, ´ ´ , not def , strad , 222);

print string (´ ␣ ␣ ␣ ␣ ␣ ´ ); new line;

search symbol table(second table, my proc);

This code is used in section 5.

10. Here we will call a library routine to check the integrity of the table. If a symbol has been referenced but never defined, the undef proc procedure is called for that symbol. undefined symbols in table, which is a function procedure which returns a boolean value, will be true if any undefined symbols were found. ⟨ Check for undefined symbols 10 ⟩ ≡

if undefined symbols in table(the table, undef proc) then

print string (´ ␣ ␣ ␣ ␣ ´ ); new line; end ; if undefined symbols in table(second table, undef proc) then

print string (´ ␣ ␣ ␣ ␣ ´ ); new line; end ;

This code is used in section 5.

11. Here we call a library procedure to delete the tables and deallocate the memory space they were using. ⟨ Delete the tables 11 ⟩ ≡

delete symbol table(the table); delete symbol table(second table);

This code is used in section 5.

12. We define some procedure variables to be used to store the procedures we are passing to the library module as parameters. ⟨ Declare some variables 4 ⟩ +≡ my proc: table proc; my error proc: error proc; undef proc: error proc;

13. ⟨ Initialize the procedure variables 13 ⟩ ≡

my error proc ← print error ; undef proc ← print undefined symbol entry ;

my proc ← show symbol entry ;

This code is used in section 28.

14. This is the procedure to display a table entry. It has to be defined as a procedure rather than inline like most of the code, since it is passed as a parameter to the search symbol table procedure, which will call it once for each entry in the table. procedure show symbol entry (ent num : cardinal ; str ptr : symbol string ptr ; its defined : boolean);

begin print string (str ptr ↑); print string (´ ␣␣´ ); print cardinal (ent num); print string (´ ␣␣´ );

if its defined then

print string (´ ´ ); else

print string (´ ␣ ´ ); end ; new line;

end show symbol entry ;

15. This error handler is called for each undefined symbol found by the undefined symbols in table function procedure. procedure print undefined symbol entry (code : symbol table error code; str : array of char );

begin

print string (str ); print string (´ ␣ ␣ ´ ); new line; end print undefined symbol entry ;

16. This is the general error handler. It is passed to the table module when a table is created, and is called if errors occur anytime while the table is in use. procedure print error (code : symbol table error code; str : array of char );

begin

case code of

undefined symbol : print string (´ ␣ ␣ ␣´ ); print string (str ); print string (´ ␣ ␣´ ) |

duplicate symbol : print string (´ ␣ ␣ ␣´ ); print string (str ); print string (´ ␣ ␣´ ) |

memory exhausted : print string (´ ␣ ␣´ ) end ;

§17 FILE TEST 5

new line; end print error ; 17. File Test. We decide to run another test of the symbol table module. This time we will read the symbols from a text file rather than assigning them statically. ⟨ Do file test 17 ⟩ ≡

⟨ Open the input file 26 ⟩; create symbol table(file symbol table, case sens , my error proc); ⟨ Read the input 19 ⟩; ⟨ Close the file, print the table and delete it 27 ⟩;

This code is used in section 28.

18. Here we define the symbols for use with file handling.

define lookup ≡ \underline{\overline{␣ ␣}} (∗ library procedure to open a file ∗) define close ≡ \underline{\overline{␣ ␣}} (∗ library procedure to close a file ∗) define failure(#) ≡ (#. \underline{\overline{}}≠ \underline{\overline{}}) (∗ last file operation sucessful ? ∗) define abort if open error (#) ≡

if failure(#) then

print string (´ ␣ ␣ ␣´ ); print string (file name); end ;

define open input file(#) ≡ lookup(#, file name, false); abort if open error (#) define close file(#) ≡ close(#); define end file ≡ \underline{\overline{}} define null char ≡ \underline{\overline{␣ ␣}} define end line(#) ≡ (ch = eol ) define end of file(#) ≡ (#.end file) define read char ≡ \underline{\overline{␣ ␣}} define input char (#) ≡ read char (#, ch); define read ln(#) ≡

while ¬end line(#) do input char (#);

end ;

define text file ≡ \underline{\overline{␣ ␣}} ⟨ Import List 2 ⟩ +≡

from \underline{\overline{␣ ␣}} import lookup, \underline{\overline{}}, read char , text file, close; from ascii import eol , null char ;

19. We simply read lines until end of file. ⟨ Read the input 19 ⟩ ≡

line number ← 0; while input ln(input file) do

inc(line number ); ⟨ Extract the symbols from the line and store them 20 ⟩; end ;

This code is used in section 17.

6  FILE TEST  §20

20. We start scanning the current line for symbols. As each is found, we store it into the table. define end of line ≡ (curr pos = line len)

⟨ Extract the symbols from the line and store them 20 ⟩ ≡ curr pos ← 0; while ¬end of line do

⟨ Move to next alpha or end of line 21 ⟩;

if ¬end of line then index ← 0; ⟨ Copy until next non-alpha or until end of line 22 ⟩; work string [index ] ← null char ; if ¬symbol is defined (file symbol table, work string ) then

set value of symbol (file symbol table, work string , this is def , strad , line number ) end ; end ;

end ;

This code is used in section 19.

21. Here we search for the start of a symbol. We continue until an alphabetic character or the end of the line is found.

define alpha ≡ ((cap(buffer [curr pos ]) ≥ ´ ´ ) ∧ (cap(buffer [curr pos ]) ≤ ´ ´ )) ⟨ Move to next alpha or end of line 21 ⟩ ≡

while (¬end of line) ∧ (¬alpha) do

inc(curr pos ); end ;

This code is used in section 20.

22. Here we copy characaters from buffer to work string until either a non-alphabetic character is found or the end of the line is reached. Both pointers are advanced as each character is copied. ⟨ Copy until next non-alpha or until end of line 22 ⟩ ≡

repeat

work string [index ] ← buffer [curr pos ]; inc(index ); inc(curr pos ); until end of line ∨ (¬alpha);

This code is used in section 20.

23. Let’s define a few constants. ⟨ Constants in the outer block 23 ⟩ ≡

buf size = 1000; (∗ maximum length of input line ∗)

file name len = 200; (∗ length of a file name ∗)

This code is used in section 1.

24. Input goes into an array called buffer . ⟨ Declare some variables 4 ⟩ +≡ buffer : array [0 . . buf size] of char ; work string : array [0 . . buf size] of char ; input file: text file; line number : cardinal ; index : cardinal ; curr pos : cardinal ; line len: cardinal ; file symbol table: symbol table; file name: array [0 . . file name len] of char ; 25. 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. Trailing blanks are ignored and the global variable line len is set to the length of the line. The value of line len must be strictly less than buf size. procedure input ln(var f : text file): boolean; (∗ inputs a line or returns false ∗)

var final line len: [0 . . buf size]; (∗ line len without trailing blanks ∗)

ch: char ; (∗ current input character ∗)

line pres : boolean; (∗ temporary result of procedure ∗) begin

line len ← 0; final line len ← 0;

if end of file(f) then line pres ← false

else input char (f); while ¬end line(f) do if ch = null char then

return false

end ;

buffer [line len] ← ch; inc(line len); if buffer [line len − 1] ≠ ´ ␣´ then

final line len ← line len end ; if line len = buf size then

read ln(f); dec(line len); return true; end ; input char (f);

end ;

read ln(f); line len ← final line len; line pres ← true; buffer [line len] ← null char ; end ; return line pres ;

end input ln;

26. In this section we open the input file, after getting the file name from the command line or the terminal. ⟨ Open the input file 26 ⟩ ≡

file name[0] ← ´ ␣´ ; print ln(´ ␣ ´ ); read string (file name); new line; print ln(file name); new line; open input file(input file);

This code is used in section 17.

27. At this point the test is complete—we can close the input file, print the table, and delete it. ⟨ Close the file, print the table and delete it 27 ⟩ ≡

close(input file); print string (´ ␣ ␣ ␣ ␣ ␣ ´ ); new line;

search symbol table(file symbol table, my proc); delete symbol table(file symbol table);

This code is used in section 17.

28. Here is the main program. begin

⟨ Initialize the procedure variables 13 ⟩;

⟨ Do static test 5 ⟩

⟨ Do file test 17 ⟩ end table test .

29. We declare a few more odd variables to finish off the program. strad is a pointer to the actual string for a symbol in the table, but we don’t really care about that. ⟨ Declare some variables 4 ⟩ +≡ n: cardinal ; strad : symbol string ptr ;

§30 INDEX 9

30. Index.

abort if open error : \underline{18}. alpha: \underline{21}, 22. ascii : 18. boolean: 14, 25. buf size: \underline{23}, 24, 25. buffer : 21, 22, \underline{24}, 25. cap: 21. cardinal : 14, 24, 29. case sens : \underline{6}, 17. ch: 18, \underline{25}. char : 15, 16, 24, 25. close: \underline{18}, 27. close file: \underline{18}. code: 15, 16. create symbol table: \underline{3}, 6, 17. curr pos : 20, 21, 22, \underline{24}. dec: 25. delete symbol table: \underline{3}, 11, 27. duplicate symbol : 16. end file: \underline{18}. end line: \underline{18}, 25. end of file: \underline{18}, 25. end of line: \underline{20}, 21, 22. ent num: \underline{14}. eol : \underline{18}. error proc: \underline{3}, 12. f: \underline{25}. failure: \underline{18}. false: 6, 7, 18, 25. file name: 18, \underline{24}, 26. file name len: \underline{23}, 24. file symbol table: 17, 20, \underline{24}, 27. : 18. final line len: \underline{25}. get value of symbol : \underline{3}, 7. inc: 19, 21, 22, 25. index : 20, 22, \underline{24}. input char : \underline{18}, 25. input file: 19, \underline{24}, 26, 27. input ln: 19, \underline{25}. its defined : \underline{14}. line len: 20, \underline{24}, 25. line number : 19, 20, \underline{24}. line pres : \underline{25}. lookup: \underline{18}. memory exhausted : 16. my error proc: 6, \underline{12}, 13, 17. my proc: 8, 9, \underline{12}, 13, 27. n: \underline{29}. new line: \underline{2}, 8, 9, 10, 14, 15, 16, 26, 27. new ln: \underline{2}. not case sens : \underline{6}. not def : \underline{7}, 9. null char : \underline{18}, 20, 25. open input file: \underline{18}, 26. output : 2. pr card : \underline{2}. pr char : \underline{2}. pr string : \underline{2}. print cardinal : \underline{2}, 14. print error : 13, \underline{16}. print ln: \underline{2}, 26. print string : \underline{2}, 8, 9, 10, 14, 15, 16, 18, 27. print undefined symbol entry : 13, \underline{15}. rd string : \underline{2}. read char : \underline{18}. read ln: \underline{18}, 25. read string : \underline{2}, 26. search symbol table: \underline{3}, 8, 9, 14, 27. second table: \underline{4}, 6, 7, 8, 9, 10, 11. set error handler : \underline{3}. set value of symbol : \underline{3}, 7, 9, 20. show symbol entry : 13, \underline{14}. str : 15, 16. str ptr : \underline{14}. strad : 7, 9, 20, \underline{29}. symbol is defined : \underline{3}, 20. symbol string ptr : \underline{3}, 14, 29. symbol table: \underline{3}, 4, 24. symbol table error code: \underline{3}, 15, 16. system dependencies: 18, 25. table handler : 3. table proc: \underline{3}, 12. table test : \underline{1}, 28. text file: \underline{18}, 24, 25. the table: \underline{4}, 6, 7, 8, 10, 11. this is def : \underline{7}, 20. true: 6, 7, 10, 25. : 18. undef proc: 10, \underline{12}, 13. undefined symbol : 16. undefined symbols in table: \underline{3}, 10, 15. work string : 20, 22, \underline{24}.

10  NAMES OF THE SECTIONS  §30

⟨ Change the value of one of the entries and redisplay 9 ⟩ Used in section 5. ⟨ Check for undefined symbols 10 ⟩ Used in section 5. ⟨ Close the file, print the table and delete it 27 ⟩ Used in section 17. ⟨ Constants in the outer block 23 ⟩ Used in section 1. ⟨ Copy until next non-alpha or until end of line 22 ⟩ Used in section 20. ⟨ Create the tables 6 ⟩ Used in section 5.

⟨ Declare some variables 4, 12, 24, 29 ⟩ Used in section 1.

⟨ Delete the tables 11 ⟩ Used in section 5. ⟨ Display the contents of the tables 8 ⟩ Used in section 5.

⟨ Do file test 17 ⟩ Used in section 28. ⟨ Do static test 5 ⟩ Used in section 28.

⟨ Extract the symbols from the line and store them 20 ⟩ Used in section 19.

⟨ Import List 2, 3, 18 ⟩ Used in section 1.

⟨ Initialize the procedure variables 13 ⟩ Used in section 28. ⟨ Move to next alpha or end of line 21 ⟩ Used in section 20.

⟨ Open the input file 26 ⟩ Used in section 17. ⟨ Read the input 19 ⟩ Used in section 17.

⟨ Store some stuff into the tables 7 ⟩ Used in section 5.

Section Page

Table Test program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1 Static test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2 File Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 5 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 9