ScaldIOImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Barth, March 31, 1987 5:38:44 pm PST
Bertrand Serlet July 8, 1986 12:45:06 pm PDT
DIRECTORY Convert, Core, CoreClasses, CoreOps, FS, RefTab, IO, Rope, ScaldIO;
ScaldIOImpl: CEDAR PROGRAM
IMPORTS Convert, CoreClasses, CoreOps, FS, RefTab, IO, Rope
EXPORTS ScaldIO
= BEGIN OPEN ScaldIO;
ROPE: TYPE = Core.ROPE;
Handle: TYPE = REF HandleRec;
HandleRec: TYPE = RECORD[
stream: Core.STREAMNIL,
cellTypeInfoTab: RefTab.Ref ← NIL,
cellID: NAT ← 0];
CellTypeInfo: TYPE = REF CellTypeInfoRec;
CellTypeInfoRec: TYPE = RECORD[
name: ROPENIL,
written: BOOLFALSE];
SaveCellType: PUBLIC PROC [cellType: Core.CellType, fileName: ROPENIL] = {
h: Handle ← NEW[HandleRec];
cellType ← CoreOps.ToBasic[cellType];
IF fileName=NIL THEN fileName ← Rope.Cat[CoreOps.GetCellTypeName[cellType], ".scald"];
h.stream ← FS.StreamOpen[fileName, $create];
h.cellTypeInfoTab ← RefTab.Create[];
WriteCellType[h, cellType];
IO.Close[h.stream];
};
WriteCellType: PUBLIC PROC [h: Handle, cellType: Core.CellType] = {
cellTypeInfo: CellTypeInfo;
cellType ← CoreOps.ToBasic[cellType];
cellTypeInfo ← NARROW[RefTab.Fetch[h.cellTypeInfoTab, cellType].val];
IF cellTypeInfo=NIL OR NOT cellTypeInfo.written THEN {
RemoveDots: PROC [old: ROPE] RETURNS [new: ROPE] = {
pos: INT;
new ← old;
WHILE (pos ← Rope.Find[new, "."])>-1 DO
new ← Rope.Replace[base: new, start: pos, len: 1, with: "x"];
ENDLOOP;
};
GenInfo: PROC [cellType: Core.CellType] RETURNS [cellTypeInfo: CellTypeInfo] = {
cellTypeID: ROPE ← Rope.Cat["Cell", Convert.RopeFromCard[from: h.cellID, showRadix: FALSE]];
h.cellID ← h.cellID + 1;
cellType ← CoreOps.ToBasic[cellType];
cellTypeID ← Rope.Cat[cellTypeID, RemoveDots[CoreOps.GetCellTypeName[cellType]]];
cellTypeInfo ← NEW[CellTypeInfoRec];
cellTypeInfo.name ← cellTypeID;
IF NOT RefTab.Insert[h.cellTypeInfoTab, cellType, cellTypeInfo] THEN ERROR;
};
IF cellTypeInfo=NIL THEN cellTypeInfo ← GenInfo[cellType];
cellTypeInfo.written ← TRUE;
SELECT cellType.class FROM
CoreClasses.transistorCellClass => NULL;
CoreClasses.recordCellClass => {
WritePublic: PROC [publicWire: Core.Wire, name: ROPE] = {
IF publicWire.size=0 THEN {
IF wireCount=0 THEN IO.PutRope[h.stream, "PARAMETER = "]
ELSE IO.PutRope[h.stream, ", "];
IO.PutRope[h.stream, name];
IF NOT RefTab.Insert[wireIDTab, publicWire, name] THEN ERROR;
wireCount ← wireCount+1;
}
ELSE FOR i: NAT IN [0..publicWire.size) DO
subWire: Core.Wire ← publicWire[i];
subName: ROPE ← PublicName[subWire, name, i];
WritePublic[subWire, subName];
ENDLOOP;
};
PublicName: PROC [publicWire: Core.Wire, prefix: ROPE, index: NAT] RETURNS [name: ROPE] = {
name ← CoreOps.GetShortWireName[publicWire];
IF name=NIL THEN name ← Convert.RopeFromCard[from: index, showRadix: FALSE];
name ← Rope.Cat[prefix, "x", name];
};
WriteBind: PROC [actual, public: Core.Wire, publicName: ROPE] = {
IF actual.size>0 THEN FOR i: NAT IN [0..actual.size) DO
WriteBind[actual[i], public[i], PublicName[public[i], publicName, i]];
ENDLOOP
ELSE {
actualName: ROPENARROW[RefTab.Fetch[wireIDTab, actual].val];
IF wireCount>0 THEN IO.PutRope[h.stream, ", "];
IO.PutRope[h.stream, publicName];
IO.PutRope[h.stream, "="];
IF actualName=NIL THEN {
actualName ← Rope.Cat["NUL%", Convert.RopeFromCard[from: idCount, showRadix: FALSE]];
idCount ← idCount + 1;
IF NOT RefTab.Insert[wireIDTab, actual, actualName] THEN ERROR;
};
IO.PutRope[h.stream, actualName];
wireCount ← wireCount+1;
};
};
wireIDTab: RefTab.Ref ← RefTab.Create[];
wireCount: NAT ← 0;
idCount: NAT ← 0;
rct: CoreClasses.RecordCellType ← NARROW[cellType.data];
IO.PutRope[h.stream, "\nMNAME = "];
IO.PutRope[h.stream, cellTypeInfo.name];
IO.PutRope[h.stream, ";\n"];
FOR i: NAT IN [0..cellType.public.size) DO
subWire: Core.Wire ← cellType.public[i];
WritePublic[subWire, PublicName[subWire, NIL, i]];
ENDLOOP;
IF wireCount>0 THEN IO.PutRope[h.stream, ";\n"];
FOR instance: NAT IN [0..rct.size) DO
subType: Core.CellType ← rct[instance].type;
subName: ROPE;
SELECT subType.class FROM
CoreClasses.transistorCellClass => {
tran: CoreClasses.Transistor ← NARROW[subType.data];
subName ← CoreClasses.transistorTypeNames[tran.type];
};
CoreClasses.recordCellClass => {
subInfo: CellTypeInfo ← NARROW[RefTab.Fetch[h.cellTypeInfoTab, subType].val];
IF subInfo=NIL THEN subInfo ← GenInfo[subType];
subName ← subInfo.name;
};
ENDCASE => ERROR;
IO.PutRope[h.stream, subName];
wireCount ← 0;
IO.PutRope[h.stream, "("];
WriteBind[rct[instance].actual, subType.public, NIL];
IO.PutRope[h.stream, ");\n"];
ENDLOOP;
IO.PutRope[h.stream, "END;\n"];
FOR instance: NAT IN [0..rct.size) DO
WriteCellType[h, rct[instance].type];
ENDLOOP;
};
ENDCASE => ERROR;
};
};
END.