DIRECTORY CDValue, CD, CDEvents, RefTab; CDValueImpl: CEDAR MONITOR IMPORTS CD, CDEvents, RefTab EXPORTS CD, CDValue = BEGIN Propagation: TYPE = CDValue.Propagation; DesignValuesRep: PUBLIC TYPE = RECORD [ values: RefTab.Ref ]; TechnologyValuesRep: PUBLIC TYPE = RECORD [ registration: RefTab.Ref, values: RefTab.Ref ]; globalTab: RefTab.Ref _ RefTab.Create[]; registerTab: RefTab.Ref _ RefTab.Create[]; DesignHasBeenCreated: CDEvents.EventProc = {design.designValues _ NEW[DesignValuesRep _ [values: RefTab.Create[]]]}; TechnologyHasBeenRegistered: CDEvents.EventProc = BEGIN tech: CD.Technology = NARROW[x]; tech.technologyValues _ NEW[TechnologyValuesRep _ [registration: RefTab.Create[], values: RefTab.Create[]]] END; EnregisterKey: PUBLIC ENTRY PROC [key: REF, boundTo: CD.Technology_NIL] = BEGIN ENABLE UNWIND => NULL; done: BOOL _ FALSE; IF boundTo=NIL THEN done _ RefTab.Insert[registerTab, key, registerTab] ELSE { x: REF; globFound: BOOL; tem: REF TechnologyValuesRep = boundTo.technologyValues; IF tem=NIL THEN RETURN WITH ERROR CD.Error[ec: callingError, explanation: "technology had not been registered"]; [globFound, x] _ RefTab.Fetch[registerTab, key]; [] _ RefTab.Insert[registerTab, key, NIL]; IF globFound AND x#NIL THEN done _ FALSE ELSE done _ RefTab.Insert[tem.registration, key, NIL]; }; IF ~done THEN RETURN WITH ERROR CD.Error[doubleRegistration] END; Fetch: PUBLIC ENTRY PROC [boundTo: REF_NIL, key: REF, propagation: Propagation_design] RETURNS [REF] = BEGIN ENABLE UNWIND => NULL; val: RefTab.Val; found: BOOL; DO WITH boundTo SELECT FROM d: CD.Design => { tem: REF DesignValuesRep = d.designValues; [found: found, val: val] _ RefTab.Fetch[tem.values, key]; IF found THEN RETURN [val]; IF propagation>design THEN boundTo_d.technology ELSE RETURN [NIL] }; t: CD.Technology => { tem: REF TechnologyValuesRep = t.technologyValues; [found: found, val: val] _ RefTab.Fetch[tem.values, key]; IF found THEN RETURN [val]; IF propagation>technology THEN boundTo_NIL ELSE RETURN [NIL] }; ENDCASE => { IF boundTo#NIL THEN RETURN WITH ERROR CD.Error[callingError, "CDValue.Fetch: bad boundTo type"] ELSE { [found: found, val: val] _ RefTab.Fetch[globalTab, key]; IF found THEN RETURN [val]; RETURN [NIL] }; }; ENDLOOP END; Store: PUBLIC ENTRY PROC [boundTo: REF_NIL, key: REF, value: REF] = BEGIN ENABLE UNWIND => NULL; ref: RefTab.Ref; WITH boundTo SELECT FROM t: CD.Technology => { tem: REF TechnologyValuesRep = t.technologyValues; ref _ tem.values; }; d: CD.Design => { tem: REF DesignValuesRep = d.designValues; ref _ tem.values; }; ENDCASE => { IF boundTo#NIL THEN RETURN WITH ERROR CD.Error[callingError, "CDValue.Store: bad boundTo type"] ELSE ref _ globalTab }; IF value#NIL THEN [] _ RefTab.Store[ref, key, value] ELSE [] _ RefTab.Delete[ref, key]; END; FetchInt: PUBLIC PROC [boundTo: REF _ NIL, key: REF, propagation: Propagation _ design, ifNotFound: INT_0] RETURNS [INT] = BEGIN x: REF ANY _ Fetch[boundTo: boundTo, key: key, propagation: propagation]; WITH x SELECT FROM r: REF INT => RETURN [r^] ENDCASE => RETURN [ifNotFound] END; StoreInt: PUBLIC PROC [boundTo: REF_NIL, key: REF, value: INT] = BEGIN x: REF INT _ NEW[INT _ value]; Store[boundTo: boundTo, key: key, value: x] END; CDEvents.RegisterEventProc[$CreateNewDesign, DesignHasBeenCreated]; CDEvents.RegisterEventProc[$RegisterTechnology, TechnologyHasBeenRegistered]; END. ÒCDValueImpl.mesa (part of ChipNDale) Copyright c 1983 by Xerox Corporation. All rights reserved. by Christian Jacobi, August 16, 1983 4:09 pm last edited Christian Jacobi, May 24, 1985 4:53:24 pm PDT Ê—˜šœ&™&Jšœ Ïmœ1™