<> <> <> <> <> <> <> <> <> <> <<>> DIRECTORY BrineIO, CD, CDProperties, CoreClasses, Core, CoreIO, CoreOps, CoreGeometry, CoreProperties, IO, Ports, Rope, Sinix, Sisyph, SymTab, TerminalIO; NewSeqIconImpl: CEDAR PROGRAM IMPORTS BrineIO, CDProperties, CoreClasses, CoreIO, CoreOps, CoreGeometry, CoreProperties, IO, Ports, Rope, Sinix, Sisyph, SymTab, TerminalIO SHARES Sinix, Sisyph = BEGIN <<>> ROPE: TYPE = Rope.ROPE; ROPES: TYPE = LIST OF ROPE; Wire: TYPE = Core.Wire; Wires: TYPE = Core.Wires; CellType: TYPE = Core.CellType; <> sequenceKeyWords: SymTab.Ref _ SymTab.Create[5]; ParseSatellites: PROC [ropes: ROPES] RETURNS [keyword, expr: ROPE _ NIL, others: ROPES _ NIL] = { WHILE ropes#NIL DO tokenKind1, tokenKind2: IO.TokenKind; token1, token2: ROPE; rest: ROPE; [tokenKind1, token1, rest] _ Sisyph.ParseRope[ropes.first]; [tokenKind2, token2, rest] _ Sisyph.ParseRope[rest]; IF tokenKind1=tokenID AND SymTab.Fetch[sequenceKeyWords, token1].found AND Sisyph.IsParsedChar[tokenKind2, token2, ':] THEN IF keyword=NIL THEN {keyword _ token1; expr _ rest} ELSE {TerminalIO.PutF["*** SisyphExtractSequence: Conflicting sequencing satellites '%g:%g' and '%g'.\n", IO.rope[keyword], IO.rope[expr], IO.rope[ropes.first]]; ERROR} ELSE others _ CONS [ropes.first, others]; ropes _ ropes.rest; ENDLOOP}; FindPorts: PROC [baseCell: CellType, wires: Wires] RETURNS [set: CoreClasses.SequenceSet] = { nats: LIST OF NAT _ NIL; size: NAT _ 0; WHILE wires#NIL DO FOR w: NAT IN [0 .. baseCell.public.size) DO sequenceName: ROPE _ CoreOps.GetShortWireName[wires.first]; IF wires.first=baseCell.public[w] OR (sequenceName#NIL AND Rope.Equal[sequenceName, CoreOps.GetShortWireName[baseCell.public[w]]]) THEN { nats _ CONS [w, nats]; size _ size + 1; EXIT}; REPEAT FINISHED => ERROR; ENDLOOP; wires _ wires.rest; ENDLOOP; set _ NEW [CoreClasses.SequenceSetRec[size]]; FOR i: INT IN [0 .. size) DO set[i] _ nats.first; nats _ nats.rest ENDLOOP}; ExtractSequence: Sinix.ExtractProc = { name: ROPE _ mode.nameProc[obj, userData]; cx: Sisyph.Context; keyword, expr: ROPE; others: ROPES; cellType: CellType; count: NAT; [keyword, expr, others] _ ParseSatellites[NARROW [CDProperties.GetObjectProp[obj, Sinix.satellitesProp]]]; IF keyword=NIL THEN { TerminalIO.PutF["*** SisyphExtractSequence: Sequence does not contain any of sequencing information (e.g. an object satellite 'SeqX: 32').\n"]; ERROR; }; CDProperties.PutObjectProp[obj, Sinix.satellitesProp, others]; cx _ Sisyph.EvaluateParameters[userData, obj, properties]; Sisyph.EvalExpr[cx, keyword, expr, FALSE]; count _ NAT [Sisyph.FetchInt[cx, keyword].value]; Sinix.PutF["Extracting [Sisyph] cell %g (%g: %g)\n", IO.rope[name], IO.rope[keyword], IO.int[count]]; name _ Rope.Substr[name, 0, Rope.Index[name, 0, ".sch"]]; -- hack name _ Rope.Substr[name, 0, Rope.Index[name, 0, ".icon"]]; -- hack cellType _ ExtractSequenceIcon[obj, cx, keyword, count, name, Sisyph.GetCoreProps[cx]]; props _ Sisyph.GetCoreInstProps[cx]; result _ cellType; }; ExtractSequenceIcon: PROC [obj: CD.Object, cx: Sisyph.Context, resultVar: ROPE, count: NAT, name: ROPE, props: Core.Properties] RETURNS [sequence: CellType] = { iconCT: CellType = NARROW [Sinix.ExtractCell[obj, Sisyph.mode, NIL, cx].result]; iconRCT: CoreClasses.RecordCellType = NARROW [iconCT.data]; subCT: CellType; sequenceWires, flatSequenceWires: Wires _ NIL; <> IF iconRCT.size#1 THEN { TerminalIO.PutF["*** SisyphExtractSequence: Sequence should contain one and only one subcell.\n"]; ERROR}; subCT _ iconRCT[0].type; <> Sisyph.ProcessGlobalNames[iconCT, cx]; <> FOR i: NAT IN [0 .. iconRCT.internal.size) DO wire: Wire = iconRCT.internal[i]; name: ROPE _ CoreOps.GetShortWireName[wire]; IF name=NIL THEN name _ "some wire"; IF NOT CoreOps.RecursiveMember[iconRCT[0].actual, wire] THEN { TerminalIO.PutF["*** SisyphExtractSequence: %g is not connected to subcell.\n", IO.rope[name]]; ERROR}; IF NOT CoreOps.RecursiveMember[iconCT.public, wire] THEN { TerminalIO.PutF["*** SisyphExtractSequence: %g is not public.\n", IO.rope[name]]; ERROR}; ENDLOOP; <> FOR i: NAT IN [0 .. subCT.public.size) DO IF CoreProperties.GetWireProp[iconRCT[0].actual[i], $Sequence]#NIL THEN sequenceWires _ CONS [subCT.public[i], sequenceWires]; IF CoreProperties.GetWireProp[iconRCT[0].actual[i], $FlatSequence]#NIL THEN flatSequenceWires _ CONS [subCT.public[i], flatSequenceWires]; ENDLOOP; <> sequence _ CoreClasses.CreateSequence[ args: NEW [CoreClasses.SequenceCellTypeRec _ [ base: subCT, count: count, sequence: FindPorts[subCT, sequenceWires], flatSequence: FindPorts[subCT, flatSequenceWires] ]], name: name, props: props ]; <<>> <> FOR i: NAT IN [0..sequence.public.size) DO iconWire: Wire = CoreClasses.CorrespondingActual[iconRCT[0], subCT.public[i]]; CopyWireProperties[from: iconWire, to: sequence.public[i]] ENDLOOP; <<>> <> <> <> <> <> <> <<>> <> CoreGeometry.PutObject[Sisyph.mode.decoration, sequence, obj]; <> CoreProperties.PutCellTypeProp[sequence, $Layout, SymTab.Fetch[sequenceKeyWords, resultVar].val]}; CopyWireProperties: PROC[from, to: Wire] = { eachProp: PROC[atom:ATOM, ref: REF] = {CoreProperties.PutWireProp[to, atom, ref]}; CoreProperties.Enumerate[from.properties, eachProp]}; <> <<$PortLevelType>> PortLevelTypeWrite: CoreIO.PropWriteProc ~ { levelType: REF Ports.LevelType = NARROW[value]; BrineIO.WriteID[stream, Ports.levelTypeNames[levelType^]]; }; PortLevelTypeRead: CoreIO.PropReadProc ~ { value _ NEW [Ports.LevelType _ Ports.FindLevelType[BrineIO.ReadID[stream]]]; }; <<$PortDriveType, $PortTesterDriveType>> PortDriveTypeWrite: CoreIO.PropWriteProc ~ { driveType: REF Ports.DriveType _ NARROW[value]; BrineIO.WriteID[stream, Ports.driveTypeNames[driveType^]]; }; PortDriveTypeRead: CoreIO.PropReadProc ~ { value _ NEW [Ports.DriveType _ Ports.FindDriveType[BrineIO.ReadID[stream]]]; }; <<$PortDrive, $PortNewTesterDrive>> PortDriveWrite: CoreIO.PropWriteProc ~ { WITH value SELECT FROM drive: REF Ports.Drive => { BrineIO.WriteInt[stream, -1]; -- to indicate not a sequence ... BrineIO.WriteID[stream, Ports.driveNames[drive^]]; }; drives: REF Ports.DriveSequence => { BrineIO.WriteInt[stream, drives.size]; FOR i: NAT IN [0..drives.size) DO BrineIO.WriteID[stream, Ports.driveNames[drives[i]]]; ENDLOOP; }; ENDCASE => ERROR; -- should never happen !!! }; PortDriveRead: CoreIO.PropReadProc ~ { size: NAT _ BrineIO.ReadInt[stream]; IF size<0 THEN value _ NEW [Ports.Drive _ Ports.FindDrive[BrineIO.ReadID[stream]]] ELSE { -- drive sequence drives: Ports.DriveSequence _ NEW[Ports.DriveSequenceRec[size]]; FOR i: NAT IN [0..size) DO drives[i] _ Ports.FindDrive[BrineIO.ReadID[stream]]; ENDLOOP; value _ drives }; }; <> FixPortsImpl: PROC [] RETURNS [] ~ { [] _ CoreIO.RegisterProperty[prop: $PortLevelType, write: PortLevelTypeWrite, read: PortLevelTypeRead]; [] _ CoreIO.RegisterProperty[prop: $PortDriveType, write: PortDriveTypeWrite, read: PortDriveTypeRead]; [] _ CoreIO.RegisterProperty[prop: $PortTesterDriveType, write: PortDriveTypeWrite, read: PortDriveTypeRead]; [] _ CoreIO.RegisterProperty[prop: $PortDrive, write: PortDriveWrite, read: PortDriveRead]; [] _ CoreIO.RegisterProperty[prop: $PortNewTesterDrive, write: PortDriveWrite, read: PortDriveRead]; }; <> <> <> [] _ SymTab.Store[sequenceKeyWords, "Seq", NIL]; [] _ SymTab.Store[sequenceKeyWords, "SeqX", $ArrayX]; [] _ SymTab.Store[sequenceKeyWords, "SeqY", $ArrayY]; [] _ SymTab.Store[sequenceKeyWords, "RSeqX", $ReverseArrayX]; [] _ SymTab.Store[sequenceKeyWords, "RSeqY", $ReverseArrayY]; <
> Sinix.RegisterExtractProc[$SisyphExtractSequence, ExtractSequence]; FixPortsImpl[]; END.