Instance:
PUBLIC
PROC [type: CellType, pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10, pa11, pa12, pa13:
PA ← []]
RETURNS [CellInstance] = {
pas: LIST OF PA ← ListifyBindings[LIST [pa1, pa2, pa3, pa4, pa5, pa6, pa7, pa8, pa9, pa10, pa11, pa12, pa13]];
actual: Wire ← CoreOps.CopyWire[type.public];
ReplaceBinding:
PROC [public: Wire]
RETURNS [actual: Wire] = {
replacementActuals: LIST OF Wire ← NIL;
FOR bindings:
LIST
OF
PA ← pas, bindings.rest
WHILE bindings#
NIL
DO
IF bindings.first.public=public 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 AND ~CoreOps.Conform[replacementActuals.first, public] THEN ERROR;
IF replacementActuals#NIL THEN RETURN [replacementActuals.first];
actual ← CoreOps.CopyWire[public];
FOR i: NAT IN [0 .. public.size) DO actual[i] ← ReplaceBinding[public[i]] ENDLOOP;
};
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;
IF type=NIL THEN ERROR; -- early detection of this error might be useful
RETURN [NEW [CoreClasses.CellInstanceRec ← [actual: ReplaceBinding[type.public], type: type]]];
};
Cell:
PUBLIC
PROC [name:
ROPE ←
NIL, public, onlyInternal: Wire ←
NIL, instances:
LIST
OF CellInstance]
RETURNS [CellType] = {
data: CoreClasses.RecordCellType;
This PROC would be different if we allow the DAG
ReplaceActualByInternal:
PROC [actual, internal: Wire]
RETURNS [newActual: Wire] = {
wire: Wire ← FindWireInWireSeq[actual, internal];
IF wire#NIL THEN RETURN [wire]; -- found!
IF actual.size=0 THEN ERROR; -- non structured wire not found in the internal
newActual ← CoreOps.CreateWire[size: actual.size];
FOR i:
NAT
IN [0 .. actual.size)
DO
newActual[i] ← ReplaceActualByInternal[actual[i], internal];
ENDLOOP;
};
cellType: CellType;
IF public=NIL THEN public ← CoreOps.CreateWire[0];
IF onlyInternal=NIL THEN onlyInternal ← CoreOps.CreateWire[0];
cellType ← CoreClasses.CreateRecordCell[public: public, internal: UnionSequences[public, onlyInternal], instances: instances, name: name];
we replace all actual wires by wires having the same name than part of the public
data ← NARROW [cellType.data];
FOR i:
NAT
IN [0 .. data.size)
DO
data[i].actual ← ReplaceActualByInternal[data[i].actual, data.internal];
ENDLOOP;
RETURN [cellType];
};