<> <> <> <> DIRECTORY ParserTypeDefs, IntDefs, IntStorageDefs, IntUtilityDefs, ParserErrorDefs, Rope; IntUtilities: CEDAR PROGRAM IMPORTS ParserErrorDefs, ParserTypeDefs EXPORTS IntDefs, IntUtilityDefs = BEGIN OPEN IntStorageDefs, IntUtilityDefs; aScale, bScale: LONG CARDINAL; -- scale factors for DS tooBigLong: LONG CARDINAL; -- largest number that can be scaled without overflow tooBigInt: INT; noScale: BOOLEAN; -- identity flag for scale TableSize: CARDINAL = 199; -- symbol table size sTable: ARRAY [0..TableSize) OF IntStorageDefs.STEntryList; MaxMMStack: CARDINAL = 50; -- max depth minmax stack left,right,bottom,top: ARRAY [1..MaxMMStack] OF INT; mmPtr: CARDINAL; -- minmax stack pointer InitUtilities: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN FOR i: CARDINAL IN [0..TableSize) DO sTable[i] _ NIL ENDLOOP; mmPtr _ 0; noScale _ TRUE; warned _ FALSE; errorCount _ 0; RETURN[TRUE]; END; FinishUtilities: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN FOR i: CARDINAL IN [0..TableSize) DO FOR cur: STEntryList _ sTable[i], cur.rest WHILE cur#NIL DO cur.first.calledBy _ NIL; -- breaks reference loops ENDLOOP; -- the rest is a tree, so should be collectable sTable[i] _ NIL; ENDLOOP; RETURN[TRUE]; END; SemanticError: PUBLIC ERROR = CODE; warned: BOOL; errorCount: CARDINAL; LogError: PUBLIC PROCEDURE [s: Rope.ROPE] = BEGIN errorCount _ errorCount + 1; ParserErrorDefs.Report[s, FatalSemantic]; ERROR SemanticError[]; END; OKToContinue: PUBLIC PROCEDURE RETURNS [BOOLEAN] = BEGIN IF errorCount > 0 AND NOT warned THEN BEGIN warned _ TRUE; ParserErrorDefs.Report["Fatal Semantic Errors Exist, Strange Results May Occur If You Proceed", Advisory]; RETURN [FALSE]; END ELSE RETURN[TRUE]; END; <> InitMM: PUBLIC PROCEDURE [x,y: INT] = BEGIN IF (mmPtr _ mmPtr+1) > MaxMMStack THEN BEGIN ParserErrorDefs.Report["InitMM: no stack space", FatalInternal]; RETURN; END ELSE BEGIN left[mmPtr] _ x; right[mmPtr] _ x; bottom[mmPtr] _ y; top[mmPtr] _ y; RETURN; END; END; MinMax: PUBLIC PROCEDURE [x,y: INT] = BEGIN IF x > right[mmPtr] THEN right[mmPtr] _ x ELSE BEGIN IF x < left[mmPtr] THEN left[mmPtr] _ x; END; IF y > top[mmPtr] THEN top[mmPtr] _ y ELSE BEGIN IF y < bottom[mmPtr] THEN bottom[mmPtr] _ y; END; END; DoneMM: PUBLIC PROCEDURE = BEGIN IF mmPtr = 0 THEN ParserErrorDefs.Report["DoneMM: empty stack", FatalInternal] ELSE mmPtr _ mmPtr-1; END; Extent: PUBLIC PROCEDURE RETURNS [l,r,b,t: INT] = BEGIN RETURN [left[mmPtr],right[mmPtr],bottom[mmPtr],top[mmPtr]]; END; LookUp: PUBLIC PROCEDURE [symNumber: LONG CARDINAL] RETURNS [ent: STEntry] = BEGIN hAddr: CARDINAL = Hash[symNumber]; prev: STEntryList _ NIL; FOR cur: STEntryList _ sTable[hAddr], cur.rest WHILE cur#NIL DO IF cur.first.symNumber=symNumber AND NOT cur.first.deleted THEN BEGIN IF prev=NIL THEN RETURN[cur.first] ELSE BEGIN prev.rest _ cur.rest; cur.rest _ sTable[hAddr]; sTable[hAddr] _ cur; RETURN[cur.first]; END; END; prev _ cur; ENDLOOP; sTable[hAddr] _ CONS[ NEW[STEntryRec _ [ bb: BBoxRecord[left:0,right:0,bottom:0,top:0], bbValid: FALSE, guts: NIL, symNumber: symNumber, deleted: FALSE, expanded: FALSE, bound: FALSE, defined: FALSE, calledBy: NIL]], sTable[hAddr]]; RETURN[sTable[hAddr].first]; END; <> MapSymbols: PUBLIC PROCEDURE [proc: PROC[IntStorageDefs.STEntry]] = BEGIN FOR hAddr: NAT IN [0..TableSize) DO FOR cur: STEntryList _ sTable[hAddr], cur.rest WHILE cur#NIL DO proc[cur.first]; ENDLOOP; ENDLOOP; END; <> SetScale: PUBLIC PROCEDURE [a,b: LONG CARDINAL] = BEGIN IF a = 0 OR b = 0 THEN LogError["Illegal Scale Factor"]; IF a = b THEN noScale _ TRUE -- no need to do any computation ELSE BEGIN aScale _ a; bScale _ b; tooBigLong _ LAST[LONG CARDINAL]/aScale; tooBigInt _ LAST[INT]/aScale; noScale _ FALSE; <> <> END; END; <> ScaleLong: PUBLIC PROCEDURE [n: LONG CARDINAL] RETURNS [LONG CARDINAL] = BEGIN IF noScale THEN RETURN[n] ELSE BEGIN IF n > tooBigLong THEN BEGIN LogError["Number Too Large to Scale"]; RETURN[LAST[LONG CARDINAL]]; END; RETURN[(aScale*n)/bScale]; END; END; <> ScalePath: PUBLIC PROCEDURE [s,d: ParserTypeDefs.Path] = BEGIN pt: ParserTypeDefs.Point; <> IF noScale THEN BEGIN ParserTypeDefs.CopyPath[s,d]; RETURN; END ELSE THROUGH [1..ParserTypeDefs.PathLength[s]] DO [,pt] _ ParserTypeDefs.RemovePoint[s]; ParserTypeDefs.AppendPoint[d,ScalePoint[pt]]; ENDLOOP; END; <> ScalePoint: PUBLIC PROCEDURE [p: ParserTypeDefs.Point] RETURNS [ParserTypeDefs.Point] = BEGIN temp: ParserTypeDefs.Point; temp.x _ ScaleLongInt[p.x]; temp.y _ ScaleLongInt[p.y]; RETURN[temp]; END; <> ScaleLongInt: PUBLIC PROCEDURE [n: INT] RETURNS [INT] = BEGIN IF noScale THEN RETURN[n] ELSE BEGIN IF ABS[n] > tooBigInt THEN BEGIN LogError["Integer Magnitude Too Large to Scale"]; RETURN[IF n < 0 THEN FIRST[INT] ELSE LAST[INT]]; END; RETURN[(aScale*n)/bScale]; END; END; <> Hash: PROCEDURE [n: LONG CARDINAL] RETURNS [[0..TableSize)] = BEGIN RETURN[n MOD TableSize]; END; END.