-- File CIFExtDict.mesa -- Written by Dan Fitzpatrick and Martin Newell, June 1980 -- Last updated: December 1, 1980 1:58 PM DIRECTORY CIFExtDictDefs: FROM "CIFExtDictDefs", CIFExtIODefs: FROM "CIFExtIODefs" USING[WriteLong], InlineDefs: FROM "InlineDefs" USING[BITSHIFT, BITOR, BITXOR, LongDivMod], IODefs: FROM "IODefs" USING[GetOutputStream, WriteString, WriteLine], SystemDefs: FROM "SystemDefs" USING[AllocateHeapNode, FreeHeapNode, AllocateHeapString, FreeHeapString], StringDefs: FROM "StringDefs" USING[AppendString, EquivalentString]; CIFExtDict: PROGRAM IMPORTS CIFExtIODefs, InlineDefs, IODefs, SystemDefs, StringDefs EXPORTS CIFExtDictDefs = BEGIN OPEN CIFExtIODefs, InlineDefs, IODefs, SystemDefs, StringDefs; InitDictionary: PUBLIC PROCEDURE = BEGIN i: CARDINAL; ptr: Entry; FOR i _ 0, i+1 WHILE i < TableSize DO FOR ptr _ NumberTable[i], NumberTable[i] UNTIL ptr = NIL DO NumberTable[i] _ ptr.nextNumber; FreeHeapString[ptr.name]; FreeEntry[ptr]; ENDLOOP; ENDLOOP; NameTable _ NumberTable _ ALL[NIL]; END; Remember: PUBLIC PROCEDURE [name: STRING, number: LONG UNSPECIFIED] = BEGIN ptr: Entry _ AllocateEntry[]; i: CARDINAL _ HashName[name]; ptr.name _ AllocateHeapString[name.length]; AppendString[ptr.name,name]; ptr.number _ number; ptr.nextName _ NameTable[i]; NameTable[i] _ ptr; i _ HashNumber[number]; ptr.nextNumber _ NumberTable[i]; NumberTable[i] _ ptr; END; KnownName: PUBLIC PROCEDURE [name: STRING] RETURNS [BOOLEAN] = BEGIN ptr: Entry; FOR ptr _ NameTable[HashName[name]],ptr.nextName UNTIL ptr = NIL DO IF EquivalentString[name,ptr.name] THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; END; KnownNumber: PUBLIC PROCEDURE [number: LONG UNSPECIFIED] RETURNS [BOOLEAN] = BEGIN ptr: Entry; FOR ptr _ NumberTable[HashNumber[number]],ptr.nextNumber UNTIL ptr = NIL DO IF number = ptr.number THEN RETURN[TRUE]; ENDLOOP; RETURN[FALSE]; END; FindName: PUBLIC PROCEDURE [name: STRING] RETURNS [LONG UNSPECIFIED] = BEGIN ptr: Entry; FOR ptr _ NameTable[HashName[name]],ptr.nextName UNTIL ptr = NIL DO IF EquivalentString[name,ptr.name] THEN RETURN[ptr.number]; ENDLOOP; WriteString["ERROR: FindName called with no entry for "]; WriteLine[name]; RETURN[LONG[0]]; END; FindNumber: PUBLIC PROCEDURE [number: LONG UNSPECIFIED] RETURNS [STRING] = BEGIN ptr: Entry; FOR ptr _ NumberTable[HashNumber[number]],ptr.nextNumber UNTIL ptr = NIL DO IF number = ptr.number THEN RETURN[ptr.name]; ENDLOOP; WriteString["ERROR: FindNumber called with no entry for "]; WriteLong[number, GetOutputStream[]]; RETURN["NULL"]; END; HashName: PROCEDURE [str: STRING] RETURNS [total: CARDINAL] = BEGIN i: CARDINAL; total _ 0; --total _ ABS[total]; FOR i IN [0..str.length) DO total _ BITXOR[BITSHIFT[total,1],BITOR[str[i],40B]]; ENDLOOP; --BITOR[str[i],40B] is to equate upper and lower case total _ total MOD TableSize; --total _ ABS[total]; END; HashNumber: PROCEDURE [number: LONG UNSPECIFIED] RETURNS [total: CARDINAL] = BEGIN dummy: CARDINAL; --total _ number MOD TableSize; [dummy,total] _ LongDivMod[number,256]; --total _ ABS[total]; END; AllocateEntry: PROCEDURE RETURNS [Entry] = BEGIN RETURN[AllocateHeapNode[SIZE[EntryRecord]]]; END; FreeEntry: PROCEDURE [x: Entry] = BEGIN FreeHeapNode[x]; END; TableSize: CARDINAL = 256; NameTable: ARRAY [0..(TableSize - 1)] OF Entry _ ALL[NIL]; NumberTable: ARRAY [0..(TableSize - 1)] OF Entry _ ALL[NIL]; Entry: TYPE = POINTER TO EntryRecord; EntryRecord: TYPE = RECORD [ nextName: Entry, nextNumber: Entry, name: STRING, number: LONG UNSPECIFIED ]; END. e12(635)\126b10B412b10B171b14B307b8B368b9B233b11B241b8B327b10B345b8B318b10B196b13B90b9B