<<-- NameSymbolTableImpl.Mesa>> <<-- written by Paxton. June 1981>> <<-- last written by Paxton. September 22, 1982 2:38 pm>> <> DIRECTORY NameSymbolTable, JaMBasic, JaMOps, Atom, Rope; NameSymbolTableImpl: CEDAR MONITOR IMPORTS JaMOps, Atom, Rope EXPORTS NameSymbolTable = BEGIN OPEN NameSymbolTable; <<-- ***** Names>> MakeNameFromRope: PUBLIC PROC [rope: Rope.ROPE] RETURNS [Name] = TRUSTED { RETURN [MakeName[LOOPHOLE[Rope.Flatten[rope], REF READONLY TEXT]]] }; MakeName: PUBLIC PROC [text: REF READONLY TEXT] RETURNS [Name] = TRUSTED { obj: name JaMBasic.Object; known: BOOLEAN; IF text=NIL OR text.length=0 THEN RETURN [nullName]; [obj,known] _ JaMOps.CreateName[LOOPHOLE[text,LONG STRING]]; RETURN [LOOPHOLE[obj.id]] }; atomText: REF TEXT _ NEW[TEXT[64]]; AtomFromName: PUBLIC PROC [name: Name] RETURNS [ATOM] = { RETURN [Atom.MakeAtom[RopeFromName[name]]] }; FromName: PUBLIC PROC [name: Name, text: REF TEXT] = TRUSTED { nameObj: name JaMBasic.Object _ [L,name[LOOPHOLE[name,JaMBasic.NameID]]]; JaMOps.StringText[JaMOps.NameToString[nameObj],LOOPHOLE[text,LONG STRING]] }; RopeFromName: PUBLIC ENTRY PROC [name: Name] RETURNS [rope: Rope.ROPE] = { ENABLE UNWIND => NULL; initloc, loc: CARDINAL; FindInRopeCache: PROC RETURNS [BOOLEAN] = { ropeCacheProbes _ ropeCacheProbes+1; DO -- search cache SELECT ropeCacheNames[loc] FROM name => { rope _ ropeCacheRopes[loc]; ropeCacheHits _ ropeCacheHits+1; RETURN [TRUE] }; nullName => RETURN [FALSE]; -- this is an unused entry ENDCASE; SELECT (loc _ loc+1) FROM ropeCacheSize => IF (loc _ 0)=initloc THEN RETURN [FALSE]; initloc => RETURN [FALSE]; ENDCASE; ENDLOOP }; PutInRopeCache: PROC = { IF ropeCacheCount = ropeCacheMax THEN ClearRopeCache[]; loc _ initloc; DO -- search cache for place to put the entry SELECT ropeCacheNames[loc] FROM name => RETURN; -- already in cache nullName => EXIT; -- this is an unused entry ENDCASE; SELECT (loc _ loc+1) FROM ropeCacheSize => IF (loc _ 0)=initloc THEN ERROR; -- cache full initloc => ERROR; -- cache full ENDCASE; ENDLOOP; ropeCacheCount _ ropeCacheCount+1; ropeCacheNames[loc] _ name; ropeCacheRopes[loc] _ rope }; IF name=nullName THEN RETURN [NIL]; loc _ initloc _ LOOPHOLE[name,CARDINAL] MOD ropeCacheSize; IF FindInRopeCache[] THEN RETURN; FromName[name, atomText]; rope _ Rope.FromRefText[atomText]; PutInRopeCache }; ropeCacheSize: CARDINAL = 64; -- should be a power of 2 ropeCacheMax: CARDINAL = (ropeCacheSize*4)/5; -- don't fill too full ropeCacheCount: CARDINAL; -- number of entries currently in use RopeCacheNames: TYPE = ARRAY [0..ropeCacheSize) OF Name; ropeCacheNames: REF RopeCacheNames _ NEW[RopeCacheNames]; RopeCacheRopes: TYPE = ARRAY [0..ropeCacheSize) OF Rope.ROPE; ropeCacheRopes: REF RopeCacheRopes _ NEW[RopeCacheRopes]; ropeCacheProbes: LONG INTEGER _ 0; ropeCacheHits: LONG INTEGER _ 0; ClearRopeCache: PROC = { IF ropeCacheCount = 0 THEN RETURN; ropeCacheCount _ 0; FOR i: CARDINAL IN [0..ropeCacheSize) DO ropeCacheNames[i] _ nullName; ENDLOOP; }; TextOverflow: PUBLIC ERROR = CODE; -- never raised by current implementation <<-- ***** Objects>> Object: PUBLIC TYPE = ARRAY [0..4) OF UNSPECIFIED; MakeObject: PUBLIC PROC [text: REF READONLY TEXT] RETURNS [Object] = TRUSTED { RETURN [LOOPHOLE[JaMOps.MakeString[LOOPHOLE[text,LONG STRING]]]] }; NullObject: PUBLIC PROC RETURNS [Object] = { null: Object _ [0,0,0,0]; RETURN [null] }; <<-- ***** Initialization>> Start: PUBLIC PROC = { ropeCacheCount _ 1; ClearRopeCache; }; END.