<> <> <> <> <> <> <<>> DIRECTORY Core, CoreClasses, CoreOps, CoreProperties, CoreSequence, IO; CoreSequenceImpl: CEDAR PROGRAM IMPORTS CoreClasses, CoreOps, CoreProperties, IO EXPORTS CoreSequence = BEGIN OPEN Core, CoreSequence; sequenceCellClass: PUBLIC CellClass _ NEW[CellClassRec _ [name: "Sequence", recast: Recast, properties: CoreProperties.Props[[CoreOps.printClassProcProp, NEW[CoreOps.PrintClassProc _ PropPrintClass]]]]]; Recast: RecastProc = { seqCell: SequenceCellType _ NARROW [me.data]; stitchesLength: NAT _ IF seqCell.stitches#NIL THEN seqCell.stitches.length ELSE 0; public: Wire _ CoreOps.CopyWire[me.public]; newInternal: Wire _ CoreOps.CreateWire[size: public.size + stitchesLength]; instances: LIST OF CoreClasses.CellInstance _ NIL; FOR w: NAT IN [0 .. public.size) DO newInternal[w] _ public[w]; ENDLOOP; FOR w: NAT IN [public.size .. newInternal.size) DO newInternal[w] _ NEW[WireRec]; CoreProperties.PutWireProp[newInternal[w], CoreOps.sequenceProp, CoreOps.sequenceProp]; newInternal[w] _ CoreOps.CreateWire[size: seqCell.count]; ENDLOOP; FOR cell: NAT IN [0 .. seqCell.count) DO newWire: Wire _ NEW [Core.WireRec[public.size] _ public^]; FOR seqWire: NAT IN [0..seqCell.length) DO seqElement: NAT _ seqCell.sequence[seqWire]; IF CoreProperties.GetWireProp[seqCell.base.public[seqElement], CoreOps.sequenceProp]#NIL THEN { size: NAT _ seqCell.base.public[seqElement].size; actWire: Wire _ CoreOps.CreateWire[size: size]; CoreProperties.PutWireProp[actWire, CoreOps.sequenceProp, CoreOps.sequenceProp]; FOR i: NAT IN [0..size) DO actWire[i] _ newWire[seqElement][(size*cell)+i]; ENDLOOP; newWire[seqElement] _ actWire; } ELSE newWire[seqElement] _ newWire[seqElement][cell]; ENDLOOP; IF stitchesLength>0 THEN ERROR; -- not yet implemented FOR stitchWire: NAT IN [0..stitchesLength) DO internal: Wire; IF cell < seqCell.count -1 THEN { internal _ CoreOps.CopyWire[wire: seqCell.base.public[seqCell.stitches[stitchWire].source]]; newInternal[stitchWire + public.size][cell] _ internal; newWire[seqCell.stitches[stitchWire].source] _ internal; }; IF cell > 0 THEN newWire[seqCell.stitches[stitchWire].sink] _ newInternal[stitchWire + public.size][cell-1]; ENDLOOP; instances _ CONS [ NEW [CoreClasses.CellInstanceRec _ [ actual: newWire, type: seqCell.base, properties: IF CoreOps.GetCellTypeName[seqCell.base]=NIL THEN NIL ELSE CoreProperties.Props[[CoreOps.nameProp, IO.PutFR["%g%g", IO.rope[CoreOps.GetCellTypeName[seqCell.base]], IO.int[cell]]]] ]], instances]; ENDLOOP; new _ CoreClasses.CreateRecordCell[ public: public, internal: newInternal, instances: instances, name: CoreOps.GetCellTypeName[me], props: CoreProperties.CopyProps[propList: me.properties]]; }; Create: PUBLIC PROC [args: SequenceCellType, name: ROPE _ NIL, props: Properties _ NIL] RETURNS [cellType: CellType] = { cellType _ CoreOps.CreateCellType[ class: sequenceCellClass, public: CoreOps.CopyWire[args.base.public], data: args, name: name, props: props]; FOR i: NAT IN [0 .. cellType.public.size) DO IF CoreOps.GetWireName[cellType.public[i]]=NIL THEN ERROR ENDLOOP; -- check that each top level wire is named (otherwise, it is probably a bug) FOR i: NAT IN [0 .. args.length) DO wire: Wire _ cellType.public[args.sequence[i]]; IF CoreProperties.GetWireProp[wire, CoreOps.sequenceProp]#NIL THEN { newSeqLength: NAT _ args.count * wire.size; newSeq: Wire _ CoreOps.CreateWire[size: newSeqLength, props: CoreProperties.CopyProps[wire.properties]]; FOR i: NAT IN [0 .. newSeqLength) DO newSeq[i] _ CoreOps.CopyWire[wire[0]]; CoreProperties.PutWireProp[newSeq[i], CoreOps.nameProp, NIL]; ENDLOOP; cellType.public[args.sequence[i]] _ newSeq; } ELSE { newWire: Wire _ CoreOps.CreateWire[size: args.count, name: CoreOps.GetWireName[wire], props: CoreProperties.Props[[CoreOps.sequenceProp, CoreOps.sequenceProp]]]; FOR i: NAT IN [0 .. args.count) DO newWire[i] _ CoreOps.CopyWire[wire]; CoreProperties.PutWireProp[newWire[i], CoreOps.nameProp, NIL]; ENDLOOP; cellType.public[args.sequence[i]] _ newWire; }; ENDLOOP; }; PropPrintClass: CoreOps.PrintClassProc = {Print[NARROW[data], out]}; Print: PUBLIC PROC [cell: SequenceCellType, out: IO.STREAM] = { IO.PutF[out, "\n\nBase cell type: %g", IO.rope[CoreOps.GetCellTypeName[cell.base]]]; IO.PutF[out, ", count: %g", IO.int[cell.count]]; IO.PutRope[out, "\nstitch wires:"]; IF cell.stitches#NIL THEN FOR stitch: NAT IN [0 .. cell.stitches.length) DO IO.PutF[out, " (%g, %g)", IO.rope[CoreOps.GetWireName[cell.base.public[cell.stitches[stitch].source]]], IO.rope[CoreOps.GetWireName[cell.base.public[cell.stitches[stitch].sink]]]]; ENDLOOP; IO.PutRope[out, "\nsequence wires:"]; FOR seq: NAT IN [0 .. cell.length) DO IO.PutF[out, " %g", IO.rope[CoreOps.GetWireName[cell.base.public[cell[seq]]]]]; ENDLOOP; }; END.