LichenFlattenning.Mesa
Last tweaked by Mike Spreitzer on August 7, 1987 5:05:41 pm PDT
DIRECTORY LichenCollections, LichenDataOps, LichenDataStructure, LichenIntFunctions, LichenPairCollections, LichenTransforms, List;
LichenFlattenning:
CEDAR
PROGRAM
IMPORTS LichenCollections, LichenDataOps, LichenDataStructure, LichenIntFunctions, LichenPairCollections, List
EXPORTS LichenTransforms
=
BEGIN OPEN LichenDataOps, LichenDataStructure, Colls:LichenCollections, PairColls:LichenPairCollections, IntFns:LichenIntFunctions;
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[];
promote: VarFunction--part of ct b part of parent-- ~ PairColls.CreateHashFn[];
SetPromotion:
PROC [inner, outer: Wire] ~ {
IF inner=NIL OR outer=NIL THEN ERROR;
IF NOT promote.Store[[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];
};
MoveCell:
PROC [ra:
REF
ANY] ~ {
ci: CellInstance ~ NARROW[ra];
sib: CellInstance ~ Instantiate[ci.type, parent, CrossNames[child, ci]];
GetPromotion:
PROC [vi, uvo: Vertex, port: Port]
RETURNS [vo: Vertex] ~ {
IF (vo ← NARROW[promote.Apply[vi].DVal])#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 vi.VertexNames.Copy.data ELSE CrossNames[child, vi]];
IF NOT promote.Store[[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, vi.VertexNames.Copy.data];
PromoteIM: PROC [q: Port, wi: Vertex] ~ {[] ← GetPromotion[wi, io, q]};
IF NOT promote.Store[[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.Append[sib];
EnumerateImmediateConnections[ci, PromoteEdge];
};
roleToSib ← CreateSeq[oneToOne: TRUE];
EnumerateTopConnections[child, NotePorting];
u.containedInstances.Enumerate[MoveCell];
DeleteVertex[child];
roleToSib ← roleToSib.Freeze;
};
CrossNames:
PROC [outer, inner: Vertex]
RETURNS [ListData] ~ {
crossed: Set--of SteppyName-- ~ [listClass, CreateSteppyNames[]];
Crossit:
PROC [v1:
REF
ANY] ~ {
outerName: SteppyName ~ NARROW[v1];
Finish:
PROC [v2:
REF
ANY] ~ {
innerName: SteppyName ~ NARROW[v2];
name: SteppyName ~ List.Append[outerName, innerName];
new: BOOL ~ crossed.AddElt[name];
RETURN};
inner.VertexNames.Enumerate[Finish];
RETURN};
outer.VertexNames.Enumerate[Crossit];
RETURN [crossed.data]};
Flatten:
PUBLIC
PROC [root: CellType, expand: ConstFilter
--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;
};
END.