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 'Seq: 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] = {
AddOp:
PROC [wire: Core.Wire, expose: PublicWireType] = {
operation: Operation ← NARROW[RefTab.Fetch[operations, wire].val];
IF operation=
NIL
THEN {
operation ← NEW[OperationRec];
IF NOT RefTab.Store[operations, wire, operation] THEN ERROR;
};
operation.expose[expose] ← TRUE;
};
MatchingPins:
PROC [firstPin, lastPin: CoreGeometry.Instance]
RETURNS [yes:
BOOL ←
FALSE] = {
TransformPin:
PROC [instance: CoreGeometry.Instance]
RETURNS [pinIR: CoreGeometry.Rect] = {
pinIR ← CDBasics.MoveRect[CDBasics.MapRect[ CD.InterestRect[instance.obj], instance.trans], CDBasics.SubPoints[[0, 0], CDBasics.BaseOfRect[ir]]];
};
firstSides: CoreGeometry.Sides ← CoreGeometry.GetSides[ir, firstPin];
lastSides: CoreGeometry.Sides ← CoreGeometry.GetSides[ir, lastPin];
IF (firstSides[top]
AND lastSides[bottom])
OR (firstSides[bottom]
AND lastSides[top])
OR (firstSides[left]
AND lastSides[right])
OR (firstSides[right]
AND lastSides[left])
THEN {
firstBBox: CoreGeometry.Rect ← TransformPin[firstPin];
lastBBox: CoreGeometry.Rect ← TransformPin[lastPin];
firstMin, firstMax, lastMin, lastMax: INT ← 0;
IF firstSides[top]
OR firstSides[bottom]
THEN {
firstMin ← firstBBox.x1;
firstMax ← firstBBox.x2;
lastMin ← lastBBox.x1;
lastMax ← lastBBox.x2;
}
ELSE {
firstMin ← firstBBox.y1;
firstMax ← firstBBox.y2;
lastMin ← lastBBox.y1;
lastMax ← lastBBox.y2;
};
yes ← firstMin<=lastMax AND firstMax>=lastMin;
};
};
BindingsAndOps: CoreOps.EachWirePairProc = {
IF CoreProperties.GetWireProp[actualWire, exposeAtoms[common]]#
NIL
THEN {
bindings ← CONS[[publicWire, publicWire], bindings];
AddOp[publicWire, common];
};
IF CoreProperties.GetWireProp[actualWire, exposeAtoms[sequence]]#NIL THEN AddOp[publicWire, sequence];
IF CoreProperties.GetWireProp[actualWire, exposeAtoms[flatSequence]]#NIL THEN AddOp[publicWire, flatSequence];
IF CoreProperties.GetWireProp[actualWire, exposeAtoms[last]]#NIL THEN AddOp[publicWire, last];
IF CoreProperties.GetWireProp[actualWire, exposeAtoms[first]]#
NIL
THEN {
EachFirstPin: CoreGeometry.EachInstanceProc = {
firstPin: CoreGeometry.Instance ← instance;
IF CDRects.IsBareRect[instance.obj]
AND instance.obj.bbox = publicWireTypeBBox[first]
THEN {
FindMatchingWire: CoreOps.EachWirePairProc = {
EachLastPin: CoreGeometry.EachInstanceProc = {
IF CDRects.IsBareRect[instance.obj] AND instance.obj.bbox = publicWireTypeBBox[last] AND MatchingPins[firstPin, instance] THEN bindings ← CONS[[firstWire, publicWire], bindings];
};
IF CoreProperties.GetWireProp[actualWire, exposeAtoms[last]]#NIL THEN [] ← CoreGeometry.EnumeratePins[Sisyph.mode.decoration, actualWire, EachLastPin];
};
[] ← CoreOps.VisitBinding[parentRCT[0].actual, base.public, FindMatchingWire];
};
};
firstWire: Core.Wire ← publicWire;
AddOp[publicWire, first];
[] ← CoreGeometry.EnumeratePins[Sisyph.mode.decoration, actualWire, EachFirstPin];
};
};
Decorate: DecorateProc = {
DecoratePin: CoreGeometry.EachInstanceProc = {
IF CDRects.IsBareRect[instance.obj]
THEN
FOR exposition: PublicWireType
IN PublicWireType
DO
IF publicWireTypeBBox[exposition]=instance.obj.bbox
THEN {
pins: CoreGeometry.Instances ← CoreGeometry.GetPins[Sisyph.mode.decoration, parentWires[exposition]];
CoreGeometry.PutPins[Sisyph.mode.decoration, parentWires[exposition], CONS[instance, pins]];
EXIT;
};
REPEAT FINISHED => ERROR;
ENDLOOP;
};
actualWire: Core.Wire ← CoreOps.CorrespondingActual[parentRCT[0].actual, base.public, baseWire];
[] ← CoreGeometry.EnumeratePins[Sisyph.mode.decoration, actualWire, DecoratePin];
};
parent: CellType = NARROW[Sinix.ExtractCell[obj, Sisyph.mode, NIL, cx].result];
parentRCT: CoreClasses.RecordCellType = NARROW[parent.data];
base: CellType;
bindings: WireBindings ← NIL;
operations: Operations ← RefTab.Create[];
ir: CoreGeometry.Rect ← CD.InterestRect[CoreGeometry.GetObject[Sisyph.mode.decoration, parent]];
There should be only one subcell
IF parentRCT.size#1
THEN {
TerminalIO.PutF["*** SisyphExtractSequence: Sequence should contain one and only one subcell.\n"];
ERROR};
base ← parentRCT[0].type;
We deal with Global Variables
Sisyph.ProcessGlobalNames[parent, cx];
Compatibility hack
FOR wireIndex:
NAT
IN [0..parent.public.size)
DO
IF parent.public[wireIndex].size=0
THEN {
FOR exposition: PublicWireType
IN PublicWireType
DO
IF CoreProperties.GetWireProp[parent.public[wireIndex], exposeAtoms[exposition]]#NIL THEN EXIT;
REPEAT FINISHED => CoreProperties.PutWireProp[parent.public[wireIndex], exposeAtoms[common], $present];
ENDLOOP;
};
ENDLOOP;
We check that there is no internal only
FOR i:
NAT
IN [0 .. parentRCT.internal.size)
DO
wire: Wire = parentRCT.internal[i];
name: ROPE ← CoreOps.GetShortWireName[wire];
IF name=NIL THEN name ← "some wire";
SELECT
TRUE
FROM
NOT CoreOps.RecursiveMember[parentRCT[0].actual, wire] => {
TerminalIO.PutF["*** SisyphExtractSequence: %g is not connected to subcell.\n", IO.rope[name]];
ERROR;
};
NOT CoreOps.RecursiveMember[parent.public, wire] => {
TerminalIO.PutF["*** SisyphExtractSequence: %g is not public.\n", IO.rope[name]];
ERROR;
};
ENDCASE;
ENDLOOP;
We compute the bindings and operations
[] ← CoreOps.VisitBinding[parentRCT[0].actual, base.public, BindingsAndOps];
We create the sequence
sequence ← CreateSequence[base, count, bindings, operations, name, props, Decorate];
The object decoration!
CoreGeometry.PutObject[Sisyph.mode.decoration, sequence, obj];
};