DIRECTORY
PrintingDefs USING [OutCode],
String USING [EqualString],
Storage USING [FreeString, CopyString],
SymbolTableDefs USING [SymbolType, SymbolEntry];
SymbolTableImpl: PROGRAM
IMPORTS PrintingDefs, String, Storage
EXPORTS SymbolTableDefs = {
foundSlot: CARDINAL;
symbolTableSize: CARDINAL = 200;
blockNestingLevel: CARDINAL ← 0;
echoSymbolTables: PUBLIC BOOLEAN; -- echo symbol tables to executive
-- at the end of each block
SymbolTable: ARRAY [0..symbolTableSize) OF SymbolTableDefs.SymbolEntry;
InitializeSymbolTable: PUBLIC PROCEDURE [] = {
blockNestingLevel ← 0;
FOR i: CARDINAL IN [0..symbolTableSize) DO
SymbolTable[i].type ← unused; ENDLOOP;
};
EnterBlock: PUBLIC PROCEDURE [] = {
blockNestingLevel ← blockNestingLevel + 1;
};
ExitBlock: PUBLIC PROCEDURE [] = {
FOR i: CARDINAL IN [0..symbolTableSize) DO
IF SymbolTable[i].type # unused
AND SymbolTable[i].blockLevel = blockNestingLevel THEN {
Storage.FreeString[SymbolTable[i].name];
Storage.FreeString[SymbolTable[i].typeName];
SymbolTable[i].type ← unused; };
ENDLOOP;
blockNestingLevel ← blockNestingLevel - 1;
};
EnterSymbol: PUBLIC PROCEDURE [symName: LONG STRING, symType: SymbolTableDefs.SymbolType,
symBaseType: SymbolTableDefs.SymbolType, symTypeName: LONG STRING,
symPointerCount: CARDINAL, blockHeader: BOOLEAN ← FALSE] = {
FOR i: CARDINAL IN [0..symbolTableSize) DO
IF SymbolTable[i].type = unused THEN GOTO FoundOne;
REPEAT
FoundOne => foundSlot ← i;
FINISHED => ERROR;
ENDLOOP;
SymbolTable[foundSlot].name ← Storage.CopyString[symName];
SymbolTable[foundSlot].type ← symType;
SymbolTable[foundSlot].baseType ← symBaseType;
SymbolTable[foundSlot].typeName ← Storage.CopyString[symTypeName];
SymbolTable[foundSlot].pointerCount ← symPointerCount;
SymbolTable[foundSlot].blockLevel ←
IF NOT blockHeader
THEN blockNestingLevel
ELSE blockNestingLevel + 1;
};
LookUpSymbol: PUBLIC PROCEDURE[symName: LONG STRING]
RETURNS [symType: SymbolTableDefs.SymbolType,
symBaseType: SymbolTableDefs.SymbolType,
symTypeName: LONG STRING, symPointerCount: CARDINAL] = {
FOR blockBeingSearched: CARDINAL DECREASING IN [0..blockNestingLevel] DO
FOR i: CARDINAL IN [0..symbolTableSize) DO
IF SymbolTable[i].type # unused
AND SymbolTable[i].blockLevel = blockBeingSearched
AND String.EqualString[symName, SymbolTable[i].name] THEN {
symType ← SymbolTable[i].type;
symBaseType ← SymbolTable[i].baseType;
symTypeName ← SymbolTable[i].typeName;
symPointerCount ← SymbolTable[i].pointerCount;
RETURN; };
ENDLOOP;
ENDLOOP;
RETURN [none, none, NIL, 0];
};
PrintSymbolTable: PUBLIC PROCEDURE[] = {
oneChar: LONG STRING ← [1];
padChars: CARDINAL;
IF NOT echoSymbolTables THEN RETURN;
PrintingDefs.OutCode["--*** SYMBOL TABLE CONTENTS IN THIS BLOCK ***\n"L, 0];
PrintingDefs.OutCode[
"--name type basetype typeName ↑s blockLevel\n"L, 0];
PrintingDefs.OutCode[
"--==== ==== ======== ======== == ==========\n"L, 0];
oneChar.length ← 1;
FOR i: CARDINAL IN [0..symbolTableSize) DO
IF SymbolTable[i].type # unused THEN {
PrintingDefs.OutCode["--"L, 0];
PrintingDefs.OutCode[SymbolTable[i].name, 0];
THROUGH [SymbolTable[i].name.length..12) DO
-- pad to size 12 field
PrintingDefs.OutCode[" "L, 0]; ENDLOOP;
SELECT SymbolTable[i].type FROM
none => PrintingDefs.OutCode["none "L, 0];
short => PrintingDefs.OutCode["short "L, 0];
long => PrintingDefs.OutCode["long "L, 0];
pointer => PrintingDefs.OutCode["pointer "L, 0];
array => PrintingDefs.OutCode["array "L, 0];
arrayArray => PrintingDefs.OutCode["arrayArray "L, 0];
structure => PrintingDefs.OutCode["structure "L, 0];
union => PrintingDefs.OutCode["union "L, 0];
enumeration => PrintingDefs.OutCode["enumeration"L, 0];
real => PrintingDefs.OutCode["real "L, 0];
double => PrintingDefs.OutCode["double "L, 0];
boolean => PrintingDefs.OutCode["boolean "L, 0];
ENDCASE => PrintingDefs.OutCode["ERROR "L, 0];
SELECT SymbolTable[i].baseType FROM
none => PrintingDefs.OutCode["none "L, 0];
short => PrintingDefs.OutCode["short "L, 0];
long => PrintingDefs.OutCode["long "L, 0];
pointer => PrintingDefs.OutCode["pointer "L, 0];
array => PrintingDefs.OutCode["array "L, 0];
arrayArray => PrintingDefs.OutCode["arrayArray "L, 0];
structure => PrintingDefs.OutCode["structure "L, 0];
union => PrintingDefs.OutCode["union "L, 0];
enumeration => PrintingDefs.OutCode["enumeration"L, 0];
real => PrintingDefs.OutCode["real "L, 0];
double => PrintingDefs.OutCode["double "L, 0];
boolean => PrintingDefs.OutCode["boolean "L, 0];
ENDCASE => PrintingDefs.OutCode["ERROR "L, 0];
PrintingDefs.OutCode[SymbolTable[i].typeName, 0];
padChars ← IF SymbolTable[i].typeName = NIL THEN 0
ELSE SymbolTable[i].typeName.length;
THROUGH [padChars..20) DO -- pad to size 20 field
PrintingDefs.OutCode[" "L, 0]; ENDLOOP;
oneChar.text[0] ← '0 + SymbolTable[i].pointerCount;
PrintingDefs.OutCode[oneChar, 0];
PrintingDefs.OutCode[" "L, 0];
oneChar.text[0] ← '0 + SymbolTable[i].blockLevel;
PrintingDefs.OutCode[oneChar, 0];
PrintingDefs.OutCode["\n"L, 0]; };
ENDLOOP;
};
FinalizeSymbolTable: PUBLIC PROCEDURE[] = {
IF FALSE THEN FOR i: CARDINAL IN [0..symbolTableSize) DO
IF SymbolTable[i].type # unused THEN {
Storage.FreeString[SymbolTable[i].name];
Storage.FreeString[SymbolTable[i].typeName];
SymbolTable[i].type ← unused; };
ENDLOOP;
};
}.