DIRECTORY CD, CDBasics, CDCells, CDDirectory, CDInstances, CDProperties, CDSymbolicObjects, Convert, PWPins, Rope; PWPinsImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDDirectory, CDInstances, CDProperties, CDSymbolicObjects, Convert, Rope EXPORTS PWPins SHARES CDCells, CDSymbolicObjects = BEGIN OPEN PWPins; EnumerationProc: TYPE = PROC [ob: CD.Object, transf: CD.Transformation, properties: CD.PropList _ NIL, eachPin: InstanceEnumerator, stopEnumerateDeepPins: BOOL, filter: FilterProc] RETURNS [quit: BOOL _ FALSE]; FilterProc: TYPE = PROC [subRect: CD.Rect] RETURNS [isSubInteresting: BOOL _ TRUE]; 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 => 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; }; EnumerateDeepPinsInContext: PUBLIC EnumerationProc = { value: REF; IF ~filter[CDBasics.MapRect[itemInCell: CD.InterestRect[ob], cellInWorld: transf]] THEN RETURN; value _ CDProperties.GetObjectProp[ob, enumerationProcProp]; IF value#NIL THEN RETURN [NARROW [value, REF EnumerationProc]^[ob, transf, properties, eachPin, stopEnumerateDeepPins, filter]]; value _ CDProperties.GetProp[ob.class, enumerationProcProp]; IF value#NIL THEN RETURN [NARROW [value, REF EnumerationProc]^[ob, transf, properties, eachPin, stopEnumerateDeepPins, filter]]; ob _ CDDirectory.Expand1[ob, NIL, NIL].new; quit _ ob#NIL AND EnumerateDeepPinsInContext[ob, transf, NIL, eachPin, stopEnumerateDeepPins, filter]; }; PinEnumerateDeepPinsInContext: EnumerationProc = { quit _ eachPin[NEW [CD.InstanceRep _ [ob: ob, trans: transf, properties: CDProperties.DCopyProps[properties]]]]; }; CellEnumerateDeepPinsInContext: EnumerationProc = { cellPtr: CD.CellSpecific _ NARROW [ob.specific]; InstEnumerate: CDCells.InstEnumerator = { IF ~stopEnumerateDeepPins OR CDProperties.GetInstanceProp[inst, $StopEnumerateDeepPins]=NIL THEN quit _ EnumerateDeepPinsInContext[ inst.ob, CDBasics.ComposeTransform[inst.trans, transf], inst.properties, eachPin, stopEnumerateDeepPins, filter]; }; quit _ CDCells.EnumerateInstances[ob, InstEnumerate]; }; EnumerateDeepPins: PUBLIC PROC [ob: CD.Object, eachPin: InstanceEnumerator, stopEnumerateDeepPins: BOOL _ TRUE] RETURNS [quit: BOOL] = { DefaultFilter: FilterProc = {}; quit _ EnumerateDeepPinsInContext[ob: ob, transf: [], eachPin: eachPin, stopEnumerateDeepPins: stopEnumerateDeepPins, filter: DefaultFilter]; }; EnumerateEdgePins: PUBLIC PROC [ob: CD.Object, eachPin: InstanceEnumerator, stopEnumerateDeepPins: BOOL _ TRUE] 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, transf: [], eachPin: EachPinFilter, stopEnumerateDeepPins: stopEnumerateDeepPins, filter: EdgeFilter]; }; ChangePins: PUBLIC PROC [ob: CD.Object, changePinProc: ChangePinProc _ DefaultChangePinProc, stopEnumerateDeepPins: BOOL _ TRUE] RETURNS [cell: CD.Object] = BEGIN cellPtr: CD.CellSpecific; 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.specific]; [] _ EnumerateEdgePins[ob, KeepPinOnEdge]; cellPtr.contents _ CONS[inst, cellPtr.contents]; CDCells.SetInterestRect[NIL, cell, CD.InterestRect[ob], dontNotify]; END; DefaultChangePinProc: PUBLIC ChangePinProc = {newPin _ oldPin}; RenamePins: PUBLIC PROC [ob: CD.Object, renameProc: RenameProc _ DefaultRenameProc, stopEnumerateDeepPins: BOOL _ TRUE] 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}; Index: PUBLIC PROC [rope: ROPE, index: INT] RETURNS [indexedRope: ROPE] = { indexedRope _ Rope.Cat[rope, "[", Convert.RopeFromInt[index], "]"]; }; KeepAll: PUBLIC SelectNamesProc = {keepIt _ TRUE}; Position: PROC [inst: CD.Instance, newObj, template: CD.Object, side: Side, orientation: CD.Orientation] RETURNS [position: CD.Position] = { position _ CDBasics.SubPoints[ CDBasics.BaseOfRect[ CDBasics.MapRect[CD.InterestRect[inst.ob], inst.trans]], CDBasics.BaseOfRect[CD.InterestRect[template]]]; SELECT side FROM top, bottom => position.y _ 0; left, right => position.x _ 0; ENDCASE => ERROR; position _ CDBasics.SubPoints[position, CDBasics.BaseOfRect[CDBasics.MapRect[CD.InterestRect[newObj], [[0, 0], orientation]]]]; }; TransferCell: PUBLIC PROC [template: CD.Object, objSide: Side, width: INT, objProc: ForEachPinProc, selectNameProc: SelectNamesProc _ KeepAll] RETURNS [cell: CD.Object] = { instances: CD.InstanceList _ NIL; KeepPinOnEdge: PWPins.InstanceEnumerator = { newObj: CD.Object; side: Side _ GetSide[template, inst].side; IF side=objSide AND selectNameProc[CDSymbolicObjects.GetName[inst]] THEN { orient: CD.Orientation _ SELECT objSide FROM bottom => rotate270, right => original, top => rotate90, left => rotate180, ENDCASE => ERROR; newObj _ objProc[inst]; IF newObj=NIL THEN RETURN; instances _ CONS [CDInstances.NewInst[ob: newObj, trans: [Position[inst, newObj, template, objSide, orient], orient]], instances]; }; }; iRect: CD.Rect = CD.InterestRect[template]; IF objSide=none THEN ERROR; [] _ EnumerateEdgePins[template, KeepPinOnEdge]; cell _ CDCells.CreateCell[il: instances, ir: SELECT objSide FROM top, bottom => [0, 0, iRect.x2-iRect.x1, width], left, right => [0, 0, width, iRect.y2-iRect.y1], ENDCASE => ERROR]; }; enumerationProcProp: PUBLIC ATOM _ $EnumerationProcPWPins; [] _ CDProperties.RegisterProperty[enumerationProcProp, $PWPins]; CDProperties.InstallProcs[enumerationProcProp, [makeCopy: CDProperties.CopyVal]]; [] _ 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.pCellClass, enumerationProcProp, NEW [EnumerationProc _ CellEnumerateDeepPinsInContext]]; END. :PWPinsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reversed. Created by Bertrand Serlet, June, 1985 10:07:28 am PDT Bertrand Serlet, December 18, 1986 5:38:14 pm PST Curry, January 28, 1986 1:42:02 pm PST pinRect.x1 = pinRect.x2 AND pinRect.y1 = pinRect.y2 => none, Because we must finally get instances, this one has in its parameters all necessary information for reconstructing the application. Useful in many RenameProcs for indexing names. e.g. Index["foo", 4]="foo[4]" -- Start with an empty cell of appropriate interestRect (origin in 0,0) Κ„˜šœ™Jšœ Οmœ1™Jšœžœ2˜Jšžœžœžœ˜%Jšœ"˜"Jšœ+˜+J˜—Jšœ8˜8Jšœ˜—J˜Jš œžœ"˜;J˜JšœL™Lš œžœžœžœ žœžœžœ˜KJšœC˜CJšœ˜—J˜š œžœžœ˜2J˜—š œžœžœžœ"žœžœ žœ˜Œšœ˜šœ˜Jšœžœ&˜9—Jšœžœ˜0—šžœž˜Jšœ˜Jšœ˜Jšžœžœ˜—JšœMžœ0˜Jšžœ˜J˜—š  œžœžœ žœžœFžœžœ ˜¬Jšœ žœžœ˜!šŸ œ˜,Jšœžœ˜Jšœ*˜*šžœžœ1žœ˜Jšœžœ ž˜,KšœL˜LKšžœžœ˜—Jš œžœžœžœžœ˜2Jšœ žœr˜‚J˜—Jšœ˜J˜—Jšœžœžœ˜+Jš‘G™GJšžœžœžœ˜Jšœ0˜0šœ-žœ ž˜@Jšœ0˜0Jšœ0˜0Jšžœžœ˜—Jšœ˜J˜—Jšœžœžœ˜:J˜JšœA˜AJšœQ˜QJ˜JšœD˜DJšœT˜TK˜KšœFžœ4˜}KšœJžœ4˜KšœGžœ4˜~Kšœ>žœ5˜vJ˜Jšžœ˜—J˜—…— 8*φ