<> <> <> <> <> <> <> <> <> <<>> DIRECTORY CD, CDCells, CDCommandOps, CDDirectory, CDImports, CDOps, CDProperties, CDSatellites, CDSequencer, Core, CoreClasses, CoreOps, CoreGeometry, CoreProperties, IO, Rope, RopeList, Sinix, SinixOps, Sisyph, SymTab, TerminalIO, ViewerClasses; SisyphCmdsImpl: CEDAR PROGRAM IMPORTS CD, CDCells, CDCommandOps, CDDirectory, CDImports, CDOps, CDProperties, CDSatellites, CDSequencer, CoreClasses, CoreOps, CoreGeometry, CoreProperties, IO, Rope, RopeList, Sinix, SinixOps, 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; <> UnMakeIcon: PROC [comm: CDSequencer.Command] = { selected: CD.Instance _ TheCellInstance[comm.design, "UnMakeIcon\n"]; IF selected=NIL THEN RETURN; CleanUpIconProperties[selected.ob]; TerminalIO.PutF ["UnMakeIcon of %g done.\n", IO.rope[CDDirectory.Name[selected.ob, comm.design]]]}; MakeCellIcon: PROC [comm: CDSequencer.Command] = { key: ATOM; rope, name: ROPE; selected: CD.Instance _ TheCellInstance[comm.design, "MakeCellIcon\n"]; IF selected=NIL THEN RETURN; name _ CDDirectory.Name[selected.ob, comm.design]; IF NOT Rope.Match["*.icon", name] THEN TerminalIO.PutF["*** Convention for icons is to suffix them with '.icon'.\n"]; SELECT TerminalIO.RequestSelection[Rope.Cat["MakeCellIcon of ", name], LIST ["From Code", "From Schematic"], "choice of the nature of the cell icon", LIST ["Code returns a CellType", "Schematic should extract as a CellType"]] FROM 1 => { key _ $CodeFor; rope _ TerminalIO.RequestRope["Type code: "]; TerminalIO.PutF["done.\n"]}; 2 => { rope _ TerminalIO.RequestRope["Type schematic name: "]; IF Rope.IsEmpty[rope] AND Rope.Match["*.icon", name] THEN rope _ Rope.Cat[Rope.Substr[name, 0, Rope.Length[name]-5], ".sch"]; IF CDDirectory.Fetch[comm.design, rope]=NIL THEN { TerminalIO.PutF["*** No object '%g' in design.\n", IO.rope[rope]]; RETURN}; IF Rope.Equal[rope, name] THEN { TerminalIO.PutF["*** You can't do that: same icon and sch name!\n"]; RETURN}; IF NOT Rope.Match["*.sch", rope] THEN TerminalIO.PutF["*** Convention for schematics is to suffix them with '.sch'.\n"]; key _ $IconFor; TerminalIO.PutF["%g made cell icon of %g.\n", IO.rope[name], IO.rope[rope]]}; ENDCASE => {TerminalIO.PutF["*** Not done.\n"]; RETURN}; CleanUpIconProperties[selected.ob]; CDProperties.PutObjectProp[selected.ob, key, rope]; CDProperties.PutObjectProp[selected.ob, Sisyph.mode.extractProcProp, $SisyphExtractCellIcon]}; MakeWireIcon: PROC [comm: CDSequencer.Command] = { key: ATOM; rope, name: ROPE; choice: INT; selected: CD.Instance _ TheCellInstance[comm.design, "MakeWireIcon\n"]; IF selected=NIL THEN RETURN; name _ CDDirectory.Name[selected.ob, comm.design]; IF NOT Rope.Match["*.icon", name] THEN TerminalIO.PutF["*** Convention for icons is to suffix them with '.icon'.\n"]; choice _ TerminalIO.RequestSelection[ Rope.Cat["MakeWireIcon of ", name], LIST ["From Code; Named", "From Code; UnNamed", "From Schematic; Named", "From Schematic; UnNamed"], "choice of the nature of the cell icon", LIST ["Code returns a Wire", "Code returns a Wire", "Schematic should extract as a CellType", "Schematic should extract as a CellType"] ]; SELECT choice FROM 1, 2 => { key _ $CodeFor; rope _ TerminalIO.RequestRope["Type code: "]; TerminalIO.PutF["done.\n"]}; 3, 4 => { rope _ TerminalIO.RequestRope["Type schematic name: "]; IF Rope.IsEmpty[rope] AND Rope.Match["*.icon", name] THEN rope _ Rope.Cat[Rope.Substr[name, 0, Rope.Length[name]-5], ".sch"]; IF CDDirectory.Fetch[comm.design, rope]=NIL THEN { TerminalIO.PutF["*** No object '%g' in design.\n", IO.rope[rope]]; RETURN}; IF Rope.Equal[rope, name] THEN { TerminalIO.PutF["*** You can't do that: same icon and sch name!\n"]; RETURN}; IF NOT Rope.Match["*.sch", rope] THEN TerminalIO.PutF["*** Convention for schematics is to suffix them with '.sch'.\n"]; key _ $IconFor; TerminalIO.PutF["%g made wire icon of %g.\n", IO.rope[name], IO.rope[rope]]}; ENDCASE => {TerminalIO.PutF["*** Not done.\n"]; RETURN}; CleanUpIconProperties[selected.ob]; CDProperties.PutObjectProp[selected.ob, key, rope]; CDProperties.PutObjectProp[selected.ob, Sisyph.mode.extractProcProp, SELECT choice FROM 1, 3 => $SisyphExtractNamedWireIcon, 2, 4 => $SisyphExtractUnNamedWireIcon, ENDCASE => ERROR]}; MakeSequenceIcon: PROC [comm: CDSequencer.Command] = { selected: CD.Instance _ TheCellInstance[comm.design, "MakeSequenceIcon\n"]; IF selected=NIL THEN RETURN; CleanUpIconProperties[selected.ob]; CDProperties.PutObjectProp[selected.ob, Sisyph.mode.extractProcProp, $SisyphExtractSequence]; IF ParseSatellites[CDSatellites.GetSatelliteRopes[selected.ob]].keyword=NIL THEN TerminalIO.PutF["*** Warning: there is no satellite of the form 'Keyword: Expression'.\n"]; TerminalIO.PutF["Sequencing of %g done.\n", IO.rope[CDDirectory.Name[selected.ob, comm.design]]]}; <> MakeInvisibleToExtractor: PROC [comm: CDSequencer.Command] = { nInstances: INT _ 0; FOR w: LIST OF CD.Instance _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO inst: CD.Instance _ w.first; IF inst.selected THEN { CDProperties.PutInstanceProp[inst, Sisyph.mode.extractProcProp, $ExtractNull]; nInstances _ nInstances+1; FlushCache[comm.design, inst.ob] } ENDLOOP; TerminalIO.PutF["Made %g instances invisible to Sisyph\n", IO.int[nInstances]] }; MakeVisibleToExtractor: PROC [comm: CDSequencer.Command] = { nInstances: INT _ 0; FOR w: LIST OF CD.Instance _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO inst: CD.Instance _ w.first; IF inst.selected THEN { CDProperties.PutInstanceProp[inst, Sisyph.mode.extractProcProp, NIL]; nInstances _ nInstances+1; FlushCache[comm.design, inst.ob]} ENDLOOP; TerminalIO.PutF["Made %g instances visible to Sisyph\n", IO.int[nInstances]]}; FlushCache: PROC [design: CD.Design, obj: CD.Object] = { name: ROPE _ CDDirectory.Name[obj, design]; iconFor: REF = CDProperties.GetObjectProp[obj, $IconFor]; schName: ROPE = IF ISTYPE [iconFor, ROPE] THEN NARROW [iconFor] ELSE NIL; sch: CD.Object = IF schName#NIL THEN CDDirectory.Fetch[design, schName] ELSE NIL; FlushEachInstance: CDCells.InstEnumerator = {FlushCache[design, inst.ob]}; IF name=NIL AND (CDCells.IsCell[obj] OR CDImports.IsImport[obj]) THEN name _ CD.Describe[ob: obj, design: design]; IF (CDProperties.GetObjectProp[obj, $SinixInstanceCache]#NIL OR CDProperties.GetObjectProp[obj, $SinixObjectCache]#NIL) AND name#NIL THEN TerminalIO.PutF["Flushing %g.\n", IO.rope[name]]; -- We use the property although it is PRIVATE because printing is just a hint Sinix.FlushCache[obj]; IF CDCells.IsCell[obj] THEN [] _ CDCells.EnumerateInstances[obj, FlushEachInstance]; IF sch#NIL THEN FlushCache[design, sch]}; FlushSisyphCaches: PROC [comm: CDSequencer.Command] = { FOR w: LIST OF CD.Instance _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO IF w.first.selected THEN FlushCache[comm.design, w.first.ob]; ENDLOOP}; ShowInstExpressions: PROC [comm: CDSequencer.Command] = { selected: CD.Instance _ CDOps.TheInstance[comm.design, "ShowInstExpressions\n"]; IF selected=NIL THEN RETURN; PutRopes["Instance Expressions:\n", NARROW [CDProperties.GetInstanceProp[selected, Sisyph.expressionsProp]]]}; AddInstExpression: PROC [comm: CDSequencer.Command] = { exprs: ROPES; selected: CD.Instance _ CDOps.TheInstance[comm.design, "AddInstExpression\n"]; IF selected=NIL THEN RETURN; exprs _ NARROW [CDProperties.GetInstanceProp[selected, Sisyph.expressionsProp]]; PutRopes["Add Instance Expression. Previous Instance Expressions:\n", exprs]; exprs _ CONS [TerminalIO.RequestRope[Rope.Cat[" New Expression: "]], exprs]; CDProperties.PutInstanceProp[selected, Sisyph.expressionsProp, exprs]}; EditInstExpressions: PROC [comm: CDSequencer.Command] = { exprs: ROPES; selected: CD.Instance _ CDOps.TheInstance[comm.design, "EditInstExpressions\n"]; IF selected=NIL THEN RETURN; TerminalIO.PutF["Edit Instance Expressions\n"]; exprs _ NARROW[CDProperties.GetInstanceProp[selected, Sisyph.expressionsProp]]; exprs _ EditExpressions[exprs, "Expression"]; CDProperties.PutInstanceProp[selected, Sisyph.expressionsProp, exprs]}; ShowObjExpressions: PROC [comm: CDSequencer.Command] = { selected: CD.Instance _ CDOps.TheInstance[comm.design, "ShowObjExpressions\n"]; IF selected=NIL THEN RETURN; PutRopes["Object Expressions:\n", NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]]; IF NOT CDImports.IsImport[selected.ob] THEN RETURN; IF NARROW [selected.ob.specific, CDImports.ImportSpecific].boundOb=NIL THEN TerminalIO.PutF["Object is an unbound import.\n"] ELSE PutRopes["Object Expressions of the bound import:\n", NARROW [CDProperties.GetObjectProp[NARROW [selected.ob.specific, CDImports.ImportSpecific].boundOb, Sisyph.expressionsProp]]]}; AddObjExpression: PROC [comm: CDSequencer.Command] = { exprs: ROPES; selected: CD.Instance _ TheCellInstance[comm.design, "AddObjExpression\n"]; IF selected=NIL THEN RETURN; exprs _ NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]; PutRopes["Add Object Expression. Previous Object Expressions:\n", exprs]; exprs _ CONS [TerminalIO.RequestRope[Rope.Cat[" New Expression: "]], exprs]; CDProperties.PutObjectProp[selected.ob, Sisyph.expressionsProp, exprs]}; EditObjExpressions: PROC [comm: CDSequencer.Command] = { exprs: ROPES; selected: CD.Instance _ TheCellInstance[comm.design, "EditObjExpressions\n"]; IF selected=NIL THEN RETURN; TerminalIO.PutF["Edit Object Expressions\n"]; exprs _ NARROW[CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]; exprs _ EditExpressions[exprs, "Expression"]; CDProperties.PutObjectProp[selected.ob, Sisyph.expressionsProp, exprs]}; ShowParmNames: PROC [comm: CDSequencer.Command] = { selected: CD.Instance _ CDOps.TheInstance[comm.design, "ShowParmNames\n"]; -- not TheCellInstance for discovering old settings IF selected=NIL THEN RETURN; PutRopes["Parameter Names (0 for no parameter):\n", NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.parmNamesProp]]]}; <<>> SetParmName: PROC [comm: CDSequencer.Command] = { insts: LIST OF CD.Instance _ AllCellInstances[comm.design, "SetParmName\n"]; IF insts=NIL THEN RETURN; SELECT TerminalIO.RequestSelection["Setting Parameters", LIST ["Explicitly", "Implicitly"], "Better ABORT and click the doc if you do not know what you are doing ...", LIST ["All selected cells with get the specified parameters", "Automatic program setting parameters"]] FROM 1 => { parms: ROPES _ NIL; DO input: ROPE _ TerminalIO.RequestRope[" Parameter: "]; IF Rope.IsEmpty[input] THEN EXIT; parms _ CONS [input, parms]; ENDLOOP; WHILE insts#NIL DO TerminalIO.PutF["Setting parameters on cell %g.\n", IO.rope[CD.Describe[ob: insts.first.ob, design: comm.design]]]; CDProperties.PutObjectProp[insts.first.ob, Sisyph.parmNamesProp, parms]; insts _ insts.rest; ENDLOOP}; 2 => { IF TRUE THEN {TerminalIO.PutF["Not yet implemented.\n"]; RETURN}; WHILE insts#NIL DO name: ROPE = CDDirectory.Name[object: insts.first.ob, design: comm.design]; parms: ROPES; reasonForWorld: ROPE; [parms, reasonForWorld] _ ComputeParameters[comm.design, insts.first.ob, insts.first.properties]; IF reasonForWorld=NIL THEN { TerminalIO.PutF["Setting parameters on cell %g.\n", IO.rope[name]]; CDProperties.PutObjectProp[insts.first.ob, Sisyph.parmNamesProp, parms]} ELSE TerminalIO.PutF["*** Could not set parameters for cell %g because %g.\n", IO.rope[name], IO.rope[reasonForWorld]]; insts _ insts.rest; ENDLOOP}; ENDCASE => RETURN}; <<>> EditParmNames: PROC [comm: CDSequencer.Command] = { parms: ROPES; selected: CD.Instance _ TheCellInstance[comm.design, "EditParmNames\n"]; IF selected=NIL THEN RETURN; TerminalIO.PutF["Edit Object Expressions\n"]; parms _ NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.parmNamesProp]]; parms _ EditExpressions[parms, "Parameter"]; CDProperties.PutObjectProp[selected.ob, Sisyph.parmNamesProp, parms]}; <> 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; layoutAtom: REF; 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]; <> layoutAtom _ SymTab.Fetch[sequenceKeyWords, resultVar].val; IF layoutAtom#NIL THEN CoreProperties.PutCellTypeProp[sequence, $Layout, layoutAtom]; }; CopyWireProperties: PROC[from, to: Wire] = { eachProp: PROC[atom:ATOM, ref: REF] = {CoreProperties.PutWireProp[to, atom, ref]}; CoreProperties.Enumerate[from.properties, eachProp]}; <> <> <> ComputeParameters: PROC [design: CD.Design, obj: CD.Object, properties: CD.PropList] RETURNS [parms: ROPES, reasonForWorld: ROPE _ NIL] = { cx: Sisyph.Context _ SymTab.Create[11]; parms _ NARROW [CDProperties.GetObjectProp[obj, Sisyph.parmNamesProp]]; IF parms#NIL THEN RETURN; Sisyph.Store[cx, "design", NEW [CD.Design _ design]]; Sisyph.Insert[cx, "globalNames", NEW [ROPES _ Sisyph.defaultGlobalNames]]; [] _ Sinix.Extract[ obj: obj, mode: Sisyph.mode, properties: properties, userData: cx ! ANY => {reasonForWorld _ "???"; GOTO Return} ]; parms _ LIST ["0"]; EXITS Return => RETURN}; <> PutRopes: PROC [rope: ROPE, ropes: ROPES] = { TerminalIO.PutF[rope]; WHILE ropes#NIL DO TerminalIO.PutF["\t%g\n", IO.rope[ropes.first]]; ropes _ ropes.rest; ENDLOOP}; TheCellInstance: PROC [design: CD.Design, text: ROPE _ NIL] RETURNS [inst: CD.Instance _ NIL] = { inst _ CDOps.TheInstance[design, text]; IF inst=NIL OR CDCells.IsCell[inst.ob] THEN RETURN; TerminalIO.PutF["*** Selected instance is not a cellcan't do it.\n"]; inst _ NIL}; AllCellInstances: PROC [design: CD.Design, text: ROPE _ NIL] RETURNS [insts: LIST OF CD.Instance _ NIL] = { IF text#NIL THEN TerminalIO.PutRope[text]; FOR w: CD.InstanceList _ CDOps.InstList[design], w.rest WHILE w#NIL DO IF NOT w.first.selected THEN LOOP; IF NOT CDCells.IsCell[w.first.ob] THEN {TerminalIO.PutRope[" selection is not a cell; failed\n"]; RETURN [NIL]}; insts _ CONS [w.first, insts]; ENDLOOP; IF insts=NIL THEN TerminalIO.PutRope[" no selection; failed\n"]}; CleanUpIconProperties: PROC [obj: CD.Object] = { Sinix.FlushCache[obj]; CDProperties.PutObjectProp[obj, $IconFor, NIL]; CDProperties.PutObjectProp[obj, $CodeFor, NIL]; CDProperties.PutObjectProp[obj, Sisyph.mode.extractProcProp, NIL]; CDProperties.PutObjectProp[obj, Sisyph.expressionsProp, StripResultExprs [NARROW [CDProperties.GetObjectProp[obj, Sisyph.expressionsProp]]]] }; <> StripResultExprs: PROC [in: ROPES] RETURNS [out: ROPES _ NIL] = { FOR l: ROPES _ in, l.rest WHILE l#NIL DO expr: ROPE _ l.first; IF NOT Rope.Match[expr, "*cI*_*"] AND NOT Rope.Match[expr, "*wI*_*"] AND NOT Rope.Match[expr, "*wire*_*"] THEN out _ CONS [expr, out] ENDLOOP}; EditExpressions: PROC [oldExprs: ROPES, prompt: ROPE] RETURNS [allExprs: ROPES _ NIL] = { input: ROPE; noOldExprs: BOOL _ oldExprs=NIL; TerminalIO.PutF["\n"]; WHILE oldExprs#NIL DO input _ TerminalIO.RequestRope[Rope.Cat[" ", prompt, ": ", oldExprs.first, " Replacement: "]]; SELECT TRUE FROM Rope.Equal[input, "-"] => TerminalIO.PutF[" ** Deleted\n"]; Rope.IsEmpty[input] => allExprs _ CONS [oldExprs.first, allExprs]; ENDCASE => allExprs _ CONS [input, allExprs]; oldExprs _ oldExprs.rest; ENDLOOP; IF noOldExprs THEN { input _ TerminalIO.RequestRope[Rope.Cat[" New ", prompt, ": "]]; WHILE ~Rope.IsEmpty[input] AND ~Rope.Equal[input, "-"] DO allExprs _ CONS [input, allExprs]; input _ TerminalIO.RequestRope[Rope.Cat[" New ", prompt, ": "]]; ENDLOOP}; allExprs _ RopeList.Reverse[allExprs]}; <> MatchProc: TYPE = PROC [old: ROPE] RETURNS [BOOL]; MatchTransistor: MatchProc = {RETURN [Rope.Match["*CreateTransistor[[*", old]]}; MatchAmpersand: MatchProc = {RETURN [Rope.Match["*&*_*", old]]}; MatchName: MatchProc = {RETURN [Rope.Match["name _ \"*\"", old]]}; MatchSchCI: MatchProc = {RETURN [Rope.Match["*cI*_*ES[\"*\",*cx]", old]]}; MatchCodeCI: MatchProc = {RETURN [Rope.Match["*cI*_*", old]]}; MatchCodeWI: MatchProc = {RETURN [Rope.Match["*wI*_*", old]]}; MatchWire: MatchProc = {RETURN [Rope.Match["*wire*_*", old]]}; MatchDeclare: MatchProc = {RETURN [Rope.Match[ "*Sisyph.Store[cx,*\"*\",*NEW[*_*]]", old]]}; Change: PROC [master: REF, location: ROPE] RETURNS [needInteraction: ROPE _ NIL] = { news: ROPES; CDProperties.PutProp[master, $CameFrom, NIL]; CDProperties.PutProp[master, $OriginalName, NIL]; CDProperties.PutProp[master, $CDBringoverLibraryName, NIL]; CDProperties.PutProp[master, $SisyphArguments, NIL]; FOR list: ROPES _ NARROW [CDProperties.GetProp[master, Sisyph.expressionsProp]], list.rest WHILE list#NIL DO old: ROPE = list.first; SELECT TRUE FROM MatchName[old] => { new: ROPE = Rope.Substr[old, 8, Rope.Length[old]-9]; TerminalIO.PutF["changed '%g' to '%g'.\n", IO.rope[old], IO.rope[new]]; news _ CONS [new, news]; }; MatchSchCI[old] => { pos1: INT _ Rope.Find[old, "\""]; pos2: INT _ Rope.Find[old, "\"", pos1+1]; sch: ROPE = Rope.Substr[old, pos1+1, pos2-pos1-1]; TerminalIO.PutF["changed '%g' to an $IconFor property '%g'.\n", IO.rope[old], IO.rope[sch]]; CDProperties.PutProp[master, $IconFor, sch]; CDProperties.PutProp[master, Sisyph.mode.extractProcProp, $SisyphExtractCellIcon]}; MatchCodeCI[old] => { code: ROPE = Rope.Substr[old, Rope.Find[old, "_"]+1]; TerminalIO.PutF["changed '%g' to an $CodeFor property '%g'.\n", IO.rope[old], IO.rope[code]]; CDProperties.PutProp[master, $IconFor, NIL]; -- because $IconFor was not the truth in CD24! CDProperties.PutProp[master, $CodeFor, code]; CDProperties.PutProp[master, Sisyph.mode.extractProcProp, $SisyphExtractCellIcon]}; MatchCodeWI[old] => { code: ROPE = Rope.Substr[old, Rope.Find[old, "_"]+1]; TerminalIO.PutF["changed '%g' to an $CodeFor property '%g'.\n", IO.rope[old], IO.rope[code]]; CDProperties.PutProp[master, $CodeFor, code]; CDProperties.PutProp[master, Sisyph.mode.extractProcProp, $SisyphExtractNamedWireIcon]}; MatchWire[old] OR MatchTransistor[old] => { TerminalIO.PutF["*** Found expression %g '%g' that is not converted automatically.\n", IO.rope[location], IO.rope[old]]; news _ CONS [old, news]}; MatchAmpersand[old] => { TerminalIO.PutF["*** Found expression %g '%g' that uses a variable starting with '&'.\n", IO.rope[location], IO.rope[old]]; news _ CONS [old, news]}; MatchDeclare[old] => { pos1: INT _ Rope.Find[old, "\""]; pos2: INT _ Rope.Find[old, "\"", pos1+1]; pos3: INT _ Rope.Find[old, "_", pos2+1]; pos4: INT _ Rope.Find[old, "]", pos3+1]; new: ROPE _ Rope.Cat[Rope.Substr[old, pos1+1, pos2-pos1-1], " ~ ", Rope.Substr[old, pos3+1, pos4-pos3-1]]; TerminalIO.PutF["changed '%g' to '%g'.\n", IO.rope[old], IO.rope[new]]; news _ CONS [new, news]}; ENDCASE => news _ CONS [old, news]; ENDLOOP; CDProperties.PutProp[master, Sisyph.expressionsProp, news]; IF MatchTransistor[NARROW [CDProperties.GetProp[master, $CodeFor]]] THEN TerminalIO.PutF["*** Found $CodeFor %g '%g' that cannot be converted automatically.\n", IO.rope[location], IO.rope[NARROW [CDProperties.GetProp[master, $CodeFor]]]]; IF CDProperties.GetProp[master, $CodeFor]#NIL AND CDProperties.GetProp[master, $IconFor]#NIL THEN TerminalIO.PutF["*** Found both $CodeFor and $IconFor %g. $CodeFor is probably the truth, but check that carefully!\n", IO.rope[location]]; FOR list: ROPES _ CDSatellites.GetSatelliteRopes[master], list.rest WHILE list#NIL DO old: ROPE = list.first; SELECT TRUE FROM MatchName[old] OR MatchSchCI[old] OR MatchCodeCI[old] OR MatchCodeWI[old] OR MatchWire[old] OR MatchDeclare[old] OR MatchTransistor[old] OR MatchAmpersand[old] => { needInteraction _ Rope.Cat["'", old, "' ", needInteraction]}; ENDCASE => {}; ENDLOOP}; Convert: PROC [comm: CDSequencer.Command] = { design: CD.Design = comm.design; EachObj: CDDirectory.EachObjectProc = { EachInst: CDCells.InstEnumerator = { needInteraction _ Change[inst, Rope.Cat["in ", name]]; IF needInteraction#NIL THEN TerminalIO.PutF["*** Some instance satellite(s) in %g need to be changed: %g.\n", IO.rope[name], IO.rope[needInteraction]]}; name: ROPE _ CDDirectory.Name[me, design]; needInteraction: ROPE _ Change[me, Rope.Cat["of ", name]]; IF needInteraction#NIL THEN TerminalIO.PutF["*** Some object satellite(s) of %g need to be changed: %g.\n", IO.rope[name], IO.rope[needInteraction]]; IF NOT CDCells.IsCell[me] THEN RETURN; [] _ CDCells.EnumerateInstances[me, EachInst]}; [] _ CDDirectory.EnumerateDesign[design, EachObj]; TerminalIO.PutF["\n*** Converted! Save the design\n"]}; NoDummiesInDir: PROC [comm: CDSequencer.Command] ~ { <> design: CD.Design = comm.design; n: INT _ 0; elem: TYPE ~ RECORD [ob: CD.Object, name: ROPE]; EachEntry: CDDirectory.EachEntryAction ~ { IF Rope.Match[pattern: "-no name*", object: name] OR -- style 1 `unnamed' object Rope.Match[pattern: "-noname-*", object: name] OR -- style 2 `unnamed' object Rope.Match[pattern: "/@*", object: name] OR -- twiddled SequencingSlash CDImports.IsImport[ob] -- Import THEN remove _ CONS [[ob, name], remove]}; remove: LIST OF elem; IF CDDirectory.Enumerate[design, EachEntry] THEN ERROR; WHILE remove#NIL DO -- remove them all, check that the name/object relation is OK n _ n+1; IF CDDirectory.Remove[design, remove.first.name, remove.first.ob]=NIL THEN ERROR; remove _ remove.rest; ENDLOOP; TerminalIO.PutF["\n%g objects made anonymous! Save the design!\n", IO.int[n]]}; <> ICom: PROC[ key: ATOM, proc: CDSequencer.CommandProc, queue: CDSequencer.QueueMethod _ doQueueAndMark ] = {CDSequencer.ImplementCommand[key, proc, NIL, queue]}; <> <<{RETURN [Rope.Match["*.sch", name] OR Rope.Match["*.icon", name]]};>> <> CDCommandOps.RegisterWithMenu [$Debug, "SisyphConvert", "Convert to new Sisyph syntax", $SisyphConvert, Convert, doQueueAndMark]; CDCommandOps.RegisterWithMenu [$Debug, "Get rid of -no name-*", "Remove from directory all entries for unnamed objects and imports", $SisyphNoDummiesInDir, NoDummiesInDir, doQueueAndMark]; <> <> [] _ 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]; ICom[key: $FlushSisyphCaches, proc: FlushSisyphCaches, queue: doQueue]; SinixOps.RegisterModeCommands[mode: Sisyph.mode]; <> <> ICom[key: $MakeCellIcon, proc: MakeCellIcon, queue: doQueueAndMark]; ICom[key: $MakeWireIcon, proc: MakeWireIcon, queue: doQueueAndMark]; ICom[key: $MakeSequenceIcon, proc: MakeSequenceIcon, queue: doQueueAndMark]; ICom[key: $UnMakeIcon, proc: UnMakeIcon, queue: doQueueAndMark]; <> ICom[key: $MakeInvisibleToExtractor, proc: MakeInvisibleToExtractor,queue: doQueueAndMark]; ICom[key: $MakeVisibleToExtractor, proc: MakeVisibleToExtractor, queue: doQueueAndMark]; <> ICom[key: $SisyphShowParmNames, proc: ShowParmNames, queue: doQueue]; ICom[key: $SisyphSetParmName, proc: SetParmName]; ICom[key: $SisyphEditParmNames, proc: EditParmNames]; <> ICom[key: $SisyphShowInstExpressions, proc: ShowInstExpressions, queue: doQueue]; ICom[key: $SisyphAddInstExpression, proc: AddInstExpression, queue: doQueueAndMark]; ICom[key: $SisyphEditInstExpressions, proc: EditInstExpressions, queue: doQueueAndMark]; ICom[key: $SisyphShowObjExpressions, proc: ShowObjExpressions, queue: doQueue]; ICom[key: $SisyphAddObjExpression, proc: AddObjExpression, queue: doQueueAndMark]; ICom[key: $SisyphEditObjExpressions, proc: EditObjExpressions, queue: doQueueAndMark]; END.