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; 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]}; 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]}; 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. vSisyphCmdsImpl.mesa Copyright Σ 1985, 1986, 1987 by Xerox Corporation. All rights reserved. Created by Pradeep Sindhu, December 9, 1985 10:01:52 pm PST Pradeep Sindhu, September 26, 1986 2:06:15 pm PDT Barth, January 13, 1986 3:30:05 pm PST Bertrand Serlet September 21, 1987 1:28:28 pm PDT Jean-Marc Frailong December 9, 1987 6:50:30 pm PST Last Edited by: Jacobi July 15, 1986 2:40:48 pm PDT Don Curry January 20, 1988 3:43:54 pm PST Icon Commands Other Commands Sequence Icons There should be only one subcell We deal with Global Variables we check that there is no internal only We compute which wires are going to be sequenced We create the sequence New code to copy properties from the extracted public to the new sequence public. The object decoration! We decorate with the appriopriate layout atom Computing Parameters This function is, of course, slightly fancy ... Not really working, either! Internal Utilities Soon obsolete? Convertion code Remove from directory all entries for unnamed objects and imports. Returns number of removed objects. Initialization FilterSch: SinixOps.FilterProc = {RETURN [Rope.Match["*.sch", name] OR Rope.Match["*.icon", name]]}; Convertion Filling the Layout atoms for sequences At this point, there is a strange dependency between Sisyph and PWCore, but it is not worth the effort making a separate module Main Menu SinixOps.RegisterBackgroundExtractionCommand[CD.FetchTechnology[$cmosB], Sisyph.mode, "Sch background extraction", $SchBackgroundExtract, FilterSch]; -- only works for CMosB. Not very clean Make Icon Menu Change Visibility Menu Make Parameter Menu (normally hidden) Expressions Menu Κ‰˜™JšœH™HJšœ8Οk™;Jšœ.™1Jšœ#™&Jšœ.™1Jšœ/™2Jšœ0™3Jšœ)™)—J™š ˜ Jšœ`˜bJšœ9˜9Jšœ˜Jšœ!˜!Jšœ˜J˜—šΟnœœ˜Jšœœ•œ=˜ήJšœ˜J™Jšœœœ˜Jš œœœœœ˜Jšœœ ˜Jšœœ˜Jšœ œ˜—head™ šž œœ ˜0Jšœ œ9˜EJšœ œœœ˜Jšœ#˜#šœ˜Jšœœ5˜T—J˜—šž œœ ˜2Jšœœ˜ Jšœ œ˜Jšœ œ;˜GJšœ œœœ˜Jšœ2˜2šœœ˜"JšœO˜S—šœAœKœH˜ζšœ˜Jšœ=˜=Jšœ˜—šœ˜Jšœ7˜7šœœ˜5JšœE˜I—šœ&œœ˜2Jšœ3œ ˜BJšœ˜—šœœ˜ JšœD˜DJšœ˜—JšœœœS˜xJšœ˜Jšœ.œ œ˜M—Jšœ)œ˜8—Jšœ#˜#Jšœ3˜3Jšœ_˜_J˜—šž œœ ˜2Jšœœ˜ Jšœ œ˜Jšœœ˜ Jšœ œ;˜GJšœ œœœ˜Jšœ2˜2šœœ˜"JšœO˜S—šœ%˜%Jšœ$˜$Jšœa˜eJšœ)˜)Jšœ†˜Š—šœ˜šœ ˜ Jšœ=˜=Jšœ˜—šœ ˜ Jšœ7˜7šœœ˜5JšœE˜I—šœ&œœ˜2Jšœ3œ ˜BJšœ˜—šœœ˜ JšœD˜DJšœ˜—JšœœœS˜xJšœ˜Jšœ.œ œ˜M—Jšœ)œ˜8—Jšœ#˜#Jšœ3˜3Jš œEœœMœœ˜ΈJ˜—šžœœ ˜6Jšœ œ?˜KJšœ œœœ˜Jšœ#˜#Jšœ]˜]JšœFœœ\˜¬Jšœ,œ5˜c——™šžœœ ˜>Jšœ œ˜š œœœœ0œœ˜OJšœœ˜šœœ˜JšœN˜NJšœ˜Jšœ"˜"—Jšœ˜—Jšœ;œ˜RJ˜—šžœœ ˜˜>Jšœ:˜:Jšœ#œ˜*Jšœœ&˜1Jšœ5œ œœ ˜eJšœ:Ÿ˜AJšœ;Ÿ˜BJšœX˜XJ˜$Jšœ˜J˜—–‘ -- [obj: CD.Object, mode: Sinix.Mode, properties: PropertyLists.PropList _ NIL, userData: REF ANY _ NIL] RETURNS [result: REF ANY, props: Core.Properties _ NIL]šžœ˜Jš œœ(œ œœœ˜†Jšœœ&œ˜PJšœ&œ˜;Jšœ˜Jšœ*œ˜.Jšœ ™ šœœ˜Jšœb˜bJšœ˜—Jšœ˜J™Jšœ&˜&Jšœ'™'šœœœ˜-Jšœ!˜!Jšœœ"˜,Jšœœœ˜$šœœ2œ˜>JšœPœ ˜_Jšœ˜—šœœ.œ˜:JšœBœ ˜QJšœ˜—Jšœ˜—Jšœ0™0šœœœ˜)šœ=œ˜CJšœœ"˜;—šœAœ˜GJšœœ&˜C—Jšœ˜—Jšœ™šœ&˜&šœœ%˜.Jšœ˜Jšœ+˜+Jšœ5˜5—Jšœ˜—J™Qšœœœ˜*JšœN˜NJšœ;œ˜C—J™Jšœ>˜>J™-Jšœb˜bJ˜—šžœœ˜,Jšœ œœœ0˜RJšœ5˜5——™Jšœ/™/J™šžœœ œœœ œ œœœ˜‹Jšœ'˜'Jšœœ9˜GJšœœœœ˜Jšœœœ˜5Jšœ!œœ˜Jšœ˜JšœB˜BJšœœœ ˜2—Jšœœ˜Jšœ œ˜——™šžœœœ œ˜-Jšœ˜šœœ˜Jšœœ(˜DJšœ˜ —J˜—š žœœ œœœ˜;Jšœœ œ˜%Jšœ'˜'Jš œœœœœ˜3JšœF˜FJšœœ˜ J˜—š žœœ œœœ˜œœ˜P—Jšœœ˜Jšœ˜—Jšœœœ2˜CJ˜—šžœœœ ˜0Jšœ˜Jšœ*œ˜/Jšœ*œ˜/Jšœ=œ˜BšœH˜HJšœœ?˜F—J˜—JšΟb™š žœœœœœœ˜Aš œœœœ˜(Jšœœ ˜Jšœœœœœœœœ ˜…Jšœ˜ —J˜—šžœœ œ œœ œœ˜YJšœœ˜ Jšœ œ œ˜ Jšœ˜šœ œ˜Jšœ`˜`šœœ˜Jšœ<˜