DIRECTORY PS; PSDictImpl: CEDAR PROGRAM IMPORTS PS EXPORTS PS ~ BEGIN OPEN PS; DictImpl: TYPE ~ REF DictImplRep; DictImplRep: PUBLIC TYPE ~ RECORD [ length: INT, data: SEQUENCE maxLength: NAT OF DictNode ]; DictNode: TYPE ~ REF DictNodeRep; DictNodeRep: TYPE ~ RECORD [key: Any, val: Any, next: DictNode]; Hash: PROC [key: Key] RETURNS [CARDINAL] ~ { HashProc: TYPE = PROC [key: Key] RETURNS [CARDINAL]; Munch: PROC [CARD32] RETURNS [CARD16] ~ TRUSTED MACHINE CODE { PrincOps.zXOR }; hash: CARD _ 0; WITH v: x.val SELECT FROM name => hash _ LOOPHOLE[x.ref]; integer => hash _ LOOPHOLE[v.int]; string => RETURN [Hash[NameFromAny[x]]]; boolean => hash _ ORD[v.bool]; operator, array, file, dict, font => hash _ LOOPHOLE[x.ref]; ENDCASE => hash _ 42; RETURN [Munch[hash]]; }; DictCreate: PUBLIC PROC [size: INT] RETURNS [Dict] ~ { IF size<0 THEN ERROR Error[rangecheck] ELSE IF size>NAT.LAST THEN ERROR Error[limitcheck] ELSE { impl: DictImpl ~ NEW[DictImplRep[size]]; ref: DictRef ~ NEW[DictRep _ [access: unlimited, impl: impl]]; impl.length _ 0; RETURN[[executable: FALSE, ref: ref]]; }; }; DictSetAccess: PUBLIC PROC [dict: Dict, access: Access] RETURNS [Dict] ~ { IF access=executeOnly THEN ERROR Error[typecheck]; IF dict.ref.access2 THEN ERROR Error[dictstackunderflow]; dstack.count _ dstack.count-1; }; CurrentDict: PUBLIC PROC [self: Root] RETURNS [Dict] ~ { dstack: DStack ~ self.dstack; IF NOT dstack.count>0 THEN ERROR Bug; -- should always be >=2 RETURN [dstack.array[dstack.count-1]]; }; CountDictStack: PROC [self: Root] RETURNS [INT] ~ { dstack: DStack ~ self.dstack; RETURN [dstack.count]; }; dictstack: PROC [self: Root] ~ { dstack: DStack ~ self.dstack; array: Array ~ PopArray[self]; subarray: Array ~ ArrayGetInterval[array, 0, dstack.count]; IF subarray.access --don't try: reals with different bit patterns may be equal!-- DictLength: PUBLIC PROC [dict: Dict] RETURNS [INT] ~ { RETURN [dict.ref.length]; }; DictMaxLength: PUBLIC PROC [dict: Dict] RETURNS [INT] ~ { base: DictBase ~ dict.base; IF base.access RETURN [val]; ENDCASE => RETURN [NIL]; }; DictPut: PUBLIC PROC [dict: Dict, key: Any, val: Any] ~ { length: INT ~ DictLength[dict]; IF NOT length™FKšœœ ˜Kšœ,œ˜Kšœ˜Kšœœ ˜&K˜—K˜K˜—š ž œœœœœ™6Kšœ™K™K™—š ž œœœœœ™9K™Kšœœœ™8Kšœ™K™K™—šž œœœœ ˜JKšœœœ˜2Kšœœœ˜:Kšœ˜Kšœ˜K˜K˜—šž œœœ œ˜JJšœ˜K˜K˜—šžœœœœ ™=šœ#œ™2Kšœ œ™Kšœœœ™—K™K™—šžœœœ%™9Kšœœ™Kšœœœœ™8K™(K™K™—š žœœœœœ™