PWCLCoreFlatExtrasImpl.mesa
Mike Spreitzer March 5, 1987 4:31:03 pm PST
Barth, February 18, 1987 8:29:51 pm PST
DIRECTORY Core, CoreClasses, CoreFlat, CoreOps, HashTable, IO, PWCLCoreFlatExtras, StructuredStreams, UnparserBuffer;
PWCLCoreFlatExtrasImpl: CEDAR PROGRAM
IMPORTS CoreClasses, CoreFlat, CoreOps, HashTable, IO, PWCLCoreFlatExtras, 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].value];
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["["];
[] ← 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: HashTable.Table = HashTable.Create[hash: FlatWireHash, equal: FlatWireEqual];
cells: HashTable.Table = HashTable.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].value];
quit ← wires.Fetch[caw].found;
};
RETURN [cells.Fetch[NEW [InstancePath ← flatCell.path]].found OR 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 [r1, r2: REF ANY] RETURNS [equal: BOOL] = {
equal ← WITH r1 SELECT FROM
x: REF InstancePath => WITH r2 SELECT FROM
y: REF InstancePath => x^.InstancePathEqual[y^],
ENDCASE => ERROR,
ENDCASE => ERROR;
};
InitialBindingTable: PUBLIC PROC [root: CellType] RETURNS [bindings: Bindings] = {
Bind: PROC [wire: Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWireProc-- = {
IF subWires ← (NOT bindings.Fetch[wire].found) THEN {
fw: FlatWire = NEW [FlatWireRec ← [wireRoot: public, wire: wire]];
IF NOT bindings.Insert[wire, fw] THEN ERROR;
};
};
bindings ← HashTable.Create[];
IF VisitWireSeq[root.public, Bind] THEN ERROR;
bindings ← bindings;
};
VisitWireSeq: PUBLIC PROC [seq: Wire, eachWire: CO.EachWireProc] RETURNS [quit: BOOL] = {
FOR i: NAT IN [0 .. seq.size) DO
IF CO.VisitWire[seq[i], eachWire] THEN RETURN [TRUE];
ENDLOOP;
quit ← FALSE;
};
VisitBindingSeq: PUBLIC PROC [actual, public: Wire, eachWirePair: CO.EachWirePairProc] RETURNS [quit: BOOL] = {
IF actual.size#public.size THEN RETURN [TRUE]; -- wires do not conform
FOR i: NAT IN [0 .. actual.size) DO
IF CO.VisitBinding[actual[i], public[i], eachWirePair] THEN RETURN [TRUE];
ENDLOOP;
quit ← FALSE;
};
CorrectConform: PUBLIC PROC [actual, public: Wire] RETURNS [BOOL] = {
p2a: HashTable.Table = HashTable.Create[];
EachWirePair: PROC [actualWire, publicWire: Wire] RETURNS [subWires: BOOLTRUE, quit: BOOLFALSE] --CO.EachWirePairProc-- = {
found: BOOL;
ra: REF ANY;
[found, ra] ← p2a.Fetch[publicWire];
subWires ← NOT found;
IF NOT found THEN {
IF NOT p2a.Insert[publicWire, actualWire] THEN ERROR;
}
ELSE IF ra # actualWire THEN quit ← TRUE;
};
RETURN [NOT VisitBindingSeq[actual, public, EachWirePair]];
};
END.