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; }; }.