ComparePrimitiveTransforms.Mesa
Last Edited by: Spreitzer, February 19, 1985 1:30:17 pm PST
DIRECTORY Basics, CompareDataStructure, CompareOps, CompareTransforms, CompareTransformsPrivate, DFUtilities, FS, IO, List, OrderedSymbolTableRef, RefTab, Rope, ViewerIO;
ComparePrimitiveTransforms: CEDAR PROGRAM
IMPORTS CompareDataStructure, CompareOps, CompareTransforms, CompareTransformsPrivate, IO, List, OrderedSymbolTableRef, RefTab, Rope
EXPORTS CompareOps, CompareTransforms, CompareTransformsPrivate =
BEGIN OPEN CompareDataStructure, CompareTransforms, CompareOps, CompareTransformsPrivate;
--Not YET implemented-- nyet: PUBLIC ERROR = CODE;
Error: PUBLIC ERROR [format: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] = CODE;
Differentiate: PUBLIC PROC [design: Design, newNames: Names, instances: REF ANY] RETURNS [newCT: CellType] =
BEGIN
oldCT: CellType ← NIL;
vl: LORANIL;
ConsumeInstance: PROC [v: Vertex] = {
SELECT v.class FROM
cell => NULL;
net => Err[[], "%g is a net, not a cell", IO.rope[GlobalVertexName[v]]];
ENDCASE => ERROR;
IF oldCT = NIL THEN oldCT ← v.type ELSE IF oldCT # v.type THEN Err[[], "%g of type %g, not %g", IO.rope[PickAName[v.names]], IO.rope[PickAName[v.type.names]], IO.rope[PickAName[oldCT.names]]];
vl ← CONS[v, vl]};
EnumerateVertices[design, instances, ConsumeInstance];
newCT ← NEW [CellTypeRep ← [design: design, names: newNames, file: NIL, publicKnown: TRUE, privateKnown: TRUE, ports: CopyPorts[oldCT.ports], parts: NIL]];
CopyParts[newCT, oldCT];
FOR vl ← vl, vl.rest WHILE vl # NIL DO
ChangeType[v: NARROW[vl.first], from: oldCT, to: newCT];
ENDLOOP;
END;
Undifferentiate: PUBLIC PROC [design: Design, toTypeA, fromTypes: REF ANY] RETURNS [changed: VertexList] =
BEGIN
toType: CellType ← ToType[design, toTypeA];
oldTypes: LIST OF CellType ← NIL;
oldCount: NAT ← 0;
ConsumeType: PROC [ct: CellType] = {
oldTypes ← CONS[ct, oldTypes];
oldCount ← oldCount + 1};
EnumerateCellTypes[design, fromTypes, ConsumeType];
FOR oldTypes ← oldTypes, oldTypes.rest WHILE oldTypes # NIL DO
WHILE oldTypes.first.firstInstance # NIL DO
v: Vertex ← oldTypes.first.firstInstance;
IF IsMirror[v] THEN ERROR; --AM2
ChangeType[v: v, from: oldTypes.first, to: toType];
changed ← CONS[v, changed];
ENDLOOP;
DeleteType[design, oldTypes.first];
ENDLOOP;
END;
NewEmptyCellType: PUBLIC PROC [design: Design, names: Names] RETURNS [cellType: CellType] =
BEGIN
cellType ← NEW [CellTypeRep ← [
design: design,
names: names,
file: NIL,
publicKnown: TRUE,
privateKnown: TRUE,
ports: NEW [PortSeq[0]],
parts: OrderedSymbolTableRef.CreateTable[CompareVertices],
mirror: NIL]];
AddWorld[cellType];
Insert[design.cellTypesByName, names, cellType];
design.cellTypesByAddress.Insert[cellType];
END;
CreateEmpty: PUBLIC PROC [design: Design, childNames: Names, childType, parentType: CellType] RETURNS [child: Vertex] =
BEGIN
child ← NEW [VertexRep ← [names: childNames, type: childType, parent: parentType, class: cell]];
IF NOT IsEmpty[childType] THEN Err[[], "Asked to create empty child %g of non-empty type %g in %g", IO.refAny[PickAName[childNames]], IO.refAny[PickAName[childType.names]], IO.refAny[PickAName[parentType.names]]];
LinkInstance[child];
AddVertex[child];
NoteChange[child.parent];
END;
DeleteEmpty: PUBLIC PROC [design: Design, child: Vertex] RETURNS [parentType: CellType] =
BEGIN
parentType ← child.parent;
IF NOT IsEmpty[child.type] THEN Err[[], "Child %g in %g is of a non-empty type (%g)", IO.rope[PickAName[child.names]], IO.rope[PickAName[child.parent.names]], IO.rope[PickAName[child.type.names]]];
IF (child.firstEdge # NIL) # (child.lastEdge # NIL) THEN ERROR;
IF child.firstEdge # NIL THEN ERROR;
NoteChange[child.parent];
DeleteVertex[child];
END;
RenameVertices: PUBLIC PROC [design: Design, parentA, vertices: REF ANY, renamer: Renamer] = {
parentType: CellType ← ToType[design, parentA];
changed: BOOLFALSE;
PerVertex: PROC [v: Vertex] = {
newNames: Names ← renamer.Rename[renamer.data, v.names, implicitClass].newNames;
IF v.parent # parentType THEN ERROR;
IF newNames # v.names THEN {
changed ← TRUE;
Delete[v.parent.parts, v.names, v];
v.names ← newNames;
Insert[v.parent.parts, v.names, v];
};
};
EnumerateVertices[parentType, vertices, PerVertex];
IF changed THEN NoteChange[parentType];
};
RenamePorts: PUBLIC PROC [design: Design, typeA: REF ANY, renamer: Renamer] = {
parentType: CellType ← ToType[design, typeA];
changed: BOOLFALSE;
FOR portIndex: PortIndex IN [0 .. parentType.ports.length) DO
newNames: Names;
newEquiv: EquivClass;
[newNames, newEquiv] ← renamer.Rename[renamer.data, parentType.ports[portIndex].names, parentType.ports[portIndex].equivClass];
IF newNames # parentType.ports[portIndex].names OR newEquiv # parentType.ports[portIndex].equivClass THEN {
changed ← TRUE;
parentType.ports[portIndex].names ← newNames;
parentType.ports[portIndex].equivClass ← newEquiv};
ENDLOOP;
IF changed THEN NoteChange[parentType];
};
RenameCellType: PUBLIC PROC [design: Design, typeA: REF ANY, renamer: Renamer] = {
ct: CellType ← ToType[design, typeA];
newNames: Names;
newEquiv: EquivClass;
[newNames, newEquiv] ← renamer.Rename[renamer.data, ct.names, ct.equivClass];
IF newNames # ct.names OR newEquiv # ct.equivClass THEN {
NoteChange[ct];
Delete[design.cellTypesByName, ct.names, ct];
ct.names ← newNames;
ct.equivClass ← newEquiv;
Insert[design.cellTypesByName, ct.names, ct];
};
};
RenameTypes: PUBLIC PROC [design: Design, typesA: REF ANY, renamer: Renamer] = {
PerType: PROC [ct: CellType] = {
newNames: Names;
newEquiv: EquivClass;
[newNames, newEquiv] ← renamer.Rename[renamer.data, ct.names, ct.equivClass];
IF newNames # ct.names OR newEquiv # ct.equivClass THEN {
NoteChange[ct];
Delete[design.cellTypesByName, ct.names, ct];
ct.names ← newNames;
ct.equivClass ← newEquiv;
Insert[design.cellTypesByName, ct.names, ct];
};
};
EnumerateCellTypes[design, typesA, PerType];
};
RenameAll: PUBLIC PROC [design: Design, renamer: Renamer] = {
FOR ct: CellType ← FirstCellType[design], NextCellType[ct] WHILE ct # NIL DO
EnsureParts[ct];
RenameCellType[design, ct, renamer];
RenamePorts[design, ct, renamer];
IF ExpansionKnown[ct] THEN RenameVertices[design, ct, all, renamer];
ENDLOOP;
};
ToNamesS: PUBLIC PROC [ra: REF ANY] RETURNS [ns: NamesS] = {
WITH ra SELECT FROM
x: NamesS => ns ← x;
x: NamesList => ns ← NamesListToSeq[x];
ENDCASE => ERROR};
NamesListToSeq: PUBLIC PROC [l: NamesList] RETURNS [s: NamesS] = {
size: CARDINAL ← 0;
FOR m: NamesList ← l, m.rest WHILE m # NIL DO size ← size+1 ENDLOOP;
s ← NEW [NamesSeq[size]];
FOR i: NAT IN [0 .. s.length) DO
s[i] ← l.first;
l ← l.rest;
ENDLOOP;
};
ListNames: PUBLIC PROC [vertexs: VertexS] RETURNS [nl: NamesList] = {
tail: NamesList ← nl ← NIL;
FOR i: NAT IN [0 .. vertexs.length) DO
last: NamesList ← LIST[vertexs[i].names];
IF tail = NIL THEN nl ← last ELSE tail.rest ← last;
tail ← last;
ENDLOOP;
};
ToType: PUBLIC PROC [design: Design, ra: REF ANY] RETURNS [type: CellType] = {
WITH ra SELECT FROM
r: ROPE => type ← NARROW[Lookup[design.cellTypesByName, r]];
ct: CellType => type ← ct;
ENDCASE => ERROR};
ToRope: PUBLIC PROC [ra: REF ANY] RETURNS [rope: ROPE] = {rope ← NARROW[ra]};
ToVertex: PUBLIC PROC [context, ra: REF ANY] RETURNS [v: Vertex] = {
WITH ra SELECT FROM
vertex: Vertex => v ← vertex;
rope: ROPE => {
ct: CellType ← NARROW[context];
EnsureParts[ct];
v ← NARROW[Lookup[ct.parts, rope]]};
lora: LORA => {
design: Design ← NARROW[context];
ct: CellType ← ToType[design, lora.first];
name: ROPENARROW[lora.rest.first];
EnsureParts[ct];
v ← NARROW[Lookup[ct.parts, name]]};
ENDCASE => ERROR};
ToVertexS: PUBLIC PROC [context, ra: REF ANY] RETURNS [vs: VertexS] = {
WITH ra SELECT FROM
s: VertexS => vs ← s;
lora: LORA => {
vs ← NEW [VertexSeq[List.Length[lora]]];
FOR i: NAT IN [0 .. vs.length) DO
vs[i] ← ToVertex[context, lora.first];
lora ← lora.rest;
ENDLOOP;
IF lora # NIL THEN ERROR};
bag: Bag => {
vl: VertexList ← NIL;
count: INT ← 0;
PerElement: PROC [e: REF ANY] = {
v: Vertex ← NARROW[e];
vl ← CONS[v, vl];
count ← count +1};
bag.Enumerate[context: context, data: bag.data, to: PerElement];
vs ← NEW [VertexSeq[count]];
FOR vl ← vl, vl.rest WHILE vl # NIL DO
count ← count - 1;
vs[count] ← vl.first;
ENDLOOP;
IF count # 0 THEN ERROR;
};
ENDCASE => ERROR};
VVMapFromTIINames: PROC [design: Design, l: TIINamesList] RETURNS [m: Mapper] = {
rtm: RefTabMapper ← NEW [RefTabMapperRep ← [NIL, RefTab.Create[]]];
rtm.asMapper ← m ← NEW [MapperRep ← [RefTabMap, rtm]];
FOR tiil: TIINamesList ← l, tiil.rest WHILE tiil # NIL DO
tiin: TIINames ← tiil.first;
ct: CellType ← NARROW[Lookup[design.cellTypesByName, tiin.typeName]];
v1: Vertex ← NARROW[Lookup[ct.parts, tiin.v1Name]];
v2: Vertex ← NARROW[Lookup[ct.parts, tiin.v2Name]];
[] ← rtm.refTab.Store[v1, v2];
ENDLOOP;
};
VVSMapFromTIIlNames: PUBLIC PROC [design: Design, l: TIIlNamesList] RETURNS [m: Mapper] = {
rtm: RefTabMapper ← NEW [RefTabMapperRep ← [NIL, RefTab.Create[]]];
rtm.asMapper ← m ← NEW [MapperRep ← [RefTabMap, rtm]];
FOR tiill: TIIlNamesList ← l, tiill.rest WHILE tiill # NIL DO
tiiln: TIIlNames ← tiill.first;
ct: CellType ← NARROW[Lookup[design.cellTypesByName, tiiln.typeName]];
v1: Vertex ← NARROW[Lookup[ct.parts, tiiln.v1Name]];
v2s: VertexS ← ToVertexS[ct, tiiln.v2Names];
[] ← rtm.refTab.Store[v1, v2s];
ENDLOOP;
};
RefTabMapper: TYPE = REF RefTabMapperRep;
RefTabMapperRep: TYPE = RECORD [
asMapper: Mapper,
refTab: RefTab.Ref
];
RefTabMap: PROC [data, domain: REF ANY] RETURNS [range: REF ANY] = {
rtm: RefTabMapper ← NARROW[data];
range ← rtm.refTab.Fetch[domain].val};
OneMap: PUBLIC PROC [from, to: REF ANY] RETURNS [mapper: Mapper] = {
om: OneMapper ← NEW [OneMapperRep ← [from, to]];
mapper ← NEW [MapperRep ← [MapOne, om]]};
OneMapper: TYPE = REF OneMapperRep;
OneMapperRep: TYPE = RECORD [from, to: REF ANY];
MapOne: PROC [data, domain: REF ANY] RETURNS [range: REF ANY] = {
om: OneMapper ← NARROW[data];
range ← IF domain = om.from THEN om.to ELSE NIL};
GenName: PROC RETURNS [name: ROPE] =
{name ← IO.PutFR[" gen%g", IO.card[genCount ← genCount + 1]]};
genCount: NAT ← 0;
JoinNames: PUBLIC PROC [parent, child: Names, dot: BOOLTRUE] RETURNS [joined: Names] =
{joined ← [progged: LIST[PickAName[parent].Cat[IF dot THEN "." ELSE NIL, PickAName[child]]]]};
QualifyEquivClass: PUBLIC PROC [qual: Names, equivClass: EquivClass, dot: BOOLTRUE] RETURNS [quald: EquivClass] =
{quald ← IF equivClass # implicitClass THEN PickAName[qual].Cat[IF dot THEN "." ELSE NIL, equivClass] ELSE implicitClass};
IsEmpty: PROC [type: CellType] RETURNS [isEmpty: BOOL] = {
EnsureParts[type];
EnsurePorts[type];
isEmpty ← type.ports.length = 0 AND type.cellCount = 0};
CopyPorts: PROC [p: PortS] RETURNS [q: PortS] = {
q ← NEW [PortSeq[p.length]];
FOR pi: NAT IN [0 .. q.length) DO q[pi] ← p[pi] ENDLOOP;
};
CopyParts: PROC [newCT, oldCT: CellType] = {
oldParts: SymbolTable ← oldCT.parts;
newParts: SymbolTable;
Copy: PROC [ra: REF ANY] RETURNS [stop: BOOL] = {
oldV: Vertex ← NARROW[AntiAlias[ra]];
AM1 says this can't be the mirror.
newV: Vertex;
stop ← FALSE;
newV ← CopyWork[oldV]};
CopyWork: PROC [oldV: Vertex] RETURNS [newV: Vertex] = {
newV ← NARROW[Lookup[newParts, PickAName[oldV.names]]];
IF newV # NIL THEN RETURN;
newV ← NEW [VertexRep ← [names: oldV.names, type: oldV.type, parent: newCT, class: oldV.class]];
AddVertex[newV];
IF newV.class = net THEN RETURN;
LinkInstance[newV];
FOR oldE: Edge ← oldV.firstEdge, oldE.sides[cell].next WHILE oldE # NIL DO
newNet: Vertex ← CopyWork[oldE.sides[net].v];
IF oldE.sides[cell].v # oldV THEN ERROR;
AddEdge[newV, newNet];
ENDLOOP;
};
IF oldCT.parts = NIL OR newCT.parts # NIL THEN ERROR;
IF newCT.mirror # NIL THEN ERROR;
newCT.parts ← newParts ← OrderedSymbolTableRef.CreateTable[CompareVertices];
oldParts.EnumerateIncreasing[Copy];
AddWorld[newCT];
};
DeleteType: PROC [design: Design, type: CellType] = {
IF (type.firstInstance = NIL) # (type.lastInstance = NIL) THEN ERROR;
IF (type.firstInstance # NIL) OR (type.lastInstance # NIL) THEN ERROR; --AM2
Delete[design.cellTypesByName, type.names, type];
IF design.cellTypesByAddress.Delete[type] # type THEN ERROR;
};
ChangeType: PROC [v: Vertex, from, to: CellType] = {
IF v.type # from THEN ERROR;
NoteChange[v.parent];
UnlinkInstance[v];
v.type ← to;
LinkInstance[v]};
AddEdge: PUBLIC PROC [cv, nv: Vertex] = {
pi: NAT = IF cv.lastEdge # NIL THEN cv.lastEdge.portIndex+1 ELSE 0;
e: Edge ← NEW [EdgeRep ← [sides: [cell: [v: cv, next: NIL, prev: cv.lastEdge], net: [v: nv, next: NIL, prev: nv.lastEdge]], color: noColor, portIndex: pi]];
IF cv.class # cell OR nv.class # net THEN ERROR;
IF e.sides[cell].prev # NIL THEN e.sides[cell].prev.sides[cell].next ← e ELSE cv.firstEdge ← e;
IF e.sides[net].prev # NIL THEN e.sides[net].prev.sides[net].next ← e ELSE nv.firstEdge ← e;
cv.lastEdge ← nv.lastEdge ← e;
};
END.
g:  

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