SCCoreUtilImpl.mesa ///StdCell/SCCoreUtilImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bryan Preas, August 26, 1985 5:47:05 pm PDT
Frank Bowers December 18, 1985 4:23:30 pm PST
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: BOOLFALSE] = {
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: BOOLFALSE] = {
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];
};
END.