PWPinsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet, June, 1985 10:07:28 am PDT
Bertrand Serlet, March 25, 1986 11:09:02 pm PST
Curry, January 28, 1986 1:42:02 pm PST
DIRECTORY
CD, CDBasics, CDCells, CDDirectory, CDInstances, CDOrient, CDProperties, CDSymbolicObjects,
Convert, PWPins, Rope;
PWPinsImpl: CEDAR PROGRAM
IMPORTS CD, CDBasics, CDCells, CDDirectory, CDInstances, CDOrient, CDProperties, CDSymbolicObjects, Convert, Rope
EXPORTS PWPins
SHARES CDCells, CDSymbolicObjects =
BEGIN
OPEN PWPins;
GetSide: PUBLIC PROC [ob: CD.Object, pin: CD.Instance] RETURNS [side: Side] = {
LargerSide: PROC [hSide, vSide: Side] RETURNS [side: Side] = {
delta: INT ← pinRect.x2-pinRect.x1- (pinRect.y2-pinRect.y1);
side ← IF delta=0 THEN ERROR ELSE IF delta>0 THEN hSide ELSE vSide;
};
rect: CD.Rect ← CD.InterestRect[ob]; -- the border
pinRect: CD.Rect ← CDSymbolicObjects.Denotes[pin]; -- bbox of the pin (CDInstances.InstRectO)
side ← SELECT TRUE FROM
pinRect.x1 = pinRect.x2 AND pinRect.y1 = pinRect.y2 => none,
pinRect.x1 = pinRect.x2 AND pinRect.y1 = pinRect.y2 => SELECT pinRect.x1 FROM
rect.x1 => left,
rect.y1 => bottom,
rect.x2 => right,
rect.y2 => top,
ENDCASE => none,
pinRect.x1 = pinRect.x2 => SELECT pinRect.x1 FROM
rect.x1 => left,
rect.x2 => right,
ENDCASE => none,
pinRect.y1 = pinRect.y2 => SELECT pinRect.y1 FROM
rect.y1 => bottom,
rect.y2 => top,
ENDCASE => none,
rect.y1 = pinRect.y1 AND rect.y2 = pinRect.y2 => ERROR, -- pin on 2 opposite sides
rect.x1 = pinRect.x1 AND rect.x2 = pinRect.x2 => ERROR, -- pin on 2 opposite sides
rect.y2 = pinRect.y2 AND rect.x1 = pinRect.x1 => LargerSide[top, left],
rect.y2 = pinRect.y2 AND rect.x2 = pinRect.x2 => LargerSide[top, right],
rect.y1 = pinRect.y1 AND rect.x1 = pinRect.x1 => LargerSide[bottom, left],
rect.y1 = pinRect.y1 AND rect.x2 = pinRect.x2 => LargerSide[bottom, right],
rect.y2 = pinRect.y2 => top,
rect.y1 = pinRect.y1 => bottom,
rect.x1 = pinRect.x1 => left,
rect.x2 = pinRect.x2 => right,
ENDCASE    => none;
};
Because we must finally get instances, this one has in its parameters all necessary information for reconstructing the application.
EnumerateDeepPinsInContext: PUBLIC EnumerationProc = {
value: REF;
IF ~filter[CDOrient.MapRect[
itemInCell: CD.InterestRect[ob],
cellSize: ob.size,
cellInstOrient: orientation,
cellInstPos: location]] THEN RETURN;
value ← CDProperties.GetObjectProp[ob, enumerationProcProp];
IF value#NIL THEN RETURN [NARROW [value, REF EnumerationProc]^[ob, location, orientation, properties, eachPin, stopEnumerateDeepPins, filter]];
value ← CDProperties.GetProp[ob.class, enumerationProcProp];
IF value#NIL THEN RETURN [NARROW [value, REF EnumerationProc]^[ob, location, orientation, properties, eachPin, stopEnumerateDeepPins, filter]];
ob ← CDDirectory.Expand[ob, NIL, NIL].new;
quit ← ob#NIL AND EnumerateDeepPinsInContext[ob, location, orientation, NIL, eachPin, stopEnumerateDeepPins, filter];
};
PinEnumerateDeepPinsInContext: EnumerationProc = {
quit ← eachPin[NEW [CD.InstanceRep ← [ob: ob, location: location, orientation: orientation, properties: CDProperties.DCopyProps[properties]]]];
};
CellEnumerateDeepPinsInContext: EnumerationProc = {
cellPtr: CD.CellPtr ← NARROW [ob.specificRef];
FOR list: CD.InstanceList ← cellPtr.contents, list.rest WHILE (list#NIL AND ~quit) DO
IF ~stopEnumerateDeepPins OR CDProperties.GetInstanceProp[list.first, $StopEnumerateDeepPins]=NIL THEN
quit ← EnumerateDeepPinsInContext[
list.first.ob,
CDBasics.BaseOfRect[
CDOrient.MapRect[
itemInCell: CDInstances.InstRectO[list.first],
cellSize: ob.size,
cellInstOrient: orientation,
cellInstPos: location]],
CDOrient.ComposeOrient[list.first.orientation, orientation],
list.first.properties,
eachPin, stopEnumerateDeepPins, filter];
ENDLOOP;
};
EnumerateDeepPins: PUBLIC PROC [ob: CD.Object, eachPin: InstanceEnumerator, stopEnumerateDeepPins: BOOLTRUE] RETURNS [quit: BOOL] = {
DefaultFilter: FilterProc = {};
quit ← EnumerateDeepPinsInContext[ob: ob, eachPin: eachPin, stopEnumerateDeepPins: stopEnumerateDeepPins, filter: DefaultFilter];
};
EnumerateEdgePins: PUBLIC PROC [ob: CD.Object, eachPin: InstanceEnumerator, stopEnumerateDeepPins: BOOLTRUE] RETURNS [quit: BOOL] = {
iRectShrank: CD.Rect ← CDBasics.Extend[CD.InterestRect[ob], -1];
EdgeFilter: FilterProc = {isSubInteresting ← ~CDBasics.Inside[subRect, iRectShrank]};
EachPinFilter: InstanceEnumerator -- [inst: CD.Instance] RETURNS [quit: BOOL ← FALSE] -- = {
IF GetSide[ob, inst]#none THEN quit ← eachPin[inst];
};
quit ← EnumerateDeepPinsInContext[ob: ob, eachPin: EachPinFilter, stopEnumerateDeepPins: stopEnumerateDeepPins, filter: EdgeFilter];
};
ChangePins: PUBLIC PROC [ob: CD.Object, changePinProc: ChangePinProc ← DefaultChangePinProc, stopEnumerateDeepPins: BOOLTRUE] RETURNS [cell: CD.Object] =
BEGIN
cellPtr: CD.CellPtr;
KeepPinOnEdge: InstanceEnumerator -- [inst: CD.Instance] RETURNS [quit: BOOL ← FALSE] -- = {
newInst: CD.Instance ← changePinProc[inst];
IF newInst#NIL THEN cellPtr.contents ← CONS [newInst, cellPtr.contents];
};
inst: CD.Instance ← NEW [CD.InstanceRep ← [ob: ob]];
IF stopEnumerateDeepPins THEN CDProperties.PutInstanceProp[inst, $StopEnumerateDeepPins, $StopEnumerateDeepPins];
cell ← CDCells.CreateEmptyCell[]; cellPtr ← NARROW [cell.specificRef];
[] ← EnumerateEdgePins[ob, KeepPinOnEdge];
cellPtr.contents ← CONS[inst, cellPtr.contents];
CDCells.SetInterestRect[cell, CD.InterestRect[ob]];
[] ← CDCells.RepositionCell[cell, NIL];
END;
DefaultChangePinProc: PUBLIC ChangePinProc = {newPin ← oldPin};
RenamePins: PUBLIC PROC [ob: CD.Object, renameProc: RenameProc ← DefaultRenameProc, stopEnumerateDeepPins: BOOLTRUE] RETURNS [cell: CD.Object] = {
ChangePin: ChangePinProc = {
newRope: ROPE ← renameProc[CDSymbolicObjects.GetName[oldPin]];
IF Rope.IsEmpty[newRope] THEN RETURN;
newPin ← CDInstances.Copy[oldPin];
CDSymbolicObjects.SetName[newPin, newRope];
};
cell ← ChangePins[ob, ChangePin, stopEnumerateDeepPins];
};
DefaultRenameProc: PUBLIC RenameProc = {newRope ← oldRope};
Useful in many RenameProcs for indexing names. e.g. Index["foo", 4]="foo[4]"
Index: PUBLIC PROC [rope: ROPE, index: INT] RETURNS [indexedRope: ROPE] = {
indexedRope ← Rope.Cat[rope, "[", Convert.RopeFromInt[index], "]"];
};
enumerationProcProp: PUBLIC ATOM ← $EnumerationProcPWPins;
[] ← CDProperties.RegisterAndInstall[enumerationProcProp, [makeCopy: CDProperties.CopyVal], $PWPins];
[] ← CDProperties.RegisterProperty[enumerationProcProp, $PWPins];
CDProperties.InstallProcs[enumerationProcProp, [makeCopy: CDProperties.CopyVal]];
[] ← CDProperties.RegisterAndInstall[$StopEnumerateDeepPins, [makeCopy: CDProperties.CopyVal], $PWPins];
[] ← CDProperties.RegisterProperty[$StopEnumerateDeepPins, $PWPins];
CDProperties.InstallProcs[$StopEnumerateDeepPins, [makeCopy: CDProperties.CopyVal]];
CDProperties.PutProp[CDSymbolicObjects.pinClass, enumerationProcProp, NEW [EnumerationProc ← PinEnumerateDeepPinsInContext]];
CDProperties.PutProp[CDSymbolicObjects.segmentClass, enumerationProcProp, NEW [EnumerationProc ← PinEnumerateDeepPinsInContext]];
CDProperties.PutProp[CDSymbolicObjects.markClass, enumerationProcProp, NEW [EnumerationProc ← PinEnumerateDeepPinsInContext]];
CDProperties.PutProp[CDCells.cellClass, enumerationProcProp, NEW [EnumerationProc ← CellEnumerateDeepPinsInContext]];
END.