LichenFlattenning.Mesa
Last tweaked by Mike Spreitzer on February 3, 1988 3:40:53 pm PST
DIRECTORY AbSets, BiRels, IntStuff, LichenDataOps, LichenDataStructure, LichenTransforms;
LichenFlattenning: CEDAR PROGRAM
IMPORTS AbSets, BiRels, IntStuff, LichenDataOps, LichenDataStructure
EXPORTS LichenTransforms, LichenDataOps
=
BEGIN OPEN LichenDataOps, LichenDataStructure, Sets:AbSets;
ExpandVertex: PUBLIC PROC [child: CellInstance] RETURNS [roleToSib: Seq--role é sibling: CellInstance--] ~ {
ct: CellType ~ child.type;
parent: CellType ~ child.containingCT;
u: Unorganized ~ ct.asUnorganized;
roles: INT ~ u.containedInstances.Size[].EN;
promote: VarFunction--part of ct b part of parent-- ~ BiRels.CreateHashFn[];
SetPromotion: PROC [inner, outer: Wire] ~ {
IF inner=NIL OR outer=NIL THEN ERROR;
SELECT promote.AddAA[inner, outer].had[leftToRight] FROM
same => RETURN;
none => NULL;
different => ERROR;
ENDCASE => ERROR;
inner ← inner.FirstChildWire[];
outer ← outer.FirstChildWire[];
WHILE inner#NIL AND outer#NIL DO
SetPromotion[inner, outer];
inner ← inner.NextChildWire[];
outer ← outer.NextChildWire[];
ENDLOOP;
IF inner#NIL OR outer#NIL THEN ERROR;
RETURN};
NotePorting: PROC [p: Port, w: Wire] ~ {SetPromotion[p.wire, w]};
MoveCell: PROC [ra: Sets.Value] ~ {
ci: CellInstance ~ NARROW[ra.VA];
sib: CellInstance ~ Instantiate[ci.type, parent, CrossNames[child.VertexNames, ci.VertexNames]];
GetPromotion: PROC [vi, uvo: Vertex, port: Port] RETURNS [vo: Vertex] ~ {
IF (vo ← NARROW[promote.ApplyA[vi].MDA])#NIL THEN RETURN;
WITH vi SELECT FROM
wi: Wire => {ERROR nyet--this is bugiferous; an unexported wire can't necessarily be created outside, because its children may already have commitments as components of other wires--;{
uwo: Wire ~ WITH uvo SELECT FROM x: Wire => x, ENDCASE => NIL;
wo: Wire ~ vo ← CreateWire[parent, uwo, IF uwo#NIL THEN [vi.VertexNames.Copy.data.VA] ELSE CrossNames[child.VertexNames, vi.VertexNames]];
promote.AddNewAA[wi, wo];
WITH uvo SELECT FROM
x: Intermediary => AddEdge[[x, wo], port];
ENDCASE => NULL;
FOR cwi: Wire ← wi.FirstChildWire, cwi.NextChildWire WHILE cwi # NIL DO [] ← GetPromotion[cwi, wo, NIL] ENDLOOP;
}};
ii: Intermediary => {
io: Intermediary ~ vo ← CreateIntermediary[uvo, wireward, parent, port, [vi.VertexNames.Copy.data.VA]];
PromoteIM: PROC [q: Port, wi: Vertex] ~ {[] ← GetPromotion[wi, io, q]};
promote.AddNewAA[ii, io];
EnumerateImmediateConnections[ii, PromoteIM, [FALSE, TRUE]];
};
cii: CellInstance => ERROR;
ENDCASE => ERROR;
IF vo=NIL THEN ERROR;
};
PromoteEdge: PROC [p: Port, v: Vertex] ~ {
w: Vertex ~ GetPromotion[v, sib, p];
AddEdge[[sib, w], p];
};
roleToSib.AppendA[sib];
EnumerateImmediateConnections[ci, PromoteEdge];
};
roleToSib ← CreateSeq[oneToOne: TRUE];
EnumerateTopConnections[child, NotePorting];
u.containedInstances.Enumerate[MoveCell];
DeleteVertex[child];
roleToSib ← roleToSib.Freeze;
};
CrossNames: PUBLIC PROC [outer, inner: Set--of SteppyName--] RETURNS [ListData] ~ {
crossed: Set--of SteppyName-- ~ Setify[CreateSteppyNames[]];
Crossit: PROC [v1: Sets.Value] ~ {
innerName: SteppyName ~ VSn[v1];
glob: BOOLFALSE;
Finish: PROC [v2: Sets.Value] ~ {
outerName: SteppyName ~ VSn[v2];
name: SteppyName ~ SNCat[outerName, innerName];
new: BOOL ~ crossed.AddElt[SnV[name]];
RETURN};
IF innerName.grade.global THEN {[] ← crossed.AddElt[SnV[innerName]]; RETURN};
outer.Enumerate[Finish];
RETURN};
inner.Enumerate[Crossit];
RETURN [[crossed.data.VA]]};
Flatten: PUBLIC PROC [root: CellType, expand: ConstFilter--of CellInstance--] ~ {
action: BOOLTRUE;
MaybeExpand: PROC [ra: Sets.Value] ~ {
ci: CellInstance ~ NARROW[ra.VA];
IF expand.HasMemA[ci] THEN {
action ← TRUE;
[] ← ExpandVertex[ci];
};
};
u: Unorganized ~ root.asUnorganized;
IF u=NIL THEN ERROR;
WHILE action DO
action ← FALSE;
u.containedInstances.Enumerate[MaybeExpand];
ENDLOOP;
root ← root;
};
END.