File IntPhase1.mesa
March 27, 1981 2:17 PM
Last Edited by: McCreight, February 8, 1985 10:58:02 am PST
DIRECTORY
Basics, IntDefs, IO, IntUtilityDefs, List, ParserErrorDefs, IntStorageDefs, IntTransDefs, OutputDefs, ParserTypeDefs, Rope;
IntPhase1: CEDAR PROGRAM IMPORTS IO, List, OutputDefs, ParserTypeDefs, IntUtilityDefs, ParserErrorDefs, IntTransDefs, Rope
EXPORTS IntDefs, IntStorageDefs =
BEGIN OPEN IntUtilityDefs, IntStorageDefs;
should modify to catch IntTransDefs errors
Layer: TYPE = RECORD [num: CARDINAL, body: Rope.ROPE];
curLayer, rootLayer: Layer;
curSymbol: STEntry; -- symbol currently being defined
rootSymbol: PUBLIC STEntry;
endSeen: BOOLEAN;
InitInterpreter: PUBLIC PROCEDURE RETURNS [BOOLEAN] =
BEGIN
curLayer ← [num: LAST[CARDINAL], body: NIL];
endSeen ← FALSE;
rootSymbol ← NEW[STEntryRec ← [
bb: BBoxRecord[left:0,right:0,bottom:0,top:0],
bbValid: FALSE,
guts: NIL,
symNumber: LAST[LONG CARDINAL],
deleted: FALSE, expanded: FALSE, bound: FALSE, defined: FALSE,
calledBy: NIL]];
curSymbol ← rootSymbol;
RETURN[IntTransDefs.InitTransformation[] AND
InitUtilities[]];
END;
FinishInterpreter: PUBLIC PROCEDURE RETURNS [BOOLEAN] =
BEGIN
rootSymbol ← curSymbol ← NIL;
RETURN[IntTransDefs.FinishTransformation[] AND
FinishUtilities[]];
END;
IDefineStart: PUBLIC PROCEDURE [symbolNumber: LONG CARDINAL, multiplier, divisor: LONG CARDINAL] =
BEGIN
rootLayer ← curLayer;
curLayer ← [num: LAST[CARDINAL], body: NIL];
SetScale[multiplier,divisor];  -- SetScale does range checking
curSymbol ← LookUp[symbolNumber];
IF curSymbol.defined THEN
redefining this symbol
BEGIN
mess: IO.STREAMIO.ROS[];
CompareSymNumbers: PROC [ ref1, ref2: REF ANY ] RETURNS [ c: Basics.Comparison ] -- List.CompareProc -- =
BEGIN
s1: STEntry = NARROW[ref1];
s2: STEntry = NARROW[ref2];
c ← SELECT s1.symNumber FROM
< s2.symNumber => less,
= s2.symNumber => equal,
ENDCASE => greater;
END;
PrintSymbol: PROC [r: REF ANY, lr: LIST OF REF ANY ] =
BEGIN
s: STEntry = NARROW[r];
IF s = rootSymbol THEN mess.PutRope[" top"]
ELSE mess.PutF[" %g", IO.int[s.symNumber]];
END;
ParserErrorDefs.Report[IO.PutFR["Redefining Symbol %g", IO.int[symbolNumber]], Advisory];
TRUSTED
BEGIN
curSymbol.calledBy ← LOOPHOLE[List.Sort[LOOPHOLE[curSymbol.calledBy, LIST OF REF ANY], CompareSymNumbers]];
List.Map[LOOPHOLE[curSymbol.calledBy, LIST OF REF ANY], PrintSymbol];
END;
IF mess.GetLength > 0 THEN
OutputDefs.SendMessage[Other, IO.PutFR["Is called in symbols: %g", IO.rope[mess.RopeFromROS[]]]];
curSymbol.deleted ← TRUE;
curSymbol ← LookUp[symbolNumber]; -- get a new one
END;
END;
IDefineEnd: PUBLIC PROCEDURE =
BEGIN
curSymbol.defined ← TRUE;
curSymbol ← rootSymbol;
SetScale[1,1];
curLayer ← rootLayer;
END;
IDeleteDef: PUBLIC PROCEDURE [nSym: LONG CARDINAL] =
BEGIN
UndefineLarge: PROC [sym: STEntry] =
BEGIN
IF sym.symNumber >= nSym AND sym.defined THEN sym.deleted ← TRUE;
END;
MapSymbols[UndefineLarge];
END;
ILayer: PUBLIC PROCEDURE [layerName: Rope.ROPE] =
BEGIN
curLayer ← [num: OutputDefs.Map[layerName], body: layerName];
END;
IWire: PUBLIC PROCEDURE [width: LONG CARDINAL, a: ParserTypeDefs.Path] =
BEGIN OPEN ParserTypeDefs;
path1,path2: ParserTypeDefs.Path;
l,r,b,t: INT;
IF ParserTypeDefs.PathLength[a] = 1 THEN
ParserErrorDefs.Report["Wire with Only One Point in Path", Advisory];
IF width = 0 THEN
BEGIN
ParserErrorDefs.Report["Wire with Null Width Specified, Ignored", Advisory];
RETURN;
END;
CheckLayer[];
path1 ← ParserTypeDefs.AllocatePath[];
ParserTypeDefs.CopyPath[a,path1];
IF curSymbol # NIL THEN
BEGIN
tpath: ParserTypeDefs.Path ← ParserTypeDefs.AllocatePath[];
ScalePath[path1,tpath];
ParserTypeDefs.FreePath[path1];
path1 ← tpath;
width ← ScaleLong[width];
END;
path2 ← ParserTypeDefs.AllocatePath[];
ParserTypeDefs.CopyPath[path1,path2];
[l,r,b,t] ← OutputDefs.BBWire[curLayer.num,width,path2];
StowObject[NEW[WireRec ← [
bb: BBoxRecord[left:l,right:r,bottom:b,top:t],
layer: curLayer.num,
width: width,
p: path1]]];
ParserTypeDefs.FreePath[path1];
ParserTypeDefs.FreePath[path2];
END;
StowObject: PROC [obj: ObjectRef] =
BEGIN
curSymbol.guts ← CONS[obj, curSymbol.guts];
END;
IFlash: PUBLIC PROCEDURE [diameter: LONG CARDINAL, center: ParserTypeDefs.Point] =
BEGIN
l,r,b,t: INT;
IF diameter = 0 THEN
BEGIN
ParserErrorDefs.Report["Flash with Null diameter Specified, Ignored", Advisory];
RETURN;
END;
CheckLayer[];
IF curSymbol # NIL THEN
BEGIN
diameter ← ScaleLong[diameter];
center ← ScalePoint[center];
END;
[l,r,b,t] ← OutputDefs.BBFlash[curLayer.num,diameter,center];
StowObject[NEW[FlashRec ← [
bb: BBoxRecord[left:l,right:r,bottom:b,top:t],
layer: curLayer.num,
diameter: diameter,
center: center]]];
END;
IPolygon: PUBLIC PROCEDURE [a: ParserTypeDefs.Path] =
BEGIN OPEN ParserTypeDefs;
path1,path2: ParserTypeDefs.Path;
l,r,b,t: INT;
IF ParserTypeDefs.PathLength[a] < 3 THEN
BEGIN
ParserErrorDefs.Report["Polygon with < 3 Points in Path, Ignored", Advisory];
RETURN;
END;
CheckLayer[];
path1 ← ParserTypeDefs.AllocatePath[];
ParserTypeDefs.CopyPath[a,path1];
IF curSymbol # NIL THEN
BEGIN
tpath: ParserTypeDefs.Path ← ParserTypeDefs.AllocatePath[];
ScalePath[path1,tpath];
ParserTypeDefs.FreePath[path1];
path1 ← tpath;
END;
path2 ← ParserTypeDefs.AllocatePath[];
ParserTypeDefs.CopyPath[path1,path2];
[l,r,b,t] ← OutputDefs.BBPolygon[curLayer.num,path2];
StowObject[NEW[PolygonRec ← [
bb: BBoxRecord[left:l,right:r,bottom:b,top:t],
layer: curLayer.num,
p: path1]]];
ParserTypeDefs.FreePath[path1];
ParserTypeDefs.FreePath[path2];
END;
IBox: PUBLIC PROCEDURE [length, width: LONG CARDINAL, center: ParserTypeDefs.Point,
xRotation, yRotation: INT] =
BEGIN
l,r,b,t: INT;
len,wid: INT;
IF width = 0 OR length = 0 THEN
BEGIN
ParserErrorDefs.Report["Box with Null Width or Length Specified, Ignored", Advisory];
RETURN;
END;
IF xRotation = 0 AND yRotation = 0 THEN
BEGIN
ParserErrorDefs.Report["0,0 Rotation Defaulted to 1,0", Advisory];
xRotation ← 1;
END;
CheckLayer[];
IF curSymbol # NIL THEN
BEGIN
length ← ScaleLong[length];
width ← ScaleLong[width];
center ← ScalePoint[center];
END;
[l,r,b,t] ← OutputDefs.BBBox[curLayer.num,length,width,center,xRotation,yRotation];
len ← length; wid ← width;
StowObject[(IF yRotation=0 AND
len=r-l AND wid=t-b AND center.x=(l+r)/2 AND center.y=(b+t)/2 THEN
NEW[MBoxRec ← [
bb: BBoxRecord[left:l,right:r,bottom:b,top:t],
layer: curLayer.num]]
ELSE
NEW[BoxRec ← [
bb: BBoxRecord[left:l,right:r,bottom:b,top:t],
layer: curLayer.num,
length: length, width: width,
center: center,
xRot: xRotation, yRot: yRotation]])];
END;
ICallSymbol: PUBLIC PROCEDURE [symbolNumber: LONG CARDINAL, list: ParserTypeDefs.TList] =
BEGIN OPEN ParserTypeDefs, IntTransDefs;
call: Call;
IntTransDefs.Push[];
build up transformation matrix for this list of transformations
WHILE TListLength[list] > 0 DO
entry: ParserTypeDefs.TEntry;
[,entry] ← ParserTypeDefs.RemoveTList[list];
WITH entry SELECT FROM
t: ParserTypeDefs.Mirror => SELECT t.coords FROM
X => IntTransDefs.Mirror[x];
Y => IntTransDefs.Mirror[y];
ENDCASE;
t: ParserTypeDefs.Translate => IF t.x # 0 OR t.y # 0 THEN -- don't do null translations
BEGIN
IF curSymbol # NIL THEN
IntTransDefs.Translate[ScaleLongInt[t.x],ScaleLongInt[t.y]]
ELSE
IntTransDefs.Translate[t.x, t.y];
END;
t: ParserTypeDefs.Rotate => IntTransDefs.Rotate[t.xRot, t.yRot];
ENDCASE => ERROR;
ENDLOOP;
call ← NEW[CallRec ← [
bb: BBoxRecord[left:0,right:0,bottom:0,top:0],
callee: LookUp[symbolNumber],
t: IntTransDefs.GetLocal[]]];
IntTransDefs.Pop[];
TRUSTED {call.callee.calledBy ← LOOPHOLE[InsertIfNotMemb[LOOPHOLE[curSymbol], LOOPHOLE[call.callee.calledBy]]]};
StowObject[call];
END;
IUserCommand: PUBLIC PROCEDURE[command: [0..9], userText: Rope.ROPE] =
BEGIN
user: UserCmd = NEW[UserCmdRec ← [
command: command,
data: userText
]];
StowObject[user];
END;
InsertIfNotMemb: PROC [ref: REF ANY, list: LIST OF REF ANY] RETURNS [LIST OF REF ANY] =
BEGIN
prev: LIST OF REF ANYNIL;
FOR l: LIST OF REF ANY ← list, l.rest WHILE l#NIL DO
IF l.first = ref THEN
BEGIN
IF prev=NIL THEN RETURN[list]
ELSE { prev.rest ← l.rest; l.rest ← list; RETURN[l] };
END;
prev ← l;
ENDLOOP;
RETURN[CONS[ref, list]];
END;
IComment: PUBLIC PROCEDURE [contents: Rope.ROPE] = {NULL};
IEnd: PUBLIC PROCEDURE =
BEGIN
endSeen ← TRUE;
END;
check for a valid layer
CheckLayer: PROCEDURE = INLINE
BEGIN
IF curLayer.body.Length = 0 THEN LogError["No Layer Specified"];
END;
IUserObject: PUBLIC PROCEDURE [data: REF ANY] =
BEGIN OPEN ParserTypeDefs;
l,r,b,t: INT;
[l,r,b,t] ← OutputDefs.BBUserObject[curLayer.num, data];
StowObject[NEW[UserObRec ← [
bb: BBoxRecord[left:l,right:r,bottom:b,top:t],
layer: curLayer.num,
data: data]]];
END;
scale a long cardinal by factors set up by a call to SetScale
IScaleLong: PUBLIC PROCEDURE [n: LONG CARDINAL] RETURNS [LONG CARDINAL] =
BEGIN
RETURN[ScaleLong[n]];
END;
scale a long integer by factors set up by a call to SetScale
IScaleLongInt: PUBLIC PROCEDURE [n: INT] RETURNS [INT] =
BEGIN
RETURN[ScaleLongInt[n]];
END;
END.