CoreInstCellImpl.mesa
Copyright c 1986 by Xerox Corporation. All rights reserved.
Created by Don Curry, February 1, 1986 2:43:22 pm PST
Edited by Don Curry, October 27, 1986 1:49:35 pm PST
DIRECTORY CD, CDOrient, Core, CoreBlock, CoreFrame, CoreGeometry, CoreInstCell, CoreOps, CoreClasses, CoreName, IO, PW, PWC;
CoreInstCellImpl: CEDAR PROGRAM
IMPORTS CoreBlock, CoreFrame, CoreClasses, CoreGeometry, CoreOps, CoreName, IO, PW, PWC
EXPORTS CoreInstCell =
BEGIN
specificGenericCellClass: PUBLIC Core.CellClass ←
CoreOps.SetClassPrintProc[
class: NEW[ Core.CellClassRec ← [name: "SpecificGeneric", recast: Recast]],
proc: ClassPrintProc];
ClassPrintProc: CoreOps.PrintClassProc = {
cell: Core.CellType ← NARROW [data];
out.PutF["\nSpecificGeneric Instance of: %g", IO.rope[CoreName.CellNm[cell].n]]};
Recast: PUBLIC Core.RecastProc = {
name: Core.ROPE ← CoreName.CellNm[me].n;
log.PutF["\nRecasting Specific Generic: %g", IO.rope[name]];
new ← CoreBlock.AbutCellList[name, left, LIST[me]]};
Recast: PUBLIC Core.RecastProc = {
name:  Core.ROPE ← CoreName.CellNm[me].n;
internal: Core.Wire ← CoreOps.CopyWire[me.public];
cell:  Core.CellType ← me;
public: Core.Wire ← CoreOps.CreateWires[cell.public.size];
actual:  Core.Wire ← CoreOps.CreateWires[cell.public.size];
log.PutF["\nRecasting Specific Generic: %g", IO.rope[name]];
IF cell.public.size#internal.size THEN Signal[];
FOR index: INT IN [0..internal.size) DO actual[index] ← internal[index] ENDLOOP;
FOR index: INT IN [0..internal.size) DO public[index] ← internal[index] ENDLOOP;
new ← CoreClasses.CreateRecordCell[
public:  public,
internal:  internal,
instances:  LIST [CoreClasses.CreateInstance[actual: actual, type: cell]]];
CoreBlock.PutCellSide [new, all];
CoreBlock.MergeSides [new]};
SpecificGeneric: PUBLIC PROC[generic: Core.CellType, proc: CoreInstCell.RenameProc]
RETURNS [specific: Core.CellType] = {
ctx:  CoreName.Context ← CoreName.NewContext[];
internal: Core.Wire ← CoreOps.CreateWires[generic.public.size];
FOR index: INT IN [0..internal.size) DO
aName: Core.ROPE ← CoreName.WireNm[generic.public[index] ].n;
aName    ← proc[aName];
internal[index] ← IF aName#NIL
THEN CoreName.CtxWire [ctx, aName]
ELSE CoreOps.CreateWires[0];
ELSE CoreOps.CreateWire[name: CoreName.ID["DeadEnd"]];
[ ] ← CoreBlock.AddWireSide
[internal[index], CoreBlock.GetWireSide[generic.public[index]]];
ENDLOOP;
IF generic.class # CoreClasses.recordCellClass AND
generic.class # PWC.rotatedCellClass THEN Signal[];
specific ← NEW[Core.CellTypeRec ← [
class:   specificGenericCellClass,
public:  internal,
data:   generic, 
properties: NIL ]];
ctx ← CoreName.KillContext[ctx];
CoreGeometry.PutIR
[PWC.extractMode.decoration, specific, PWC.InterestRect[generic]];
CoreBlock.PutCellSide [specific, all];
PWC.SetLayout[specific, $SpecificGenericLayout]};
SGLayout: PWC.LayoutProc = {
genericObj: CD.Object ← PWC.Layout[NARROW[cellType.data]];
CoreGeometry.PutIR[PWC.extractMode.decoration, cellType, CD.InterestRect[genericObj]];
obj ← PW.ChangeOrientation[genericObj, CDOrient.original]};
SGDecorate: PWC.DecorateProc = {
genericCell: Core.CellType ← NARROW[cellType.data];
name:   Core.ROPE  ← CoreName.CellNm[cellType].n;
Visit: CoreOps.EachWirePairProc ~ {
new: Core.ROPE ← CoreName.WireNm[publicWire].n;
IF publicWire.size#0 THEN RETURN[TRUE, FALSE];
[ ] ← CoreBlock.AddWireSide[publicWire, CoreBlock.GetWireSide[actualWire]];
CoreGeometry.AddIndirectLazyPins[PWC.extractMode.decoration, publicWire, actualWire]};
log.PutF["\nDecorating Specific Generic: %g | %g",
IO.rope[name], IO.rope[CoreName.CellNm[genericCell].n]];
[ ] ← CoreOps.VisitBinding
[actual: genericCell.public, public: cellType.public, eachWirePair: Visit]};
SGLayout: PWC.LayoutProc = {
recast: Core.CellType;
name: Core.ROPE ← CoreName.CellNm[cellType].n;
log.PutF["\nRedefine Specific Generic: %g", IO.rope[name]];
recast ← CoreOps.Recast[cellType];
obj ← PW.ChangeOrientation[PWC.Layout[recast], CDOrient.original];
IF cellType.public.size#temp.public.size THEN Signal[];
FOR i: INT IN [0..cellType.public.size) DO
wireNm: Core.ROPE ← CoreName.WireNm[cellType.public[i]].n;
wire:  Core.Wire ← CoreOps.FindWire[temp.public, wireNm];
IF wire=NIL THEN Signal[];
cellType.public[i] ← wire;
ENDLOOP;
CoreOps.FlushNameCaches[cellType.public];
cellType.class ← temp.class;
cellType.data  ← temp.data;
CoreBlock.PutCellSide[cellType, all]};
Signal: SIGNAL = CODE;
log: IO.STREAM ← CoreFrame.GetLog[];
[ ] ← PWC.RegisterLayoutAtom[$SpecificGenericLayout, SGLayout, SGDecorate]
END.