ExtractSequence: Sinix.ExtractProc = {
name: ROPE ← mode.nameProc[obj, userData];
cx: Sisyph.Context;
keyword, expr: ROPE;
others: ROPES;
cellType: CellType;
count: NAT;
[keyword, expr, others] ← ParseSatellites[NARROW [CDProperties.GetObjectProp[obj, Sinix.satellitesProp]]];
IF keyword=
NIL
THEN {
TerminalIO.PutF["*** SisyphExtractSequence: Sequence does not contain any of sequencing information (e.g. an object satellite 'SeqX: 32').\n"];
ERROR;
};
CDProperties.PutObjectProp[obj, Sinix.satellitesProp, others];
cx ← Sisyph.EvaluateParameters[userData, obj, properties];
Sisyph.EvalExpr[cx, keyword, expr, FALSE];
count ← NAT [Sisyph.FetchInt[cx, keyword].value];
Sinix.PutF["Extracting [Sisyph] cell %g (%g: %g)\n", IO.rope[name], IO.rope[keyword], IO.int[count]];
name ← Rope.Substr[name, 0, Rope.Index[name, 0, ".sch"]]; -- hack
name ← Rope.Substr[name, 0, Rope.Index[name, 0, ".icon"]]; -- hack
cellType ← ExtractSequenceIcon[obj, cx, keyword, count, name, Sisyph.GetCoreProps[cx]];
props ← Sisyph.GetCoreInstProps[cx];
result ← cellType;
};
ExtractSequenceIcon:
PROC [obj:
CD.Object, cx: Sisyph.Context, resultVar:
ROPE, count:
NAT, name:
ROPE, props: Core.Properties]
RETURNS [sequence: CellType] = {
iconCT: CellType = NARROW [Sinix.ExtractCell[obj, Sisyph.mode, NIL, cx].result];
iconRCT: CoreClasses.RecordCellType = NARROW [iconCT.data];
subCT: CellType;
sequenceWires, flatSequenceWires: Wires ← NIL;
There should be only one subcell
IF iconRCT.size#1
THEN {
TerminalIO.PutF["*** SisyphExtractSequence: Sequence should contain one and only one subcell.\n"];
ERROR};
subCT ← iconRCT[0].type;
We deal with Global Variables
Sisyph.ProcessGlobalNames[iconCT, cx];
we check that there is no internal only
FOR i:
NAT
IN [0 .. iconRCT.internal.size)
DO
wire: Wire = iconRCT.internal[i];
name: ROPE ← CoreOps.GetShortWireName[wire];
IF name=NIL THEN name ← "some wire";
IF
NOT CoreOps.RecursiveMember[iconRCT[0].actual, wire]
THEN {
TerminalIO.PutF["*** SisyphExtractSequence: %g is not connected to subcell.\n", IO.rope[name]];
ERROR};
IF
NOT CoreOps.RecursiveMember[iconCT.public, wire]
THEN {
TerminalIO.PutF["*** SisyphExtractSequence: %g is not public.\n", IO.rope[name]];
ERROR};
ENDLOOP;
We compute which wires are going to be sequenced
FOR i:
NAT
IN [0 .. subCT.public.size)
DO
IF CoreProperties.GetWireProp[iconRCT[0].actual[i], $Sequence]#
NIL
THEN sequenceWires ← CONS [subCT.public[i], sequenceWires];
IF CoreProperties.GetWireProp[iconRCT[0].actual[i], $FlatSequence]#
NIL
THEN flatSequenceWires ← CONS [subCT.public[i], flatSequenceWires];
ENDLOOP;
We create the sequence
sequence ← CoreClasses.CreateSequence[
args:
NEW [CoreClasses.SequenceCellTypeRec ← [
base: subCT, count: count,
sequence: FindPorts[subCT, sequenceWires],
flatSequence: FindPorts[subCT, flatSequenceWires] ]],
name: name, props: props ];
New code to copy properties from the extracted public to the new sequence public.
FOR i:
NAT
IN [0..sequence.public.size)
DO
iconWire: Wire = CoreClasses.CorrespondingActual[iconRCT[0], subCT.public[i]];
CopyWireProperties[from: iconWire, to: sequence.public[i]] ENDLOOP;
Since the section above will include the geometry and pins the section below (which set up links to the pins and geometry) has been commented out.
FOR i: NAT IN [0 .. sequence.public.size) DO
iconWire: Wire = CoreClasses.CorrespondingActual[iconRCT[0], subCT.public[i]];
IF iconWire=NIL THEN ERROR;
CoreGeometry.PutIndirectLazyPins[Sisyph.mode.decoration, sequence.public[i], iconWire];
CoreGeometry.PutGeometry[Sisyph.mode.decoration, sequence.public[i], CoreGeometry.GetGeometry[Sisyph.mode.decoration, iconWire]] ENDLOOP;
The object decoration!
CoreGeometry.PutObject[Sisyph.mode.decoration, sequence, obj];
We decorate with the appriopriate layout atom
CoreProperties.PutCellTypeProp[sequence, $Layout, SymTab.Fetch[sequenceKeyWords, resultVar].val]};