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.STREAM ← IO.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]]]};
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 ANY ← NIL;
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.