Instance:
PUBLIC
PROC [type: CellType, pa1, pa2, pa3, pa4, pa5, pa6:
PA ← []]
RETURNS [CellInstance] = {
pas: LIST OF PA ← ListifyBindings[LIST [pa1, pa2, pa3, pa4, pa5, pa6]];
actual: WireSequence ← CoreOps.CopyWireSequence[type.public];
ReplaceBinding: CoreOps.EachWirePairProc = {
replacementActuals: LIST OF Wire ← NIL;
FOR bindings:
LIST
OF
PA ← pas, bindings.rest
WHILE bindings#
NIL
DO
IF bindings.first.public=publicWire THEN replacementActuals ← CONS [WRToWire[bindings.first.actual], replacementActuals];
ENDLOOP;
IF replacementActuals#NIL AND replacementActuals.rest#NIL THEN ERROR; -- more than one actual for the same public. replacementActuals gives all the actuals
IF replacementActuals#
NIL
THEN {
actualWire^ ← replacementActuals.first^; subWires ← FALSE;
};
};
FOR bindings:
LIST
OF
PA ← pas, bindings.rest
WHILE bindings#
NIL
DO
we make sure each of the given public is really a public, and we replace in the bindings so that we will only have to do pointer comparison later
bindings.first.public ← FindWireInWireSeq[bindings.first.public, type.public];
ENDLOOP;
[] ← CoreOps.VisitBinding[actual, type.public, ReplaceBinding];
IF type=NIL THEN ERROR; -- early detection of this error might be useful
RETURN [NEW [CoreClasses.CellInstanceRec ← [actual: actual, type: type]]];
};
Cell:
PUBLIC
PROC [name:
ROPE ←
NIL, public, onlyInternal: WireSequence ←
NIL, instances:
LIST
OF CellInstance]
RETURNS [CellType] = {
data: CoreClasses.RecordCellType ← NEW [CoreClasses.RecordCellTypeRec ← [internal: UnionSequences[public, onlyInternal], instances: instances]];
This PROC would be different if we allow the DAG
ReplaceABI:
PROC [actualWire: Wire, internal: WireSequence]
RETURNS [newActualWire: Wire] = {
newActualWire ← FindWireInWireSeq[actualWire, internal];
IF newActualWire#NIL THEN RETURN;
IF actualWire.elements=NIL THEN ERROR; -- non structured wire not found in the internal
newActualWire ← CoreOps.WireSequenceToWire[ReplaceActualByInternal[actualWire.elements, internal]];
};
ReplaceActualByInternal:
PROC [actual, internal: WireSequence]
RETURNS [newActual: WireSequence] = {
wire: Wire ← FindWireInWireSeq[actual, internal];
IF wire#NIL THEN RETURN [wire.elements];
newActual ← CoreOps.CreateBasicSequenceWire[actual.size].elements;
FOR i:
NAT
IN [0 .. actual.size)
DO
newActual[i] ← ReplaceABI[actual[i], internal];
ENDLOOP;
};
cellType: CellType;
IF public=NIL THEN public ← CoreOps.CreateBasicSequenceWire[0].elements;
IF onlyInternal=NIL THEN onlyInternal ← CoreOps.CreateBasicSequenceWire[0].elements;
cellType ← CoreOps.CreateCellType[class: CoreClasses.recordCellClass, public: public, data: data, name: name];
we replace all actual wires by wires having the same name than part of the public
FOR insts:
LIST
OF CellInstance ← instances, insts.rest
WHILE insts#
NIL
DO
insts.first.actual ← ReplaceActualByInternal[insts.first.actual, data.internal];
ENDLOOP;
RETURN [cellType];
};