<<>> <> <> <> <<>> DIRECTORY Prop USING [MapAction, PropList]; PropImpl: CEDAR PROGRAM EXPORTS Prop ~ BEGIN OPEN Prop; <> <<>> Zap: PROC [propList: PropList, key: REF] RETURNS [PropList] ~ { IF propList=NIL THEN RETURN [NIL] ELSE { IF propList.first.key=key THEN RETURN [propList.rest] ELSE { remRest: PropList ~ Zap[propList.rest, key]; IF propList.rest=remRest THEN ERROR; -- should have changed! RETURN [CONS[propList.first, remRest]]; }; }; }; Get: PUBLIC PROC [propList: PropList, key: REF] RETURNS [val: REF] ~ { FOR list: PropList ¬ propList, list.rest UNTIL list=NIL DO IF list.first.key=key THEN RETURN[list.first.val]; ENDLOOP; RETURN[NIL]; }; Put: PUBLIC PROC [propList: PropList, key: REF, val: REF] RETURNS [PropList] ~ { old: REF ~ Get[propList, key]; IF val=old THEN RETURN [propList]; -- same val, or both NIL IF old#NIL THEN propList ¬ Zap[propList, key]; -- remove old IF val#NIL THEN propList ¬ CONS[[key: key, val: val], propList]; -- add new RETURN [propList]; }; Rem: PUBLIC PROC [propList: PropList, key: REF] RETURNS [PropList] ~ { old: REF ~ Get[propList, key]; RETURN[IF old=NIL THEN propList ELSE Zap[propList, key]]; }; Map: PUBLIC PROC[propList: PropList, action: MapAction] RETURNS [BOOL] ~ { FOR list: PropList ¬ propList, list.rest UNTIL list=NIL DO IF action[list.first.key, list.first.val] THEN RETURN [TRUE]; ENDLOOP; RETURN [FALSE]; }; END.