<> <> <> <> <> <<>> DIRECTORY Core, CoreOps, CoreProperties, CoreRecordCells, CoreSequenceCells, HashTable, IO; CoreSequenceCellsImpl: CEDAR PROGRAM IMPORTS CoreOps, CoreProperties, CoreRecordCells, HashTable, IO EXPORTS CoreSequenceCells = BEGIN OPEN Core, CoreSequenceCells; sequenceCellClass: PUBLIC CellClass _ NEW[CellClassRec _ [name: "SequenceCell", recast: Recast, write: Write, read: Read]]; cacheAtom: ATOM = $SequenceCellCache; Start: PROC = { CoreOps.RegisterCellClass[sequenceCellClass]; CoreProperties.RegisterProperty[prop: cacheAtom]; }; Write: WriteProc = { }; Read: ReadProc = { }; Recast: RecastProc = { seqCell: SequenceCell _ NARROW[me.data]; recCell: CoreRecordCells.RecordCell _ NEW[CoreRecordCells.RecordCellRec]; new _ NEW[CellTypeRec _ [ name: me.name, class: CoreRecordCells.recordCellClass, publicWire: CoreOps.CopyWire[wire: me.publicWire], data: recCell, properties: CoreProperties.CopyProps[propList: me.properties]]]; recCell.internalWire _ NEW[WireRec _ [ structure: sequence]]; recCell.internalWire.elements _ NEW[WireSequenceRec[new.publicWire.elements.size + seqCell.stitches.length]]; FOR w: NAT IN [0..new.publicWire.elements.size) DO recCell.internalWire.elements[w] _ new.publicWire.elements[w]; ENDLOOP; FOR w: NAT IN [new.publicWire.elements.size..recCell.internalWire.elements.size) DO recCell.internalWire.elements[w] _ NEW[WireRec _ [structure: sequence]]; recCell.internalWire.elements[w].elements _ NEW[WireSequenceRec[ seqCell.count]]; ENDLOOP; FOR cell: NAT IN [0..seqCell.count) DO newWire: Wire _ NEW[WireRec _ new.publicWire^]; newWire.elements _ NEW[WireSequenceRec[new.publicWire.elements.size] _ new.publicWire.elements^]; FOR seqWire:NAT IN [0..seqCell.length) DO newWire.elements[seqCell.sequence[seqWire]] _ newWire.elements[seqCell.sequence[seqWire]].elements[cell]; ENDLOOP; FOR stitchWire: NAT IN [0..seqCell.stitches.length) DO internal: Wire; IF cell < seqCell.count -1 THEN { internal _ CoreOps.CopyWire[wire: seqCell.base.publicWire.elements[seqCell.stitches[stitchWire].source]]; recCell.internalWire.elements[stitchWire + new.publicWire.elements.size].elements[cell] _ internal; newWire.elements[seqCell.stitches[stitchWire].source] _ internal; }; IF cell > 0 THEN newWire.elements[seqCell.stitches[stitchWire].sink] _ recCell.internalWire.elements[stitchWire + new.publicWire.elements.size].elements[cell-1]; ENDLOOP; recCell.instances _ CONS[NEW[CoreRecordCells.InstanceRec _ [ name: IF seqCell.base.name=NIL THEN NIL ELSE IO.PutFR["%g%g", IO.rope[seqCell.base.name], IO.int[cell]], actualWire: newWire, type: seqCell.base]], recCell.instances]; ENDLOOP; }; Create: PUBLIC PROC [design: Design, name: ROPE, args: SequenceCell] RETURNS [cellType: CellType] = { cache: HashTable.Table _ NARROW[CoreProperties.GetProp[from: design.properties, prop: cacheAtom]]; IF cache = NIL THEN { cache _ HashTable.Create[equal: CompareType]; design.properties _ CoreProperties.PutProp[on: design.properties, prop: cacheAtom, value: cache]; }; cellType _ NARROW [HashTable.Fetch[table: cache, key: args].value]; IF cellType=NIL THEN { cellType _ NEW[CellTypeRec _ [ name: name, class: sequenceCellClass, publicWire: CoreOps.CopyWire[wire: args.base.publicWire], data: args]]; FOR i:NAT IN [0..args.length) DO wire: Wire _ cellType.publicWire.elements[args.sequence[i]]; newWire: Wire _ CoreOps.CreateSequenceWire[name: wire.name, base: wire, count: args.count]; cellType.publicWire.elements[args.sequence[i]] _ newWire; ENDLOOP; }; }; CompareType: PROC [key1, key2: HashTable.Key] RETURNS [BOOL] = { s1: SequenceCell _ NARROW[key1]; s2: SequenceCell _ NARROW[key2]; IF s1.base#s2.base OR s1.count#s2.count OR s1.length#s2.length OR s1.stitches.length#s2.stitches.length THEN RETURN[FALSE]; FOR i:NAT IN [0..s1.length) DO IF s1.sequence[i]#s2.sequence[i] THEN RETURN[FALSE]; ENDLOOP; FOR i:NAT IN [0..s1.stitches.length) DO IF s1.stitches[i]#s2.stitches[i] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE]; }; Print: PUBLIC PROC [cell: SequenceCell, out: STREAM] = { IO.PutF[out, "\n\nBase cell type: %g", IO.rope[cell.base.name]]; IO.PutF[out, ", count: %g, sequence wires:", IO.int[cell.count]]; FOR seq: NAT IN [0..cell.length) DO IO.PutF[out, " %g", IO.rope[cell.base.publicWire.elements[cell[seq]].name]]; ENDLOOP; }; Start[]; END.