SisyphCmdsImpl.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
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;
Icon Commands
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]]]};
Other Commands
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]};
Sequence Icons
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;
There should be only one subcell
IF iconRCT.size#1
THEN {
TerminalIO.PutF["*** SisyphExtractSequence: Sequence should contain one and only one subcell.\n"];
ERROR};
subCT ← iconRCT[0].type;
We deal with Global Variables
Sisyph.ProcessGlobalNames[iconCT, cx];
we check that there is no internal only
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;
We compute which wires are going to be sequenced
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;
We create the sequence
sequence ← CoreClasses.CreateSequence[
args:
NEW [CoreClasses.SequenceCellTypeRec ← [
base: subCT, count: count,
sequence: FindPorts[subCT, sequenceWires],
flatSequence: FindPorts[subCT, flatSequenceWires] ]],
name: name, props: props ];
New code to copy properties from the extracted public to the new sequence public.
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;
The object decoration!
CoreGeometry.PutObject[Sisyph.mode.decoration, sequence, obj];
We decorate with the appriopriate layout atom
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]};
Convertion code
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] ~ {
Remove from directory all entries for unnamed objects and imports. Returns number of removed objects.
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]]};
Initialization
ICom:
PROC[
key: ATOM,
proc: CDSequencer.CommandProc,
queue: CDSequencer.QueueMethod ← doQueueAndMark ] =
{CDSequencer.ImplementCommand[key, proc, NIL, queue]};
FilterSch: SinixOps.FilterProc =
{RETURN [Rope.Match["*.sch", name] OR Rope.Match["*.icon", name]]};
Convertion
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];
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
[] ← 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];
Main Menu
Sinix.RegisterExtractProc[$SisyphExtractSequence, ExtractSequence];
ICom[key: $FlushSisyphCaches, proc: FlushSisyphCaches, queue: doQueue];
SinixOps.RegisterModeCommands[mode: Sisyph.mode];
SinixOps.RegisterBackgroundExtractionCommand[CD.FetchTechnology[$cmosB], Sisyph.mode, "Sch background extraction", $SchBackgroundExtract, FilterSch]; -- only works for CMosB. Not very clean
Make Icon Menu
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];
Change Visibility Menu
ICom[key: $MakeInvisibleToExtractor, proc: MakeInvisibleToExtractor,queue: doQueueAndMark];
ICom[key: $MakeVisibleToExtractor, proc: MakeVisibleToExtractor, queue: doQueueAndMark];
Make Parameter Menu (normally hidden)
ICom[key: $SisyphShowParmNames, proc: ShowParmNames, queue: doQueue];
ICom[key: $SisyphSetParmName, proc: SetParmName];
ICom[key: $SisyphEditParmNames, proc: EditParmNames];
Expressions Menu
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];