<> <> 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: ROPE _ NARROW[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: INT _ LOOPHOLE[k]; i2: INT _ LOOPHOLE[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.