--routeUtilities.mesa

DIRECTORY  ZoneAllocDefs, RouteDefs, IODefs;

RouteUtilities:PROGRAM IMPORTS ZoneAllocDefs, IODefs EXPORTS RouteDefs=BEGIN
OPEN RouteDefs;


Error:SIGNAL=CODE;

channels:PUBLIC RectangleListPtr←NIL;
problem:PUBLIC Problem←[cells:NIL,chipSize:[0,0],wirelist:NIL];
example:PUBLIC INTEGER←1;
chipmonk,plot,print:PUBLIC BOOLEAN;
inters:PUBLIC RectangleListPtr←NIL;
topology:PUBLIC TopologyListPtr←NIL;
paths:PUBLIC PathwayListPtr←NIL;
layout:PUBLIC SiliconListPtr←NIL;
rectangles:PUBLIC RectangleListPtr←NIL;

EnumerateChannels:PUBLIC PROCEDURE[c:PROCEDURE[RectanglePtr]]=
{FOR l:RectangleListPtr←channels,l.t UNTIL l=NIL DO c[l.h]; ENDLOOP};

EnumerateInters:PUBLIC PROCEDURE[c:PROCEDURE[RectanglePtr]]=
{FOR l:RectangleListPtr←inters,l.t UNTIL l=NIL DO c[l.h]; ENDLOOP};

EnumerateRectangles:PUBLIC PROCEDURE[c:PROCEDURE[RectanglePtr]]=
{FOR l:RectangleListPtr←rectangles,l.t UNTIL l=NIL DO c[l.h]; ENDLOOP};

EnumerateCells:PUBLIC PROCEDURE[call:PROCEDURE[CellPtr]]=
{FOR l:CellListPtr←problem.cells,l.t UNTIL l=NIL DO call[l.h]; ENDLOOP};

EnumerateAllSignals:PUBLIC PROCEDURE[call:PROCEDURE[CellPtr,SignalPtr]]=BEGIN
FOR l:CellListPtr←problem.cells,l.t UNTIL l=NIL DO
  FOR l2:SignalListPtr←l.h.signals,l2.t UNTIL l2=NIL
   DO call[l.h,l2.h]; ENDLOOP; ENDLOOP;
END;

EnumerateSignals:PUBLIC PROCEDURE[c:CellPtr,x:PROCEDURE[CellPtr,SignalPtr]]=
  {FOR l:SignalListPtr←c.signals,l.t UNTIL l=NIL DO x[c,l.h]; ENDLOOP};

EnumerateConns:PUBLIC PROCEDURE[r:RectanglePtr,
      c:PROCEDURE[RectanglePtr,ConnPtr]]=
{FOR l:ConnListPtr←r.conns, l.t UNTIL l=NIL DO c[r,l.h]; ENDLOOP};

EnumerateEvents:PUBLIC PROCEDURE[r:RectanglePtr,
    c:PROCEDURE[RectanglePtr,EventPtr]]=
{FOR l:EventListPtr←r.events, l.t UNTIL l=NIL DO c[r,l.h]; ENDLOOP};

EnumerateRuns:PUBLIC PROCEDURE[r:RectanglePtr,
    c:PROCEDURE[RectanglePtr,RunPtr]]=
{FOR l:RunListPtr←r.runs,l.t UNTIL l=NIL DO c[r,l.h]; ENDLOOP};

EnumerateAllRuns:PUBLIC PROCEDURE[c:PROCEDURE[RectanglePtr,RunPtr]]=BEGIN
  temp:PROCEDURE[r:RectanglePtr]={EnumerateRuns[r,c]};
  EnumerateChannels[temp];
  END;

EnumerateAllConns:PUBLIC PROCEDURE[call:PROCEDURE[RectanglePtr,ConnPtr]]=BEGIN
Cm1:PROCEDURE[rect:RectanglePtr]={EnumerateConns[rect,call]};
EnumerateChannels[Cm1];
END;

EnumerateSilicon:PUBLIC PROCEDURE[call:PROCEDURE[SiliconPtr]]=BEGIN
FOR l:SiliconListPtr←layout,l.t UNTIL l=NIL
  DO IF l.h.pos#outOfSight THEN call[l.h]; ENDLOOP;
END;

Return:PUBLIC PROCEDURE={ShowChar['
]};

ShowString:PUBLIC PROCEDURE[s:STRING]=BEGIN
IF ~chipmonk THEN IODefs.WriteString[s];
END;

ShowChar:PUBLIC PROCEDURE[c:CHARACTER]=BEGIN
IF ~chipmonk THEN IODefs.WriteChar[c];
END;


ShowLabel:PUBLIC PROCEDURE[s:STRING]=BEGIN
Return[]; Return[]; ShowString[s]; Return[];
END;

