EnumerateInstances:
PUBLIC
PROC [cellType: Core.CellType, eachInstance: SCCoreUtil.EachInstanceProc]
RETURNS [quit:
BOOL ←
FALSE] = {
May raise StructureError[MissingParameter].
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 = {
added test for actualWire = NIL - Frank Bowers January 10, 1986 11:05:46 am PST
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];
};