Command Implementation
ExtractSelectedCellsCommand:
PROC [command: CDSequencer.Command] = {
NullProcedure: CoreCDUser.EachRootCellTypeProc = {};
[] ← CoreCDUser.EnumerateSelectedCellTypes[command.design, NullProcedure];
TerminalIO.PutRope["CoreCDUser: Done\n"];
};
HighlightSelectedFlatWireCommand:
PROC [command: CDSequencer.Command] = {
CanonizeWire:
PROC [root: Core.CellType, child: CoreFlat.FlatWireRec]
RETURNS [parent: CoreFlat.FlatWireRec] = {
WindUp: CoreFlat.UnboundFlatCellProc = {
FindBoundWire: CoreOps.EachWirePairProc = {
IF publicWire=canonized.wire
THEN {
new ← actualWire;
quit ← TRUE;
};
};
new: Core.Wire;
previousCells ← CONS [cell, previousCells];
previousInstances ← CONS [instance, previousInstances];
CoreFlat.NextUnboundCellType[cell, target, flatCell, instance, index, parent, flatParent, NIL, WindUp];
previousCells ← previousCells.rest;
previousInstances ← previousInstances.rest;
IF CoreGeometry.HasObject[decoration, cell] AND ExtractOps.SameCDObject[rootObject, CoreGeometry.GetObject[decoration, cell]] THEN stop ← TRUE;
IF stop OR previousCells=NIL THEN RETURN;
IF instance=previousInstances.first AND cell=previousCells.first THEN RETURN;
IF CoreOps.VisitBinding[actual: IF instance=NIL OR instance.type#cell THEN previousCells.first.public ELSE instance.actual, public: cell.public, eachWirePair: FindBoundWire] THEN canonized ← [flatCell: flatParent, wireRoot: IF instance=NIL OR instance.type#cell THEN public ELSE internal, wire: new]
ELSE stop ← TRUE;
};
canonized: CoreFlat.FlatWireRec ← child;
previousCells: LIST OF Core.CellType ← NIL;
previousInstances: LIST OF CoreClasses.CellInstance ← NIL;
stop: BOOL ← FALSE;
WindUp[cell: root, target: child.flatCell];
RETURN [parent: canonized];
};
HighlightAWire: CoreCDUser.SelectedFlatWireActionProc = {
flatWires ← CONS[CanonizeWire[root, selectedFlatWire^], flatWires];
};
root: Core.CellType ← CoreCDUser.GetDesignRootCellType[command.design];
decoration: CoreGeometry.Decoration ← CoreCDUser.GetRootCellTypeDecoration[root];
rootObject: CD.Object ← NIL;
flatWires: LIST OF CoreFlat.FlatWireRec ← NIL;
IF root=NIL THEN TerminalIO.PutRope["CoreCDUser: No root cell type\n"]
ELSE {
foundNotPower: BOOL ← FALSE;
FOR stack:
LIST
OF
CD.PushRec ← command.design.actual, stack.rest
WHILE stack.rest#
NIL
DO
rootObject ← stack.first.mightReplace.ob;
ENDLOOP;
CoreCDUser.DoForSelectedFlatWires[root: root, action: HighlightAWire, design: command.design];
FOR fwl:
LIST
OF CoreFlat.FlatWireRec ← flatWires, fwl.rest
UNTIL fwl=
NIL
DO
canonicalName: Rope.ROPE ← CoreFlat.WirePathRope[root, fwl.first];
IF
NOT (Rope.Equal["public.Vdd", canonicalName]
OR Rope.Equal["public.Gnd", canonicalName])
THEN {
IF foundNotPower
THEN {
TerminalIO.PutRope["CoreCDUser: Multiple wires not Vdd or Gnd selected:\n"];
FOR afwl:
LIST
OF CoreFlat.FlatWireRec ← flatWires, afwl.rest
UNTIL afwl=
NIL
DO
TerminalIO.PutRopes[" ", CoreFlat.WirePathRope[root, afwl.first], "\n"];
ENDLOOP;
TerminalIO.PutRope["CoreCDUser: Cannot highlight more than one wire at once"];
GOTO oops;
};
foundNotPower ← TRUE;
};
ENDLOOP;
FOR fwl:
LIST
OF CoreFlat.FlatWireRec ← flatWires, fwl.rest
UNTIL fwl=
NIL
DO
canonicalName: Rope.ROPE ← CoreFlat.WirePathRope[root, fwl.first];
IF
NOT (Rope.Equal["public.Vdd", canonicalName]
OR Rope.Equal["public.Gnd", canonicalName])
THEN {
CoreCDUser.HighlightFlatWire[root, fwl.first, command.design ! CoreCDUser.CoreCDUserError => {TerminalIO.PutRope[msg]; GOTO oops}];
};
ENDLOOP;
TerminalIO.PutRope["CoreCDUser: Done\n"];
EXITS oops => NULL;
};
};
PrintSelectedFlatWiresCoreCommand:
PROC [command: CDSequencer.Command] = {
PrintAWire: CoreCDUser.SelectedFlatWireActionProc = {
CoreOps.PrintWire[selectedFlatWire.wire, TerminalIO.TOS[]];
};
root: Core.CellType ← CoreCDUser.GetDesignRootCellType[command.design];
IF root=NIL THEN TerminalIO.PutRope["CoreCDUser: No root cell type\n"]
ELSE {
CoreCDUser.DoForSelectedFlatWires[root: root, action: PrintAWire, design: command.design];
TerminalIO.PutRope["\nCoreCDUser: Done\n"];
};
};
PrintSelectedFlatCellTypesCoreCommand:
PROC [command: CDSequencer.Command] = {
PrintACellType: CoreCDUser.SelectedFlatCellActionProc = {
CoreOps.PrintCellType[CoreFlat.ResolveFlatCellType[root, selectedFlatCell^].cellType, TerminalIO.TOS[]];
};
root: Core.CellType ← CoreCDUser.GetDesignRootCellType[command.design];
IF root=NIL THEN TerminalIO.PutRope["CoreCDUser: No root cell type\n"]
ELSE {
CoreCDUser.DoForSelectedFlatCells[root: root, action: PrintACellType, design: command.design];
TerminalIO.PutRope["\nCoreCDUser: Done\n"];
};
};
PrintSelectedFlatCellTypesRecastedCoreCommand:
PROC [command: CDSequencer.Command] ~ {
PrintACellTypeWithRecasts: CoreCDUser.SelectedFlatCellActionProc = {
cell: Core.CellType ← CoreFlat.ResolveFlatCellType[root, selectedFlatCell^].cellType;
FOR c: Core.CellType ← cell, CoreOps.Recast[c] UNTIL c.class.recast=NIL DO NULL ENDLOOP;
DO
CoreOps.PrintCellType[cell, TerminalIO.TOS[]];
IF cell.class=Sinix.iconClass THEN cell ← CoreOps.Recast[cell]; -- already printed...
IF cell.class.recast=NIL THEN EXIT;
cell ← CoreOps.Recast[cell];
TerminalIO.PutF["\n\nRecasts into:"];
ENDLOOP;
TerminalIO.PutF["\n\n--- End of recast chain ---\n"];
};
root: Core.CellType ← CoreCDUser.GetDesignRootCellType[command.design];
IF root=NIL THEN TerminalIO.PutRope["CoreCDUser: No root cell type\n"]
ELSE {
CoreCDUser.DoForSelectedFlatCells[root: root, action: PrintACellTypeWithRecasts, design: command.design];
TerminalIO.PutRope["\nCoreCDUser: Done\n"];
};
};
HighlightFlatCellTypeCommand:
PROC [command: CDSequencer.Command] = {
DoFlatCellType: CellTypeCommandActionProc =
{CoreCDUser.HighlightFlatCellType[root, flatCell]};
DoFlatCellTypeCommand[command, DoFlatCellType]};
SelectFlatCellTypeCommand:
PROC [command: CDSequencer.Command] = {
DoFlatCellType: CellTypeCommandActionProc =
{CoreCDUser.SelectFlatCellType[root, flatCell]};
DoFlatCellTypeCommand[command, DoFlatCellType]};
CellTypeCommandActionProc:
TYPE =
PROC[root: Core.CellType, flatCell: CoreFlat.FlatCellTypeRec];
DoFlatCellTypeCommand:
PROC [command: CDSequencer.Command, action: CellTypeCommandActionProc] = {
root: Core.CellType ← CoreCDUser.GetDesignRootCellType[command.design];
IF root=NIL THEN TerminalIO.PutRope["CoreCDUser: No root cell type\n"]
ELSE {
flatCell: CoreFlat.FlatCellTypeRec ← CoreFlat.ParseCellTypePath[root, TerminalIO.RequestRope["Flat Cell>"] ! CoreFlat.PathError => {TerminalIO.PutRopes[msg, "\n"]; GOTO Quit}];
action[root, flatCell ! CoreCDUser.CoreCDUserError => {TerminalIO.PutRopes[msg, "\n"]; GOTO Quit}];
TerminalIO.PutRopes["CoreCDUser: Done\n"];
EXITS Quit => NULL;
};
};
PrintSelectedFlatCellTypesCommand:
PROC [command: CDSequencer.Command] = {
PrintACellType: CoreCDUser.SelectedFlatCellActionProc = {
TerminalIO.PutF[
"Selected flat cell: %g\n",
IO.rope[CoreFlat.CellTypePathRope[root, selectedFlatCell^]]];
};
root: Core.CellType ← CoreCDUser.GetDesignRootCellType[command.design];
IF root=NIL THEN TerminalIO.PutRope["CoreCDUser: No root cell type\n"]
ELSE {
CoreCDUser.DoForSelectedFlatCells[root: root, action: PrintACellType, design: command.design];
TerminalIO.PutRope["CoreCDUser: Done\n"];
};
};
HighlightFlatWireCommand:
PROC [command: CDSequencer.Command] = {
DoFlatWire: WireCommandActionProc =
{CoreCDUser.HighlightFlatWire[root, flatWire]};
DoFlatWireCommand[command, DoFlatWire]};
SelectFlatWireCommand:
PROC [command: CDSequencer.Command] = {
DoFlatWire: WireCommandActionProc =
{CoreCDUser.SelectFlatWire[root, flatWire]};
DoFlatWireCommand[command, DoFlatWire]};
WireCommandActionProc:
TYPE =
PROC[root: Core.CellType, flatWire: CoreFlat.FlatWireRec];
DoFlatWireCommand:
PROC [command: CDSequencer.Command, action: WireCommandActionProc] = {
root: Core.CellType ← CoreCDUser.GetDesignRootCellType[command.design];
IF root=NIL THEN TerminalIO.PutRope["CoreCDUser: No root cell type\n"]
ELSE {
flatWire: CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[root, TerminalIO.RequestRope["Flat Wire>"] ! CoreFlat.PathError => {TerminalIO.PutRopes[msg, "\n"]; GOTO Quit}];
action[root, flatWire! CoreCDUser.CoreCDUserError => {TerminalIO.PutRopes[msg, "\n"]; GOTO Quit}];
TerminalIO.PutRopes["CoreCDUser: Done\n"];
EXITS Quit => NULL;
};
};
PrintSelectedFlatWiresCommand:
PROC [command: CDSequencer.Command] = {
PrintAWire: CoreCDUser.SelectedFlatWireActionProc = {
TerminalIO.PutF[
"Selected flat wire: %g, canonical wire: %g\n",
IO.rope[CoreFlat.WirePathRope[root, selectedFlatWire^]],
IO.rope[CoreFlat.WirePathRope[root, CoreFlat.CanonizeWire[root, selectedFlatWire^]]]];
};
root: Core.CellType ← CoreCDUser.GetDesignRootCellType[command.design];
IF root=NIL THEN TerminalIO.PutRope["CoreCDUser: No root cell type\n"]
ELSE {
CoreCDUser.DoForSelectedFlatWires[root: root, action: PrintAWire, design: command.design];
TerminalIO.PutRope["CoreCDUser: Done\n"];
};
};
RemoveHighlight:
PROC [command: CDSequencer.Command] = {
ExtractOps.HighlightDesign[command.design];
};
indirectStack: LIST OF IndirectStackRec;
IndirectStackRec: TYPE = RECORD[design: CD.Design, name: Rope.ROPE];
PopIndirect:
PROC [command: CDSequencer.Command] = {
IF indirectStack#
NIL
THEN {
design: CD.Design ← indirectStack.first.design;
name: Rope.ROPE ← indirectStack.first.name;
indirectStack ← indirectStack.rest;
CDSequencer.ExecuteCommand[comm:
NEW[CDSequencer.CommandRec ← [
key: $PushNamed,
design: design,
data: name,
ref: GetOpenViewer[design] ]]]} };
PushIndirect:
PROC [command: CDSequencer.Command] = {
Err: PROC[msg: Rope.ROPE] = {TerminalIO.PutF["CoreCDUser: %g. No action\n", IO.rope[msg]]};
selName: Rope.ROPE ← NIL;
pushedName: Rope.ROPE ← NIL;
design: CD.Design ← command.design;
multiple: BOOL ← FALSE;
instance: CD.Instance ← NIL;
maskName: Rope.ROPE ← NIL;
maskobj: CD.Object ← NIL;
localObjSch: Rope.ROPE;
localInstSch: Rope.ROPE;
newComm: CDSequencer.Command ← NEW[CDSequencer.CommandRec ← [design: design]];
[instance, multiple] ← CDOps.SelectedInstance[design];
localObjSch ← NARROW[CDProperties.GetProp[instance.ob, $IconFor]];
localInstSch ← NARROW[CDProperties.GetProp[instance, $IconFor]];
selName ← CDDirectory.Name[instance.ob, design];
maskName ← selName.Substr[0, selName.Index[0, "."]].Cat[".mask"];
maskobj ← CDDirectory.Fetch[design, maskName];
pushedName ←
IF CDCells.IsPushedIn[design]
THEN CDDirectory.Name[design.actual.first.mightReplace.ob, design]
ELSE selName;
SELECT
TRUE
FROM
multiple => {Err["Multiple selections"]; RETURN};
instance=NIL => {Err["No selection"]; RETURN};
CDImports.IsImport[instance.ob] => {
specific: CDImports.ImportSpecific ← NARROW[instance.ob.specific];
iDesign: CD.Design ← specific.boundDesign;
IF iDesign=
NIL
THEN {Err["Import not bound yet"]; RETURN}
ELSE {
newComm.key ← $PushNamed;
newComm.design ← iDesign;
newComm.data ← GetIconFor[iDesign, specific.objectName];
newComm.ref ← GetOpenViewer[iDesign]} };
localInstSch#NIL => {newComm.key ← $PushNamed; newComm.data ← localInstSch};
localObjSch#NIL => {newComm.key ← $PushNamed; newComm.data ← localObjSch};
maskobj#NIL => {newComm.key ← $PushNamed; newComm.data ← maskName};
ENDCASE => {newComm.key ← $PushS};
IF pushedName.Length#
0
THEN
indirectStack ← CONS[[design, pushedName], indirectStack];
CDSequencer.ExecuteCommand[comm: newComm]};
GetOpenViewer:
PROC [design:
CD.Design]
RETURNS[viewer: ViewerClasses.Viewer] = {
viewer ← ExtractOps.FindViewer[design, CoreCDUser.GetDesignLabel[design]];
IF viewer.iconic THEN ViewerOps.OpenIcon[viewer];
WHILE CDCells.IsPushedIn[design]
DO
[] ← CDCellsInteractions.PopFromCell[design, interactive] ENDLOOP};
PushIntoImportViewer:
PROC [command: CDSequencer.Command] = {
multiple: BOOL ← FALSE;
instance: CD.Instance ← NIL;
err: Rope.ROPE ← NIL;
importedDesign: CD.Design ← NIL;
specific: CDImports.ImportSpecific ← NIL;
[instance, multiple] ← CDOps.SelectedInstance[command.design];
SELECT
TRUE
FROM
multiple => err ← "Multiple selections";
instance=NIL => err ← "No selection";
NOT CDImports.IsImport[instance.ob] => err ← "Not an import";
ENDCASE => {
-- normal case (well, almost)
specific ← NARROW[instance.ob.specific];
importedDesign ← specific.boundDesign;
IF importedDesign=NIL THEN err ← "Import not bound yet";
};
IF err#NIL THEN {TerminalIO.PutF["CoreCDUser: %g. No action\n", IO.rope[err]]; RETURN};
CDSequencer.ExecuteCommand[comm:
NEW [CDSequencer.CommandRec ← [
key: $PushNamed,
design: importedDesign,
ref: ExtractOps.FindViewer[importedDesign, CoreCDUser.GetDesignLabel[importedDesign]],
data: GetIconFor[importedDesign, specific.objectName]]]]};
GetIconFor:
PROC [design:
CD.Design, name: Rope.
ROPE]
RETURNS [target: Rope.
ROPE] ~ {
Return schematic name if any, or return initial name
obj: CD.Object = CDDirectory.Fetch[design, name];
IF obj=NIL THEN RETURN [NIL];
target ← NARROW[CDProperties.GetProp[obj, $IconFor]];
IF target=NIL THEN target ← name};
PrintTransitiveObjectClosure: PROC [command: CDSequencer.Command] = {
PrintName: PROC [object: CD.Object, design: CD.Design] = {
name: Rope.ROPE ← CDDirectory.Name[object, design];
SELECT TRUE FROM
Rope.Length[name]>0 => TerminalIO.PutRope[name];
Rope.Length[object.class.description]>0 => TerminalIO.PutRopes["<", object.class.description, ">"];
ENDCASE => TerminalIO.PutRope["~unknown~"];
};
PrintObject: RefTab.EachPairAction = {
PrintObjectEntry: RefTab.EachPairAction = {
TerminalIO.PutRope[" "];
PrintName[NARROW[key], NARROW[val]];
};
PrintName[NARROW[key], NARROW[RefTab.Fetch[NARROW[val], key].val]];
TerminalIO.PutRope[": "];
[] ← RefTab.Pairs[NARROW[val], PrintObjectEntry];
TerminalIO.PutRope["\n"];
};
design: CD.Design ← command.design;
topInstances: CD.InstanceList ← GetTopInstances[design];
TerminalIO.PutRope["\n"];
[] ← RefTab.Pairs[ObjectTransitiveClosure[design, topInstances], PrintObject];
};
Start Code
CDSequencer.ImplementCommand[key: $ExtractSelectedCellsCommand, proc: ExtractSelectedCellsCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $HighlightSelectedFlatWireCommand, proc: HighlightSelectedFlatWireCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $PrintSelectedFlatWiresCoreCommand, proc: PrintSelectedFlatWiresCoreCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $PrintSelectedFlatCellTypesCoreCommand, proc: PrintSelectedFlatCellTypesCoreCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $PrintSelectedFlatCellTypesRecastedCoreCommand, proc: PrintSelectedFlatCellTypesRecastedCoreCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $HighlightFlatCellTypeCommand, proc: HighlightFlatCellTypeCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $SelectFlatCellTypeCommand, proc: SelectFlatCellTypeCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $PrintSelectedFlatCellTypesCommand, proc: PrintSelectedFlatCellTypesCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $HighlightFlatWireCommand, proc: HighlightFlatWireCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $SelectFlatWireCommand, proc: SelectFlatWireCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $PrintSelectedFlatWiresCommand, proc: PrintSelectedFlatWiresCommand, queue: doQueue];
CDSequencer.ImplementCommand[key: $RemoveHighlight, proc: RemoveHighlight, queue: doQueue];
CDSequencer.ImplementCommand[key: $PushIntoImportViewer, proc: PushIntoImportViewer, queue: doQueue];
CDSequencer.ImplementCommand[key: $PrintTransitiveObjectClosure, proc: PrintTransitiveObjectClosure, queue: doQueue];
CDSequencer.ImplementCommand[$PushSIconic, PushIndirect,, doQueue];
CDSequencer.ImplementCommand[$PopIndirect, PopIndirect,, doQueue];