LichenFlattenning.Mesa
Last tweaked by Mike Spreitzer on May 5, 1987 11:12:44 am PDT
DIRECTORY Asserting, LichenDataOps, LichenDataStructure, LichenSetTheory, LichenTransforms, Rope;
LichenFlattenning: CEDAR PROGRAM
IMPORTS Asserting, LichenDataOps, LichenDataStructure, LichenSetTheory, Rope
EXPORTS LichenTransforms
=
BEGIN OPEN LichenDataOps, LichenDataStructure, LichenSetTheory;
ExpandVertex: PUBLIC PROC [child: CellInstance] RETURNS [roleToSib: RefSeq--role b sibling: CellInstance--] ~ {
ct: CellType ~ child.type;
parent: CellType ~ child.containingCT;
u: Unorganized ~ ct.asUnorganized;
roles: INT ~ u.containedInstances.Size[];
promote: Mapper--part of ct b part of parent-- ~ CreateHashMapper[];
SetPromotion: PROC [inner, outer: Wire] ~ {
IF inner=NIL OR outer=NIL THEN ERROR;
IF NOT promote.PutMapping[inner, outer] THEN 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;
};
NotePorting: PROC [p: Port, w: Wire] ~ {
SetPromotion[p.wire, w];
};
role: INT ← 0;
MoveCell: PROC [ra: REF ANY] ~ {
ci: CellInstance ~ NARROW[ra];
sib: CellInstance ~ Instantiate[ci.type, parent, CrossNames[child.other, ci.other]];
GetPromotion: PROC [vi, uvo: Vertex, port: Port] RETURNS [vo: Vertex] ~ {
IF (vo ← NARROW[promote.Map[vi]])#NIL THEN RETURN;
WITH vi SELECT FROM
wi: Wire => {
uwo: Wire ~ WITH uvo SELECT FROM x: Wire => x, ENDCASE => NIL;
wo: Wire ~ vo ← CreateWire[parent, uwo, IF uwo#NIL THEN Asserting.AssertionsAbout[nameReln, vi.other] ELSE CrossNames[child.other, vi.other]];
IF NOT promote.PutMapping[wi, wo] THEN ERROR;
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, Asserting.AssertionsAbout[nameReln, vi.other]];
PromoteIM: PROC [q: Port, wi: Vertex] ~ {[] ← GetPromotion[wi, io, q]};
IF NOT promote.PutMapping[ii, io] THEN ERROR;
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[role] ← sib;
EnumerateImmediateConnections[ci, PromoteEdge];
role ← role+1;
};
roleToSib ← CreateRefSeq[roles];
EnumerateTopConnections[child, NotePorting];
u.containedInstances.Enumerate[MoveCell];
DeleteVertex[child];
};
CrossNames: PROC [outer, inner: Assertions] RETURNS [crossed: Assertions] ~ {
Crossit: PROC [a1: Assertion] ~ {
outerName: ROPE ~ NARROW[Asserting.TermOf[a1]];
Finish: PROC [a2: Assertion] ~ {
innerName: ROPE ~ NARROW[Asserting.TermOf[a2]];
name: ROPE ~ outerName.Cat["/", innerName];
crossed ← Asserting.Assert1[nameReln, name, crossed];
};
Asserting.EnumerateAssertionsAbout[nameReln, inner, Finish];
};
crossed ← NIL;
Asserting.EnumerateAssertionsAbout[nameReln, outer, Crossit];
crossed ← crossed;
};
Flatten: PUBLIC PROC [root: CellType, expand: Filter--of CellInstance--] ~ {
action: BOOLTRUE;
MaybeExpand: PROC [ra: REF ANY] ~ {
ci: CellInstance ~ NARROW[ra];
IF expand.HasMember[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.