NameSymbolTableImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
written by Paxton. June 1981
last written by Paxton. September 22, 1982 2:38 pm
Last Edited by: Maxwell, January 5, 1983 12:34 pm
Plass, March 1, 1985 4:31:29 pm PST
Doug Wyatt, March 5, 1985 9:28:20 am PST
DIRECTORY
Atom,
NameSymbolTable,
Rope,
TJaMBasic,
TJaMOps;
NameSymbolTableImpl: CEDAR MONITOR
IMPORTS TJaMOps, 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 TJaMBasic.Object;
known: BOOL;
IF text=NIL OR text.length=0 THEN RETURN [nullName];
[obj,known] ← TJaMOps.CreateName[LOOPHOLE[text,LONG STRING]];
RETURN [LOOPHOLE[obj.id]];
};
atomText: REF TEXTNEW[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 TJaMBasic.Object ← [L,name[LOOPHOLE[name,TJaMBasic.NameID]]];
TJaMOps.StringText[TJaMOps.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 [BOOL] = {
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[TJaMOps.MakeString[LOOPHOLE[text,LONG STRING]]]] };
NullObject: PUBLIC PROC RETURNS [Object] = {
null: Object ← [0,0,0,0];
RETURN [null] };
***** Initialization
Start: PROC = {
ropeCacheCount ← 1;
ClearRopeCache[];
};
Start[];
END.