10.5. The Symbol Table

There's one problem with the compiler as it stands so far: it doesn't do anything to record a variable when we declare it. So the compiler is perfectly content to allocate storage for several variables with the same name. You can easily verify this with an input like

     pvavavabe.

Here we've declared the variable A three times. As you can see, the compiler will cheerfully accept that, and generate three identical labels. Not good.

Later on, when we start referencing variables, the compiler will also let us reference variables that don't exist. The assembler will catch both of these error conditions, but it doesn't seem friendly at all to pass such errors along to the assembler. The compiler should catch such things at the source language level.

So even though we don't need a symbol table to record data types, we ought to install one just to check for these two conditions. Since at this point we are still restricted to single-character variable names, the symbol table can be trivial. To provide for it, first add the following declaration at the beginning of your program:

     var ST: array['A'..'Z'] of char;

and insert the following function:

{ Look for Symbol in Table }
function InTable(n: char): Boolean;
begin
   InTable := ST[n] <> ' ';
end;

We also need to initialize the table to all blanks. The following lines in Init will do the job:

var i: char;
begin
   for i := 'A' to 'Z' do
      ST[i] := ' ';
   …

Finally, insert the following two lines at the beginning of Alloc:

   if InTable(N) then Abort('Duplicate Variable Name ' + N);
   ST[N] := 'v';

That should do it. The compiler will now catch duplicate declarations. Later, we can also use InTable when generating references to the variables.