LichenOpsImpl.Mesa
Last Edited by: Spreitzer, July 15, 1985 7:54:14 pm PDT
DIRECTORY Basics, LichenDataStructure, LichenOps, IO, RedBlackTree, Rope, ViewerIO;
LichenOpsImpl: CEDAR PROGRAM
IMPORTS LichenOps, IO, RedBlackTree, Rope, ViewerIO
EXPORTS LichenDataStructure, LichenOps =
BEGIN OPEN LichenDataStructure, LichenOps;
MirrorName: PUBLIC ROPE ← " world ";
log: IO.STREAM ← ViewerIO.CreateViewerStreams["Compare Log"].out;
Warn: PUBLIC PROC [source: Source, format: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] = {
IF source.stream # NIL THEN {
log.PutRope["Before "];
IF source.name # NIL THEN log.PutRope[source.name];
log.PutF["[%g]: ", IO.int[source.stream.GetIndex[]]];
}
ELSE IF source.name # NIL THEN log.PutF["In %g: ", IO.rope[source.name]];
log.PutF[format, v1, v2, v3, v4, v5];
log.PutChar['\n];
};
Err: PUBLIC PROC [source: Source, format: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] = {
IF source.stream # NIL THEN {
log.PutRope["Before "];
IF source.name # NIL THEN log.PutRope[source.name];
log.PutF["[%g]: ", IO.int[source.stream.GetIndex[]]];
}
ELSE IF source.name # NIL THEN log.PutF["In %g: ", IO.rope[source.name]];
log.PutF[format, v1, v2, v3, v4, v5];
log.PutChar['\n];
log.Flush[];
ERROR;
};
Log: PUBLIC PROC [format: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] =
{log.PutF[format, v1, v2, v3, v4, v5]};
Fail: PUBLIC PROC [af: AssertionFamily, ao: FailableAssertionOp, format: ROPE, v1, v2, v3, v4, v5: IO.Value ← [null[]]] = {
SELECT ao FROM
report => {log.PutF[format, v1, v2, v3, v4, v5]; log.PutRope["\n"]};
check => (SELECT af FROM normal => NotNormal, comparable => NotComparable, ENDCASE => ERROR)[IO.PutFR[format, v1, v2, v3, v4, v5]];
ENDCASE => ERROR
};
FlushLog: PUBLIC PROC = {log.Flush[]};
IsMirror: PUBLIC PROC [v: Vertex] RETURNS [isMirror: BOOL] =
{isMirror ← v = v.parent.mirror};
EnumerateNames: PUBLIC PROC [names: Names, consume: PROC [name: ROPE, class: ATOM--UNION[$designed, $unknown, $progged]--]] = {
Doit: PROC [rl: RopeList, class: ATOM] = {
FOR rl ← rl, rl.rest WHILE rl # NIL DO consume[rl.first, class] ENDLOOP;
};
Doit[names.designed, $designed];
Doit[names.unknown, $unknown];
Doit[names.progged, $progged];
};
NamesInclude: PUBLIC PROC [names: Names, name: ROPE] RETURNS [incl: BOOL] = {
incl
RopeListIncludes[names.designed, name] OR
RopeListIncludes[names.unknown, name] OR
RopeListIncludes[names.progged, name];
};
AddVertex: PUBLIC PROC [v: Vertex] =
BEGIN
Insert[v.parent.parts, v.names, v];
SELECT v.class FROM
net => v.parent.netCount ← v.parent.netCount + 1;
cell => v.parent.cellCount ← v.parent.cellCount + 1;
ENDCASE => ERROR;
END;
FindPort: PUBLIC PROC [ports: PortS, name: ROPE] RETURNS [portIndex: NAT] = {
FOR i: NAT IN [0 .. ports.length) DO
IF NamesInclude[ports[i].names, name] THEN RETURN [i];
ENDLOOP;
portIndex ← notFound;
};
RopeListIncludes: PUBLIC PROC [rl: RopeList, r: ROPE] RETURNS [found: BOOL] = {
FOR rl ← rl, rl.rest WHILE rl # NIL DO
IF rl.first.Equal[r] THEN RETURN [TRUE];
ENDLOOP;
found ← FALSE};
AddNames: PUBLIC PROC [ra: REF ANY--UNION[Vertex, CellType]--, names: Names] = {
Work: PROC [old: Names, byName: SymbolTable] RETURNS [new: Names] = {
ReallyWork: PROC [old, add: RopeList] RETURNS [new: RopeList] = {
new ← old;
FOR add ← add, add.rest WHILE add # NIL DO
a: Alias ← NEW [AliasRep ← [name: add.first, thing: ra]];
byName.Insert[a, a.name];
new ← CONS[add.first, new];
ENDLOOP;
};
new.designed ← ReallyWork[old.designed, names.designed];
new.unknown ← ReallyWork[old.unknown, names.unknown];
new.progged ← ReallyWork[old.progged, names.progged];
};
WITH ra SELECT FROM
ct: CellType => ct.names ← Work[ct.names, ct.design.cellTypesByName];
v: Vertex => v.names ← Work[v.names, v.parent.parts];
ENDCASE => ERROR;
};
Insert: PUBLIC PROC [st: SymbolTable, names: Names, val: REF ANY] = {
Work: PROC [rl: RopeList] = {
FOR rl ← rl, rl.rest WHILE rl # NIL DO
a: Alias ← NEW [AliasRep ← [name: rl.first, thing: val]];
st.Insert[a, a.name];
ENDLOOP;
};
Work[names.designed];
Work[names.unknown];
Work[names.progged];
};
Delete: PUBLIC PROC [st: SymbolTable, names: Names, val: REF ANY] = {
Work: PROC [rl: RopeList] = {
FOR rl ← rl, rl.rest WHILE rl # NIL DO
deld: REF ANY ← AntiAlias[st.Delete[rl.first].data];
IF deld # val THEN ERROR;
ENDLOOP;
};
Work[names.designed];
Work[names.unknown];
Work[names.progged];
};
GetIDKey: PUBLIC PROC [data: REF ANY] RETURNS [key: REF ANY] --RedBlackTree.GetKey-- =
{key ← data};
CompareRopes: PUBLIC PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
c ← NARROW[k, ROPE].Compare[NARROW[data]];
END;
GetAliasKey: PUBLIC PROC [data: REF ANY] RETURNS [key: ROPE] --RedBlackTree.GetKey-- =
{a: Alias ← NARROW[data]; key ← a.name};
CompareAliases: PUBLIC PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
k1: ROPENARROW[k];
k2: ROPE ← GetAliasKey[data];
c ← k1.Compare[k2];
END;
CompareByAddress: PUBLIC PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
i1: INTLOOPHOLE[k];
i2: INTLOOPHOLE[data];
c ← SELECT i1 - i2 FROM
<0 => less,
=0 => equal,
>0 => greater,
ENDCASE => ERROR;
END;
GetECParentNet: PUBLIC PROC [data: REF ANY] RETURNS [key: Vertex] --RedBlackTree.GetKey-- =
{ec: ExtraConnection ← NARROW[data]; key ← ec.parentNet};
CompareECParentNet: PUBLIC PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
k1: Vertex ← NARROW[k];
k2: Vertex ← GetECParentNet[data];
c ← CompareByAddress[k1, k2];
END;
GetECSubCell: PUBLIC PROC [data: REF ANY] RETURNS [key: Vertex] --RedBlackTree.GetKey-- =
{ec: ExtraConnection ← NARROW[data]; key ← ec.subCell};
CompareECSubCell: PUBLIC PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
k1: Vertex ← NARROW[k];
k2: Vertex ← GetECSubCell[data];
c ← CompareByAddress[k1, k2];
END;
GetECChildNet: PUBLIC PROC [data: REF ANY] RETURNS [key: Vertex] --RedBlackTree.GetKey-- =
{ec: ExtraConnection ← NARROW[data]; key ← ec.childNet};
CompareECChildNet: PUBLIC PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
k1: Vertex ← NARROW[k];
k2: Vertex ← GetECChildNet[data];
c ← CompareByAddress[k1, k2];
END;
CompareECSubCellThenChildNet: PUBLIC PROC [k, data: REF ANY] RETURNS [c: Basics.Comparison] --RedBlackTree.Compare-- =
BEGIN
k1: ExtraConnection ← NARROW[k];
k2: ExtraConnection ← NARROW[data];
IF (c ← CompareByAddress[k1.subCell, k2.subCell]) # equal THEN RETURN;
c ← CompareByAddress[k1.childNet, k2.childNet]
END;
Lookup: PUBLIC PROC [st: SymbolTable, key: ROPE] RETURNS [val: REF ANY] =
{val ← AntiAlias[st.Lookup[key]]};
AntiAlias: PUBLIC PROC [ra: REF ANY] RETURNS [val: REF ANY] = {
FOR val ← ra, NARROW[val, Alias].thing WHILE (val # NIL) AND ISTYPE[val, Alias] DO NULL ENDLOOP;
};
GlobalCellTypeName: PUBLIC PROC [ct: CellType] RETURNS [r: ROPE] = {
r ← ct.design.name.Cat[".", PickAName[ct.names]]};
GlobalPortName: PUBLIC PROC [ct: CellType, portIndex: PortIndex] RETURNS [r: ROPE] = {
r ← GlobalCellTypeName[ct].Cat[".", PickAName[ct.ports[portIndex].names]]};
GlobalVertexName: PUBLIC PROC [v: Vertex] RETURNS [r: ROPE] = {
r ← GlobalCellTypeName[v.parent].Cat[".", PickAName[v.names]]};
GlobalName: PUBLIC PROC [ra: REF ANY, soFar: Naming ← [NIL, NIL]] RETURNS [name: ROPE] = {
nn: Names ← NamingNames[soFar];
name ← PickAName[nn];
WITH ra SELECT FROM
design: Design => NULL;
ct: CellType => name ← ct.design.name.Cat[".", name];
v: Vertex => name ← GlobalCellTypeName[v.type].Cat[".", name];
s: Socket => name ← GlobalCellTypeName[s.ct].Cat[".", name];
ENDCASE => ERROR;
};
KeepAll: PUBLIC PROC [ra: REF ANY] RETURNS [keepAll: BOOL] = {
keepAll ← WITH ra SELECT FROM
d: Design => d.allKept,
ct: CellType => ct.design.allKept,
v: Vertex => v.type.design.allKept,
s: Socket => s.ct.design.allKept,
ENDCASE => ERROR};
PickAName: PUBLIC PROC [names: Names] RETURNS [name: ROPE] = {
Try: PROC [rl: RopeList] RETURNS [done: BOOL] =
{IF done ← (rl # NIL) THEN name ← rl.first};
IF Try[names.designed] THEN RETURN;
IF Try[names.unknown] THEN RETURN;
IF Try[names.progged] THEN RETURN;
ERROR;
};
END.