-- File IntPhase1.mesa -- March 27, 1981 2:17 PM DIRECTORY IntDefs: FROM "IntDefs", AuxIntDefs: FROM "AuxIntDefs", -- exports IntUtilityDefs: FROM "IntUtilityDefs", ParserErrorDefs: FROM "ParserErrorDefs" USING [ErrorType, Report], IntStorageDefs: FROM "IntStorageDefs" USING [InitStorage, FinishStorage, StoreObject, FetchObject, ReplaceObject, BBoxRecord, NilObjectName, Object, ObjectName, ObjectRecord], IntPhase2Defs: FROM "IntPhase2Defs" USING [InitPhase2, FinishPhase2, BareItem], IntSetsDefs: FROM "IntSetsDefs" USING [PrintSet, InsertSet, RemoveFromSet], IntTransDefs: FROM "IntTransDefs" USING [InitTransformation, FinishTransformation, TransformRecord, Push, Pop, GetLocal, Mirror, Translate, Rotate, ApplyLocal, TransformPoint], StringDefs: FROM "StringDefs" USING [AppendString, AppendLongNumber], OutputDefs: FROM "OutputDefs" USING [BBBox, BBWire, BBPolygon, BBFlash, BBUserObject, SendMessage, OutputUserCommand, Map], ParserTypeDefs: FROM "ParserTypeDefs" USING [Point, Path, PathLength, AllocatePath, FreePath, CopyPath, TList, RemoveTList, TEntry, TListLength, FreeUserNode]; IntPhase1: PROGRAM IMPORTS OutputDefs, ParserTypeDefs, IntUtilityDefs, ParserErrorDefs, StringDefs, IntStorageDefs, IntTransDefs, IntSetsDefs, IntPhase2Defs EXPORTS IntDefs, AuxIntDefs, IntUtilityDefs = BEGIN OPEN IntUtilityDefs, IntStorageDefs, IntSetsDefs; SemanticError: PUBLIC ERROR = CODE; -- should modify to catch IntTransDefs errors Layer: TYPE = RECORD [length,num: CARDINAL, body: PACKED ARRAY [0..4) OF CHARACTER]; curLayer,oldLayer: Layer; curSymbol: ObjectName; -- obj name of symbol currently being defined curSymbolNumber: LONG CARDINAL; -- number of symbol currently being defined defInProg: BOOLEAN; -- definition in progress openFlag: BOOLEAN; -- a symbol is open for appending UserObjects endSeen: BOOLEAN; lastObj: ObjectName; -- last object in symbol guts defSet: ObjectName; -- set of defined symbols openMess: STRING = "Can't Process CIF Commands While in Open Mode";(670)\50b10B308i13I736b9B254b13B73b5B InitInterpreter: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN defInProg _ FALSE; openFlag _ FALSE; curLayer.length _ 0; curLayer.num _ LAST[CARDINAL]; endSeen _ FALSE; defSet _ NilObjectName; IF ~IntStorageDefs.InitStorage[] OR ~IntTransDefs.InitTransformation[] OR ~InitUtilities[] OR ~IntPhase2Defs.InitPhase2[] THEN RETURN[FALSE] ELSE RETURN[TRUE]; END; FinishInterpreter: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN IF ~IntStorageDefs.FinishStorage[] OR ~IntTransDefs.FinishTransformation[] OR ~FinishUtilities[] OR ~IntPhase2Defs.FinishPhase2[] THEN RETURN[FALSE] ELSE RETURN[TRUE]; END; DefinedSet: PUBLIC PROCEDURE RETURNS [ObjectName] = {RETURN [defSet];};k792\2b15B174i13I190b17B243b10B  IDefineStart: PUBLIC PROCEDURE [symbolNumber: LONG CARDINAL, multiplier, divisor: LONG CARDINAL] = BEGIN OPEN StringDefs; obj: ObjectName; objRec: STEntry ObjectRecord; IF openFlag THEN BEGIN OPEN ParserErrorDefs; Report[openMess, FatalInternal]; RETURN; END ELSE defInProg _ TRUE; oldLayer _ curLayer; curLayer.length _ 0; SetScale[multiplier,divisor]; -- SetScale does range checking curSymbolNumber _ symbolNumber; curSymbol _ lastObj _ obj _ LookUp[symbolNumber]; FetchObject[obj,@objRec]; IF objRec.defined THEN -- redefining this symbol BEGIN OPEN ParserErrorDefs, OutputDefs; mess: STRING _ [300]; AppendString[mess,"Redefining Symbol "L]; AppendLongNumber[mess,symbolNumber,10]; Report[mess,Advisory]; mess.length _ 0; PrintSet[objRec.cby,mess]; IF mess.length > 0 THEN BEGIN SendMessage[Other,"Is called in symbols: "L,FALSE]; SendMessage[Other,mess]; END; defSet _ RemoveFromSet[defSet,symbolNumber]; IF objRec.bound THEN lastObj _ curSymbol _ RedefineSymbol[symbolNumber] -- copy, invalidate ancestors ELSE BEGIN -- re-use this STEntry -- should also remove this symbol from son's cby sets FreeGuts[objRec.guts]; -- release storage of internals objRec.guts _ NilObjectName; objRec.defined _ FALSE; objRec.bbValid _ FALSE; ReplaceObject[@objRec,obj]; END; RETURN; END ELSE RETURN; END;k792\1b12B859i5I51i5I207i7I136i13I IDefineEnd: PUBLIC PROCEDURE = BEGIN objRec: STEntry ObjectRecord; defSet _ InsertSet[defSet,curSymbolNumber]; defInProg _ FALSE; SetScale[1,1]; curLayer _ oldLayer; FetchObject[curSymbol,@objRec]; objRec.defined _ TRUE; ReplaceObject[@objRec,curSymbol]; END; IDeleteDef: PUBLIC PROCEDURE [nSym: LONG CARDINAL] = BEGIN defSet _ DeleteSymbol[defSet,nSym]; END; ILayer: PUBLIC PROCEDURE [layerName: STRING] = BEGIN IF openFlag THEN BEGIN OPEN ParserErrorDefs; Report[openMess, FatalInternal]; RETURN; END; curLayer.length _ layerName.length; SELECT layerName.length FROM 1 => BEGIN curLayer.body[0] _ layerName[0]; curLayer.body[1] _ ' ; curLayer.body[2] _ ' ; curLayer.body[3] _ ' ; END; 2 => BEGIN curLayer.body[0] _ layerName[0]; curLayer.body[1] _ layerName[1]; curLayer.body[2] _ ' ; curLayer.body[3] _ ' ; END; 3 => BEGIN curLayer.body[0] _ layerName[0]; curLayer.body[1] _ layerName[1]; curLayer.body[2] _ layerName[2]; curLayer.body[3] _ ' ; END; 4 => BEGIN curLayer.body[0] _ layerName[0]; curLayer.body[1] _ layerName[1]; curLayer.body[2] _ layerName[2]; curLayer.body[3] _ layerName[3]; END; ENDCASE; curLayer.num _ OutputDefs.Map[curLayer.body]; END; k792\2b10B272b10B98b6B IWire: PUBLIC PROCEDURE [width: LONG CARDINAL, a: ParserTypeDefs.Path] = BEGIN OPEN ParserTypeDefs; obj: ObjectName; path1,path2: Path; l,r,b,t: LONG INTEGER; IF openFlag THEN BEGIN OPEN ParserErrorDefs; Report[openMess, FatalInternal]; RETURN; END; IF 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 _ AllocatePath[]; CopyPath[a,path1]; IF defInProg THEN BEGIN tpath: Path _ AllocatePath[]; ScalePath[path1,tpath]; FreePath[path1]; path1 _ tpath; width _ ScaleLong[width]; END; path2 _ AllocatePath[]; CopyPath[path1,path2]; [l,r,b,t] _ OutputDefs.BBWire[curLayer.num,width,path2]; obj _ StoreObjectRecord[ObjectRecord[Wire[ bb: BBoxRecord[left:l,right:r,bottom:b,top:t], next: NilObjectName, layer: curLayer.num, width: width, p: path1]]]; IF defInProg THEN BEGIN LinkObject[lastObj,obj]; lastObj _ obj; END ELSE IntPhase2Defs.BareItem[obj]; FreePath[path1]; FreePath[path2]; END;k792\1b5B357i9I100i9I401i4I61i13I IFlash: PUBLIC PROCEDURE [diameter: LONG CARDINAL, center: ParserTypeDefs.Point] = BEGIN obj: ObjectName; l,r,b,t: LONG INTEGER; IF openFlag THEN BEGIN OPEN ParserErrorDefs; Report[openMess, FatalInternal]; RETURN; END; IF diameter = 0 THEN BEGIN ParserErrorDefs.Report["Flash with Null diameter Specified, Ignored", Advisory]; RETURN; END; CheckLayer[]; IF defInProg THEN BEGIN diameter _ ScaleLong[diameter]; center _ ScalePoint[center]; END; [l,r,b,t] _ OutputDefs.BBFlash[curLayer.num,diameter,center]; obj _ StoreObjectRecord[ObjectRecord[Flash[ bb: BBoxRecord[left:l,right:r,bottom:b,top:t], next: NilObjectName, layer: curLayer.num, diameter: diameter, center: center]]]; IF defInProg THEN BEGIN LinkObject[lastObj,obj]; lastObj _ obj; END ELSE IntPhase2Defs.BareItem[obj]; END;k792\2b6B339i9I247i5I61i13I IPolygon: PUBLIC PROCEDURE [a: ParserTypeDefs.Path] = BEGIN OPEN ParserTypeDefs; obj: ObjectName; path1,path2: Path; l,r,b,t: LONG INTEGER; IF openFlag THEN BEGIN OPEN ParserErrorDefs; Report[openMess, FatalInternal]; RETURN; END; IF ParserTypeDefs.PathLength[a] < 3 THEN BEGIN ParserErrorDefs.Report["Polygon with < 3 Points in Path, Ignored", Advisory]; RETURN; END; CheckLayer[]; path1 _ AllocatePath[]; CopyPath[a,path1]; IF defInProg THEN BEGIN tpath: Path _ AllocatePath[]; ScalePath[path1,tpath]; FreePath[path1]; path1 _ tpath; END; path2 _ AllocatePath[]; CopyPath[path1,path2]; [l,r,b,t] _ OutputDefs.BBPolygon[curLayer.num,path2]; obj _ StoreObjectRecord[ObjectRecord[Polygon[ bb: BBoxRecord[left:l,right:r,bottom:b,top:t], next: NilObjectName, layer: curLayer.num, p: path1]]]; IF defInProg THEN BEGIN LinkObject[lastObj,obj]; lastObj _ obj; END ELSE IntPhase2Defs.BareItem[obj]; FreePath[path1]; FreePath[path2]; END;k792\2b8B367i9I369i7I61i13I IBox: PUBLIC PROCEDURE [length, width: LONG CARDINAL, center: ParserTypeDefs.Point, xRotation, yRotation: LONG INTEGER] = BEGIN obj: ObjectName; l,r,b,t: LONG INTEGER; len,wid: LONG INTEGER; IF openFlag THEN BEGIN OPEN ParserErrorDefs; Report[openMess, FatalInternal]; RETURN; END; 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 defInProg 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; IF yRotation=0 AND len=r-l AND wid=t-b AND center.x=(l+r)/2 AND center.y=(b+t)/2 THEN obj _ StoreObjectRecord[ObjectRecord[MBox[ bb: BBoxRecord[left:l,right:r,bottom:b,top:t], next: NilObjectName, layer: curLayer.num]]] ELSE obj _ StoreObjectRecord[ObjectRecord[Box[ bb: BBoxRecord[left:l,right:r,bottom:b,top:t], next: NilObjectName, layer: curLayer.num, length: length, width: width, center: center, xRot: xRotation, yRot: yRotation]]]; IF defInProg THEN BEGIN LinkObject[lastObj,obj]; lastObj _ obj; END ELSE IntPhase2Defs.BareItem[obj]; END; k792\2b4B424i8I132i8I425i4I61i13I75i3I61i13I ICallSymbol: PUBLIC PROCEDURE [symbolNumber: LONG CARDINAL, list: ParserTypeDefs.TList] = BEGIN OPEN ParserTypeDefs, IntTransDefs; entry: TEntry; obj: ObjectName; IF openFlag THEN BEGIN OPEN ParserErrorDefs; Report[openMess, FatalInternal]; RETURN; END; Push[]; -- build up transformation matrix for this list of transformations THROUGH [1..TListLength[list]] DO [,entry] _ RemoveTList[list]; WITH entry SELECT FROM Mirror => SELECT coords FROM X => Mirror[x]; Y => Mirror[y]; ENDCASE; Translate => IF x # 0 OR y # 0 THEN -- don't do null translations IF defInProg THEN Translate[ScaleLongInt[x],ScaleLongInt[y]] ELSE Translate[x,y]; Rotate => Rotate[xRot,yRot]; ENDCASE; ENDLOOP; obj _ StoreObjectRecord[ObjectRecord[Call[ bb: BBoxRecord[left:0,right:0,bottom:0,top:0], next: NilObjectName, symNumber: symbolNumber, uniqueID: NilObjectName, t: GetLocal[]]]]; Pop[]; IF defInProg THEN BEGIN -- make entries in calls/called by sets lRec: STEntry ObjectRecord; callee: ObjectName; LinkObject[lastObj,obj]; lastObj _ obj; callee _ LookUp[symbolNumber]; FetchObject[callee,@lRec]; lRec.cby _ InsertSet[lRec.cby,curSymbolNumber]; ReplaceObject[@lRec,callee]; END ELSE IntPhase2Defs.BareItem[obj]; END;k792\1b11B442i6I83i9I165i6I88i4I241i7I -- bind a symbol (and all of its internals) now BindSymbol: PUBLIC PROCEDURE [sym: LONG CARDINAL] RETURNS [ObjectName] = BEGIN this: ObjectName _ LookUp[sym]; lRec: STEntry ObjectRecord; temp,next: ObjectName; tempRec: ObjectRecord; -- get STEntry for sym FetchObject[this,@lRec]; IF ~lRec.defined THEN BEGIN OPEN StringDefs; s: STRING _ [100]; AppendString[s,"Call to Undefined Symbol: "]; AppendLongNumber[s,lRec.symNumber,10]; LogError[s]; RETURN [NilObjectName]; END; IF lRec.expanded THEN BEGIN OPEN StringDefs; s: STRING _ [100]; AppendString[s,"Symbol Calls Itself: "]; AppendLongNumber[s,lRec.symNumber,10]; LogError[s]; lRec.expanded _ FALSE; -- patch and go on ReplaceObject[@lRec,this]; RETURN [NilObjectName]; END ELSE BEGIN IF lRec.bound THEN RETURN [this]; lRec.expanded _ TRUE; ReplaceObject[@lRec,this]; END; -- now bind up all internals FOR temp _ lRec.guts, next UNTIL temp = NilObjectName DO FetchObject[temp,@tempRec]; WITH locRec : tempRec SELECT FROM Call => BEGIN locRec.uniqueID _ BindSymbol[locRec.symNumber]; ReplaceObject[@locRec,temp]; next _ locRec.next; END; Box => next _ locRec.next; MBox => next _ locRec.next; Flash => next _ locRec.next; Polygon => {ParserTypeDefs.FreePath[locRec.p]; next _ locRec.next;}; Wire => {ParserTypeDefs.FreePath[locRec.p]; next _ locRec.next;}; User => {ParserTypeDefs.FreeUserNode[locRec.data]; next _ locRec.next;}; ENDCASE; ENDLOOP; lRec.bound _ TRUE; lRec.expanded _ FALSE; -- now get the bounding box FindSymBB[@lRec]; ReplaceObject[@lRec,this]; RETURN [this]; END; k792\51b10B113i7I75i7I226i13I272i13I200i13I75i4I135i3I27i4I27i5I27i7I65i4I65i4I -- find the bounding box for a symbol call, leave results in thing^ FindCallBB: PUBLIC PROCEDURE [thing: Object] = BEGIN WITH symCall: thing^ SELECT FROM Call => BEGIN OPEN IntTransDefs; lRec: STEntry ObjectRecord; x,y: LONG INTEGER; IF symCall.uniqueID # NilObjectName THEN FetchObject[symCall.uniqueID,@lRec] ELSE BEGIN symCall.bb _ BBoxRecord[left:1,right:0,bottom:0,top:0]; RETURN; -- ignore symbols that couldn't be bound END; IF ~lRec.bbValid THEN BEGIN FindSymBB[@lRec]; -- get bounding box for this symbol ReplaceObject[@lRec,symCall.uniqueID]; END; IF lRec.bb.left>lRec.bb.right THEN -- null BB symCall.bb _ BBoxRecord[left:1,right:0,bottom:0,top:0] ELSE BEGIN Push[]; ApplyLocal[@symCall.t]; [x,y] _ TransformPoint[lRec.bb.left,lRec.bb.bottom]; InitMM[x,y]; [x,y] _ TransformPoint[lRec.bb.right,lRec.bb.bottom]; MinMax[x,y]; [x,y] _ TransformPoint[lRec.bb.right,lRec.bb.top]; MinMax[x,y]; [x,y] _ TransformPoint[lRec.bb.left,lRec.bb.top]; MinMax[x,y]; [symCall.bb.left,symCall.bb.right,symCall.bb.bottom,symCall.bb.top] _ Extent[]; DoneMM[]; Pop[]; END; END; ENDCASE; END;k792\70b10B82i4I41i7I63i13I -- find the bounding box for a symbol, leave results in sym^ FindSymBB: PROCEDURE [sym: POINTER TO STEntry ObjectRecord] = BEGIN OPEN IntTransDefs; first: BOOLEAN _ TRUE; -- first point flag temp,next: ObjectName; tempRec: ObjectRecord; IF sym.bbValid THEN RETURN; IF sym.guts = NilObjectName THEN BEGIN OPEN StringDefs; foo: STRING _ [100]; AppendString[foo,"Null BB Assumed for Empty Symbol: "]; AppendLongNumber[foo,sym.symNumber,10]; ParserErrorDefs.Report[foo, Advisory]; sym.bb _ BBoxRecord[left:1,right:0,bottom:0,top:0]; sym.bbValid _ TRUE; RETURN; END; FOR temp _ sym.guts, next UNTIL temp = NilObjectName DO FetchObject[temp,@tempRec]; WITH locRec : tempRec SELECT FROM Call => IF locRec.uniqueID # NilObjectName THEN BEGIN FindCallBB[@locRec]; IF locRec.bb.left<=locRec.bb.right THEN -- ignore null BBs BEGIN IF first THEN {first _ FALSE; InitMM[locRec.bb.right,locRec.bb.top];} ELSE MinMax[locRec.bb.right,locRec.bb.top]; MinMax[locRec.bb.left,locRec.bb.bottom]; END; -- save the result ReplaceObject[@locRec,temp]; next _ locRec.next; END; -- otherwise ignore Box => BEGIN IF first THEN BEGIN first _ FALSE; InitMM[locRec.bb.right,locRec.bb.top]; END ELSE MinMax[locRec.bb.right,locRec.bb.top]; MinMax[locRec.bb.left,locRec.bb.bottom]; next _ locRec.next; END; MBox => BEGIN IF first THEN BEGIN first _ FALSE; InitMM[locRec.bb.right,locRec.bb.top]; END ELSE MinMax[locRec.bb.right,locRec.bb.top]; MinMax[locRec.bb.left,locRec.bb.bottom]; next _ locRec.next; END; Flash => BEGIN IF first THEN BEGIN first _ FALSE; InitMM[locRec.bb.right,locRec.bb.top]; END ELSE MinMax[locRec.bb.right,locRec.bb.top]; MinMax[locRec.bb.left,locRec.bb.bottom]; next _ locRec.next; END; Polygon => BEGIN OPEN ParserTypeDefs; IF first THEN BEGIN first _ FALSE; InitMM[locRec.bb.right,locRec.bb.top]; END ELSE MinMax[locRec.bb.right,locRec.bb.top]; MinMax[locRec.bb.left,locRec.bb.bottom]; ParserTypeDefs.FreePath[locRec.p]; next _ locRec.next; END; Wire => BEGIN OPEN ParserTypeDefs; IF first THEN BEGIN first _ FALSE; InitMM[locRec.bb.right,locRec.bb.top]; END ELSE MinMax[locRec.bb.right,locRec.bb.top]; MinMax[locRec.bb.left,locRec.bb.bottom]; ParserTypeDefs.FreePath[locRec.p]; next _ locRec.next; END; User => BEGIN IF locRec.bb.left<=locRec.bb.right THEN -- ignore null BBs BEGIN IF first THEN {first _ FALSE; InitMM[locRec.bb.right,locRec.bb.top];} ELSE MinMax[locRec.bb.right,locRec.bb.top]; MinMax[locRec.bb.left,locRec.bb.bottom]; END; ParserTypeDefs.FreeUserNode[locRec.data]; next _ locRec.next; END; ENDCASE; ENDLOOP; IF first THEN -- no error free contents {sym.bb.left _ 1; sym.bb.right _ sym.bb.bottom _ sym.bb.top _ 0;} ELSE BEGIN [sym.bb.left,sym.bb.right,sym.bb.bottom,sym.bb.top] _ Extent[]; DoneMM[]; END; sym.bbValid _ TRUE; END;k792\64b9B29i7I186i13I189i8I142i13I76i4I29i13I427i3I230i4I230i5I230i7I290i4I290i4I IComment: PUBLIC PROCEDURE [contents: STRING] = BEGIN NULL; END; IUserCommand: PUBLIC PROCEDURE[command: [0..9], userText: STRING] = BEGIN IF openFlag THEN BEGIN OPEN ParserErrorDefs; Report[openMess, FatalInternal]; RETURN; END; OutputDefs.OutputUserCommand[command,userText]; END; IEnd: PUBLIC PROCEDURE = BEGIN endSeen _ TRUE; END;k792\2b8B65b12B228b4B -- check for a valid layer CheckLayer: PROCEDURE = INLINE BEGIN IF curLayer.length = 0 THEN LogError["No Layer Specified"]; END; StoreObjectRecord: PROCEDURE [object: ObjectRecord] RETURNS[ObjectName] = INLINE BEGIN RETURN[StoreObject[@object]]; END;\30b10B99b18B64b1B7b1B31b1B IOpenSymbol: PUBLIC PROCEDURE [sym: ObjectName] = BEGIN temp,nextTemp: ObjectName; tempRec: ObjectRecord; symRec: STEntry ObjectRecord; IF defInProg THEN BEGIN OPEN ParserErrorDefs; Report["Can't Enter Open Mode While DS in Progress", FatalInternal]; RETURN; END ELSE openFlag _ TRUE; FetchObject[sym,@symRec]; IF symRec.guts = NilObjectName THEN lastObj _ sym ELSE FOR temp _ symRec.guts, nextTemp UNTIL temp = NilObjectName DO lastObj _ temp; FetchObject[temp,@tempRec]; -- get next object in symbol def WITH foo:tempRec SELECT FROM Call => nextTemp _ foo.next; Wire => {nextTemp _ foo.next; ParserTypeDefs.FreePath[foo.p];}; Flash => nextTemp _ foo.next; Polygon => {nextTemp _ foo.next; ParserTypeDefs.FreePath[foo.p];}; Box => nextTemp _ foo.next; MBox => nextTemp _ foo.next; User => {nextTemp _ foo.next; ParserTypeDefs.FreeUserNode[foo.data];}; ENDCASE; ENDLOOP; END; ICloseSymbol: PUBLIC PROCEDURE = { openFlag _ FALSE; RETURN;}; ISymBB: PUBLIC PROCEDURE [sym: ObjectName] RETURNS [l,r,b,t: LONG INTEGER] = BEGIN symRec: STEntry ObjectRecord; FetchObject[sym,@symRec]; RETURN[ symRec.bb.left, symRec.bb.right, symRec.bb.bottom, symRec.bb.top]; END; IUserObject: PUBLIC PROCEDURE [size: CARDINAL, data: POINTER TO UNSPECIFIED] = BEGIN OPEN ParserTypeDefs; obj: ObjectName; l,r,b,t: LONG INTEGER; [l,r,b,t] _ OutputDefs.BBUserObject[curLayer.num,size,data]; obj _ StoreObjectRecord[ObjectRecord[User[ bb: BBoxRecord[left:l,right:r,bottom:b,top:t], next: NilObjectName, layer: curLayer.num, size: size, data: data]]]; IF defInProg OR openFlag THEN BEGIN LinkObject[lastObj,obj]; lastObj _ obj; END ELSE IntPhase2Defs.BareItem[obj]; END;k792\2b11B111i7I229i13I75i13I124i4I29i4I64i5I29i7I64i3I30i4I29i4I102b12B53b6B89i7I141b11B245i4I61i13I -- 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: LONG INTEGER] RETURNS [LONG INTEGER] = BEGIN RETURN[ScaleLongInt[n]]; END; END. \68b10B170b13B