DIRECTORY Basics USING [BYTE, CARD, Comparison, HighHalf, LongNumber, LowHalf, NonNegative], Convert USING [IntFromRope], IO USING [PutBlock, PutChar, STREAM], IPSkeleton USING [GetSkeleton], IPMaster, IPReal USING [Rational, RationalFromReal], Real USING [FScale, NumberType, RealToPair, RoundLI], Rope USING [ActionType, Concat, Fetch, Length, Map, MaxLen, ROPE, Substr], SymTab USING [Create, Fetch, Ref, Store]; IPMasterImpl: CEDAR PROGRAM IMPORTS Basics, Convert, IPReal, IO, Real, Rope, SymTab, IPSkeleton EXPORTS IPMaster ~ BEGIN OPEN IPMaster; BYTE: TYPE ~ Basics.BYTE; CARD: TYPE ~ Basics.CARD; ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; Error: PUBLIC ERROR [error: ErrorDesc] ~ CODE; Bug: PROC [x: ROPE] ~ { ERROR Error[[code: $bug, explanation: x]] }; InvalidIdentifier: PROC [x: ROPE] ~ { ERROR Error[[code: $invalidIdentifier, explanation: x]] }; InvalidString: PROC [x: ROPE] ~ { ERROR Error[[code: $invalidString, explanation: x]] }; InvalidName: PROC [x: ROPE] ~ { ERROR Error[[code: $invalidName, explanation: x]] }; InvalidVersion: PROC [x: ROPE] ~ { ERROR Error[[code: $invalidVersion, explanation: x]] }; EvFromOp: TYPE ~ REF READONLY EvFromOpArray; EvFromOpArray: TYPE ~ PACKED ARRAY Op OF EncodingValue; encodingValueFromOp: EvFromOp ~ NEW[EvFromOpArray = [ nil: nil, get: get, makeveclu: makeveclu, makevec: makevec, shape: shape, getprop: getprop, getp: getp, mergeprop: mergeprop, fget: fget, fset: fset, makesimpleco: makesimpleco, findoperator: findoperator, do: do, dosave: dosave, dosaveall: dosaveall, dosavesimplebody: dosavesimplebody, pop: pop, copy: copy, dup: dup, roll: roll, exch: exch, mark: mark, unmark: unmark, unmark0: unmark0, count: count, nop: nop, error: error, if: if, ifelse: ifelse, ifcopy: ifcopy, eq: eq, gt: gt, ge: ge, and: and, or: or, not: not, type: type, add: add, sub: sub, neg: neg, abs: abs, floor: floor, ceiling: ceiling, trunc: trunc, round: round, mul: mul, div: div, mod: mod, rem: rem, iget: iget, iset: iset, maket: maket, translate: translate, rotate: rotate, scale: scale, scale2: scale2, concat: concat, concatt: concatt, move: move, trans: trans, setxy: setxy, setxyrel: setxyrel, setxrel: setxrel, setyrel: setyrel, getcp: getcp, makepixelarray: makepixelarray, finddecompressor: finddecompressor, extractpixelarray: extractpixelarray, makegray: makegray, findcolor: findcolor, findcoloroperator: findcoloroperator, findcolormodeloperator: findcolormodeloperator, makesampledcolor: makesampledcolor, makesampledblack: makesampledblack, setgray: setgray, setsampledcolor: setsampledcolor, setsampledblack: setsampledblack, moveto: moveto, lineto: lineto, linetox: linetox, linetoy: linetoy, curveto: curveto, conicto: conicto, arcto: arcto, makeoutline: makeoutline, makeoutlineodd: makeoutlineodd, maskfill: maskfill, maskfillparity: maskfillparity, maskrectangle: maskrectangle, startunderline: startunderline, maskunderline: maskunderline, masktrapezoidx: masktrapezoidx, masktrapezoidy: masktrapezoidy, maskstroke: maskstroke, maskstrokeclosed: maskstrokeclosed, maskvector: maskvector, maskdashedstroke: maskdashedstroke, maskpixel: maskpixel, clipoutline: clipoutline, cliprectangle: cliprectangle, maskchar: maskchar, makefont: makefont, findfont: findfont, modifyfont: modifyfont, setfont: setfont, show: show, showandxrel: showandxrel, showandfixedxrel: showandfixedxrel, correctmask: correctmask, correctspace: correctspace, correct: correct, space: space, setcorrectmeasure: setcorrectmeasure, setcorrecttolerance: setcorrecttolerance, beginBody: beginBody, endBody: endBody, beginBlock: beginBlock, endBlock: endBlock, contentInstructions: contentInstructions ]]; OpFromEv: TYPE ~ REF READONLY OpFromEvArray; OpFromEvArray: TYPE ~ PACKED ARRAY EncodingValue OF Op; opFromEncodingValue: OpFromEv ~ InvertEvFromOp[encodingValueFromOp]; InvertEvFromOp: PROC [encodingValueFromOp: EvFromOp] RETURNS [OpFromEv] ~ { opFromEncodingValue: REF OpFromEvArray ~ NEW[OpFromEvArray _ ALL[nil]]; FOR op: Op IN Op DO opFromEncodingValue[encodingValueFromOp[op]] _ op ENDLOOP; RETURN[opFromEncodingValue]; }; EncodingValueFromOp: PUBLIC PROC [op: Op] RETURNS [EncodingValue] ~ { RETURN[encodingValueFromOp[op]]; }; OpFromEncodingValue: PUBLIC PROC [ev: EncodingValue] RETURNS [Op] ~ { RETURN[opFromEncodingValue[ev]]; }; GetOpFromEv: PUBLIC PROC RETURNS [OpFromEv] ~ { RETURN[opFromEncodingValue]; }; NonDefaultingRope: TYPE ~ ROPE _; RopeFromOpArray: TYPE ~ ARRAY Op OF NonDefaultingRope; ropeFromOp: REF RopeFromOpArray ~ NEW[RopeFromOpArray _ [nil: NIL, get: "GET", makeveclu: "MAKEVECLU", makevec: "MAKEVEC", shape: "SHAPE", getprop: "GETPROP", getp: "GETP", mergeprop: "MERGEPROP", fget: "FGET", fset: "FSET", makesimpleco: "MAKESIMPLECO", findoperator: "FINDOPERATOR", do: "DO", dosave: "DOSAVE", dosaveall: "DOSAVEALL", dosavesimplebody: "DOSAVESIMPLEBODY", pop: "POP", copy: "COPY", dup: "DUP", roll: "ROLL", exch: "EXCH", mark: "MARK", unmark: "UNMARK", unmark0: "UNMARK0", count: "COUNT", nop: "NOP", error: "ERROR", if: "IF", ifelse: "IFELSE", ifcopy: "IFCOPY", eq: "EQ", gt: "GT", ge: "GE", and: "AND", or: "OR", not: "NOT", type: "TYPE", add: "ADD", sub: "SUB", neg: "NEG", abs: "ABS", floor: "FLOOR", ceiling: "CEILING", trunc: "TRUNC", round: "ROUND", mul: "MUL", div: "DIV", mod: "MOD", rem: "REM", iget: "IGET", iset: "ISET", maket: "MAKET", translate: "TRANSLATE", rotate: "ROTATE", scale: "SCALE", scale2: "SCALE2", concat: "CONCAT", concatt: "CONCATT", move: "MOVE", trans: "TRANS", setxy: "SETXY", setxyrel: "SETXYREL", setxrel: "SETXREL", setyrel: "SETYREL", getcp: "GETCP", makepixelarray: "MAKEPIXELARRAY", finddecompressor: "FINDDECOMPRESSOR", extractpixelarray: "EXTRACTPIXELARRAY", makegray: "MAKEGRAY", setgray: "SETGRAY", findcolor: "FINDCOLOR", findcoloroperator: "FINDCOLOROPERATOR", findcolormodeloperator: "FINDCOLORMODELOPERATOR", makesampledcolor: "MAKESAMPLEDCOLOR", makesampledblack: "MAKESAMPLEDBLACK", setsampledcolor: "SETSAMPLEDCOLOR", setsampledblack: "SETSAMPLEDBLACK", moveto: "MOVETO", lineto: "LINETO", linetox: "LINETOX", linetoy: "LINETOY", curveto: "CURVETO", conicto: "CONICTO", arcto: "ARCTO", makeoutline: "MAKEOUTLINE", makeoutlineodd: "MAKEOUTLINEODD", maskfill: "MASKFILL", maskfillparity: "MASKFILLPARITY", maskrectangle: "MASKRECTANGLE", startunderline: "STARTUNDERLINE", maskunderline: "MASKUNDERLINE", masktrapezoidx: "MASKTRAPEZOIDX", masktrapezoidy: "MASKTRAPEZOIDY", maskstroke: "MASKSTROKE", maskstrokeclosed: "MASKSTROKECLOSED", maskvector: "MASKVECTOR", maskdashedstroke: "MASKDASHEDSTROKE", maskpixel: "MASKPIXEL", clipoutline: "CLIPOUTLINE", cliprectangle: "CLIPRECTANGLE", maskchar: "MASKCHAR", makefont: "MAKEFONT", findfont: "FINDFONT", modifyfont: "MODIFYFONT", setfont: "SETFONT", show: "SHOW", showandxrel: "SHOWANDXREL", showandfixedxrel: "SHOWANDFIXEDXREL", correctmask: "CORRECTMASK", correctspace: "CORRECTSPACE", space: "SPACE", setcorrectmeasure: "SETCORRECTMEASURE", setcorrecttolerance: "SETCORRECTTOLERANCE", correct: "CORRECT", beginBody: "{", endBody: "}", beginBlock: "BEGIN", endBlock: "END", contentInstructions: "CONTENTINSTRUCTIONS" ]]; opFromRope: SymTab.Ref ~ InvertRopeFromOp[ropeFromOp]; OpFromRopeVal: TYPE ~ REF OpFromRopeValRep; OpFromRopeValRep: TYPE ~ RECORD[op: Op]; InvertRopeFromOp: PROC [ropeFromOp: REF RopeFromOpArray] RETURNS [SymTab.Ref] ~ { opFromRope: SymTab.Ref ~ SymTab.Create[mod: ORD[Op.LAST], case: FALSE]; FOR op: Op IN Op DO key: ROPE ~ ropeFromOp[op]; val: OpFromRopeVal ~ NEW[OpFromRopeValRep _ [op: op]]; IF SymTab.Store[x: opFromRope, key: key, val: val] THEN NULL ELSE Bug["Duplicate name in opFromRope table."]; ENDLOOP; RETURN[opFromRope]; }; RopeFromOp: PUBLIC PROC [op: Op] RETURNS [ROPE] ~ { RETURN[ropeFromOp[op]]; }; OpFromRope: PUBLIC PROC [rope: ROPE] RETURNS [Op] ~ { found: BOOL; val: REF; [found, val] _ SymTab.Fetch[x: opFromRope, key: rope]; IF found THEN WITH val SELECT FROM val: OpFromRopeVal => RETURN[val.op]; ENDCASE => Bug["Bogus value in opFromRope table."]; RETURN[nil]; }; RopeFromImagerVarArray: TYPE ~ ARRAY ImagerVariable OF NonDefaultingRope; ropeFromImagerVar: REF RopeFromImagerVarArray ~ NEW[RopeFromImagerVarArray _ [ DCScpx: "DCScpx", DCScpy: "DCScpy", correctMX: "correctMX", correctMY: "correctMY", T: "T", priorityImportant: "priorityImportant", mediumXSize: "mediumXSize", mediumYSize: "mediumYSize", fieldXMin: "fieldXMin", fieldYMin: "fieldYMin", fieldXMax: "fieldXMax", fieldYMax: "fieldYMax", font: "font", color: "color", noImage: "noImage", strokeWidth: "strokeWidth", strokeEnd: "strokeEnd", underlineStart: "underlineStart", amplifySpace: "amplifySpace", correctPass: "correctPass", correctShrink: "correctShrink", correctTX: "correctTX", correctTY: "correctTY", strokeJoint: "strokeJoint", clipper: "clipper" ]]; RopeFromImagerVariable: PUBLIC PROC [var: ImagerVariable] RETURNS [ROPE] ~ { RETURN[ropeFromImagerVar[var]]; }; MapParts: PUBLIC PROC [base: ROPE, start: INT _ 0, len: INT _ MaxLen, delimiter: CHAR, action: PartActionType] RETURNS [BOOL] ~ { next, pos: INT _ start; -- next = next char index, pos = start of part mapPartsAction: Rope.ActionType ~ { index: INT ~ next; next _ next+1; IF c=delimiter THEN { quit _ action[base: base, start: pos, len: index-pos]; pos _ next }; }; IF Rope.Map[base: base, start: start, len: len, action: mapPartsAction] THEN RETURN[TRUE]; RETURN[action[base: base, start: pos, len: next-pos]]; -- don't forget the last one! }; ValidateIdentifier: PUBLIC PROC [rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { state: {first, rest} _ first; identifierChar: Rope.ActionType ~ { SELECT state FROM first => SELECT c FROM IN['a..'z], IN['A..'Z] => state _ rest; ENDCASE => RETURN[quit: TRUE]; -- illegal first char rest => SELECT c FROM IN['a..'z], IN['A..'Z], IN['0..'9], '- => NULL; ENDCASE => RETURN[quit: TRUE]; -- illegal char ENDCASE => Bug["Undefined state in ValidateIdentifier."]; }; IF Rope.Map[base: rope, start: start, len: len, action: identifierChar] THEN SELECT state FROM first => InvalidIdentifier["Identifier begins with an illegal character."]; rest => InvalidIdentifier["Identifier contains an illegal character."]; ENDCASE => Bug["Undefined state in ValidateIdentifier."]; IF state=first THEN InvalidIdentifier["Identifier is empty."]; }; ValidateName: PUBLIC PROC [rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { parts: INT _ 0; namePart: PartActionType ~ { parts _ parts+1; ValidateIdentifier[base, start, len] }; [] _ MapParts[base: rope, start: start, len: len, delimiter: '/, action: namePart]; IF parts=0 THEN InvalidName["Name is empty."]; }; ValidateString: PUBLIC PROC [rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { state: {run, escape, escape2, extended, extended2} _ run; index: INT _ start; stringChar: Rope.ActionType ~ { SELECT state FROM run => IF c='\377 THEN state _ escape; escape => IF c='\377 THEN state _ escape2 ELSE state _ run; escape2 => IF c='\000 THEN state _ extended ELSE quit _ TRUE; extended => IF c='\377 THEN state _ escape ELSE state _ extended2; extended2 => IF c='\377 THEN quit _ TRUE ELSE state _ extended; ENDCASE => Bug["Undefined state in ValidateString."]; index _ index+1; }; IF Rope.Map[base: rope, start: start, len: len, action: stringChar] THEN InvalidString["String contains an invalid escape sequence."]; IF state=run OR state=extended THEN NULL ELSE InvalidString["String ends in the middle of an escape sequence."]; }; ValidateNumber: PROC [rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { chars: INT _ 0; numberChar: Rope.ActionType ~ { chars _ chars+1; RETURN[quit: NOT (c IN['0..'9])] }; IF Rope.Map[base: rope, start: start, len: len, action: numberChar] THEN InvalidVersion["Version number contains an illegal character."]; IF chars=0 THEN InvalidVersion["Version number part is empty."]; }; ValidateVersion: PUBLIC PROC [rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { parts: NAT _ 0; versionPart: PartActionType ~ { parts _ parts+1; ValidateNumber[base, start, len] }; [] _ MapParts[base: rope, start: start, len: len, delimiter: '., action: versionPart]; SELECT parts FROM 0 => InvalidVersion["Version number is empty."]; 1 => InvalidVersion["Version number has no dot."]; 2 => NULL; ENDCASE => InvalidVersion["Version number has too many parts."]; }; VersionFromRope: PUBLIC PROC [rope: ROPE, start: INT _ 0, len: INT _ MaxLen] RETURNS [version: Version] ~ { parts: NAT _ 0; versionPart: PartActionType ~ { val: INT ~ Convert.IntFromRope[Rope.Substr[base, start, len]]; IF val NOT IN CARDINAL THEN InvalidVersion["Version number part is too big."]; SELECT parts FROM 0 => version.major _ val; 1 => version.minor _ val; ENDCASE => Bug["ValidateVersion failed."]; parts _ parts+1; }; ValidateVersion[rope, start, len]; [] _ MapParts[base: rope, start: start, len: len, delimiter: '., action: versionPart]; IF parts#2 THEN Bug["ValidateVersion failed."]; }; CompareVersion: PUBLIC PROC [a, b: Version] RETURNS [Basics.Comparison] ~ { SELECT a.major FROM RETURN[less]; >b.major => RETURN[greater]; ENDCASE => SELECT a.minor FROM RETURN[less]; >b.minor => RETURN[greater]; ENDCASE => RETURN[equal]; }; PutShortNumber: PUBLIC PROC [stream: STREAM, n: ShortNumber] ~ { x: [0..77777B] ~ n-ShortNumber.FIRST; IO.PutChar[stream, VAL[x/400B]]; IO.PutChar[stream, VAL[x MOD 400B]]; }; PutShortOp: PUBLIC PROC [stream: STREAM, op: ShortEncodingValue] ~ { x: [0..37B] ~ ORD[op]; IO.PutChar[stream, VAL[200B+x]]; }; PutLongOp: PUBLIC PROC [stream: STREAM, op: EncodingValue] ~ { x: [0..17777B] ~ ORD[op]; IO.PutChar[stream, VAL[240B+x/400B]]; IO.PutChar[stream, VAL[x MOD 400B]]; }; PutShortSequence: PUBLIC PROC [ stream: STREAM, seq: SequenceType, len: ShortSequenceLength] ~ { x: [0..37B] ~ ORD[seq]; IO.PutChar[stream, VAL[300B+x]]; IO.PutChar[stream, VAL[len]]; }; PutLongSequence: PUBLIC PROC [ stream: STREAM, seq: SequenceType, len: LongSequenceLength] ~ { x: [0..37B] ~ ORD[seq]; lenH: [0..377B] ~ Basics.HighHalf[len]; -- bounds check lenL: CARDINAL ~ Basics.LowHalf[len]; IO.PutChar[stream, VAL[340B+x]]; IO.PutChar[stream, VAL[lenH]]; IO.PutChar[stream, VAL[lenL/400B]]; IO.PutChar[stream, VAL[lenL MOD 400B]]; }; BytesInInt: PUBLIC PROC [val: INT] RETURNS [ByteCount] ~ { x: CARD ~ IF val<0 THEN -(val+1) ELSE val; SELECT x FROM <00000080H => RETURN[1]; <00008000H => RETURN[2]; <00800000H => RETURN[3]; ENDCASE => RETURN[4]; }; PutIntBytes: PUBLIC PROC [stream: STREAM, val: INT, len: ByteCount] ~ { bytes: Basics.LongNumber ~ [li[val]]; IF len>3 THEN IO.PutChar[stream, VAL[bytes.hh]]; IF len>2 THEN IO.PutChar[stream, VAL[bytes.hl]]; IF len>1 THEN IO.PutChar[stream, VAL[bytes.lh]]; IF len>0 THEN IO.PutChar[stream, VAL[bytes.ll]]; }; PutByte: PUBLIC PROC [stream: STREAM, byte: BYTE] ~ { IO.PutChar[stream, VAL[byte]]; }; PutOp: PUBLIC PROC [stream: STREAM, op: Op] ~ { ev: EncodingValue ~ encodingValueFromOp[op]; IF ev IN ShortEncodingValue THEN PutShortOp[stream, ev] ELSE PutLongOp[stream, ev]; }; PutSequence: PUBLIC PROC [stream: STREAM, seq: SequenceType, len: INT] ~ { IF len IN ShortSequenceLength THEN PutShortSequence[stream, seq, len] ELSE PutLongSequence[stream, seq, len]; }; PutInt: PUBLIC PROC [stream: STREAM, n: INT] ~ { IF n IN ShortNumber THEN PutShortNumber[stream, n] ELSE { len: ByteCount ~ BytesInInt[n]; PutShortSequence[stream, sequenceInteger, len]; PutIntBytes[stream: stream, val: n, len: len]; }; }; PutRational: PUBLIC PROC [stream: STREAM, n, d: INT] ~ { len: ByteCount ~ MAX[BytesInInt[n], BytesInInt[d]]; PutShortSequence[stream, sequenceRational, len+len]; PutIntBytes[stream: stream, val: n, len: len]; PutIntBytes[stream: stream, val: d, len: len]; }; tryDecimal: BOOL _ FALSE; tryRational: BOOL _ TRUE; decimalPrecision: NAT _ 6; maxRelativeError: REAL _ 0.00001; PutReal: PUBLIC PROC [stream: STREAM, val: REAL] ~ { r: REAL _ val; n: INT _ 0; d: INT _ 1; IF ABS[r]>INT.LAST THEN { tail: NAT _ 0; -- number of trailing zero bytes WHILE ABS[r]>INT.LAST DO r _ r/256; tail _ tail+1 ENDLOOP; PutSequence[stream, sequenceInteger, 4+tail]; PutIntBytes[stream: stream, val: Real.RoundLI[r], len: 4]; THROUGH [0..tail) DO IO.PutChar[stream, VAL[0]] ENDLOOP; RETURN; }; IF (n _ Real.RoundLI[r])=r THEN { PutInt[stream, n]; RETURN }; IF tryDecimal THEN { type: Real.NumberType; exp10: INTEGER; [type: type, fr: n, exp10: exp10] _ Real.RealToPair[r: r, precision: decimalPrecision]; IF type=$normal AND exp10 IN[-9..0) THEN { e: NAT _ -exp10; WHILE (n MOD 10)=0 AND e>0 DO n _ n/10; e _ e-1 ENDLOOP; THROUGH [0..e) DO d _ d*10 ENDLOOP; PutRational[stream, n, d]; RETURN; }; }; IF tryRational THEN { rat: IPReal.Rational _ IPReal.RationalFromReal[r]; IF rat.denominator # 0 AND ABS[REAL[rat.numerator]/REAL[rat.denominator] - r] <= maxRelativeError * ABS[r] THEN { IF rat.denominator = 1 THEN PutInt[stream, rat.numerator] ELSE PutRational[stream, rat.numerator, rat.denominator]; RETURN; }; }; THROUGH [0..30) DO r _ r*2; d _ d*2; IF (n _ Real.RoundLI[r])=r THEN EXIT; REPEAT FINISHED => { d _ INT.LAST; n _ Real.RoundLI[d*val] }; ENDLOOP; PutRational[stream, n, d]; }; PutSequenceRope: PUBLIC PROC [stream: STREAM, seq: SequenceType, rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { count: INT _ 0; charAction: Rope.ActionType ~ { IO.PutChar[stream, c]; count _ count+1 }; size: INT ~ Rope.Length[rope]; length: INT ~ MIN[MAX[0, len], Basics.NonNegative[size-Basics.NonNegative[start]]]; PutSequence[stream, seq, length]; [] _ Rope.Map[base: rope, start: start, len: length, action: charAction]; IF count#length THEN ERROR Error[[code: $bug, explanation: "Bug in PutSequenceRope."]]; }; PutSequenceText: PUBLIC PROC [stream: STREAM, seq: SequenceType, text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ MaxTextLen] ~ { length: INT ~ MIN[len, NAT[text.length-start]]; PutSequence[stream, seq, length]; IO.PutBlock[self: stream, block: text, startIndex: start, count: length]; }; PutIdentifier: PUBLIC PROC [stream: STREAM, rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { ValidateIdentifier[rope, start, len]; PutSequenceRope[stream, sequenceIdentifier, rope, start, len]; }; PutString: PUBLIC PROC [stream: STREAM, rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { ValidateString[rope, start, len]; PutSequenceRope[stream, sequenceString, rope, start, len]; }; PutName: PUBLIC PROC [stream: STREAM, rope: ROPE, start: INT _ 0, len: INT _ MaxLen] ~ { count: INT _ 0; namePart: PartActionType ~ { PutIdentifier[stream, base, start, len]; count _ count+1 }; [] _ MapParts[base: rope, start: start, len: len, delimiter: '/, action: namePart]; PutInt[stream, count]; PutOp[stream, makevec]; }; GetToken: PUBLIC PROC [encoding: ROPE, start: INT] RETURNS [token: Token, next: INT] ~ { token _ []; next _ start; { GetByte: PROC RETURNS [BYTE] ~ INLINE { i: INT ~ next; next _ i+1; RETURN[ORD[CHAR[Rope.Fetch[encoding, i]]]]; }; b0: BYTE ~ GetByte[]; SELECT b0 FROM <200B => { token.num _ ShortNumber.FIRST+(b0*400B+GetByte[]); token.type _ num}; <240B => { token.op _ VAL[b0 MOD 40B]; token.type _ op}; <300B => { token.op _ VAL[(b0 MOD 40B)*400B+GetByte[]]; token.type _ op}; <340B => { token.seq _ VAL[b0 MOD 40B]; token.len _ GetByte[]; token.type _ seq}; ENDCASE => { long: Basics.LongNumber _ [li[0]]; long.hl _ GetByte[]; long.lh _ GetByte[]; long.ll _ GetByte[]; token.seq _ VAL[b0 MOD 40B]; token.len _ long.li; token.type _ seq}; }; }; SkipToEndOfBody: PUBLIC PROC [encoding: ROPE, start: INT] RETURNS [next: INT] ~ { next _ start; DO token: Token; [token, next] _ GetToken[encoding, next]; next _ next+token.len; SELECT token.op FROM beginBody => next _ SkipToEndOfBody[encoding, next]; endBody => EXIT; ENDCASE; ENDLOOP; }; GetSequenceRope: PUBLIC PROC [encoding: ROPE, start, len: INT] RETURNS [rope: ROPE, next: INT] ~ { rope _ Rope.Substr[encoding, start, len]; next _ start+len; DO peekToken: Token; peekStart: INT; [peekToken, peekStart] _ GetToken[encoding, next]; IF peekToken.seq=sequenceContinued THEN { rope _ Rope.Concat[rope, Rope.Substr[encoding, peekStart, peekToken.len]]; next _ peekStart+peekToken.len; } ELSE EXIT; ENDLOOP; }; GetSkeleton: PUBLIC PROC [master: ROPE, start: INT] RETURNS [IPMaster.SkeletonRecord] ~ { RETURN [IPSkeleton.GetSkeleton[master, start].skeleton^]}; IntFromLong: PROC [long: Basics.LongNumber] RETURNS [INT] ~ INLINE { RETURN [long.li] }; IntFromSequenceData: PUBLIC PROC [text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST] RETURNS [INT] ~ { b: ARRAY [0..4) OF BYTE _ ALL[0]; j: NAT _ 4; len _ MIN[len, NAT[text.length-start]]; FOR i: NAT DECREASING IN[start..start+len) DO b[j _ j-1] _ ORD[text[i]]; ENDLOOP; IF b[j] >= 200B THEN {WHILE j > 0 DO b[j _ j-1] _ 377B ENDLOOP}; RETURN [IntFromLong[[bytes[hh: b[0], hl: b[1], lh: b[2], ll: b[3]]]]]; }; RealFromSequenceData: PUBLIC PROC [text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST] RETURNS [val: REAL _ 0] ~ { len _ MIN[len, NAT[text.length-start]]; IF ORD[text[start]]<200B THEN { FOR i: NAT IN[start..start+len) DO val _ Real.FScale[val, 8]+ORD[text[i]] ENDLOOP; } ELSE { FOR i: NAT IN[start..start+len) DO val _ Real.FScale[val, 8]+(377B-ORD[text[i]]) ENDLOOP; val _ -1-val; }; }; END. vIPMasterImpl.mesa Copyright c 1984, 1985, 1986 by Xerox Corporation. All rights reserved. Michael Plass, November 15, 1985 2:13:48 pm PST Doug Wyatt, May 17, 1986 2:59:41 pm PDT Allan H. Wax November 24, 1986 2:41:18 pm PST Appends a Number literal. Chooses a rational approximation if necessary. PutBits: PUBLIC PROC [stream: STREAM, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT] ~ { scanBytes: NAT ~ 4*((fSize+31)/32); -- bytes per output scan line block: REF TEXT ~ NEW[TEXT[scanBytes]]; -- scan line buffer length: INT ~ LONG[4]+LONG[scanBytes]*LONG[sSize]; -- length of token data bbspace: PrincOps.BBTableSpace; bb: PrincOps.BitBltTablePtr; PutDescriptor[stream, sequencePackedPixelVector, length]; PutSigned[stream, 2, 1]; -- BitsPerSample PutSigned[stream, 2, fSize]; -- ScanLength TRUSTED { bb _ PrincOpsUtils.AlignedBBTable[@bbspace]; bb^ _ [dst: [word: NIL, bit: 0], dstBpl: 0, src: [word: NIL, bit: 0], srcDesc: [srcBpl[0]], width: 0, height: 0, flags: [disjoint: TRUE, gray: FALSE]]; bb.dst.word _ LOOPHOLE[block, LONG POINTER]+SIZE[TEXT[0]]; bb.dstBpl _ scanBytes*Basics.bitsPerByte; bb.src.word _ base+Basics.LongMult[sMin, wordsPerLine]+fMin/Basics.bitsPerWord; bb.src.bit _ fMin MOD Basics.bitsPerWord; bb.srcDesc.srcBpl _ wordsPerLine*Basics.bitsPerWord; bb.width _ fSize; bb.height _ 1; PrincOpsUtils.LongZero[where: bb.dst.word, nwords: scanBytes/2]; }; THROUGH [0..sSize) DO TRUSTED { PrincOpsUtils.BITBLT[bb] }; IO.PutBlock[self: stream, block: block, startIndex: 0, count: scanBytes]; TRUSTED { bb.src.word _ bb.src.word+wordsPerLine }; ENDLOOP; }; IF j = 0 THEN EXIT; bounds fault without this Κ=˜code™Kšœ Οmœ=™HKšœ,Οk™/Kšœ$ž™'Kšœ-™-—K˜šž ˜ Kšœžœžœžœ:˜RKšœžœ˜Kšžœžœžœ˜%Kšœ žœ˜Kšœ ˜ Kšœžœ˜*Kšœžœ+˜5Kšœžœ2žœ ˜JKšœžœ˜)—K˜KšΡbln œžœž˜Kšžœžœ ˜CKšžœ ˜Kšœžœžœ ˜K˜Kšžœžœ žœ˜Kšžœžœ žœ˜Kšžœžœžœ˜Kšžœžœžœžœ˜K˜KšΟnœžœžœžœ˜.K˜Kš œžœžœžœ'˜DKš œžœžœžœ5˜`Kš  œžœžœžœ1˜XKš  œžœžœžœ/˜Tš œžœžœžœ2˜ZK˜—K˜Kšœ žœžœžœ˜,š œžœžœžœžœ˜7K˜—šœ žœ˜5Kšœ ˜ Kšœ?˜?Kšœ4˜4KšœP˜PKšœR˜RKšœ7˜7Kšœ-˜-Kšœ%˜%Kšœ(˜(Kšœ?˜?Kšœ'˜'Kšœ;˜;Kšœ(˜(Kšœ˜KšœQ˜QKšœ;˜;KšœT˜TKšœC˜CKšœ:˜:Kšœ;˜;Kšœ/˜/KšœG˜GKšœU˜UKšœC˜CKšœK˜KKšœ4˜4Kšœ=˜=Kšœ=˜=Kšœ?˜?KšœT˜TKšœ9˜9Kšœ8˜8Kšœ(˜(Kšœ=˜=KšœI˜IKšœU˜UKšœP˜PKšœ(˜(KšœT˜TKšœ˜K˜—Kšœ žœžœžœ˜,š œžœžœžœžœ˜7K˜—šœD˜DK˜—š œžœ!žœ˜KKšœžœžœžœ˜GKšžœžœžœ3žœ˜NKšžœ˜K˜K˜—š œžœžœ žœ˜EKšžœ˜ K˜K˜—š œžœžœžœ ˜EKšžœ˜ K˜K˜—š  œžœžœžœ˜/Kšžœ˜K˜K˜—K˜Kšœžœžœ˜!šœžœžœžœ˜6K˜—šœ žœžœžœ˜BKšœG˜GKšœ9˜9KšœW˜WKšœ4˜4Kšœ&˜&KšœA˜AKšœ3˜3Kšœ+˜+Kšœ.˜.Kšœ˜Kšœ/˜/Kšœ/˜/KšœC˜CKšœ0˜0Kšœ,˜,KšœK˜KKšœC˜CKšœM˜MKšœ2˜2KšœN˜NKšœ)˜)Kšœ?˜?Kšœ1˜1KšœK˜KKšœG˜GKšœK˜KKšœ8˜8Kšœ>˜>Kšœ8˜8Kšœ˜KšœA˜AKšœC˜CKšœ?˜?Kšœ@˜@Kšœ˜Kšœ<˜K˜K˜—š   œžœžœžœ žœ žœ˜MKšœžœ˜KšœU˜UKšœS˜SKšžœ žœ˜.K˜K˜—š  œžœžœžœ žœ žœ˜OKšœ9˜9Kšœžœ ˜šœ˜šžœž˜Kšœžœ žœ˜&Kšœ žœ žœžœ ˜;Kš œ žœ žœžœžœ˜=Kšœ žœ žœžœ˜BKš œ žœ žœžœžœ˜?Kšžœ.˜5—K˜K˜—šžœBž˜HKšœ=˜=—Kšžœ žœžœž˜(KšžœC˜GK˜K˜—š  œžœžœ žœ žœ˜HKšœžœ˜Kšœ1žœžœžœ ˜TšžœBž˜HKšœ@˜@—Kšžœ žœ1˜@K˜K˜—š  œžœžœžœ žœ žœ˜PKšœžœ˜KšœT˜TKšœV˜Všžœž˜Kšœ0˜0Kšœ2˜2Kšœžœ˜ Kšžœ9˜@—K˜K˜—š œžœžœžœ žœ žœ žœ˜lKšœžœ˜šœ˜Kšœžœ6˜>Kš žœžœžœžœžœ3˜Nšžœž˜Kšœ˜Kšœ˜Kšžœ#˜*—K˜Kšœ˜—K˜"KšœV˜VKšžœ žœ ˜/K˜K˜—š œžœžœžœ˜Kšžœ ž˜Kšœ žœ˜Kšœ žœ ˜šžœžœ ž˜Kšœ žœ˜Kšœ žœ ˜Kšžœžœ˜——K˜K˜—K˜š œžœžœ žœ˜@Kšœžœ˜%Kšžœžœ ˜ Kšžœžœžœ˜$K˜K˜—š  œžœžœ žœ˜DKšœžœ˜Kšžœžœ ˜ K˜K˜—š  œžœžœ žœ˜>Kšœžœ˜Kšžœžœ˜%Kšžœžœžœ˜$K˜K˜—š œžœžœ žœ2˜`Kšœžœ˜Kšžœžœ ˜ Kšžœžœ˜K˜K˜—š œžœžœ žœ1˜^Kšœžœ˜Jšœ(‘˜7Jšœžœ˜%Kšžœžœ ˜ Kšžœžœ˜Kšžœžœ ˜#Kšžœžœžœ˜'K˜K™—š   œžœžœžœžœ˜:Kš œžœžœžœ žœ˜*šžœž˜ Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšžœžœ˜—K˜K˜—š   œžœžœ žœžœ˜GKšœ%˜%Kšžœžœžœžœ ˜0Kšžœžœžœžœ ˜0Kšžœžœžœžœ ˜0Kšžœžœžœžœ ˜0K˜K˜—š  œžœžœ žœžœ˜5Kšžœžœ˜K˜K˜—K˜š œžœžœ žœ ˜/K˜,Kšžœžœžœ˜7Kšžœ˜K˜K˜—š   œžœžœ žœžœ˜JKšžœžœžœ#˜EKšžœ#˜'K˜K˜—š  œžœžœ žœžœ˜0Kšžœžœ žœ˜2šžœ˜Kšœ˜Kšœ/˜/Kšœ.˜.K˜—K˜K˜—š   œžœžœ žœžœ˜8Kšœžœ˜3Kšœ4˜4Kšœ.˜.Kšœ.˜.K˜K˜—Kšœ žœžœ˜Kšœ žœžœ˜Kšœžœ˜šœžœ ˜!K˜—š  œžœžœ žœžœ˜4K™HKšœžœ˜Kšœžœ žœ˜š žœžœžœžœžœ˜Kšœžœ‘ ˜/Kš žœžœžœžœžœžœ˜:Kšœ-˜-Kšœ:˜:Kš žœ žœžœžœžœ˜8Kšžœ˜K˜—Kšžœžœžœ˜>šžœ žœ˜Kšœžœ˜&KšœW˜Wšžœžœžœžœ˜*Kšœžœ ˜Kš žœžœžœžœžœ˜8Kšžœžœ žœ˜#Kšœžœ˜"K˜—K˜—šžœ žœ˜Kšœ2˜2šžœžœžœžœžœ-žœžœ˜qKšžœžœ˜9Kšžœ5˜9Kšžœ˜K˜—K˜—šžœ ž˜Kšœ˜Kšžœžœžœ˜%Kšžœžœ žœžœ˜=Kšžœ˜—Kšœ˜K˜K˜—š œžœžœ žœžœ žœ žœ˜tKšœžœ˜Kšœ žœ'˜IKšœžœ˜Kšœžœžœžœ>˜SKšœ!˜!KšœI˜IKšžœžœžœ=˜WK˜K˜—š œžœžœ žœžœžœžœ žœ žœ˜…Kšœžœžœžœ˜/Kšœ!˜!KšžœG˜IK˜K˜—š  œžœžœ žœžœ žœ žœ˜^Kšœ%˜%Kšœ>˜>K˜K˜—š  œžœžœ žœžœ žœ žœ˜ZKšœ!˜!Kšœ:˜:K˜K˜—š œžœžœ žœžœ žœ žœ˜XKšœžœ˜KšœX˜XKšœS˜SKšœ.˜.K˜K˜—š œžœžœ žœ žœžœžœžœ™pKšœ žœ‘™AKš œžœžœžœžœ‘™;Kš œžœžœžœ žœ ‘™JK™Kšœ™Kšœ9™9Kšœ‘™)Kšœ‘ ™*šžœ™ Kšœ,™,Kš œžœ"žœIžœžœ™˜Kš œžœžœžœžœžœ™:Kšœ)™)KšœO™OKšœžœ™)Kšœ4™4Kšœ™Kšœ™Kšœ@™@Kšœ™—šžœ ž™Kšžœžœ™%KšžœG™IKšžœ,™3Kšžœ™—K™K™—K˜š œžœžœ žœ žœžœžœ˜XKšœ ˜ Kšœ ˜ ˜š  œžœžœžœžœ˜'Kš œžœžœžœžœ˜FK˜—Kšœžœ ˜šžœž˜˜ Kšœžœ˜2Kšœ˜—˜ Kšœ žœžœ˜K˜—˜ Kšœ žœžœ˜,K˜—˜ Kšœ žœžœ˜Kšœ˜K˜—šžœ˜ Kšœ"˜"Kšœ˜Kšœ˜Kšœ˜Kšœ žœžœ˜Kšœ˜K˜—K˜——K˜K˜—š œžœžœ žœ žœžœžœ˜QK˜ šžœ˜Kšœ)˜)K˜šžœ ž˜Kšœ4˜4Kšœ žœ˜Kšžœ˜—Kšžœ˜—K˜K˜—š œžœžœ žœžœžœžœžœ˜cK˜)K˜šžœžœ˜$Kšœ2˜2šžœ!žœ˜)KšœJ˜JKšœ˜K˜—Kšžœžœ˜ Kšžœ˜—K˜K˜—š   œžœžœ žœ žœžœ˜ZKšžœ4˜:K˜—š   œžœžœžœžœ˜DKšžœ ˜Kšœ˜K˜—š œžœžœžœžœžœ žœ žœžœžœžœžœ˜rKš œžœžœžœžœ˜!Kšœžœ˜ Kšœžœžœ˜'š žœžœž œžœž˜-Kšœ žœ ˜Kšžœžœžœ™-Kšžœ˜—Jš žœžœžœžœžœ˜@Kšžœ@˜FK˜K™—š œžœžœžœžœžœ žœ žœžœžœžœžœ ˜}Kšœžœžœ˜'šžœžœžœ˜Kš žœžœžœžœžœ žœ˜RK˜—šžœ˜Kš žœžœžœžœ!žœ žœ˜YKšœ ˜ K˜—K˜K˜—Kšžœ˜—…—R˜qK