CompareSpecialTransforms.Mesa
Last Edited by: Spreitzer, March 9, 1985 5:35:01 pm PST
DIRECTORY Basics, CompareDataStructure, CompareOps, CompareTransforms, CompareTransformsPrivate, DFUtilities, FS, IO, List, OrderedSymbolTableRef, RefTab, Rope, TextReplace, ViewerIO;
CompareSpecialTransforms: CEDAR PROGRAM
IMPORTS CompareOps, CompareTransforms, CompareTransformsPrivate, OrderedSymbolTableRef, RefTab, Rope, TextReplace
EXPORTS CompareTransforms, CompareOps, CompareTransformsPrivate =
BEGIN OPEN CompareDataStructure, CompareTransforms, CompareOps, CompareTransformsPrivate;
Special: TYPE = REF SpecialRep;
SpecialRep: TYPE = RECORD [ra: REF ANY];
all: PUBLIC REF ANYNEW [SpecialRep ← [$all]];
ExpandVertex: PUBLIC PROC [design: Design, childA: REF ANY] =
BEGIN
child: Vertex ← ToVertex[design, childA];
parentType: CellType ← child.parent;
childType: CellType ← child.type;
[] ← ExpandVertexWork[child];
NoteChange[parentType];
CheckType[parentType, ignore, ignore];
CheckType[childType, ignore, ignore];
END;
igig: LORALIST[$ignore, $ignore];
ExpandChildren: PUBLIC PROC [design: Design, parentTypeA: REF ANY, flatten: BOOLFALSE] =
BEGIN
parentType: CellType ← ToType[design, parentTypeA];
childTypes: RefTab.Ref ← RefTab.Create[];
children: RefTab.Ref ← RefTab.Create[];
NoteOldChild: PROC [ra: REF ANY] RETURNS [stop: BOOL] = {
v: Vertex ← NARROW[AntiAlias[ra]];
[] ← children.Insert[v, $T];
stop ← FALSE};
ExpandOldChild: PROC [key, val: REF ANY] RETURNS [quit: BOOL] = {
v: Vertex ← NARROW[key];
quit ← FALSE;
SELECT v.class FROM
cell => {
childType: CellType ← v.type;
EnsureParts[childType];
IF ExpansionKnown[childType] THEN {
sibs: VertexList ← ExpandVertexWork[v];
[] ← childTypes.Insert[childType, igig];
IF flatten THEN {
FOR sibs ← sibs, sibs.rest WHILE sibs # NIL DO
[] ← ExpandOldChild[sibs.first, NIL];
ENDLOOP;
};
};
};
net => NULL;
ENDCASE => ERROR;
};
EnsureParts[parentType];
IF NOT ExpansionKnown[parentType] THEN ERROR;
parentType.parts.EnumerateIncreasing[NoteOldChild];
[] ← children.Pairs[ExpandOldChild];
NoteChange[parentType];
CheckType[parentType, ignore, ignore];
[] ← childTypes.Pairs[CheckPerType];
END;
ExpandVertexWork: PROC [childCell: Vertex] RETURNS [newSibs: VertexList] =
BEGIN
parentType: CellType ← childCell.parent;
childType: CellType ← childCell.type;
NILEquiv: PROC [ra: REF ANY] RETURNS [stop: BOOL] = {
v: Vertex ← NARROW[AntiAlias[ra]];
stop ← FALSE;
v.equiv ← NIL};
SetPortedNetEquivs: PROC = {
innerEdge: Edge ← childType.mirror.firstEdge;
outerEdge: Edge ← childCell.firstEdge;
FOR portIndex: NAT IN [0 .. childType.ports.length) DO
IF innerEdge.portIndex # portIndex THEN ERROR;
IF outerEdge.portIndex # portIndex THEN ERROR;
IF innerEdge.sides[cell].v # childType.mirror THEN ERROR;
IF outerEdge.sides[cell].v # childCell THEN ERROR;
innerEdge.sides[net].v.equiv ← outerEdge.sides[net].v;
innerEdge ← innerEdge.sides[cell].next;
outerEdge ← outerEdge.sides[cell].next;
ENDLOOP;
IF innerEdge # NIL OR outerEdge # NIL THEN ERROR};
Copy: PROC [ra: REF ANY] RETURNS [stop: BOOL] = {
v: Vertex ← NARROW[AntiAlias[ra]];
stop ← FALSE;
[] ← CopyWork[v]};
CopyWork: PROC [gc: Vertex] RETURNS [newChild: Vertex] = {
IF gc.equiv # NIL THEN RETURN [gc.equiv];
gc.equiv ← newChild ← NEW [VertexRep ← [names: JoinNames[childCell.names, gc.names], type: gc.type, parent: parentType, class: gc.class, other: gc.other]];
AddVertex[newChild];
IF newChild.class = net THEN RETURN;
LinkInstance[newChild];
FOR oldE: Edge ← gc.firstEdge, oldE.sides[cell].next WHILE oldE # NIL DO
newNet: Vertex ← CopyWork[oldE.sides[net].v];
IF oldE.sides[cell].v # gc THEN ERROR;
AddEdge[newChild, newNet];
ENDLOOP;
newSibs ← CONS[newChild, newSibs];
};
newSibs ← NIL;
EnsureParts[childType];
IF NOT ExpansionKnown[childType] THEN ERROR;
childType.mirror.equiv ← NIL;
childType.parts.EnumerateIncreasing[NILEquiv];
childType.mirror.equiv ← childCell;
SetPortedNetEquivs[];
childType.parts.EnumerateIncreasing[Copy];
DeleteVertex[childCell];
childType.mirror.equiv ← NIL;
childType.parts.EnumerateIncreasing[NILEquiv];
CheckType[parentType, ignore, ignore, TRUE];
END;
Group: PUBLIC PROC [design: Design, parentTypeA, childrenA: REF ANY, childNames, childTypeNames: Names, newPortNamer: NewPortNamer] RETURNS [newChild: Vertex, newGrandchildren: VertexS] =
BEGIN
parentType: CellType ← ToType[design, parentTypeA];
oldChildren: VertexS ← ToVertexS[parentType, childrenA];
newChildType: CellType ← NewEmptyCellType[design, childTypeNames];
newChild ← CreateEmpty[design: design, childNames: childNames, childType: newChildType, parentType: parentType];
[gcs: newGrandchildren] ← LowerChildren[design: design, childTypeA: newChildType, gcNamesl: ListNames[oldChildren], sibber: OneMap[newChild, oldChildren], newPortNamer: newPortNamer];
END;
NameNewPortFromAnyOldPort: PUBLIC PROC
[
data: REF ANY, first: BOOL, ct: CellType,
ports: PortS, portIndex: PortIndex,
oldNet: Vertex, oldConnections: EdgeList]
RETURNS [names: Names, equivClass: EquivClass] =
{
from: Vertex ← oldConnections.first.sides[cell].v;
index: PortIndex ← oldConnections.first.portIndex;
names ← from.type.ports[index].names;
equivClass ← from.type.ports[index].equivClass};
NameNewPortFromAnyOldPortInstance: PUBLIC PROC
[
data: REF ANY, first: BOOL, ct: CellType,
ports: PortS, portIndex: PortIndex,
oldNet: Vertex, oldConnections: EdgeList]
RETURNS [names: Names, equivClass: EquivClass] =
{
from: Vertex ← oldConnections.first.sides[cell].v;
index: PortIndex ← oldConnections.first.portIndex;
names ← from.type.ports[index].names;
IF NOT first THEN names ← JoinNames[from.names, names, FALSE];
equivClass ← from.type.ports[index].equivClass;
IF NOT first THEN equivClass ← QualifyEquivClass[from.names, equivClass, FALSE];
};
NameNewPortFromOldNet: PUBLIC PROC
[
data: REF ANY, first: BOOL, ct: CellType,
ports: PortS, portIndex: PortIndex,
oldNet: Vertex, oldConnections: EdgeList]
RETURNS [names: Names, equivClass: EquivClass] =
{
names ← oldNet.names;
equivClass ← implicitClass};
DontNameNewPort: PUBLIC PROC
[
data: REF ANY, first: BOOL, ct: CellType,
ports: PortS, portIndex: PortIndex,
oldNet: Vertex, oldConnections: EdgeList]
RETURNS [names: Names, equivClass: EquivClass] =
{ERROR};
FavorSimpleNames: PUBLIC PROC [data: REF ANY, oldNames: Names, oldEquiv: EquivClass] RETURNS [newNames: Names, newEquiv: EquivClass] = {
newNames ← oldNames;
newEquiv ← oldEquiv;
IF newNames.progged = NIL OR newNames.progged.rest = NIL THEN RETURN;
FOR rl: RopeList ← newNames.progged, rl.rest WHILE rl # NIL DO
class: CARDINAL ← 0;
seeingGen: BOOLFALSE;
For detecting name segments matching {n|C|Q}{0..9}+
lastWasGen, lastWasDash, lastWasAlpha, nextLastWasAlpha: BOOLFALSE;
FOR i: INT IN [0 .. rl.first.Length[]) DO
c: CHAR ← rl.first.Fetch[i];
SELECT c FROM
'., '- => IF seeingGen THEN class ← class + 1;
ENDCASE;
SELECT c FROM
'. => {class ← class + 1; seeingGen ← FALSE};
IN ['0 .. '9] => {
IF lastWasDash THEN {class ← class + 1; IF seeingGen THEN ERROR};
IF lastWasGen AND NOT nextLastWasAlpha THEN seeingGen ← TRUE;
};
ENDCASE => seeingGen ← FALSE;
nextLastWasAlpha ← lastWasAlpha;
SELECT c FROM
'., '- => lastWasAlpha ← FALSE;
ENDCASE => lastWasAlpha ← TRUE;
SELECT c FROM
'n, 'C, 'Q => {lastWasGen ← TRUE; lastWasDash ← FALSE};
'- => {lastWasGen ← FALSE; lastWasDash ← TRUE};
ENDCASE => lastWasGen ← lastWasDash ← FALSE;
ENDLOOP;
IF seeingGen THEN class ← class + 1;
classes[MIN[WorstClass, class]].Insert[rl.first];
ENDLOOP;
newNames.progged ← NIL;
FOR c: CARDINAL IN [0 .. WorstClass] DO
name: ROPENARROW[classes[c].LookupLargest[]];
IF name = NIL THEN LOOP;
WHILE name # NIL DO
newNames.progged ← CONS[name, newNames.progged];
name ← NARROW[classes[c].LookupNextSmaller[name]];
ENDLOOP;
FOR d: CARDINAL IN [c .. WorstClass] DO classes[d].DeleteAllItems[] ENDLOOP;
EXIT;
ENDLOOP;
IF newNames.progged = NIL THEN ERROR;
};
WorstClass: CARDINAL ~ 8;
classes: ARRAY [0 .. WorstClass] OF SymbolTable;
CompareRopes: PROC [r1, r2: REF ANY] RETURNS [c: Basics.Comparison] = {
c ← NARROW[r1, ROPE].Compare[NARROW[r2]];
};
InitClasses: PROC = {
FOR c: CARDINAL IN [0 .. WorstClass] DO classes[c] ← OrderedSymbolTableRef.CreateTable[CompareRopes] ENDLOOP;
};
ReNameByName: PUBLIC PROC [rm: RopeMap] RETURNS [r: Renamer] = {
r ← [rm, RenameByName];
};
RenameByName: PROC [data: REF ANY, oldNames: Names, oldEquiv: EquivClass] RETURNS [newNames: Names, newEquiv: EquivClass] = {
rm: RopeMap ← NARROW[data];
diff: BOOLFALSE;
RenameRope: PROC [old: ROPE] RETURNS [new: ROPE] = {
new ← rm.Apply[old];
diff ← diff OR NOT new.Equal[old];
};
RenameList: PROC [old: RopeList] RETURNS [new: RopeList] = {
newTail: RopeList ← new ← NIL;
FOR old ← old, old.rest WHILE old # NIL DO
[new, newTail] ← RopeListCat[RenameRope[old.first], new, newTail];
ENDLOOP;
};
newEquiv ← RenameRope[oldEquiv];
newNames.designed ← RenameList[oldNames.designed];
newNames.unknown ← RenameList[oldNames.unknown];
newNames.progged ← RenameList[oldNames.progged];
IF NOT diff THEN RETURN [oldNames, oldEquiv];
};
MapRopePairs: PUBLIC PROC [pairs: RopePairList] RETURNS [rm: RopeMap] = {
st: SymbolTableHolder ← NEW [SymbolTable ← OrderedSymbolTableRef.CreateTable[ComparePairs]];
FOR pairs ← pairs, pairs.rest WHILE pairs # NIL DO
st^.Insert[pairs];
ENDLOOP;
rm ← NEW [TextReplace.RopeMapRep ← [MapByPairs, st]];
};
ComparePairs: PROC [r1, r2: REF ANY] RETURNS [c: Basics.Comparison] = {
Key: PROC [ra: REF ANY] RETURNS [k: ROPE] = {
IF ra = NIL THEN k ← NIL ELSE WITH ra SELECT FROM
r: ROPE => k ← r;
p: RopePairList => k ← p.first.old;
ENDCASE => ERROR};
c ← Key[r1].Compare[Key[r2]];
};
MapByPairs: PROC [data: REF ANY, old: ROPE] RETURNS [new: ROPE] = {
st: SymbolTableHolder ← NARROW[data];
p: RopePairList ← NARROW[st^.Lookup[old]];
new ← IF p # NIL THEN p.first.new ELSE old;
};
RenamePairs: PUBLIC PROC [pairs: RopePairList] RETURNS [r: Renamer] = {
r ← ReNameByName[MapRopePairs[pairs]];
};
Setter: TYPE = REF SetterRep;
SetterRep: TYPE = RECORD [names: Names, equivClass: EquivClass];
useOldNames: PUBLIC Names ← [LIST["use old designed"], LIST["use old unknown"], LIST["use old progged"]];
useOldEquivClass: PUBLIC ROPE ← "use old equiv class";
SetNames: PUBLIC PROC [names: Names ← useOldNames, equivClass: EquivClass ← useOldEquivClass] RETURNS [r: Renamer] = {
r ← [NEW [SetterRep ← [names, equivClass]], DoSetNames];
};
DoSetNames: PROC [data: REF ANY, oldNames: Names, oldEquiv: EquivClass] RETURNS [newNames: Names, newEquiv: EquivClass] = {
s: Setter ← NARROW[data];
newNames ← IF s.names = useOldNames THEN oldNames ELSE s.names;
newEquiv ← IF s.equivClass = useOldEquivClass THEN oldEquiv ELSE s.equivClass;
};
RopeListCat: PROC [rope: ROPE, oldHead, oldTail: RopeList] RETURNS [newHead, newTail: RopeList] = {
newHead ← oldHead;
newTail ← LIST[rope];
IF oldTail # NIL THEN oldTail.rest ← newTail ELSE newHead ← newTail;
};
CellTypePair: TYPE = REF CellTypePairRep;
CellTypePairRep: TYPE = RECORD [ct1, ct2: CellType];
ChildrenOfType: PUBLIC PROC [design: Design, parentTypeA, childTypeA: REF ANY] RETURNS [bag: Bag] = {
parentType: CellType ← ToType[design, parentTypeA];
childType: CellType ← ToType[design, childTypeA];
bag ← NEW [BagRep ← [
data: NEW [CellTypePairRep ← [parentType, childType]],
Enumerate: EnumerateTypedChildren ]];
};
ImplicitChildrenOfType: PUBLIC PROC [design: Design, childTypeA: REF ANY] RETURNS [bag: Bag] = {
childType: CellType ← ToType[design, childTypeA];
bag ← NEW [BagRep ← [
data: NEW [CellTypePairRep ← [implicitType, childType]],
Enumerate: EnumerateTypedChildren ]];
};
implicitType: CellType ← NEW [CellTypeRep ← [design: NIL, names: [designed: LIST["implicitType"]] ]];
EnumerateTypedChildren: PROC [context, data: REF ANY, to: PROC [REF ANY]] = {
PerChild: PROC [ra: REF ANY] RETURNS [quit: BOOL] = {
a: Alias ← NARROW[ra];
v: Vertex ← NARROW[AntiAlias[a]];
quit ← FALSE;
IF a.name # PickAName[v.names] THEN RETURN;
SELECT v.class FROM
net => RETURN;
cell => NULL;
ENDCASE => ERROR;
IF v.type = childType THEN to[v];
};
ctp: CellTypePair ← NARROW[data];
parentType: CellType ← IF ctp.ct1 # implicitType THEN ctp.ct1 ELSE NARROW[context];
childType: CellType ← ctp.ct2;
parentType.parts.EnumerateIncreasing[PerChild];
};
FirstCellType: PUBLIC PROC [design: Design] RETURNS [ct: CellType] = {
ct ← NARROW[design.cellTypesByAddress.LookupSmallest[]];
};
NextCellType: PUBLIC PROC [prev: CellType] RETURNS [next: CellType] = {
next ← NARROW[prev.design.cellTypesByAddress.LookupNextLarger[prev]];
};
EnumerateCellTypes: PUBLIC PROC [design: Design, ra: REF ANY, consume: PROC [CellType]] = {
EatAny: PROC [ra: REF ANY] = {
ct: CellType ← NARROW[ra];
consume[ct]};
WITH ra SELECT FROM
cl: LIST OF CellType => FOR l: LIST OF CellType ← cl, l.rest WHILE l # NIL DO
consume[l.first]
ENDLOOP;
lora: LORA => FOR l: LORA ← lora, l.rest WHILE l # NIL DO
consume[ToType[design, l.first]]
ENDLOOP;
bag: Bag => {
bag.Enumerate[design, bag.data, EatAny];
};
ENDCASE => ERROR};
EnumerateParts: PUBLIC PROC [ct: CellType, consume: PROC [Vertex]] = {
PerPart: PROC [ra: REF ANY] RETURNS [stop: BOOL] = {
a: Alias ← NARROW[ra];
v: Vertex ← NARROW[AntiAlias[a]];
stop ← FALSE;
IF a.name.Equal[PickAName[v.names]] THEN consume[v];
};
ct.parts.EnumerateIncreasing[PerPart];
};
EnumerateVertices: PUBLIC PROC [context, ra: REF ANY, consume: PROC [Vertex]] = {
EatAny: PROC [ra: REF ANY] = {
v: Vertex ← NARROW[ra];
consume[v]};
PerPart: PROC [ra: REF ANY] RETURNS [stop: BOOL] = {
a: Alias ← NARROW[ra];
v: Vertex ← NARROW[AntiAlias[a]];
IF PickAName[v.names] = a.name THEN consume[v];
stop ← FALSE};
WITH ra SELECT FROM
vl: VertexList => FOR l: VertexList ← vl, l.rest WHILE l # NIL DO
consume[l.first]
ENDLOOP;
lora: LORA => FOR l: LORA ← lora, l.rest WHILE l # NIL DO
consume[ToVertex[context, l.first]]
ENDLOOP;
bag: Bag => {
bag.Enumerate[context, bag.data, EatAny];
};
s: Special => SELECT s.ra FROM
$all => {ct: CellType ← NARROW[context];
EnsureParts[ct];
IF NOT ExpansionKnown[ct] THEN ERROR;
ct.parts.EnumerateIncreasing[PerPart]};
ENDCASE => ERROR;
ENDCASE => ERROR};
UnlinkInstance: PUBLIC PROC [v: Vertex] = {
IF v.prevInstance # NIL THEN v.prevInstance.nextInstance ← v.nextInstance ELSE v.type.firstInstance ← v.nextInstance;
IF v.nextInstance # NIL THEN v.nextInstance.prevInstance ← v.prevInstance ELSE v.type.lastInstance ← v.prevInstance;
};
LinkInstance: PUBLIC PROC [v: Vertex] = {
v.nextInstance ← NIL;
v.prevInstance ← v.type.lastInstance;
IF v.prevInstance # NIL THEN v.prevInstance.nextInstance ← v ELSE v.type.firstInstance ← v;
IF v.nextInstance # NIL THEN v.nextInstance.prevInstance ← v ELSE v.type.lastInstance ← v;
};
DeleteVertex: PUBLIC PROC [v: Vertex] = {
v ← v;
WHILE v.firstEdge # NIL DO RemoveEdge[v.firstEdge] ENDLOOP;
Delete[v.parent.parts, v.names, v];
SELECT v.class FROM
net => v.parent.netCount ← v.parent.netCount - 1;
cell => {v.parent.cellCount ← v.parent.cellCount - 1;
UnlinkInstance[v]};
ENDCASE => ERROR;
v ← v};
RemoveEdge: PUBLIC PROC [e: Edge] = {
UnlinkSide: PROC [side: VertexClass] = {
head: Vertex ← e.sides[side].v;
IF e.sides[side].next # NIL
THEN e.sides[side].next.sides[side].prev ← e.sides[side].prev
ELSE head.lastEdge ← e.sides[side].prev;
IF e.sides[side].prev # NIL
THEN e.sides[side].prev.sides[side].next ← e.sides[side].next
ELSE head.firstEdge ← e.sides[side].next;
e.sides[side].next ← e.sides[side].prev ← badEdge};
UnlinkSide[net];
UnlinkSide[cell];
};
badEdge: PUBLIC Edge ← NEW [EdgeRep ← [sides: [[NIL, NIL, NIL], [NIL, NIL, NIL]], color: 0, portIndex: NullPortIndex]];
InitClasses[];
END.
g:  

— !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^←`abcdefghijklmnopqrstuvwxyz{|}~
m: ııııııı 
ıı
ıııııııııııııııııı# °÷'P`± +˜Ë¡.•–— Æ"§®d`e¿ï!‚…‡[ ÜÄ]H¥*({ ´õzı{Ëbıè©CéÒËĞ%¬¢«®gfh¡¢)£¼ı¾ı