--File: IPToolBox.mesa
Last Edited by: Preas, August 2, 1986 10:10:25 am PDT
--Intro: Contains a lot of the highly commonly used procedures
DIRECTORY
CD,
D2Basic,
IO,
Misc,
IP,
IPOrient,
Rope,
RTStructure;
IPToolBox: CEDAR DEFINITIONS
IMPORTS IPOrient
= BEGIN
PhysicalPins: TYPE = LIST OF REF IP.PhysicalPinRep;
IntVector: TYPE = IP.IntVector;
IPPinsFromCDPins: PROC[cdObj: CD.Object] RETURNS [LIST OF REF IP.PinRep];
--Calls IPPinFromCDPin repeatedly.
--Note: order of pins will be reveresed
-- IPPinFromCDPin: PROC[cdPin: REF CDPins.Pin] RETURNS [REF IP.PinRep];
--Note: Order of physicalPins will be reversed
MakeIPPins: PROC[ipPins: LIST OF REF IP.PinRep, origin: IntVector ← [0, 0], coShape: REF IP.ShapeRep ← NIL, cutOff: NAT ← 0] RETURNS [LIST OF REF IP.PinRep];
--Basically deep copy ipPins with coordinates of copy recomputed wrt  
-- origin, if coShape # NIL. Side of all physical pins in iPins
-- will be assigned to the nearest side of the component when
-- distance of pin from side is less then cutOff, else it will be an interior pin.
-- If coShape = NIL then coordinates of (physical) pins is meaningless
MakeIPPinsFromStructure: PROC[object: RTStructure.Object, origin: IntVector ← [0, 0], coShape: REF IP.ShapeRep ← NIL, cutOff: NAT ← 0] RETURNS [LIST OF REF IP.PinRep];
--Basically deep copy ipPins with coordinates of copy recomputed wrt  
-- origin, if coShape # NIL. Side of all physical pins in iPins
-- will be assigned to the nearest side of the component when
-- distance of pin from side is less then cutOff, else it will be an interior pin.
-- If coShape = NIL then coordinates of (physical) pins is meaningless
--Shape manipulation routines
NearestSide: PROC [shape: REF IP.ShapeRep, point: IntVector, cutOff: NAT ← 0] RETURNS [inShape: BOOL, side: IP.PinSideType];
-- Compute the side closest to point. If (distance of point from closest side) > cutOff
-- then side = interior (even though point may actually lie outside shape.)
-- inShape = TRUE iff coord actually lies on the boundary or within shape
DistFromSide: PROC[shape: REF IP.ShapeRep, point: IntVector, side: IP.PinSideType] RETURNS [INT];
-- returns perpendicular distance of point from side
-- returns LAST[INT] for pathological/meaningless cases.
GetCorner: PROC [shape: IP.ShapeRep, corner: IP.CornerTypes] RETURNS [REF IP.NatVector];
GetBRect: PROC[shape: REF IP.ShapeRep, origin: IntVector ← [0, 0]] RETURNS [Misc.Rect];
GetCornerRect: PROC[shape: REF IP.ShapeRep, corner: IP.CornerTypes, origin: IntVector ← [0, 0], crop: INT ← 1] RETURNS [Misc.Rect];
GetCornerRects: PROC[shape: REF IP.ShapeRep, origin: IntVector ← [0, 0], crop: INT ← 1] RETURNS [sw, se, ne, nw: Misc.Rect];
CopyShape: PROC[oShape: REF IP.ShapeRep, orient: IP.Orientation] RETURNS [nShape: REF IP.ShapeRep];
--doesn't modify oShape. nShape and oShape shares all REF IP.NatVector
-- For examples, see IPCoTabImpl
--Copy oShape and apply OrientShape
OrientShape: PROC[shape: REF IP.ShapeRep, orient: IP.Orientation];
--modifies shape
MirrorXShape: PROC[shape: REF IP.ShapeRep];
Rotate90Shape: PROC [shape: REF IP.ShapeRep, numberOfRot: INT ← 1];
--Some primitives for reading data from stream
ParseError: ERROR [reason: ATOM, at: REF];
GetIdRope: PROC[stream: IO.STREAM] RETURNS [Rope.ROPE];
--read <Id>: from stream into "Id"
-- ! Raise ParseError[$syntaxError, char];
GetIdAtom: PROC[stream: IO.STREAM] RETURNS [ATOM];
--read <Id>: from stream into $Id
-- ! Raise ParseError[$syntaxError, char];
EnterBlock: PROC [stream: IO.STREAM];
--Remove { from stream. If char read is not '{ then
--! Raise ParseError[$noBegn, char];
ExitBlock: PROC [stream: IO.STREAM] RETURNS [BOOLTRUE];
-- Return TRUE iff first non-blank char = }
RemoveBlock: PROC [stream: IO.STREAM];
--Remove {<any number/nesting of blocks> } from stream
GetNatVector: PROC[stream: IO.STREAM] RETURNS [REF IP.NatVector];
--Read (<x: NAT> , <y: NAT>)
GetIntVector: PROC[stream: IO.STREAM] RETURNS [REF IntVector];
--Read (<x: INT> , <y: INT>)
GetShape: PROC[stream: IO.STREAM] RETURNS [REF IP.ShapeRep];
--Read {(<xDim> <yDim>) sw: (<x1 , <y1>) ...<xy>: (<xx>, <yy>) }
-- where xy IN {sw, se, ne, nw} and xx, yy are NAT's
--! Raise ParseError[$badToken, $<token>];
GetPhysicalPins: PROC[stream: IO.STREAM] RETURNS [PhysicalPins];
--Some high level stream output routines:
PutShape: PROC[stream: IO.STREAM, shape: REF IP.ShapeRep];
--inverse of GetShape
PutPhysicalPins: PROC[stream: IO.STREAM, physicalPins: PhysicalPins];
-- inverse of GetPhysicalPins
--Physical pins manipulation procedures
OrientPhysicalPins: PROC [phyPins: PhysicalPins, cellDim: IP.NatVector, cellOrient: IP.Orientation, cellOrigin: IntVector ← [0, 0]];
MirrorXPhysicalPins: PROC [phyPins: PhysicalPins, cellDim: IP.NatVector, cellOrigin: IntVector ← [0, 0]];
Rotate90PhysicalPins: PROC [phyPins: PhysicalPins, cellDim: IP.NatVector, numberOfRot: INT ← 1, cellOrigin: IntVector ← [0, 0]];
OrientPinSide: PROC[side: IP.PinSideType, orient: IP.Orientation] RETURNS [IP.PinSideType];
MirrorXPinSide: PROC[side: IP.PinSideType] RETURNS [IP.PinSideType];
Rotate90PinSide: PROC [side: IP.PinSideType, numberOfRot: INT ← 1] RETURNS [IP.PinSideType];
--Some commonly used operation on Component
CoChannels: PROC[co: REF IP.ComponentRep, action: PROC[REF IP.ChannelRep] RETURNS [quit: BOOL]];
--enumerate channels in co in the following order:
-- (i) prinChannels: south, east, north, west, followed by
-- (2) cornerChannels: sw.hor, sw.ver, se.hor, ...., nw.hor, hw.ver
GetCoDim: PROC[co: REF IP.ComponentRep] RETURNS[x, y: NAT] = INLINE {
IF IPOrient.IncludesOddRot90[co.orient]
THEN [y, x] ← co.shape.dim^
ELSE [x, y] ← co.shape.dim^;
}; --GetCoDim
GetCoOrigin: PROC[co: REF IP.ComponentRep] RETURNS[IntVector] = INLINE {RETURN[co.origin]};
ConstructFileName: PROC[defaultDir, inputFile, defaultExt: Rope.ROPE]
RETURNS[fullName: Rope.ROPE];
END.