WHILE (isRecordCell ← expand[cellType])
AND cellType.class#CoreClasses.recordCellClass
DO
cellType ← CoreOps.Recast[cellType];
IF cellType=NIL THEN ERROR;
ENDLOOP;
BEGIN
data: CoreClasses.RecordCellType ← NARROW [cellType.data];
flatInterns: LIST OF Wire ← NIL;
flatInstances: LIST OF CoreClasses.CellInstance ← NIL;
correspondindFlatWires: HashTable.Table ← HashTable.Create[];
FOR i:
NAT
IN [0 .. data.internal.size)
DO
thisFlat: Wire ← CoreOps.CopyWire[data.internal[i]];
flatInterns ← CONS [thisFlat, flatInterns];
[] ← HashTable.Store[correspondindFlatWires, data.internal[i], thisFlat];
ENDLOOP;
FOR i:
NAT
IN [0 .. data.size)
DO
instance: CoreClasses.CellInstance ← data[i];
subCell: CellType; isSubRecordCell: BOOL;
[subCell, isSubRecordCell] ← Flatten[instance.type, expand];
IF ~isSubRecordCell
THEN {
thisInstance: CoreClasses.CellInstance ←
NEW [CoreClasses.CellInstanceRec ← [
actual: MakeFlattenedWire[correspondindFlatWires, instance.actual],
type: subCell,
properties: CoreProperties.CopyProps[instance.properties]]];
flatInstances ← CONS [thisInstance, flatInstances];
} ELSE {
The game is now to mark each of the internal wires of the instance. Some are derived from the actual, others must be added to flatInterns;
subData: CoreClasses.RecordCellType ← NARROW [subCell.data];
subCorrespondingFlatWires: HashTable.Table ← HashTable.Create[];
FOR i:
NAT
IN [0 .. subCell.public.size)
DO
val: REF ← HashTable.Fetch[correspondindFlatWires, instance.actual[i]].value;
IF val=NIL THEN ERROR;
[] ← HashTable.Store[subCorrespondingFlatWires, subCell.public[i], val];
ENDLOOP;
FOR i:
NAT
IN [0 .. subData.internal.size)
DO
IF HashTable.Fetch[subCorrespondingFlatWires, subData.internal[i]].value=
NIL
THEN {
thisFlat: Wire ← CoreOps.CopyWire[subData.internal[i]];
flatInterns ← CONS [thisFlat, flatInterns];
[] ← HashTable.Store[subCorrespondingFlatWires, subData.internal[i], thisFlat];
Sinix.PutWireGeometryProp[
thisFlat,
Sinix.TransformList[NARROW[CoreProperties.GetCellInstanceProp[instance, Sinix.instanceProp]], Sinix.GetWireGeometryProp[subData.internal[i]]]];
};
ENDLOOP;
FOR i:
NAT
IN [0 .. subData.size)
DO
subInstance: CoreClasses.CellInstance ← subData[i];
thisInstance: CoreClasses.CellInstance ←
NEW [CoreClasses.CellInstanceRec ← [
actual: MakeFlattenedWire[subCorrespondingFlatWires, subInstance.actual],
type: subInstance.type,
properties: CoreProperties.CopyProps[subInstance.properties]]];
CoreProperties.PutCellInstanceProp[
thisInstance,
Sinix.instanceProp,
Sinix.Transform[
NARROW [CoreProperties.GetCellInstanceProp[instance, Sinix.instanceProp]],
NARROW [CoreProperties.GetCellInstanceProp[subInstance, Sinix.instanceProp]]]];
flatInstances ← CONS [thisInstance, flatInstances];
ENDLOOP;
};
ENDLOOP;
flat ← CoreClasses.CreateRecordCell[
public: MakeFlattenedWire[correspondindFlatWires, cellType.public],
internal: CoreOps.CreateWire[flatInterns],
instances: flatInstances,
name: CoreOps.GetCellTypeName[cellType],
props: CoreProperties.CopyProps[cellType.properties]
];
END;