LichenPrintingImpl.Mesa
Last tweaked by Mike Spreitzer on May 4, 1988 6:50:53 pm PDT
DIRECTORY AbSets, BiRels, FS, IntStuff, IO, LichenDataStructure, LichenIntBasics, LichenPrinting, Rope, SetBasics, StructuredStreams, TiogaAccess, UnparserBuffer;
LichenPrintingImpl:
CEDAR
PROGRAM
IMPORTS AbSets, BiRels, FS, IntStuff, IO, LichenDataStructure, Rope, SetBasics, StructuredStreams, TiogaAccess, UnparserBuffer
EXPORTS LichenPrinting
=
BEGIN OPEN IB:LichenIntBasics, IB, LichenDataStructure, LichenPrinting, Ints:IntStuff, Sets:AbSets, SS:StructuredStreams, UB:UnparserBuffer;
printStep: INT ← 2;
printWidth: INT ← 76;
sortTops: BOOL ← TRUE;
PrintObject:
PROC [to:
IO.
STREAM, united:
BOOL,
PrintIt:
PROC] = {
SS.Bp[to, IF united THEN united ELSE lookLeft, printStep];
SS.Begin[to];
PrintIt[!UNWIND => SS.End[to]];
SS.End[to];
RETURN};
PrintRope:
PROC [to:
IO.
STREAM, united:
BOOL, rope:
ROPE] = {
SS.Bp[to, IF united THEN united ELSE lookLeft, printStep];
SS.Begin[to];
to.PutRope[rope !UNWIND => SS.End[to]];
SS.End[to];
RETURN};
PrintDesignOnFile:
PUBLIC
PROC [d: Design, nameGen: NameGenerator ←
NIL, fileName:
ROPE ←
NIL, tioga:
BOOL ←
FALSE, pacify:
IO.
STREAM ←
NIL,
Filter: CellTypeFilter ←
NIL] = {
realFileName: ROPE = IF fileName # NIL THEN fileName ELSE Rope.Cat[Describe[d: d, subject: d, nameGen: nameGen], ".design"];
ss, fs: IO.STREAM;
taw: TiogaAccess.Writer;
IF tioga
THEN {
taw ← TiogaAccess.Create[];
ss ← SS.Create[UB.NewInittedHandle[[output: [access[taw, printStep]], margin: printWidth]]];
}
ELSE {
fs ← FS.StreamOpen[fileName: realFileName, accessOptions: create, keep: 10];
ss ← SS.Create[UB.NewInittedHandle[[output: [stream[fs]], margin: printWidth]]];
};
PrintDesignSubset[ss, d, nameGen, pacify, Filter];
IF tioga THEN TiogaAccess.WriteFile[taw, realFileName] ELSE IO.Close[fs];
ss.Close[];
RETURN};
PrintDesign:
PUBLIC
PROC [to:
IO.
STREAM, d: Design, nameGen: NameGenerator ←
NIL, pacify:
IO.
STREAM ←
NIL] = {
PrintDesignSubset[to, d, nameGen, pacify, NIL];
RETURN};
PrintDesignSubset:
PUBLIC
PROC [to:
IO.
STREAM, d: Design, nameGen: NameGenerator ←
NIL, pacify:
IO.
STREAM ←
NIL,
Filter: CellTypeFilter ←
NIL] = {
n: NAT ← 0;
CTPrint:
PROC [ra:
REF
ANY] = {
ct: CellType = NARROW[ra];
Inner:
PROC = {
IF pacify#NIL THEN pacify.PutF["%g: %g ", [integer[n ← n+1]], [rope[Describe[d, ct, d, nameGen]]]];
PrintCellType[to, ct, nameGen];
IF pacify#NIL THEN pacify.PutRope[" .\n"];
RETURN};
IF Filter=NIL OR Filter[ct] THEN PrintObject[to, TRUE, Inner];
RETURN};
IF pacify#NIL AND Filter=NIL THEN pacify.PutF["Total: %g\n", [integer[d.cellTypes.Size.EN]]];
IF NOT SS.IsAnSS[to] THEN to ← SS.Create[UB.NewInittedHandle[[output: [stream[to]], margin: printWidth]]];
to.PutF["%g: Design {", [rope[Describe[d: d, subject: d, nameGen: nameGen]]]];
d.cellTypes.EnumA[CTPrint];
to.PutF["}"];
RETURN};
PrintNameAndAliases:
PROC [to:
IO.
STREAM, names: Set
--of SteppyName--, nonrelnames: Set ← nilSet] ~ {
first, second: BOOL ← TRUE;
prefix: ROPE ← NIL;
PerName:
PROC [val: Sets.Value] ~ {
name: SteppyName ~ VSn[val];
IF first
THEN first ←
FALSE
ELSE {
IF second THEN {to.PutRope["(a.k.a."]; second ← FALSE} ELSE to.PutRope[","];
SS.Bp[to, width, printStep, " "];
};
to.PutRope[prefix];
to.PutRope[UnparseSteppyName[name]];
RETURN};
names.Enumerate[PerName];
IF nonrelnames#nilSet
THEN {
prefix ← "/";
nonrelnames.Enumerate[PerName]};
IF NOT second THEN to.PutRope[")"];
RETURN};
PrintCellType:
PUBLIC
PROC [to:
IO.
STREAM, ct: CellType, nameGen: NameGenerator ←
NIL] = {
PortPrint:
PROC = {
tops: Set ~ ct.CTParts[p].Intersection[ct.d.isTop];
sep: ROPE ← NIL;
PrintAPort:
PROC [pv: Sets.Value]
RETURNS [
BOOL] ~ {
p: Port ~ NARROW[pv.VA];
PPrint: PROC ~ {PrintPW[to, ct, p, p, NIL, nameGen]};
to.PutRope[sep]; PrintObject[to, FALSE, PPrint];
sep ← ", "; RETURN [FALSE]};
to.PutRope["ports: ["];
IF tops.Scan[PrintAPort, IF sortTops THEN ct.fullName[p].MapOrder[leftToRight, steppyNameSpace.SpaceOrder] ELSE Sets.alleq].found THEN ERROR;
to.PutRope["]"];
RETURN};
IWPrint:
PROC = {
tops: Set ~ ct.CTParts[w].Intersection[ct.d.isTop];
sep: ROPE ← NIL;
PrintAWire:
PROC [wv: Sets.Value]
RETURNS [
BOOL] ~ {
w: Wire ~ NARROW[wv.VA];
WPrint: PROC ~ {PrintPW[to, ct, w, w, NIL, nameGen]};
to.PutRope[sep]; PrintObject[to, FALSE, WPrint];
sep ← ", "; RETURN [FALSE]};
to.PutRope["internal wires: ["];
IF tops.Scan[PrintAWire, IF sortTops THEN ct.fullName[w].MapOrder[leftToRight, steppyNameSpace.SpaceOrder] ELSE Sets.alleq].found THEN ERROR;
to.PutRope["]"];
RETURN};
CIPrint:
PROC = {
to.PutF["connection sites: "];
PrintCells[to, ct, ct.TypeSites, nameGen];
RETURN};
AyPrint:
PROC = {
to.PutRope["asArray: "];
PrintArray[to, ct, nameGen]
};
IF NOT SS.IsAnSS[to] THEN to ← SS.Create[UB.NewInittedHandle[[output: [stream[to]], margin: printWidth]]];
to.PutRope[Describe[ct.d, ct, ct.d, nameGen]];
to.PutRope[": CellType["];
PrintObject[to, TRUE, PortPrint];
IF ct.asu #
NIL
THEN {
to.PutRope[", "]; PrintObject[to, TRUE, IWPrint];
to.PutRope[", "]; PrintObject[to, TRUE, CIPrint];
};
IF ct.asArray #
NIL
THEN {
to.PutRope[", "]; PrintObject[to, TRUE, AyPrint];
};
to.PutRope["]"];
};
PrintPW:
PROC [to:
IO.
STREAM, ct: CellType, class: PWClass, pw:
PW, parent:
PW ←
NIL, nameGen: NameGenerator ←
NIL] ~ {
[] ← ct.d.Describe[pw, IF parent#NIL THEN parent ELSE ct, nameGen];
{fullNames: Set ~ ct.fullName[class].MappingA[pw];
IF parent#
NIL
THEN {
relNames: Set ~ RelativeNames[ct, class, parent, pw];
reldNames: Set ~ SNsCat[ct.fullName[class].MappingA[parent], relNames];
nonRelNames: Set ~ fullNames.Difference[reldNames];
PrintNameAndAliases[to, relNames, nonRelNames];
to ← to}
ELSE PrintNameAndAliases[to, fullNames];
IF ct.d.Atomic[pw] THEN RETURN;
{shape: LOI ~ Shape[ct, class, pw];
IF shape#
NIL
THEN {
IF shape.rest=NIL THEN ERROR;
FOR dims:
LOI ← shape, dims.rest
WHILE dims.rest#
NIL
DO
to.PutF["*%g", [integer[dims.first]]];
ENDLOOP;
RETURN};
{kids: Seq ~ BiRels.DeRef[ct.d.sub.ApplyA[pw].MA];
first: BOOL ← TRUE;
to.PutRope["["];
FOR i:
INT
IN [0 .. kids.Size.
EN)
DO
kid: PW ~ kids.ApplyI[i].MA;
PWPrint: PROC ~ {PrintPW[to, ct, class, kid, pw, nameGen]};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, PWPrint];
ENDLOOP;
to.PutRope["]"];
RETURN}}}};
listOne: LOI ~ LIST[1];
Shape:
PROC [ct: CellType, class: PWClass, pw:
PW]
RETURNS [
LOI] ~ {
IF ct.d.Atomic[pw] THEN RETURN [listOne];
{kids: Seq ~ BiRels.DeRef[ct.d.sub.ApplyA[pw].MA];
width: LNAT ~ kids.Size.EN;
subShape: LOI ← NIL;
FOR i:
INT
IN [0 .. width)
DO
kid: PW ~ kids.ApplyI[i].MA;
thissub: LOI;
AcceptIndex:
PROC [sn: SteppyName]
RETURNS [
BOOL] ~ {
IF sn.grade.nonsubs#0 OR sn.grade.subs#1 THEN RETURN [FALSE];
IF NARROW[sn.steps.first, REF INT]^ # i THEN RETURN [FALSE];
RETURN [TRUE]};
IF NOT ct.ScanRelativeNames[class, pw, kid, AcceptIndex].found THEN RETURN [NIL];
thissub ← Shape[ct, class, kid];
IF thissub=NIL THEN RETURN [NIL];
IF subShape=NIL THEN subShape ← thissub ELSE IF NOT LoiEqual[subShape, thissub] THEN RETURN [NIL];
ENDLOOP;
RETURN [CONS[width, subShape]]}};
LoiEqual:
PROC [l1, l2:
LOI]
RETURNS [
BOOL] ~ {
WHILE l1#l2
DO
IF l1=NIL OR l2=NIL OR l1.first#l2.first THEN RETURN [FALSE];
l1 ← l1.rest;
l2 ← l2.rest;
ENDLOOP;
RETURN [TRUE]};
PrintCells:
PUBLIC
PROC [to:
IO.
STREAM, cct: CellType, set: Set
--OF Cell--, nameGen: NameGenerator ←
NIL] = {
first: BOOL ← TRUE;
PrintIt:
PROC [cell: Cell] = {
IPrint: PROC = {PrintCell[to, cct, cell, nameGen]};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, TRUE, IPrint];
};
to.PutRope["["];
set.EnumA[PrintIt];
to.PutRope["]"];
};
PrintCell:
PUBLIC
PROC [to:
IO.
STREAM, cct: CellType, cell: Cell, nameGen: NameGenerator ←
NIL] = {
conns: Fn--Port b Wire--;
PrintForPorts:
PROC [pct: CellType, ports: Set
--of Port--, rel:
REF
ANY, sort:
BOOL] = {
first: BOOL ← TRUE;
PrintForPort:
PROC [val: Sets.Value]
RETURNS [
BOOL] ~ {
p: Port ~ NARROW[val.VA];
CPrint:
PROC ~ {
w: Wire ~ NARROW[conns.ApplyA[p].MDA];
to.PutRope[cct.d.Describe[p, rel, nameGen]];
to.PutRope[": "];
IF w#NIL THEN {to.PutRope[cct.d.Describe[w, cct, nameGen]]; RETURN};
{pkids: Seq--of Port-- ~ BiRels.DeRef[cct.d.sub.ApplyA[p].MDA];
IF pkids=nilBiRel THEN {to.PutRope["??"]; RETURN};
{wkids: Seq--of Wire-- ~ pkids.Compose[conns];
nwkids: NATURAL ~ wkids.Size.EN;
npkids: NATURAL ~ pkids.Size.EN;
IF nwkids#npkids THEN GOTO NotEasy;
{ws: Set--of Wire-- ~ wkids.SetOn[right];
IF ws.Size=Ints.one THEN {to.PutF["%g*%g", [rope[cct.d.Describe[ws.TheElt.VA, cct, nameGen]]], [integer[pkids.Size.EN]]]; RETURN};
{wparents: Set--of Wire-- ~ cct.d.parent.Image[ws];
IF wparents.Size#Ints.one THEN GOTO NotEasy;
{wparent: Wire ~ NARROW[wparents.TheElt.VA];
allwkids: Seq--of Wire-- ~ BiRels.DeRef[cct.d.sub.ApplyA[wparent].MA];
mi: Sets.MaybeValue ~ allwkids.Index[wkids];
IF NOT mi.found THEN GOTO NotEasy;
{base: NATURAL ~ mi.it.VI;
to.PutRope[cct.d.Describe[wparent, cct, nameGen]];
IF base#0 OR allwkids.Size.EN#npkids THEN to.PutF["[%g..%g]", [integer[base]], [integer[base+npkids-1]] ];
RETURN}}}};
EXITS NotEasy => NULL};
PrintForPorts[pct, pkids.SetOn[right], p, FALSE];
RETURN}};
IF first THEN first ← FALSE ELSE to.PutRope[", "];
PrintObject[to, FALSE, CPrint];
RETURN [FALSE]};
to.PutRope["["];
IF ports.Scan[PrintForPort, IF sort AND sortTops THEN pct.fullName[p].MapOrder[leftToRight, steppyNameSpace.SpaceOrder] ELSE Sets.alleq].found THEN ERROR;
to.PutRope["]"];
RETURN};
WITH cell
SELECT
FROM
ct: CellType => {
IF ct # cct THEN ERROR;
conns ← ct.asu.exports;
to.PutRope["exports"];
PrintForPorts[ct, ct.TopParts[p], ct, TRUE];
RETURN};
ci: CellInstance => {
ict: CellType ~ cct.d.CiT[ci];
conns ← ci.conns;
[] ← cct.d.Describe[ci, cct, nameGen];
PrintNameAndAliases[to, cct.INames[ci]];
to.PutF[": %g", [rope[cct.d.Describe[ict, cct.d, nameGen]]] ];
PrintForPorts[ict, ict.TopParts[p], ict, TRUE];
RETURN};
ENDCASE => ERROR;
};
printStatRep: BOOL ← TRUE;
printDumbRep: BOOL ← FALSE;
PrintArray:
PUBLIC
PROC [to:
IO.
STREAM, act: CellType, nameGen: NameGenerator ←
NIL] = {
a: Array = act.asArray;
ect: CellType ~ act.EltType[];
BasePrint:
PROC = {
to.PutF["base period = [%g, %g]", [integer[a.basePeriod[X]]], [integer[a.basePeriod[Y]]]]};
StatPrint:
PROC = {
to.PutRope["static graph = ["];
PrintStatRep[to, act, nameGen];
to.PutRope["]"];
};
to.PutF["{%g BY %g OF %g, ",
[integer[a.size2[X]]], [integer[a.size2[Y]]],
[rope[act.d.Describe[ect, act.d, nameGen]]]
];
PrintObject[to, FALSE, BasePrint];
IF printStatRep
THEN {
to.PutRope[", "];
PrintObject[to, TRUE, StatPrint];
};
IF printDumbRep THEN ERROR nyet;
to.PutRope["}"];
};
PrintStatRep:
PROC [to:
IO.
STREAM, act: CellType, nameGen: NameGenerator] ~ {
a: Array = act.asArray;
ect: CellType ~ act.EltType[];
firstEdge: BOOL ← TRUE;
EnsureNamed:
PROC [part: Part] ~ {
[] ← act.d.Describe[part, ect, nameGen];
RETURN};
PrintEdge:
PROC [val: Sets.Value] ~ {
IF firstEdge THEN firstEdge ← FALSE ELSE to.PutRope[", "];
PrintRope[to, TRUE, a.statrep.edgeSpace.SFormat[val]];
RETURN};
ect.EnumCTParts[p, TRUE, TRUE, EnsureNamed];
a.statrep.edges.Enumerate[PrintEdge, Sets.fwd];
RETURN};
IsArray: PROC [ct: CellType] RETURNS [pass: BOOL] = {pass ← ct.asArray # NIL};
Is1D:
PROC [ct: CellType]
RETURNS [
BOOL]
~ {RETURN [ct.asArray#NIL AND (ct.asArray.size2[X]=1 OR ct.asArray.size2[Y]=1)]};
Is2D:
PROC [ct: CellType]
RETURNS [
BOOL]
~ {RETURN [ct.asArray#NIL AND ct.asArray.size2[X]#1 AND ct.asArray.size2[Y]#1]};
PrintArrays:
PROC [to:
IO.
STREAM, d: Design, nameGen: NameGenerator ←
NIL, pacify:
IO.
STREAM ←
NIL] = {
PrintDesignSubset[to, d, nameGen, pacify, IsArray];
};
END.