<> <> <> <> <<>> DIRECTORY Core, CoreBeau, CoreClasses, CoreOps, CoreProperties, CoreSequence, IO, Rope; CoreBeauImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreOps, CoreProperties, CoreSequence, IO, Rope EXPORTS CoreBeau = BEGIN OPEN CoreBeau; <> UnionSequences: PROC [wire1, wire2: Wire] RETURNS [wire: Wire] = { wire _ CoreOps.CreateWire[size: wire1.size+wire2.size]; FOR i: NAT IN [0 .. wire1.size) DO wire[i] _ wire1[i] ENDLOOP; FOR i: NAT IN [0 .. wire2.size) DO wire[i+wire1.size] _ wire2[i] ENDLOOP; }; WRsToWires: PROC [wrs: LIST OF WR] RETURNS [wires: LIST OF Wire _ NIL] = { WHILE wrs#NIL DO IF wrs.first#NIL THEN wires _ CONS [WRToWire[wrs.first], wires]; wrs _ wrs.rest; ENDLOOP; wires _ CoreOps.Reverse[wires]; }; WRToWire: PROC [wr: WR] RETURNS [Wire] = { WITH wr SELECT FROM wire: Wire => RETURN [wire]; rope: ROPE => RETURN [CoreOps.CreateWire[name: rope]]; text: REF TEXT => RETURN [CoreOps.CreateWire[name: IO.PutR1[IO.text[text]]]]; ENDCASE => ERROR }; FindWireInWireSeq: PROC [wr: WR, wire: Wire] RETURNS [Wire] = { matchingWires: LIST OF Wire _ NIL; FindInEach: PROC [wire: Wire, name: ROPE _ NIL] = { match: BOOL _ WITH wr SELECT FROM wrwire: Wire => match _ wire=wrwire OR (name#NIL AND Rope.Equal[name, CoreOps.GetWireName[wrwire]]), wrrope: ROPE => match _ Rope.Equal[name, wrrope], text: REF TEXT => match _ Rope.Equal[name, IO.PutR1[IO.text[text]]], ENDCASE => ERROR; IF match THEN matchingWires _ CONS [wire, matchingWires]; FOR i: NAT IN [0 .. wire.size) DO subName: ROPE _ CoreOps.GetWireName[wire[i]]; new: ROPE _ SELECT TRUE FROM CoreProperties.GetWireProp[wire, CoreOps.sequenceProp]#NIL => IO.PutFR["%g[%g]", IO.rope[name], IO.int[i]], subName#NIL => IF name=NIL THEN subName ELSE Rope.Cat[name, ".", subName], ENDCASE => IF name=NIL THEN "?" ELSE Rope.Cat[name, ".?"]; FindInEach[wire[i], new]; ENDLOOP; }; FindInEach[wire]; RETURN [IF matchingWires=NIL THEN NIL ELSE matchingWires.first]; }; ListifyBindings: PROC [pas: LIST OF PA] RETURNS [revpas: LIST OF PA _ NIL] = { <> WHILE pas#NIL DO IF pas.first#[] THEN revpas _ CONS [pas.first, revpas]; pas _ pas.rest; ENDLOOP; }; IndexInPublic: PROC [wire: Wire, public: Wire] RETURNS [index: INT] = { FOR i: NAT IN [0 .. public.size) DO IF Rope.Equal[CoreOps.GetWireName[public[i]], CoreOps.GetWireName[wire]] THEN RETURN [i]; ENDLOOP; ERROR; -- not found }; <> WireList: PUBLIC PROC [wrs: LIST OF WR _ NIL] RETURNS [Wire] = { RETURN [CoreOps.WiresToWire[WRsToWires[wrs]]]; }; <<>> Wires: PUBLIC PROC [wr1, wr2, wr3, wr4, wr5, wr6, wr7, wr8, wr9, wr10, wr11, wr12, wr13: WR _ NIL] RETURNS [Wire] = { RETURN [WireList[LIST [wr1, wr2, wr3, wr4, wr5, wr6, wr7, wr8, wr9, wr10, wr11, wr12, wr13]]]; }; <<>> Seq: PUBLIC PROC [wr: WR, size: NAT] RETURNS [Wire] = { RETURN [CoreOps.CreateWire[ size: size, name: WITH wr SELECT FROM wire: Wire => CoreOps.GetWireName[wire], rope: ROPE => rope, text: REF TEXT => IO.PutR1[IO.text[text]], ENDCASE => ERROR, props: CoreProperties.Props[[CoreOps.sequenceProp, CoreOps.sequenceProp]]]]; }; <<>> Index: PUBLIC PROC [wr: WR, index: NAT] RETURNS [WR] = { WITH wr SELECT FROM wire: Wire => RETURN [wire[index]]; rope: ROPE => RETURN [IO.PutFR["%g[%g]", IO.rope[rope], IO.int[index]]]; text: REF TEXT => RETURN [IO.PutFR["%g[%g]", IO.text[text], IO.int[index]]]; ENDCASE => ERROR }; <<>> Indexes: PUBLIC PROC [wr: WR, start: NAT _ 0, length: NAT] RETURNS [Wire] = { WITH wr SELECT FROM wire: Wire => RETURN [CoreOps.SubrangeWire[wire, start, length]]; rope: ROPE => { subWires: LIST OF Wire _ NIL; FOR i: NAT DECREASING IN [0 .. length) DO subWires _ CONS [CoreOps.CreateWire[name: IO.PutFR["%g[%g]", IO.rope[rope], IO.int[i+start]]], subWires]; ENDLOOP; RETURN [CoreOps.WiresToWire[subWires]]; }; text: REF TEXT => { subWires: LIST OF Wire _ NIL; FOR i: NAT DECREASING IN [0 .. length) DO subWires _ CONS [CoreOps.CreateWire[name: IO.PutFR["%g[%g]", IO.text[text], IO.int[i+start]]], subWires]; ENDLOOP; RETURN [CoreOps.WiresToWire[subWires]]; }; ENDCASE => ERROR }; <> 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 <> 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; <> 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]; <> data _ NARROW [cellType.data]; FOR i: NAT IN [0 .. data.size) DO data[i].actual _ ReplaceActualByInternal[data[i].actual, data.internal]; ENDLOOP; RETURN [cellType]; }; <> Transistor: PUBLIC PROC [name: ROPE _ NIL, type: TransistorType _ nE, length: NAT _ 2, width: NAT _ 4] RETURNS [CellType] = { cellType: CellType _ CoreClasses.CreateTransistor[[ type: type, length: length, width: width ]]; CoreProperties.PutCellTypeProp[cellType, CoreOps.nameProp, name]; RETURN [cellType]; }; <<>> SequenceCell: PUBLIC PROC [name: ROPE _ NIL, baseCell: CellType, count: NAT, sequencePorts: Wire _ NIL] RETURNS [CellType] = { cellType: CellType; seqCell: CoreSequence.SequenceCellType; IF sequencePorts=NIL THEN sequencePorts _ CoreOps.CreateWire[size: 0]; seqCell _ NEW [CoreSequence.SequenceCellTypeRec[sequencePorts.size]]; FOR i: INT IN [0 .. sequencePorts.size) DO publicWire: Wire _ FindWireInWireSeq[sequencePorts[i], baseCell.public]; IF publicWire=NIL THEN ERROR; seqCell.sequence[i] _ IndexInPublic[publicWire, baseCell.public]; ENDLOOP; seqCell.base _ baseCell; seqCell.count _ count; cellType _ CoreSequence.Create[name: name, args: seqCell]; RETURN [cellType]; }; <> FindWire: PUBLIC PROC [cell: CellType, wr: WR] RETURNS [Wire] = { RETURN [IF cell.class=CoreClasses.recordCellClass THEN FindWireInWireSeq[wr, NARROW [cell.data, CoreClasses.RecordCellType].internal] ELSE FindWireInWireSeq[wr, cell.public] ]; }; END.