EnterString:
PUBLIC
PROC [s: SubString]
RETURNS [hti: Symbols.HTIndex]~{
hvi: Symbols.HVIndex~HashValue[s];
desc: SubString¬[base~ssb, offset~, length~];
charsPerWord: CARDINAL = BYTES[WORD];
unitsPerWord: CARDINAL = UNITS[WORD];
offset, length, nw: CARDINAL;
ssi: Alloc.Index;
FOR hti ¬ hashVec[hvi], htb[hti].link
UNTIL hti = HTNull
DO
desc ¬ SubStringForHash[hti];
IF ConvertUnsafe.EqualSubStrings[s, desc] THEN RETURN [hti];
ENDLOOP;
offset ¬ ssb.length; -- current length of packed string
length ¬ s.length + 1; -- bytes to be added to packed string
nw ¬ (offset + length - ssb.maxlength + (charsPerWord-1))/charsPerWord;
IF nw # 0
THEN {
-- need more words
IF (ssi ¬ table.Units[ssType, nw*unitsPerWord]) # ssw THEN ERROR;
ssw ¬ ssw + nw*unitsPerWord;
ssb ¬ [length: ssb.length, maxlength: ssb.maxlength+nw*charsPerWord, text:]; };
ssb[ssb.length] ¬ VAL[s.length];
ssb.length ¬ ssb.length + 1;
ConvertUnsafe.AppendSubString[ssb, s];
hti ¬ AllocateHash[];
htb[hti].link ¬ hashVec[hvi];
hashVec[hvi] ¬ hti;
RETURN };