-- SymbolTableImpl.mesa -- last edited by Suzuki: 12 Oct. 1981 3:02 pm PDT (Monday) DIRECTORY Rope: TYPE USING [Concat, Ref], SymbolTable: TYPE, SymTab: TYPE; SymbolTableImpl: PROGRAM IMPORTS Rope, SymTab EXPORTS SymbolTable = { PrivateRef: TYPE = REF Table; Table: PUBLIC TYPE = RECORD [ hash: SymTab.Ref, table: REF PairTable, nest: REF Nest, level: CARDINAL, marker: CARDINAL]; PairTable: TYPE = RECORD [val: SEQUENCE length: CARDINAL OF RECORD[pred: CARDINAL, key: Rope.Ref, val: SymbolTable.Value, port: BOOLEAN]]; Nest: TYPE = RECORD [val: SEQUENCE length: CARDINAL OF CARDINAL]; Create: PUBLIC PROC [hashSize, tableSize, nestLevel:CARDINAL, case:BOOLEAN] RETURNS [PrivateRef] = { tab: PrivateRef ← NEW[Table]; tab.hash ← SymTab.Create[hashSize, case]; tab.table ← NEW[PairTable[tableSize]]; tab.nest ← NEW[Nest[nestLevel]]; tab.level ← 0; tab.marker ← 0; RETURN[tab]}; Mark: PUBLIC PROC [tab: PrivateRef] = { IF tab.nest.length<=tab.level THEN ERROR; tab.nest[tab.level] ← tab.marker; tab.level←tab.level+1}; Add: PUBLIC PROC [tab: PrivateRef, key: SymbolTable.Key, val: SymbolTable.Value, port: BOOLEAN] = { found: BOOLEAN; oldValue: SymbolTable.Value; pred: CARDINAL; storedKey: SymbolTable.Key; [found, storedKey, oldValue] ← SymTab.Fetch[tab.hash, key]; IF found THEN pred ← NARROW[oldValue, REF CARDINAL]↑ ELSE { storedKey ← Rope.Concat[NIL, key]; pred ← 0}; [] ← SymTab.Store[tab.hash, storedKey, NEW[CARDINAL ← tab.marker]]; IF tab.marker>=tab.table.length THEN ERROR Overflow; tab.table[tab.marker] ← [pred, storedKey, val, port]; tab.marker ← tab.marker+1}; Get: PUBLIC PROC [tab: PrivateRef, key: SymbolTable.Key] RETURNS [found: BOOLEAN, val: SymbolTable.Value, port: BOOLEAN] = { value: SymbolTable.Value; [found, ,value] ← SymTab.Fetch[tab.hash, key]; IF NOT found THEN RETURN[FALSE, NIL, FALSE]; [,,val,port] ← tab.table[NARROW[value,REF CARDINAL]↑]}; Pop: PUBLIC PROC [tab: PrivateRef] = { FOR i: CARDINAL IN [tab.nest[tab.level-1]..tab.nest[tab.level]) DO [] ← SymTab.Store[tab.hash, tab.table[i].key, NEW[CARDINAL ← tab.table[i].pred]]; ENDLOOP; tab.level ← tab.level-1}; Underflow: PUBLIC SIGNAL = CODE; Overflow: PUBLIC SIGNAL = CODE; }.