CoreCDUserCmdsImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Barth, October 14, 1987 4:34:52 pm PDT
Jean-Marc Frailong January 4, 1988 4:48:02 pm PST
DIRECTORY CD, CDCellsInteractions, CDCells, CDDirectory, CDImports, CDOps, CDProperties, CDSequencer, Core, CoreCDUser, CoreClasses, CoreFlat, CoreGeometry, CoreOps, ExtractOps, IO, Rope, Sinix, TerminalIO, ViewerClasses, ViewerOps;
CoreCDUserCmdsImpl: CEDAR PROGRAM
IMPORTS CDCellsInteractions, CDCells, CDDirectory, CDImports, CDOps, CDProperties, CDSequencer, CoreCDUser, CoreFlat, CoreGeometry, CoreOps, ExtractOps, IO, Rope, Sinix, TerminalIO, ViewerOps
SHARES CDImports
= BEGIN
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: BOOLFALSE;
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: BOOLFALSE;
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: BOOLFALSE;
instance: CD.Instance ← NIL;
err: Rope.ROPENIL;
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];
END.