ShowCircuit:PUBLIC PROCEDURE[c:Circuit] RETURNS[CHARACTER]=BEGIN
s:INTEGER=c-1;
RETURN[SELECT c FROM
  0=>'0, IN [1..26)=>'A + s, ENDCASE=>'2];
END;

ShowDecimal:PUBLIC PROCEDURE[i:INTEGER,s:STRING←NIL]=BEGIN
IF chipmonk THEN RETURN;
IF s#NIL THEN IODefs.WriteString[s];
IODefs.WriteDecimal[i];
END;

SameString:PUBLIC PROCEDURE[a,b:STRING] RETURNS[BOOLEAN]=BEGIN
IF a.length#b.length THEN RETURN[FALSE];
FOR i:CARDINAL IN [0..a.length)
  DO IF a[i]#b[i] THEN RETURN[FALSE]; ENDLOOP;
RETURN[TRUE];
END;

Clear:PUBLIC PROCEDURE[s:STRING]=BEGIN
FOR i:CARDINAL IN [0..s.length←s.maxlength) DO s[i]←' ; ENDLOOP;
END;

ShowPoint:PUBLIC PROCEDURE[s:STRING,x,y:INTEGER]=BEGIN OPEN IODefs;
IF chipmonk THEN RETURN;
WriteString[s];
WriteChar['[];
WriteDecimal[x];
WriteString[" , "];
WriteDecimal[y];
WriteChar[']];
END;

ShowWire:PUBLIC PROCEDURE[s:SiliconPtr]=BEGIN
ShowString[SELECT s.level FROM
    red=>" red ", blue=>" blue", ENDCASE=>" both"];
ShowPoint[" loc ",s.pos.x,s.pos.y];
ShowPoint["  ",s.pos2.x,s.pos2.y];
END;

WritePoint:PUBLIC PROCEDURE[x,y:INTEGER]=BEGIN OPEN IODefs;
IF chipmonk THEN RETURN;
WriteChar['[];
WriteDecimal[x];
WriteString[" , "];
WriteDecimal[y];
WriteChar[']];
END;

MakeType:PUBLIC PROCEDURE[n,e,s,w:BOOLEAN] RETURNS[InterType]=BEGIN
RETURN[(IF n THEN 1 ELSE 0)+(IF e THEN 4 ELSE 0)
 +(IF s THEN 2 ELSE 0)+(IF w THEN 8 ELSE 0)];
END;

-- ALLOCATIONS

ListEntry:TYPE=RECORD[a:LONG POINTER,b:LONG POINTER TO ListEntry];

zone:UNCOUNTED ZONE;

ReturnStorage:PUBLIC PROCEDURE=
  {zone←ZoneAllocDefs.DestroyAnXMZone[zone]};

InitStorage:PUBLIC PROCEDURE=
  {zone←ZoneAllocDefs.GetAnXMZone[]};

cntList:INTEGER←4000;
AllocateList:PUBLIC PROCEDURE RETURNS[LONG POINTER]=BEGIN
  x:LONG POINTER TO ListEntry←zone.NEW[ListEntry];
  IF (cntList←cntList-1)<0 THEN Error;
  x↑←[NIL,NIL];
  RETURN[x];
  END;
FreeList:PUBLIC PROCEDURE[y:LONG POINTER]=
 {x:LONG POINTER TO ListEntry←y;
 zone.FREE[@x]; cntEvent←cntEvent+1};

cntEvent:INTEGER←500;
AllocateEvent:PUBLIC PROCEDURE RETURNS[x:EventPtr]=
 {x←zone.NEW[Event←[]]; IF (cntEvent←cntEvent-1)<0 THEN Error};
FreeEvent:PUBLIC PROCEDURE[x:EventPtr]=
 {zone.FREE[@x]; cntEvent←cntEvent+1};

cntNet:INTEGER←600;
AllocateNet:PUBLIC PROCEDURE RETURNS[x:NetPtr]=
 {x←zone.NEW[Net←[]]; IF (cntNet←cntNet-1)<0 THEN Error};
FreeNet:PUBLIC PROCEDURE[x:NetPtr]=
 {zone.FREE[@x]; cntNet←cntNet+1};

cntPathway:INTEGER←300;
AllocatePathway:PUBLIC PROCEDURE RETURNS[x:PathwayPtr]=
 {x←zone.NEW[Pathway←[]]; IF (cntPathway←cntPathway-1)<0 THEN Error};
FreePathway:PUBLIC PROCEDURE[x:PathwayPtr]=
 {zone.FREE[@x]; cntPathway←cntPathway+1};

cntJunction:INTEGER←300;
AllocateJunction:PUBLIC PROCEDURE RETURNS[x:JunctionPtr]=
 {x←zone.NEW[Junction←[]]; IF (cntJunction←cntJunction-1)<0 THEN Error};
FreeJunction:PUBLIC PROCEDURE[x:JunctionPtr]=
 {zone.FREE[@x]; cntJunction←cntJunction+1};

cntCell:INTEGER←125;
AllocateCell:PUBLIC PROCEDURE RETURNS[x:CellPtr]=
 {x←zone.NEW[Cell←[]]; IF (cntCell←cntCell-1)<0 THEN Error};
FreeCell:PUBLIC PROCEDURE[x:CellPtr]=
 {zone.FREE[@x]; cntCell←cntCell+1};

cntSignal:INTEGER←1000;
AllocateSignal:PUBLIC PROCEDURE RETURNS[x:SignalPtr]=
 {x←zone.NEW[Signal←[]]; IF (cntSignal←cntSignal-1)<0 THEN Error};
FreeSignal:PUBLIC PROCEDURE[x:SignalPtr]=
 {zone.FREE[@x]; cntSignal←cntSignal+1};

cntSilicon:INTEGER←4000;
AllocateSilicon:PUBLIC PROCEDURE RETURNS[x:SiliconPtr]=
 {x←zone.NEW[Silicon←[]]; IF (cntSilicon←cntSilicon-1)<0 THEN Error};
FreeSilicon:PUBLIC PROCEDURE[x:SiliconPtr]=
 {zone.FREE[@x]; cntSilicon←cntSilicon+1};

cntPath:INTEGER←1000;
AllocatePath:PUBLIC PROCEDURE RETURNS[x:PathPtr]=
 {x←zone.NEW[Path←[]]; IF (cntPath←cntPath-1)<0 THEN Error};
FreePath:PUBLIC PROCEDURE[x:PathPtr]=
 {zone.FREE[@x]; cntPath←cntPath+1};

cntRectangle:INTEGER←400;
AllocateRectangle:PUBLIC PROCEDURE RETURNS[x:RectanglePtr]=
 {x←zone.NEW[Rectangle←[]]; IF (cntRectangle←cntRectangle-1)<0 THEN Error};
FreeRectangle:PUBLIC PROCEDURE[x:RectanglePtr]=
 {zone.FREE[@x]; cntRectangle←cntRectangle+1};

cntPlace:INTEGER←400;
AllocatePlace:PUBLIC PROCEDURE RETURNS[x:PlacePtr]=
 {x←zone.NEW[Place←[]]; IF (cntPlace←cntPlace-1)<0 THEN Error};
FreePlace:PUBLIC PROCEDURE[x:PlacePtr]=
 {zone.FREE[@x]; cntPlace←cntPlace+1};

cntGrid:INTEGER←300;
AllocateGrid:PUBLIC PROCEDURE RETURNS[x:GridPtr]=
 {x←zone.NEW[Grid←[]]; IF (cntGrid←cntGrid-1)<0 THEN Error};
FreeGrid:PUBLIC PROCEDURE[x:GridPtr]=
 {zone.FREE[@x]; cntGrid←cntGrid+1};

cntTopology:INTEGER←500;
AllocateTopology:PUBLIC PROCEDURE RETURNS[x:TopologyPtr]=
 {x←zone.NEW[Topology←[]]; IF (cntTopology←cntTopology-1)<0 THEN Error};
FreeTopology:PUBLIC PROCEDURE[x:TopologyPtr]=
 {zone.FREE[@x]; cntTopology←cntTopology+1};

cntConn:INTEGER←500;
AllocateConn:PUBLIC PROCEDURE RETURNS[x:ConnPtr]=
 {x←zone.NEW[Conn←[]]; IF (cntConn←cntConn-1)<0 THEN Error};
FreeConn:PUBLIC PROCEDURE[x:ConnPtr]=
 {zone.FREE[@x]; cntConn←cntConn+1};

cntRun:INTEGER←500;
AllocateRun:PUBLIC PROCEDURE RETURNS[x:RunPtr]=
 {x←zone.NEW[Run←[]]; IF (cntRun←cntRun-1)<0 THEN Error};
FreeRun:PUBLIC PROCEDURE[x:RunPtr]=
 {zone.FREE[@x]; cntRun←cntRun+1};

cntIWire:INTEGER←1000;
AllocateIWire:PUBLIC PROCEDURE RETURNS[x:IWirePtr]=
 {x←zone.NEW[IWire←[]]; IF (cntIWire←cntIWire-1)<0 THEN Error};
FreeIWire:PUBLIC PROCEDURE[x:IWirePtr]=
 {zone.FREE[@x]; cntIWire←cntIWire+1};

END.

AllocateList:PUBLIC PROCEDURE RETURNS[LONG POINTER]=BEGIN
ans:LONG POINTER TO ListEntry←freeList;
freeList←ans.b;
ans↑←[NIL,NIL];
RETURN[ans];
END;

FreeList:PUBLIC PROCEDURE[x:POINTER]=BEGIN
ans:POINTER TO ListEntry=x;
ans↑←[NIL,freeList];
freeList←ans;
END;