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:
ROPE ←
NIL] = {
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: BOOL ← TRUE;
Flatten:
PROC [cell: Core.CellType, target: FlatCellTypeRec ← allFlatCells, flatCell: FlatCellTypeRec ← [], instance: CellInstance ←
NIL, index:
NAT ←
LAST[
NAT], parent: Core.CellType ←
NIL, flatParent: FlatCellTypeRec ← [], data:
REF
ANY ←
NIL, 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: BOOL ← TRUE;
PrintBinding:
PROC [actualWire, publicWire: Wire]
RETURNS [subWires:
BOOL ←
TRUE, quit:
BOOL ←
FALSE]
--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:
BOOL ←
TRUE, quit:
BOOL ←
FALSE]
--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:
BOOL ←
TRUE, quit:
BOOL ←
FALSE]
--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:
BOOL ←
TRUE, quit:
BOOL ←
FALSE]
--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.