LichenFlattenning:
CEDAR
PROGRAM
IMPORTS Asserting, LichenDataOps, LichenDataStructure, LichenSetTheory, Rope
EXPORTS LichenTransforms
=
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: BOOL ← TRUE;
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;
};