<> <> <> <> DIRECTORY Properties; PropertiesImpl: CEDAR MONITOR EXPORTS Properties = BEGIN <<>> PropList: TYPE = Properties.PropList; <<>> GetProp: PUBLIC ENTRY PROC [propList: PropList, prop: REF] RETURNS [REF _ NIL] = { ENABLE UNWIND => NULL; IF propList=NIL THEN RETURN [NIL]; IF propList.first.key = prop THEN RETURN [propList.first.val] ELSE { lst: PropList _ propList.rest; lag: PropList _ propList; UNTIL lst = NIL DO rest: PropList _ lst.rest; IF lst.first.key = prop THEN { lag.rest _ rest; lst.rest _ propList.rest; propList.rest _ lst; RETURN [lst.first.val] }; lag _ lst; lst _ rest; ENDLOOP; }; }; PutProp: PUBLIC ENTRY PROC [propList: PropList, prop: REF, val: REF _ NIL] RETURNS [PropList] = { ENABLE UNWIND => NULL; IF val=NIL THEN RETURN [RemPropInternal[propList, prop]] ELSE RETURN [PutPropInternal[propList, prop, val]] }; RemPropInternal: INTERNAL PROC [propList: PropList, prop: REF] RETURNS [PropList] = INLINE { lst: PropList _ propList; lag: PropList _ NIL; UNTIL lst = NIL DO rest: PropList _ lst.rest; IF lst.first.key = prop THEN { IF lag = NIL THEN RETURN [rest]; lag.rest _ rest; RETURN [propList]; }; lag _ lst; lst _ rest; ENDLOOP; RETURN [propList]; }; PutPropInternal: INTERNAL PROC [propList: PropList, prop: REF, val: REF] RETURNS [PropList] = INLINE { lst: PropList _ propList; lag: PropList _ NIL; WHILE lst # NIL DO IF lst.first.key = prop THEN { <<--Update list element in place>> lst.first.val _ val; RETURN [propList]; }; lag _ lst; lst _ lst.rest; ENDLOOP; <<--prop not found on property list>> lst _ LIST[[key: prop, val: val]]; IF lag = NIL THEN RETURN [lst]; lag.rest _ lst; RETURN [propList]; }; END.