<> <> <> <> <> <<>> DIRECTORY Basics USING [BITSHIFT, BITXOR, HighHalf, LowHalf], TJaMBasic USING [Object], TJaMDict USING [], TJaMVM USING [GetText]; TJaMHashImpl: PROGRAM IMPORTS TJaMVM, Basics EXPORTS TJaMDict = { HashObject: PUBLIC PROC[key: TJaMBasic.Object] RETURNS[CARDINAL] = { <> <> WITH k: key SELECT FROM integer => RETURN[Basics.LowHalf[k.ivalue]]; real => RETURN[Basics.HighHalf[LOOPHOLE[k.rvalue]]]; boolean => RETURN[LOOPHOLE[k.bvalue]]; name => RETURN[k.id.index]; string => RETURN[HashString[k]]; stream => RETURN[k.index]; command => RETURN[k.index]; ENDCASE => RETURN[0]; }; <> maxLength: CARDINAL = 20; HashString: PUBLIC PROC[s: string TJaMBasic.Object] RETURNS[CARDINAL] = { text: STRING _ [maxLength]; TJaMVM.GetText[s,text]; RETURN[InlineHash[text,s.length]] }; HashText: PUBLIC PROC[text: LONG STRING] RETURNS[CARDINAL] = { RETURN[InlineHash[text,text.length]] }; InlineHash: PROC[text: LONG STRING, h: CARDINAL] RETURNS[CARDINAL] = INLINE { len: CARDINAL _ MIN[text.length,maxLength]; FOR i: CARDINAL IN[1..MIN[3,len]) DO h _ Basics.BITXOR[Basics.BITSHIFT[h,1], LOOPHOLE[text[i]]]; ENDLOOP; IF len >= 2 THEN FOR i: CARDINAL IN[len - 2..len) DO h _ Basics.BITXOR[Basics.BITSHIFT[h,1], LOOPHOLE[text[i]]]; ENDLOOP; RETURN[h]; }; }.