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 [wireSeq1, wireSeq2: WireSequence] RETURNS [wireSeq: WireSequence] = { wireSeq _ CoreOps.CreateBasicSequenceWire[wireSeq1.size+wireSeq2.size].elements; FOR i: NAT IN [0 .. wireSeq1.size) DO wireSeq[i] _ wireSeq1[i] ENDLOOP; FOR i: NAT IN [0 .. wireSeq2.size) DO wireSeq[i+wireSeq1.size] _ wireSeq2[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]; wireSeq: WireSequence => RETURN [CoreOps.WireSequenceToWire[wireSeq]]; rope: ROPE => RETURN [CoreOps.CreateAtomWire[name: rope]]; ENDCASE => ERROR }; FindWireInWireSeq: PROC [wr: WR, wireSeq: WireSequence] RETURNS [Wire] = { matchingWires: LIST OF Wire _ NIL; FindInEach: CoreOps.EachWireProc = { name: ROPE _ CoreOps.GetWireName[wire]; match: BOOL _ FALSE; WITH wr SELECT FROM wrwire: Wire => match _ wire=wrwire OR (name#NIL AND Rope.Equal[name, CoreOps.GetWireName[wrwire]]); wrwireSeq: WireSequence => match _ wire.elements=wrwireSeq; wrrope: ROPE => match _ Rope.Equal[name, wrrope]; ENDCASE => ERROR; IF match THEN matchingWires _ CONS [wire, matchingWires]; }; [] _ CoreOps.VisitWireSequence[wireSeq, FindInEach]; 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: WireSequence] RETURNS [index: INT _ -1] = { FOR i: NAT IN [0 .. public.size) DO IF public[i]=wire THEN RETURN [i] ENDLOOP; }; Wires: PUBLIC PROC [wr1, wr2, wr3, wr4, wr5, wr6, wr7: WR _ NIL] RETURNS [WireSequence] = { RETURN [CoreOps.WiresToWireSequence[WRsToWires[LIST [wr1, wr2, wr3, wr4, wr5, wr6, wr7]]]]; }; Seq: PUBLIC PROC [wr: WR, length: NAT] RETURNS [WireSequence] = { WITH wr SELECT FROM wire: Wire => RETURN [CoreOps.CreateBasicSequenceWire[length].elements]; rope: ROPE => RETURN [CoreOps.CreateBasicSequenceWire[length, rope].elements]; ENDCASE => ERROR }; Index: PUBLIC PROC [wr: WR, index: NAT] RETURNS [WR] = { WITH wr SELECT FROM wire: Wire => RETURN [wire.elements[index]]; wireSeq: WireSequence => RETURN [wireSeq[index]]; rope: ROPE => RETURN [IO.PutFR["%g[%g]", IO.rope[rope], IO.int[index]]]; ENDCASE => ERROR }; Indexes: PUBLIC PROC [wr: WR, start: NAT _ 0, length: NAT] RETURNS [WireSequence] = { WITH wr SELECT FROM wire: Wire => RETURN [CoreOps.SubrangeWire[wire, start, length].elements]; wireSeq: WireSequence => RETURN [CoreOps.SubrangeWire[CoreOps.WireSequenceToWire[wireSeq], start, length].elements]; rope: ROPE => { subWires: LIST OF Wire _ NIL; FOR i: NAT DECREASING IN [0 .. length) DO subWires _ CONS [CoreOps.CreateAtomWire[IO.PutFR["%g[%g]", IO.rope[rope], IO.int[i]]], subWires]; ENDLOOP; RETURN [CoreOps.CreateSequenceWire[subWires].elements]; }; ENDCASE => ERROR }; 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 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]]; 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]; FOR insts: LIST OF CellInstance _ instances, insts.rest WHILE insts#NIL DO insts.first.actual _ ReplaceActualByInternal[insts.first.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.TransistorCreate[[ 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: WireSequence _ NIL] RETURNS [CellType] = { cellType: CellType; seqCell: CoreSequence.SequenceCellType; IF sequencePorts=NIL THEN sequencePorts _ CoreOps.CreateBasicSequenceWire[0].elements; 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; IF (seqCell.sequence[i] _ IndexInPublic[publicWire, baseCell.public])=-1 THEN ERROR; 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 [FindWireInWireSeq[wr, IF cell.class=CoreClasses.recordCellClass THEN NARROW[cell.data, CoreClasses.RecordCellType].internal ELSE cell.public]]; }; END. hCoreBeauImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Created by Bertrand Serlet, November 13, 1985 2:59:33 pm PST Bertrand Serlet, November 13, 1985 7:48:15 pm PST Internal utilities We just get rid of the [] ones Creation of Wires Bindings, Instances and RecordCell 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 This PROC would be different if we allow the DAG we replace all actual wires by wires having the same name than part of the public Other cell type creation Utility Κρ˜codešœ™Kšœ Οmœ1™