[
design: Design,
fromAncestorCT, toAncestorCT: CellType,
eltConnections: ConstFunction--port of toAncestorCT b port of fromAncestorCT--,
doomedFromPorts: ConstSet--of port of fromAncestorCT--,
eltTPToWire: UWFunction--port of toAncestorCT b prototypical wire--,
subTail: ROPE--to append to name of from array--,
pairs: VarOneToOne--instance of from or ancestor é instance of to or ancestor--
SplitArray:
PROC [fromArrayCT: CellType] ~ {
fa: Array ~ fromArrayCT.asArray;
faName: ROPE ~ NARROW[Asserting.FnVal[nameReln, fromArrayCT.otherPublic]];
taName: ROPE ~ faName.Cat[subTail];
toArrayCT: CellType ~ CreateArray[design, taName, NIL, toAncestorCT, fa.size, fa.jointsPeriod, GetBorders[fa], NIL, NIL];
ta: Array ~ toArrayCT.asArray;
toNewGroup: VarFunction--group of fa b group of ta-- ~ PairColls.CreateHashFn[];
toNewTie: VarFunction--tie of ta b tie of fa-- ~ PairColls.CreateHashFn[];
arrayConnectionsV: VarFunction--port of toArrayCT b port of fromArrayCT-- ~ PairColls.CreateHashFn[invable: TRUE];
arrayTPToWireV: VarFunction--port of ta b wire-- ~ PairColls.CreateHashFn[];
doomedArrayPortsV: VarSet--of port of fa-- ~ Colls.CreateHashSet[];
AddConnection:
PROC [fai: ArrayIndex, fg: Group, tai: ArrayIndex, tg: Group] ~ {
IF fg=NIL OR tg=NIL THEN ERROR;
{fp: Port ~ GetArrayPortForGroup[fromArrayCT, fa, fai, fg, TRUE];
tp: Port ~ GetArrayPortForGroup[toArrayCT, ta, tai, tg, TRUE];
w: Wire ~ NARROW[eltTPToWire.Apply[tg.ports.first].Val];
IF fp=NIL OR tp=NIL THEN ERROR;
IF w=NIL THEN ERROR;
SELECT arrayConnectionsV.Apply[tp].DVal
FROM
fp => NULL;
NIL => IF NOT arrayConnectionsV.Store[[tp, fp]] THEN ERROR;
ENDCASE => ERROR;
[] ← arrayTPToWireV.Store[[tp, w]];
}};
IF IsIncompleteArray[fromArrayCT] THEN ERROR;
IF ta.groupingParmses # fa.groupingParmses THEN ERROR;
{UnroleOldPort: PROC [ra: REF ANY] ~ {UnrolePort[fa, NARROW[ra]]};
doomedFromPorts.Enumerate[UnroleOldPort];
};
FOR gi:
NATURAL
IN [0 .. fa.groupingses.length)
DO
fgs: Groupings ~ NARROW[fa.groupingses[gi]];
tgs: Groupings ~ NARROW[ta.groupingses[gi]];
MoveGroup:
PROC [ra:
REF
ANY] ~ {
fg: Group ~ NARROW[ra];
tg: Group ~ MakeGroup[ta, fg.gi2, tgs];
IF NOT toNewGroup.Store[[fg, tg]] THEN ERROR;
FOR pl: PortList ← fg.ports, pl.rest
WHILE pl #
NIL
DO
fp: Port ~ NARROW[pl.first];
EnGroup:
PROC [ra:
REF
ANY] ~ {
tp: Port ~ NARROW[ra];
AddPortToGroup[ta, gi, tp, tg, FALSE];
};
eltConnections.EnumerateMapping[fp, EnGroup, rightToLeft];
IF doomedFromPorts.HasMember[fp] THEN RemovePortFromGroup[fa, gi, fp, fg];
ENDLOOP;
ra ← ra;
};
fgs.groups.Enumerate[MoveGroup];
ENDLOOP;
{
MoveTie:
PROC [d: Dim, phase: Nat2, jgi:
NATURAL, jgi2: Nat2, j: Joint, tie: Tie] ~ {
fj: Joint ~ j;
ftie: Tie ~ tie;
IF ftie.groups[low]#
NIL
AND ftie.groups[high]#
NIL
THEN {
tj: Joint ~ GetArrayJoint[ta, d, phase];
ttie: Tie ~
NEW [TiePrivate ← [groups: [
low: NARROW[toNewGroup.Apply[ftie.groups[low]].Val],
high: NARROW[toNewGroup.Apply[ftie.groups[high]].Val]]]];
IF ttie.groups[low]=NIL OR ttie.groups[high]=NIL THEN ERROR;
AddTie[tj, jgi, ttie];
IF NOT toNewTie.Store[[ftie, ttie]] THEN ERROR;
};
};
EnumerateTies[fa, MoveTie];
};
FlushArrayWires[fa, doomedArrayPortsV];
{
ConnectGroup:
PROC [pair: PairColls.Pair] ~ {
fg: Group ~ NARROW[pair[left]];
tg: Group ~ NARROW[pair[right]];
IF tg.gi2#fg.gi2 THEN ERROR;
IF tg.ports#
NIL
AND (fg.ports#
NIL
OR fa.toWire.Fetch[fg].val#
NIL)
THEN {
air: Range2 ~ Gi2ToAir[fa, fg.gi2].air;
FOR f:
INT
IN [air[Foo].min .. air[Foo].maxPlusOne)
DO
FOR b:
INT
IN [air[Bar].min .. air[Bar].maxPlusOne)
DO
ai: ArrayIndex ~ [f, b];
IF fg.ports#NIL OR GetArrayPortForGroup[fromArrayCT, fa, ai, fg, FALSE]#NIL THEN AddConnection[ai, fg, ai, tg];
ENDLOOP ENDLOOP;
};
};
toNewGroup.Enumerate[ConnectGroup];
};
{
ConnectTie:
PROC [d: Dim, phase: Nat2, jgi:
NATURAL, jgi2: Nat2, j: Joint, tie: Tie] ~ {
ftie: Tie ~ tie;
ttie: Tie ~ NARROW[toNewTie.Apply[ftie].DVal];
IF ttie#
NIL
AND ((ttie.groups[low].ports=NIL) # (ttie.groups[high].ports=NIL))
AND ((ttie.groups[low].ports=NIL) # (ftie.groups[low].ports=NIL))
AND ((ttie.groups[high].ports=NIL) # (ftie.groups[high].ports=NIL))
THEN {
o: Dim ~ OtherDim[d];
toHigh: BOOL ~ ttie.groups[low]=NIL;
FOR perp:
NATURAL
IN [0 .. fa.size[o])
DO
FOR para:
NATURAL
IN [0 .. fa.size[d]-1)
DO
lai: ArrayIndex ~ ConsInt2[d, para, perp];
hai: ArrayIndex ~ Int2Tweak[lai, d, 1];
IF toHigh THEN AddConnection[lai, ftie.groups[low], hai, ttie.groups[high]] ELSE AddConnection[lai, ftie.groups[high], hai, ttie.groups[low]];
ENDLOOP ENDLOOP;
};
};
EnumerateTies[fa, ConnectTie];
};
TrimEmptyGroups[fa];
TrimEmptyGroups[ta];
{arrayConnections: ConstFunction ~ arrayConnectionsV.Freeze;
doomedArrayPorts: ConstSet ~ doomedArrayPortsV.Freeze;
arrayTPToWire: ConstFunction ~ arrayTPToWireV.Freeze;
KillDoomedArrayPort:
PROC [ra:
REF
ANY] ~ {
p: Port--of fromArrayCT-- ~ NARROW[ra];
RemovePort[p];
};
FixArrays[design, fromArrayCT, toArrayCT, arrayConnections, doomedArrayPorts, arrayTPToWire, subTail, pairs];
FixInstances[fromArrayCT, toArrayCT, arrayConnections, doomedArrayPorts, arrayTPToWire, pairs];
doomedArrayPorts.Enumerate[KillDoomedArrayPort];
};
};