CompareRead.Mesa
Last Edited by: Spreitzer, July 10, 1984 4:50:43 pm PDT
DIRECTORY Basics, ComparePrivate, DFUtilities, FS, IO, List, OrderedSymbolTableRef, Rope, ViewerIO;
CompareRead: CEDAR PROGRAM
IMPORTS ComparePrivate, DFUtilities, FS, IO, List, OrderedSymbolTableRef, Rope, ViewerIO
EXPORTS ComparePrivate =
BEGIN OPEN ComparePrivate;
LORA: TYPE = LIST OF REF ANY;
Int: TYPE = REF INT;
graphIDToRope: PUBLIC ARRAY GraphID OF ROPE ← ["A", "B"];
log: IO.STREAM ← ViewerIO.CreateViewerStreams["Compare Read"].out;
cellDefs: ARRAY GraphID OF SymbolTable;
Log: PUBLIC PROC [format: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] =
{log.PutF[format, v1, v2, v3, v4, v5]};
DFTest: PROC [dfName: ROPE] =
BEGIN
PerItem: PROC [item: REF ANY] RETURNS [stop: BOOLFALSE] =
{Log["%g\n", IO.refAny[item]]};
from: IO.STREAMFS.StreamOpen[dfName];
Log["\nTesting DF file %g\n", IO.rope[dfName]];
DFUtilities.ParseFromStream[in: from, proc: PerItem, filter: [comments: TRUE]];
from.Close[];
Log["\nDone testing DF file %g\n", IO.rope[dfName]];
END;
ReadDesign: PROC [graphID: GraphID, dfName: ROPE] =
BEGIN
commentText: ROPENIL;
PerItem: PROC [item: REF ANY] RETURNS [stop: BOOLFALSE] =
BEGIN
WITH item SELECT FROM
di: REF DFUtilities.DirectoryItem => NULL;
fi: REF DFUtilities.FileItem => IF NOT dfName.Equal[fi.name] THEN {
cs: IO.STREAMIO.RIS[commentText];
typeName, fullFName, fileName: ROPE;
ct: ComponentType;
cp: FS.ComponentPositions;
[fullFName, cp, ] ← FS.ExpandName[fi.name];
fileName ← fullFName.Substr[start: 0, len: cp.ext.start + cp.ext.length];
IF cs.GetChar[] # '- THEN ERROR;
IF cs.GetChar[] # '- THEN ERROR;
typeName ← cs.GetRopeLiteral[];
cs.Close[];
ct ← NEW [ComponentTypeRep ← [name: typeName, file: fileName]];
cellDefs[graphID].Insert[ct];
};
ii: REF DFUtilities.ImportsItem => ERROR;
ii: REF DFUtilities.IncludeItem => ERROR;
ci: REF DFUtilities.CommentItem => commentText ← ci.text;
wi: REF DFUtilities.WhiteSpaceItem => NULL;
ENDCASE => ERROR;
END;
from: IO.STREAMFS.StreamOpen[dfName];
cellDefs[graphID] ← OrderedSymbolTableRef.CreateTable[CompareCellTypes];
DFUtilities.ParseFromStream[in: from, proc: PerItem, filter: [comments: TRUE]];
from.Close[];
END;
Test: PROC [names: ARRAY GraphID OF ROPE] =
BEGIN
vertices: SymbolTablePair ← [OrderedSymbolTableRef.CreateTable[CompareVertices], OrderedSymbolTableRef.CreateTable[CompareVertices]];
Log["\nTesting %g %g\n", IO.rope[names[A]], IO.rope[names[B]]];
ReadGraph[A, names[A], vertices[A]];
ReadGraph[B, names[B], vertices[B]];
CompareCDs[vertices];
Log["\nDone\n"];
log.Flush[];
END;
ReadGraph: PROC [graphID: GraphID, fileName: ROPE, symbolTable: SymbolTable] =
BEGIN
Add: PROC [v: Vertex] =
BEGIN
color: Color ← v.curColor;
IF v.curColor # v.oldColor THEN ERROR;
symbolTable.Insert[v];
END;
Connect: PROC [i: CARDINAL, cv: ComponentVertex, nv: NetVertex] =
BEGIN
cv.neighbors[i] ← nv;
nv.neighbors[nv.used] ← [cv, cv.ports[i].color];
nv.used ← nv.used + 1;
END;
GetStart: PROC =
BEGIN
IF from.GetChar[] # '- THEN ERROR;
IF from.GetChar[] # '- THEN ERROR;
IF NOT from.GetTokenRope[IO.IDProc].token.Equal["CellType"] THEN ERROR;
graphTypeName ← from.GetRopeLiteral[];
[] ← from.GetLineRope[];
ports ← NARROW[from.GetRefAny[]];
IF ports.first # $Ports THEN ERROR;
END;
AddWorld: PROC =
BEGIN
ct: ComponentType;
cv: ComponentVertex;
ct ← NARROW[cellDefs[graphID].Lookup[graphTypeName]];
IF ct.ports = NIL THEN ReadPorts[ct];
cv ← NEW [VertexRep[component][ct.ports.length]];
cv.name ← "world";
cv.QNext ← notInQ;
cv.colorNext ← cv.equiv ← NIL;
cv.oldColor ← cv.curColor ← 0;
cv.graph ← graphID;
cv.unique ← FALSE;
cv.suspect ← FALSE;
cv.ports ← ct.ports;
FOR i: CARDINAL IN [0 .. ct.ports.length) DO
port: Port ← ct.ports[i];
nv: NetVertex ← NARROW[symbolTable.Lookup[port.name]];
Connect[i, cv, nv];
ENDLOOP;
Add[cv];
END;
from: IO.STREAMFS.StreamOpen[fileName];
graphTypeName: ROPE;
ports: LORA;
GetStart[];
DO
item: LORA;
[] ← from.SkipWhitespace[];
IF from.EndOf[] THEN EXIT;
item ← NARROW[from.GetRefAny[]];
SELECT item.first FROM
$N => BEGIN
netName, netType: ROPE;
connections: CARDINAL;
nv: NetVertex;
netName ← NARROW[item.rest.first];
netType ← NARROW[item.rest.rest.first];
connections ← NARROW[item.rest.rest.rest.first, Int]^;
nv ← NEW [VertexRep[net][connections]];
nv.name ← netName;
nv.QNext ← notInQ;
nv.colorNext ← nv.equiv ← NIL;
nv.oldColor ← nv.curColor ← HashRope[netType, MinHashSize];
nv.graph ← graphID;
nv.unique ← FALSE;
nv.suspect ← FALSE;
nv.used ← 0;
Add[nv];
END;
$C => BEGIN
instName, typeName: ROPE;
cv: ComponentVertex;
ct: ComponentType;
connections: CARDINAL;
con: LORA ← item.rest.rest.rest;
instName ← NARROW[item.rest.first];
typeName ← NARROW[item.rest.rest.first];
connections ← List.Length[con];
cv ← NEW [VertexRep[component][connections]];
cv.name ← instName;
cv.QNext ← notInQ;
cv.colorNext ← cv.equiv ← NIL;
cv.oldColor ← cv.curColor ← HashRope[typeName, MinHashSize];
cv.graph ← graphID;
cv.unique ← FALSE;
cv.suspect ← FALSE;
ct ← NARROW[cellDefs[graphID].Lookup[typeName]];
IF ct.ports = NIL THEN ReadPorts[ct];
cv.ports ← ct.ports;
FOR i: CARDINAL IN [0 .. connections) DO
pair: LORANARROW[con.first];
portName: ROPENARROW[pair.first];
netName: ROPENARROW[pair.rest.first];
net: NetVertex ← NARROW[symbolTable.Lookup[netName]];
IF NOT portName.Equal[cv.ports[i].name] THEN ERROR;
Connect[i, cv, net];
con ← con.rest;
ENDLOOP;
Add[cv];
END;
$Leaf => ERROR;
ENDCASE => ERROR;
ENDLOOP;
AddWorld[];
from.Close[];
END;
ReadPorts: PROC [ct: ComponentType] =
BEGIN
from: IO.STREAMFS.StreamOpen[ct.file];
ports: LORANARROW[from.GetRefAny[]];
i, len: CARDINAL ← 0;
IF ports.first # $Ports THEN ERROR;
len ← List.Length[ports]-1;
ct.ports ← NEW [PortSeq[len]];
FOR pl: LORA ← ports.rest, pl.rest WHILE pl # NIL DO
item: LORANARROW[pl.first];
portName: ROPENARROW[item.first];
portClass: ROPENARROW[item.rest.first];
portType: ROPENARROW[item.rest.rest.first];
ct.ports[i] ← [name: portName, color: HashRope[portClass, MinHashSize]];
i ← i + 1;
ENDLOOP;
IF i # len THEN ERROR;
from.Close[];
END;
WriteAll: PUBLIC PROC [when: ROPE, vertices: SymbolTablePair, hashTable: HashTable] =
BEGIN
Log["\n%g\n", IO.rope[when]];
WriteHashTable[hashTable];
WriteSymbolTable["A", vertices[A]];
WriteSymbolTable["B", vertices[B]];
Log["\nDone %g\n", IO.rope[when]];
END;
WriteHashTable: PROC [hashTable: HashTable] =
BEGIN
Log["\nHashTable:\n"];
FOR hti: HashTableIndex ← hashTable.firstNonEmpty, hashTable[hti].nextNonEmpty WHILE hti # NullIndex DO
hte: HashTableEntry ← hashTable[hti];
Log["%05d %g %g", IO.card[hti], IO.card[hte.count[A]], IO.card[hte.count[B]]];
Log[" %05d %g %g", IO.card[hte.newColor], IO.bool[hte.multicolored], IO.bool[hte.suspect]];
FOR v: Vertex ← hte.v, v.colorNext WHILE v # NIL DO
Log[" %g.%g", IO.rope[graphIDToRope[v.graph]], IO.rope[v.name]];
ENDLOOP;
Log["\n"];
ENDLOOP;
END;
WriteSymbolTable: PROC [graphID: ROPE, vertices: SymbolTable] =
BEGIN
WriteVertex: PROC [any: REF ANY] RETURNS [stop: BOOL] =
BEGIN
v: Vertex ← NARROW[any];
stop ← FALSE;
Log["(%05d)\t%05d\t%g\t%g\t%g", IO.card[v.oldColor], IO.card[v.curColor], bool[v.unique], bool[v.suspect], IO.rope[v.name]];
IF v.equiv # NIL THEN Log["\t%g\n", IO.rope[v.equiv.name]] ELSE Log["\n"];
END;
Log["\nGraph %g vertices:\n", IO.rope[graphID]];
vertices.EnumerateIncreasing[WriteVertex];
END;
bool: PROC [b: BOOL] RETURNS [v: IO.Value[rope]] =
{v.value ← IF b THEN "TRUE " ELSE "FALSE"};
HashRope: PUBLIC PROC [r: ROPE, hashTableSize: CARDINAL] RETURNS [c: Color] =
BEGIN
rot: LONG CARDINAL = 128 + 32 + 2;
len: INT = r.Length[];
c ← 1;
FOR i: INT DECREASING IN [0 .. len) DO
char: CHAR ← r.Fetch[i];
long: LONG CARDINAL ← rot*c + (char-0C);
c ← long MOD hashTableSize;
ENDLOOP;
END;
CompareCellTypes: PROC [r1, r2: REF ANY] RETURNS [c: Basics.Comparison] =
BEGIN
Key: PROC [r: REF ANY] RETURNS [k: ROPE] = {
WITH r SELECT FROM
rr: ROPE => k ← rr;
ct: ComponentType => k ← ct.name;
ENDCASE => ERROR};
c ← Key[r1].Compare[Key[r2]];
END;
CompareVertices: PROC [r1, r2: REF ANY] RETURNS [c: Basics.Comparison] =
BEGIN
Key: PROC [r: REF ANY] RETURNS [k: ROPE] = {
WITH r SELECT FROM
rr: ROPE => k ← rr;
v: Vertex => k ← v.name;
ENDCASE => ERROR};
c ← Key[r1].Compare[Key[r2]];
END;
END.