<> <> <> <> DIRECTORY Core, CoreClasses, CoreFlat, CoreOps, CoreProperties, HashTable, Rope, SC, SCCoreUtil, SCPrivate; SCCoreUtilImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreFlat, CoreOps, CoreProperties, HashTable, Rope, SC EXPORTS SCCoreUtil = BEGIN EnumerateInstances: PUBLIC PROC [cellType: Core.CellType, eachInstance: SCCoreUtil.EachInstanceProc] RETURNS [quit: BOOL _ FALSE] = { <> parentRCT: CoreClasses.RecordCellType _ NARROW[cellType.data]; IF parentRCT = NIL THEN SC.Error[callingError, Rope.Cat["Invalid Record Cell: ", CoreOps.GetCellTypeName[cellType]]]; FOR in: NAT IN [0..parentRCT.size) DO instance: CoreClasses.CellInstance _ parentRCT[in]; quit _ eachInstance[instance]; ENDLOOP; }; EnumerateFlatWires: PUBLIC PROC [wire: Core.Wire, eachWire: SCCoreUtil.EachWireProc] RETURNS [quit: BOOL _ FALSE] = { DoWire: CoreOps.EachWireProc = { IF wire.size = 0 THEN [subWires, quit] _ eachWire[wire]}; quit _ CoreOps.VisitWire[wire, DoWire]}; EnumFlatInstancePins: PUBLIC PROC [cellInstance: CoreClasses.CellInstance, eachInstancePin: SCCoreUtil.EachInstancePinProc] = { DoWire: CoreOps.EachWirePairProc = { <> IF actualWire # NIL AND actualWire.size = 0 AND publicWire.size = 0 THEN [subWires, quit] _ eachInstancePin[actualWire, publicWire]}; [] _ CoreOps.VisitBinding[cellInstance.actual, cellInstance.type.public, DoWire]}; Flatten: PUBLIC PROC [root: Core.CellType, flattenCellType: CoreFlat.FlattenCellTypeProc, definePublicWire, defineInternalWire: SCCoreUtil.FlatWireProc, defineInstance: SCCoreUtil.FlatInstanceProc] = { BuildPublic: PROC [wire: Core.Wire] = { name: Rope.ROPE; flatWire: CoreFlat.FlatWire = NEW [CoreFlat.FlatWireRec _ [wire: wire, path: CoreFlat.NullPath]]; IF HashTable.Fetch[rootFlatsToInternals, flatWire].value#NIL THEN RETURN; -- public already seen name _ CoreOps.GetFullWireName[root.public, wire]; [] _ HashTable.Store[rootFlatsToInternals, flatWire, wire]; [] _ defineInternalWire[wire, name]; [] _ definePublicWire[wire, name]; }; BuildActual: PROC [actual: Core.Wire, bindings: CoreFlat.Bindings] RETURNS [newActual: Core.Wire] = { IF actual.size=0 THEN { wireBind: CoreFlat.WireBind _ NARROW [HashTable.Fetch[bindings, actual].value]; flatWire: CoreFlat.FlatWire = NEW [CoreFlat.FlatWireRec _ [wire: wireBind.wire, path: wireBind.path]]; wireName: Rope.ROPE _ CoreFlat.WirePathRope[root, flatWire^]; newActual _ NARROW [HashTable.Fetch[rootFlatsToInternals, flatWire].value]; IF newActual#NIL THEN RETURN; newActual _ CoreOps.CopyWire[wireBind.wire]; [] _ HashTable.Store[rootFlatsToInternals, flatWire, newActual]; [] _ defineInternalWire[newActual, wireName]} ELSE { newActual _ CoreOps.CreateWires[size: actual.size]; FOR i: NAT IN [0 .. actual.size) DO newActual[i] _ BuildActual[actual[i], bindings]; ENDLOOP}}; EachInstance: CoreFlat.EachInstanceProc = { basic: Core.CellType; newActual: Core.Wire; name: Rope.ROPE _ CoreFlat.InstancePathRope[root, [path, instance]]; IF flattenCellType # NIL AND flattenCellType[instance.type] THEN RETURN [TRUE]; newActual _ BuildActual[instance.actual, bindings]; FOR basic _ instance.type, CoreOps.Recast[basic] UNTIL CoreProperties.GetCellTypeProp[basic, $Layout]#NIL DO NULL ENDLOOP; <<-- make an instance from basic>> [] _ defineInstance[CoreClasses.CreateInstance[newActual, basic, name, instance.properties], name]; RETURN[FALSE]}; rootFlatsToInternals: CoreFlat.Bindings _ HashTable.Create[equal: CoreFlat.FlatWireEqual, hash: CoreFlat.FlatWireHash]; CoreOps.VisitAtomicWires[root.public, BuildPublic]; CoreFlat.EnumerateLeaves[root, EachInstance]; }; END.