CoreXformImpl.mesa
Created by Don Curry, February 1, 1986 2:43:22 pm PST
Edited by Don Curry, March 25, 1986 4:24:02 pm PST
DIRECTORY Core, CoreOps, CoreProperties, CoreXform, IO;
CoreXformImpl: CEDAR PROGRAM
IMPORTS CoreOps, CoreProperties, IO
EXPORTS CoreXform =
BEGIN OPEN CoreXform;
Signal: SIGNAL = CODE;
xformProp: ATOM ← CoreProperties.RegisterProperty[
$CoreXformProp, CoreProperties.Props[
[CoreProperties.propPrint,  NEW[CoreProperties.PropPrintProc ← Print ]] ] ];
Print: CoreProperties.PropPrintProc = {
xfm: Xform ← NARROW[val];
CoreOps.PrintIndent[indent, to];
to.PutRope["Xform: "];
FOR i: INT IN [0..xfm.size) DO
to.PutF[" %g %g %g %g %g",
IO.int[xfm[i].size], IO.int[xfm[i].toLev], IO.int[xfm[i].fmLev],
IO.int[xfm[i].fmSubSize], IO.int[xfm[i].toSubSize]]
ENDLOOP};
LinkXform: PROC [xform: Xform] = {
FOR index: INT IN [0..xform.size) DO
temp: INT ← xform[xform[index].toLev].fmLev;
IF temp#index THEN
IF temp#-1
THEN Signal[]
ELSE xform[xform[index].toLev].fmLev ← index ENDLOOP;
xform[xform.size-1].toSubSize ← 1;
FOR seq: INT DECREASING IN [0..xform.size-1) DO
size: INT ← xform[xform[seq+1].fmLev].size;
xform[seq].toSubSize ← size*xform[seq+1].toSubSize;
ENDLOOP;
xform[xform.size-1].fmSubSize ← 1;
FOR seq: INT DECREASING IN [0..xform.size-1) DO
xform[seq].fmSubSize ← xform[seq+1].size*xform[seq+1].fmSubSize;
ENDLOOP};
GenXform: PUBLIC PROC[xforms: Xforms]
RETURNS[xform: Xform ← NIL] = {
size:   INT ← 0;
index:   INT ← 0;
IF xforms=NIL THEN RETURN[NIL];
FOR list: Xforms ← xforms, list.rest WHILE list#NIL
DO size ← size+1 ENDLOOP;
xform ← NEW[XformSeq[size]];
FOR list: Xforms ← xforms, list.rest WHILE list#NIL DO
xform[index] ← list.first; index ← index+1 ENDLOOP;
LinkXform[xform]};
GenXforms: PUBLIC PROC[xform: Xform]
RETURNS[xforms: Xforms ← NIL] = {
IF xform#NIL THEN FOR index: INT DECREASING IN [0..xform.size) DO
xforms ← CONS[xform[index], xforms] ENDLOOP};
SetXforms: PUBLIC PROC[on: REF, xforms: Xforms] =
{SetXform[on, GenXform[xforms]]};
SetXform: PUBLIC PROC[on: REF, xform: Xform] = {
WITH on SELECT FROM
wire: Core.Wire   => CoreProperties.PutWireProp   [wire, xformProp, xform];
cell: Core.CellType => CoreProperties.PutCellTypeProp [cell, xformProp, xform];
ENDCASE     => Signal[]};
GetXforms: PUBLIC PROC[from: REF] RETURNS[xforms: Xforms ← NIL] =
{xforms ← GenXforms[GetXform[from]]};
GetXform: PUBLIC PROC[from: REF] RETURNS[ xform: Xform ← NIL] =
{IF from#NIL THEN WITH from SELECT FROM
xf: Xform =>
xform ← xf;
wire: Core.Wire =>
xform ← NARROW[CoreProperties.GetWireProp[wire, xformProp].value];
cell: Core.CellType =>
xform ← NARROW[CoreProperties.GetCellTypeProp[cell, xformProp].value];
ENDCASE => Signal[]};
XformSize: PUBLIC PROC[from: REF] RETURNS[ domain: INT𡤀] =
{xform: Xform ← GetXform[from];
IF xform=NIL OR xform.size=0 THEN RETURN[0];
RETURN[xform[0].size*xform[0].fmSubSize]};
SourceSizeTempIdx: PROC[xform: Xform, dir: Dir, seq: INT] RETURNS[index: INT] =
{index ← IF dir = ll OR dir = lr THEN seq      ELSE xform[seq].fmLev};
SourceSubSize: PROC[xform: Xform, dir: Dir, seq: INT] RETURNS[index: INT] =
{index ← IF dir = ll OR dir = lr THEN xform[seq].fmSubSizeELSE xform[seq].toSubSize};
DestSizeTempIdx: PROC[xform: Xform, dir: Dir, seq: INT] RETURNS[index: INT] =
{index ← IF dir = lr OR dir = rr THEN xform[seq].fmLev  ELSE seq};
DestSubSize: PROC[xform: Xform, dir: Dir, seq: INT] RETURNS[index: INT] =
{index ← IF dir = lr OR dir = rr THEN xform[seq].toSubSizeELSE xform[seq].fmSubSize};
XformAddr: PUBLIC PROC[xform: Xform, dir: Dir, addr: Addr] RETURNS[i: INT, a: Addr] = {
index: INT ← 0;
size: INT ← 1;
FOR seq: INT IN [0..xform.size) DO
index: INT   ← SourceSizeTempIdx[xform, dir, seq];
xform[index].temp ← addr.first;
addr ← addr.rest;
REPEAT FINISHED => IF addr#NIL THEN ERROR ENDLOOP;
[i, a] ← ReadOut[xform, dir]};
XformIndex: PUBLIC PROC[xform: Xform, dir: Dir, index: INT] RETURNS[i: INT, a: Addr] = {
IF xform=NIL THEN Signal[];
FOR seq: INT IN [0..xform.size) DO
idx:  INT ← SourceSizeTempIdx[xform, dir, seq];
subSize: INT ← SourceSubSize[xform, dir, seq];
xform[idx].temp ← index / subSize;
index    ← index MOD subSize; ENDLOOP;
[i, a] ← ReadOut[xform, dir]};
ReadOut: PROC[xform: Xform, dir: Dir] RETURNS[i: INT𡤀, a: Addr←NIL] = {
FOR seq: INT DECREASING IN [0..xform.size) DO
index:  INT ← DestSizeTempIdx[xform, dir, seq];
subSize: INT ← DestSubSize[xform, dir, seq];
i ← i + xform[index].temp*subSize;
a ← CONS[xform[index].temp, a] ENDLOOP};
FlatTreeIndex: PUBLIC PROC[size, index: INT]  RETURNS[coord: Coord] = {
val:  INT ← 0;
level:  INT ← 0;
levels: INT ← 0;
FOR val ← size,  val/2 WHILE val#0    DO levels ← levels +1 ENDLOOP;
FOR val ← index, val/2 WHILE (val MOD 2) = 1 DO level ← level +1 ENDLOOP;
coord.index ← val/2;
coord.degrees ← levels;
coord.degree ← levels - level - 1};
END.