LichenFromExtImpl3.Mesa
Last tweaked by Mike Spreitzer on July 22, 1988 2:43:15 pm PDT
DIRECTORY AbSets, BasicTime, BiRels, FS, Histograms, HistogramsViewing, IntStuff, IO, LichenDataOps, LichenDataStructure, LichenFromExtPrivate, LichenIntBasics, RefText, Rope, SetBasics;
LichenFromExtImpl3: CEDAR MONITOR
LOCKS dr USING dr: DesignReading
IMPORTS AbSets, BiRels, FS, Histograms, HistogramsViewing, IntStuff, IO, LichenDataStructure, LichenFromExtPrivate, RefText, Rope, SetBasics
EXPORTS LichenFromExtPrivate
=
BEGIN OPEN LIB:LichenIntBasics, LIB, LichenDataStructure, LichenDataOps, LichenFromExtPrivate, Sets:AbSets;
nsh: Histograms.Histogram ~ Histograms.Create1D[];
TestRangeMerges: PROC [fileNamePattern: ROPE, log: IO.STREAM, range: BOOL] ~ {
buffer: REFTEXT ~ RefText.New[200];
token: REFTEXT;
PerName: PROC [fullFName: ROPE] RETURNS [continue: BOOL] ~ {
in: IO.STREAM ~ FS.StreamOpen[fullFName];
i1, i2, i3: INT;
DO
i1 ← in.GetIndex[];
[] ← in.SkipWhitespace[];
i2 ← in.GetIndex[];
IF in.EndOf[] THEN EXIT;
[token,] ← in.GetToken[TokenBreak, buffer];
i3 ← in.GetIndex[];
IF RefText.Equal[token, "merge"] THEN {
DO
char: CHAR ~ in.GetChar[];
SELECT char FROM
'\n => IF range
THEN {
log.PutF["%g[%g]\n", [rope[fullFName]], [integer[in.GetIndex]]];
in.Close[];
RETURN [TRUE]}
ELSE EXIT;
': => IF range
THEN {
[] ← in.GetLine[buffer];
EXIT}
ELSE {
log.PutF["%g[%g]\n", [rope[fullFName]], [integer[in.GetIndex]]];
in.Close[];
RETURN [TRUE]};
ENDCASE => NULL;
ENDLOOP;
}
ELSE [] ← in.GetLine[buffer];
ENDLOOP;
in.Close[];
RETURN [TRUE]};
FS.EnumerateForNames[fileNamePattern, PerName];
RETURN};
DoMerges: PUBLIC PROC [s: Source, cr: CellReading] = {
from: CellType = cr.ct;
dr: DesignReading = cr.dr;
nSets: INT ~ dr.toMerge.Size[].EN;
i: INT ← 0;
lastPath: Path ← [];
firstSet: REF Set--of Path--NIL;
DoAMerge: PROC [ra: Sets.Value] ~ {
path: Path ~ VPath[ra];
IF lastPath # [] THEN [] ← MergeWork[cr, lastPath, path];
IF nSets=1 THEN lastPath ← path;
RETURN};
DoASet: PROC [pair: BiRels.Pair] ~ {
arrayPrefix: Path ~ VPath[pair[left]];
rs: REF Set--of Path-- ~ NARROW[pair[right].VA];
IF i=0 THEN firstSet ← rs;
IF nSets=1 AND arrayPrefix.cells#NIL THEN ERROR;
IF nSets=1 OR i>0 THEN rs^.Enumerate[DoAMerge];
lastPath ← VPath[rs^.First[].Val];
IF i=1 THEN firstSet^.Enumerate[DoAMerge];
i ← i + 1;
RETURN};
nsh.Increment[nSets];
dr.toMerge.Enumerate[DoASet];
IF i # nSets THEN ERROR;
dr.toMerge.Erase[];
IF NOT dr.toMerge.Empty[] THEN ERROR;
dr.mostRecentPathToMerge ← []};
MergeWork: PUBLIC PROC [cr: CellReading, path1, path2: Path] RETURNS [success: BOOL] = {
ct: CellType = cr.ct;
IF ct.asArray # NIL THEN ERROR;
IF path1.cells # NIL AND path2.cells # NIL THEN WITH path1.cells.first SELECT FROM
x: ROPE => WITH path2.cells.first SELECT FROM
y: ROPE => IF x.Equal[y] THEN {
ci: CellInstance = FetchSubcell[ct, OSn[x]];
it: CellType ~ cr.dr.d.CiT[ci];
IF it.asArray # NIL THEN {
CheckArrayUsage[cr.dr.d, it];
success ← ArrayMerge[cr, ci, x, path1.PTail, path2.PTail, cr.dr.curArray];
IF cr.dr.curArray AND NOT success THEN cr.waitingMerges ← CONS[NEW [PathPairPrivate ← [path1, path2]], cr.waitingMerges];
IF cr.dr.curArray OR success THEN RETURN;
};
};
y: REF Range2 => ERROR;
ENDCASE => ERROR;
x: REF Range2 => ERROR;
ENDCASE => ERROR;
MergeFinal[cr.dr, ct, path1, path2];
success ← TRUE;
};
FmtPath: PUBLIC PROC [path: Path] RETURNS [r: ROPE] = {
wr: ROPE ~ path.wireName.UnparseSteppyName[];
r ← NIL;
FOR cells: LORA ← path.cells, cells.rest WHILE cells # NIL DO
step: ROPEWITH cells.first SELECT FROM
x: ROPE => x,
x: REF Range2 => IO.PutFR["[%g:%g,%g:%g]", [integer[x[X].min]], [integer[x[X].maxPlusOne-1]], [integer[x[Y].min]], [integer[x[Y].maxPlusOne-1]]],
ENDCASE => ERROR;
r ← (IF r # NIL THEN r.Concat["/"] ELSE r).Concat[step];
ENDLOOP;
r ← IF r#NIL THEN r.Cat["/", wr] ELSE wr;
RETURN};
Start: PROC = {
[] ← HistogramsViewing.Show[h: nsh, viewerInit: [name: "LichenFromExt2Impl.DoMerges.nSets"], updatePeriod: 5];
RETURN};
Start[];
END.