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