<> <> <> <> <<>> 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]]]; < --don't try: reals with different bit patterns may be equal!-->> 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]]; }; }; <> <> <<};>> <<>> <> <> <> <> <<};>> <<>> DictFetch: PROC [dict: Dict, key: Any] RETURNS [found: BOOL, val: Any] ~ { ERROR; }; <> <> < RETURN [val];>> < RETURN [NIL];>> <<};>> <<>> <> <> <> <<[] _ RefTab.Store[dict.table, key, val];>> <<};>> <<>> <> <> <<};>> <<>> DStack: TYPE ~ REF DStackRep; DStackRep: PUBLIC TYPE ~ RECORD [ count: ArrayIndex, size: ArrayIndex, array: DArrayRef ]; DArrayRef: TYPE ~ REF DArrayRep; DArrayRep: TYPE ~ RECORD [SEQUENCE size: ArrayIndex OF Dict]; Begin: PUBLIC PROC [self: Root, dict: Dict] ~ { dstack: DStack ~ self.dstack; IF NOT dstack.count2 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> <> <<[] _ RefTab.Pairs[dict.table, action];>> <<};>> <<>> DictCopy: PUBLIC PROC [dict1, dict2: Dict] RETURNS [Dict] ~ { ERROR; }; END.