PWCLCoreFlatExtrasImpl.mesa
Barth, February 18, 1987 8:29:51 pm PST
Last tweaked by Mike Spreitzer on February 16, 1988 1:22:48 pm PST
DIRECTORY BitOps, Core, CoreClasses, CoreFlat, CoreOps, IO, PWCLCoreFlatExtras, RefTab, StructuredStreams, UnparserBuffer;
PWCLCoreFlatExtrasImpl: CEDAR PROGRAM
IMPORTS BitOps, CoreClasses, CoreFlat, CoreOps, IO, PWCLCoreFlatExtras, RefTab, StructuredStreams, UnparserBuffer
EXPORTS PWCLCoreFlatExtras
=
BEGIN OPEN CC: CoreClasses, CoreFlat, CO: CoreOps, PWCLCoreFlatExtras, SS: StructuredStreams, UB: UnparserBuffer;
SetCut: PUBLIC PROC [cs: CutSet] RETURNS [Cut] = {
RETURN [[IsCutSetMember, cs]];
};
IsCutSetMember: PROC [cutData: REF ANY, root: CellType, cellType: CellType, flatCell: FlatCellTypeRec, instance: CellInstance] RETURNS [BOOL] = {RETURN [CutSetMember[root, flatCell, NARROW[cutData]]]};
leaves: PUBLIC Cut ← [IsLeaf, NIL];
IsLeaf: PROC [cutData: REF ANY, root: CellType, cellType: CellType, flatCell: FlatCellTypeRec, instance: CellInstance] RETURNS [BOOL] --CutMembershipTester-- = {
cellType ← CO.ToBasic[cellType];
RETURN [cellType.class # CC.recordCellClass AND cellType.class.recast = NIL];
};
PrintObject: PROC [to: IO.STREAM, PrintIt: PROC, cond: UB.BreakCondition ← width, sep: ROPENIL] = {
SS.Bp[to, cond, step, sep];
SS.Begin[to];
PrintIt[!UNWIND => SS.End[to]];
SS.End[to];
};
step: NAT ← 3;
FlatPrint: PUBLIC PROC
[
root: CellType,
filter: Filter ← NIL,
to: IO.STREAM,
Annotator: PROC [subject: Descendant, to: IO.STREAM] ← NIL,
leaves: Cut
]
= {
firstCell: BOOLTRUE;
Flatten: PROC [cell: Core.CellType, target: FlatCellTypeRec ← allFlatCells, flatCell: FlatCellTypeRec ← [], instance: CellInstance ← NIL, index: NATLAST[NAT], parent: Core.CellType ← NIL, flatParent: FlatCellTypeRec ← [], data: REF ANYNIL, bindings: Bindings ← NIL] --BoundFlatCellProc-- = {
flatten: BOOL = NOT leaves.Includes[root, cell, flatCell, instance];
IF flatten THEN {
NextBoundCellType[cell, target, flatCell, instance, index, parent, flatParent, data, bindings, Flatten];
}
ELSE {
PrintCell: PROC = {
firstBind: BOOLTRUE;
PrintBinding: PROC [actualWire, publicWire: Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWirePairProc-- = {
publicName: ROPE = CO.GetFullWireName[cell.public, publicWire];
caw: FlatWire = NARROW[bindings.Fetch[publicWire].val];
actualName: ROPE = WirePathRope[root, caw^];
PrintBinding: PROC = {
to.PutRope[publicName];
to.PutRope[": "];
to.PutRope[actualName];
IF Annotator # NIL THEN Annotator[caw, to];
};
subWires ← CO.GetShortWireName[publicWire]=NIL;
IF NOT subWires THEN {
IF firstBind THEN firstBind ← FALSE ELSE to.PutRope[", "];
PrintObject[to, PrintBinding, width];
};
};
to.PutRope[InstancePathRope[root, flatCell.path]];
IF Annotator # NIL THEN Annotator[NEW [FlatCellTypeRec ← flatCell], to];
to.PutRope["["];
[] ← CO.VisitBindingSeq[instance.actual, cell.public, PrintBinding];
to.PutRope["]"];
};
IF filter = NIL OR filter[cell, flatCell, instance, bindings] THEN {
IF firstCell THEN firstCell ← FALSE ELSE to.PutRope[";"];
PrintObject[to, PrintCell, united, " "];
};
};
};
IF NOT SS.IsAnSS[to] THEN to ← SS.Create[UB.NewInittedHandle[[margin: 50, output: [stream[to]]]]];
to.PutRope["{"];
Flatten[root, allFlatCells, [], NIL, LAST[NAT], NIL, [], NIL, InitialBindingTable[root]];
to.PutRope["}"];
};
PrintNeighborhood: PUBLIC PROC
[
root: CellType,
of: DescendantListList,
to: IO.STREAM,
Annotator: PROC [subject: Descendant, to: IO.STREAM] ← NIL,
leaves: Cut
]
= {
WithFilter: PROC [filter: Filter] ~ {
FlatPrint[root, filter, to, Annotator, leaves];
};
MakeNeighborhoodFilter[of, WithFilter];
root ← root;
};
MakeNeighborhoodFilter: PUBLIC PROC [of: DescendantListList, Consume: PROC [Filter]] ~ {
wires: RefTab.Ref = RefTab.Create[hash: FlatWireHash, equal: FlatWireEqual];
cells: RefTab.Ref = RefTab.Create[hash: HashIP, equal: IPEqual];
filter: Filter = {
FindSubject: PROC [wire: Core.Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWireProc-- = {
caw: FlatWire = NARROW[bindings.Fetch[wire].val];
quit ← wires.Fetch[caw].found;
};
RETURN [cells.Fetch[NEW [InstancePath ← flatCell.path]].found OR CO.VisitWireSeq[cellType.public, FindSubject]];
};
FOR dll: DescendantListList ← of, dll.rest WHILE dll # NIL DO
FOR ds: DescendantList ← dll.first, ds.rest WHILE ds # NIL DO
WITH ds.first SELECT FROM
x: FlatWire => IF NOT wires.Insert[x, $T] THEN ERROR;
x: REF InstancePath => IF NOT cells.Insert[x, $T] THEN ERROR;
x: FlatCellType => IF NOT cells.Insert[NEW [InstancePath ← x.path], $T] THEN ERROR;
ENDCASE => ERROR;
ENDLOOP;
ENDLOOP;
Consume[filter];
of ← of;
};
HashIP: PROC [ra: REF ANY] RETURNS [hash: CARDINAL] = {
hash ← WITH ra SELECT FROM
x: REF InstancePath => FlatCellTypeHashRec[[x^]],
ENDCASE => ERROR;
};
IPEqual: PROC [key1, key2: REF ANY] RETURNS [equal: BOOL] = {
equal ← WITH key1 SELECT FROM
x: REF InstancePath => WITH key2 SELECT FROM
y: REF InstancePath => x^.InstancePathEqual[y^],
ENDCASE => ERROR,
ENDCASE => ERROR;
};
LowerInstancePath: PUBLIC PROC [path, by: InstancePath] RETURNS [lower: InstancePath] ~ {
length: NATURAL ~ NATURAL[path.length] + by.length;
lower ← [
length: length,
bits: LOOPHOLE[BitOps.QOR[
LOOPHOLE[by.bits],
BitOps.QShift[LOOPHOLE[path.bits], -by.length]
]]];
RETURN};
LowerFlatCell: PUBLIC PROC [fc: FlatCellTypeRec, by: FlatCellTypeRec] RETURNS [lower: FlatCellTypeRec] ~ {
lower ← [
path: LowerInstancePath[fc.path, by.path],
recastCount: IF fc.path.length#0 THEN fc.recastCount ELSE by.recastCount];
RETURN};
LowerFlatWire: PUBLIC PROC [fw: FlatWireRec, by: FlatCellTypeRec] RETURNS [lower: FlatWireRec] ~ {
lower ← fw;
lower.flatCell ← LowerFlatCell[lower.flatCell, by];
RETURN};
END.