RawExtractCell: Sinix.ExtractProc = {
flattenSomeChild: BOOL ← FALSE;
rct: CoreClasses.RecordCellType;
new, record: CellType;
newInternals: Wires ← NIL; -- used only if flatten of a child necessary
instances: LIST OF CoreClasses.CellInstance ← NIL; -- used only if flatten of a child necessary
[result, props] ← Sinix.ExtractCell[obj, mode, properties, userData];
record ← NARROW [result];
rct ← NARROW [record.data];
IF rct.size=0 THEN CoreProperties.PutCellTypeProp[record, $RawFlatten, $Keep];
IF CDProperties.GetObjectProp[obj, $RawFlatten]=$RawFlatten THEN CoreProperties.PutCellTypeProp[record, $RawFlatten, $Smash];
FOR i:
NAT
IN [0 .. rct.size)
DO
IF CoreProperties.GetCellTypeProp[rct[i].type, $RawFlatten]#NIL THEN flattenSomeChild ← TRUE;
ENDLOOP;
IF flattenSomeChild OR CoreProperties.GetCellTypeProp[record, $RawFlatten]#NIL THEN [] ← CoreOps.VisitWireSeq[record.public, ExplicitPins];
[] ← CoreOps.VisitWireSeq[record.public, ExplicitPins]; -- we want to avoid the TransWireIR lazyness which is using the InterestRect
IF NOT flattenSomeChild THEN RETURN;
TerminalIO.PutF["In cell %g, flattening:", IO.rope[CDDirectory.Name[obj]]];
we explicit the pins to avoid circularity (and to gain some speed up in the shared case)
[] ← CoreOps.VisitWireSeq[record.public, ExplicitPins];
FOR i:
NAT
IN [0 .. rct.size)
DO
IF CoreProperties.GetCellTypeProp[rct[i].type, $RawFlatten]=
NIL
THEN instances ← CONS [rct[i], instances]
ELSE {
The following code does not deal properly with DAGS. Who cares?
CreateWire:
PROC [old: Wire]
RETURNS [wire: Wire] = {
geometry: CoreGeometry.Instances ← CoreGeometry.GetGeometry[mode.decoration, old];
IF geometry#NIL THEN geometry ← LIST [CoreGeometry.Transform[trans, geometry.first]]; -- Hack to save some space for now!
wire ← CoreOps.CreateWire[];
CoreGeometry.PutGeometry[mode.decoration, wire, geometry];
newInternals ← CONS [wire, newInternals];
};
AddInTable:
PROC [subInternal: Wire] = {
IF HashTable.Fetch[intToInt, subInternal].value#NIL THEN RETURN;
[] ← HashTable.Store[intToInt, subInternal, CreateWire[subInternal]];
};
CreateActual:
PROC [oldAct: Wire]
RETURNS [newAct: Wire] = {
newAct ← NARROW [HashTable.Fetch[intToInt, oldAct].value];
IF newAct#NIL THEN RETURN;
IF oldAct.size=0
THEN [] ← HashTable.Store[intToInt, oldAct, newAct ← CreateWire[oldAct]]
ELSE {
newAct ← CoreOps.CreateWires[size: oldAct.size];
FOR i: NAT IN [0 .. oldAct.size) DO newAct[i] ← CreateActual[oldAct[i]] ENDLOOP;
};
};
DecorateBinding: HashTable.EachPairAction = {
pub: Wire = NARROW [key];
act: Wire = NARROW [value];
geometry: CoreGeometry.Instances ← CoreGeometry.GetGeometry[mode.decoration, pub];
IF geometry#
NIL
THEN CoreGeometry.AddGeometry[
mode.decoration, act, LIST [CoreGeometry.Transform[trans, geometry.first]]
]; -- Hack to save some space for now!
};
name: ROPE = CoreOps.GetCellTypeName[rct[i].type];
trans: CoreGeometry.Transformation = CoreGeometry.GetTrans[mode.decoration, rct[i]];
subrct: CoreClasses.RecordCellType = NARROW [rct[i].type.data];
intToInt: HashTable.Table ← CoreOps.CreateBindingTable[rct[i].type.public, rct[i].actual];
[] ← HashTable.Pairs[intToInt, DecorateBinding];
IF NOT Rope.Equal[CDDirectory.Name[CoreGeometry.GetObject[mode.decoration, rct[i].type]], name] THEN ERROR;
TerminalIO.PutF[" %g[%g]", IO.rope[name], IO.int[subrct.size]];
CoreOps.VisitRootAtomics[subrct.internal, AddInTable];
FOR j:
NAT
IN [0 .. subrct.size)
DO
instance: CoreClasses.CellInstance ← CoreClasses.CreateInstance[actual: CreateActual[subrct[j].actual], type: subrct[j].type, props: subrct[j].properties];
CoreGeometry.PutTrans[mode.decoration, instance, CDBasics.ComposeTransform[itemInCell: CoreGeometry.GetTrans[mode.decoration, subrct[j]], cellInWorld: trans]];
instances ← CONS [instance, instances]
ENDLOOP;
-- We flush the Sinix cache for name
IF CoreProperties.GetCellTypeProp[rct[i].type, $RawFlatten]=$Smash THEN Sinix.FlushCache[CoreGeometry.GetObject[mode.decoration, rct[i].type]];
};
ENDLOOP;
new ← CoreClasses.CreateRecordCell[record.public, CoreOps.UnionWire[rct.internal, CoreOps.CreateWire[newInternals]], instances, NIL, record.properties, TRUE];
CoreGeometry.PutObject[mode.decoration, new, CoreGeometry.GetObject[mode.decoration, record]];
IF CDProperties.GetObjectProp[obj, $RawFlatten]#$RawFlatten AND instances=NIL THEN CoreProperties.PutCellTypeProp[new, $RawFlatten, $Keep];
TerminalIO.PutF[".\n"];
result ← new;
};