CDValueImpl.mesa (part of Chipndale)
by Christian Jacobi August 16, 1983 4:09 pm
last edited Christian Jacobi November 21, 1983 7:22 pm
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: Propagationsign]
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𡤍.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: Propagationsign, ifNotFound:
INT𡤀]
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.