DIRECTORY FS USING [StreamOpen], Imager USING [Context, ContextRep, DoSave, DoSaveAll, ShowText], ImagerFont USING [MapText, XStringProc], Interpress USING [classMasterError, classMasterWarning, LogProc, Master, MasterImplRep, MasterRep, Credentials, Instructions], IO USING [int, PutFR1, STREAM], IPExecute USING [defaultMaxStackLength], IPInterpreter USING [Any, Apply, Array, ArrayFromVector, Cardinal, Context, ContextRep, Count, Get, Mark, Marker, Operator, OperatorClass, OperatorClassRep, OperatorRep, PopToActiveMark, PushIdentifier, PushNum, PushVector, Ref, Rep, StackArrayRep, Unmark, Vector, VectorFromArray, VectorFromBits, VectorFromBytes, VectorFromString, ZeroVec], IPMaster USING [Block, Body, BYTE, GetSkeleton, GetToken, IntFromSequenceData, OpFromEncodingValue, Node, NodeRep, Preamble, RealFromSequenceData, SequenceType, Skeleton, SkeletonRecord, SkipBytes, SkipToEndOfBody, Token, Vector], RefText USING [ReserveChars], Rope USING [AppendChars, Concat, Fetch, FromRefText, ROPE, Size, Substr], RopeFile USING [FromStream]; IPExecImpl: CEDAR PROGRAM IMPORTS FS, IO, Imager, ImagerFont, IPInterpreter, IPMaster, RefText, Rope, RopeFile EXPORTS Interpress, IPInterpreter, IPExecute ~ { ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; Token: TYPE ~ IPMaster.Token; Body: TYPE ~ IPMaster.Body; Block: TYPE ~ IPMaster.Block; Node: TYPE ~ IPMaster.Node; NodeRep: TYPE ~ IPMaster.NodeRep; BYTE: TYPE ~ IPMaster.BYTE; MarkRecovery: PUBLIC ERROR ~ CODE; Bug: PUBLIC ERROR ~ CODE; contextFreeCountMax: INT _ 8; AllocContext: PROC [self: IPInterpreter.Ref] RETURNS [context: IPInterpreter.Context] ~ { IF self.contextFreeCount>0 THEN { context _ self.contextFree; self.contextFree _ context.caller; self.contextFreeCount _ self.contextFreeCount-1} ELSE context _ NEW [IPInterpreter.ContextRep]; }; FreeContext: PROC [self: IPInterpreter.Ref, context: IPInterpreter.Context] ~ { IF self.contextFreeCount { self.context _ context.caller; FreeContext[self, context] }]; IF self.context=context THEN { self.context _ context.caller; FreeContext[self, context] } ELSE ERROR Bug; }; Frame: PUBLIC PROC[self: IPInterpreter.Ref] RETURNS[IPMaster.Vector] ~ { context: IPInterpreter.Context ~ self.context; IF context.frame=NIL THEN RETURN[context.initialFrame] ELSE RETURN[IPInterpreter.VectorFromArray[context.frame]]; }; FGet: PUBLIC PROC[self: IPInterpreter.Ref, i: IPInterpreter.Cardinal] RETURNS[IPInterpreter.Any] ~ { context: IPInterpreter.Context ~ self.context; IF context.frame=NIL THEN RETURN[IPInterpreter.Get[context.initialFrame, i]] ELSE { array: IPInterpreter.Array ~ context.frame; RETURN[array[i-array.lowerBound]] }; }; FSet: PUBLIC PROC[self: IPInterpreter.Ref, x: IPInterpreter.Any, i: IPInterpreter.Cardinal] ~ { context: IPInterpreter.Context ~ self.context; IF context.frame=NIL THEN context.frame _ IPInterpreter.ArrayFromVector[context.initialFrame]; { array: IPInterpreter.Array ~ context.frame; array[i-array.lowerBound] _ x }; }; Env: PUBLIC PROC[self: IPInterpreter.Ref] RETURNS[IPMaster.Vector] ~ {RETURN[self.context.env]}; DoSave: PUBLIC PROC[self: IPInterpreter.Ref, action: PROC] ~ { Imager.DoSave[self.imager, action]; }; DoSaveAll: PUBLIC PROC[self: IPInterpreter.Ref, action: PROC] ~ { Imager.DoSaveAll[self.imager, action]; }; Run: TYPE ~ RECORD[start, len: INT]; RunList: TYPE ~ LIST OF Run; DoString: PROC [self: IPInterpreter.Ref, text: REF TEXT] ~ { string: ImagerFont.XStringProc ~ { ImagerFont.MapText[text: text, charAction: charAction] }; IPInterpreter.PushVector[self, IPInterpreter.VectorFromString[string]]; }; DoIdentifier: PROC [self: IPInterpreter.Ref, text: REF TEXT] ~ { len: NAT ~ text.length; warn: BOOL _ FALSE; FOR i: NAT IN[0..len) DO char: CHAR ~ text[i]; SELECT char FROM IN['a..'z], IN['A..'Z] => NULL; IN['0..'9], '- => IF i=0 THEN warn _ TRUE; ENDCASE => warn _ TRUE; ENDLOOP; IF len=0 THEN warn _ TRUE; IPInterpreter.PushIdentifier[self, Rope.FromRefText[text]]; IF warn THEN MasterWarning[$invalidEncoding, "Invalid Identifier"]; }; DoCardinal: PROC [self: IPInterpreter.Ref, text: REF TEXT] ~ { len: NAT ~ text.length; IF len<=4 THEN { val: INT ~ IPMaster.IntFromSequenceData[text]; IPInterpreter.PushNum[self, [int[val]]]} ELSE { val: REAL ~ IPMaster.RealFromSequenceData[text]; IPInterpreter.PushNum[self, [real[val]]]}; }; DoRational: PROC [self: IPInterpreter.Ref, text: REF TEXT] ~ { len: NAT ~ text.length; half: NAT ~ len/2; IF half<=4 THEN { n: INT ~ IPMaster.IntFromSequenceData[text: text, start: 0, len: half]; d: INT ~ IPMaster.IntFromSequenceData[text: text, start: half, len: half]; IF n IN INTEGER AND d IN INTEGER THEN IPInterpreter.PushNum[self, [rational[n: n, d: d]]] ELSE IPInterpreter.PushNum[self, [real[REAL[n]/REAL[d]]]]} ELSE { n: REAL ~ IPMaster.RealFromSequenceData[text: text, start: 0, len: half]; d: REAL ~ IPMaster.RealFromSequenceData[text: text, start: half, len: half]; IPInterpreter.PushNum[self, [real[n/d]]]}; IF (half+half)#len THEN MasterWarning[$invalidEncoding, IO.PutFR1["Invalid sequenceRational (length=%g)", IO.int[len]]]; }; DoInsertFile: PROC [self: IPInterpreter.Ref, text: REF TEXT] ~ { MasterWarning[$unimplemented, "sequenceInsertFile found after PreScanning"]; }; Fetch16: PROC [rope: ROPE, startByte: INT] RETURNS [CARDINAL] ~ { b0: CARDINAL ~ Rope.Fetch[rope, startByte]-'\000; b1: CARDINAL ~ Rope.Fetch[rope, startByte+1]-'\000; RETURN [b0*256+b1]; }; RopeFromRuns: PROC [ropeChunk: ROPE, runs: LIST OF Run, sequenceLength: INT] RETURNS [rope: ROPE _ NIL] ~ { FOR r: LIST OF Run _ runs, r.rest UNTIL r = NIL DO run: Run _ r.first; rope _ Rope.Concat[rope, Rope.Substr[ropeChunk, run.start, run.len]]; ENDLOOP; IF Rope.Size[rope] # sequenceLength THEN ERROR; }; ExecuteToEndOfBody: PROC [self: IPInterpreter.Ref] ~ { sequenceData: {nil, text, runs, skip} _ nil; sequenceType: IPMaster.SequenceType _ nil; sequenceLength: INT _ 0; sequenceRuns: INT _ 0; text: REF TEXT _ NIL; buffer: REF TEXT ~ self.buffer; runsHead, runsTail: LIST OF Run _ NIL; token: IPMaster.Token; BeginSequence: PROC [seq: IPMaster.SequenceType] ~ { SELECT sequenceType _ seq FROM sequenceString, sequenceIdentifier, sequenceInsertFile, sequenceComment, sequenceInteger, sequenceRational => sequenceData _ text; sequenceLargeVector, sequencePackedPixelVector, sequenceCompressedPixelVector, sequenceAdaptivePixelVector => sequenceData _ runs; ENDCASE => sequenceData _ skip; SELECT sequenceData FROM text => { text _ buffer; text.length _ 0 }; runs => { runsHead _ runsTail _ NIL }; ENDCASE; sequenceLength _ 0; }; ExtendSequence: PROC [length: INT] ~ { SELECT sequenceData FROM nil => { MasterWarning[$invalidEncoding, "Misplaced sequenceContinued"]; self.index _ IPMaster.SkipBytes[self.rope, self.index, length]}; text => { len: NAT ~ length; IF (text.maxLength-text.length) < len THEN text _ RefText.ReserveChars[text, len]; [] _ Rope.AppendChars[buffer: text, rope: self.rope, start: self.index, len: len]; self.index _ IPMaster.SkipBytes[self.rope, self.index, length] -- This wasn't here before -- }; runs => { prevTail: LIST OF Run ~ runsTail; runsTail _ LIST[[start: self.index, len: length]]; IF prevTail=NIL THEN runsHead _ runsTail ELSE prevTail.rest _ runsTail; self.index _ IPMaster.SkipBytes[self.rope, self.index, length]}; skip => self.index _ IPMaster.SkipBytes[self.rope, self.index, length]; ENDCASE => ERROR; sequenceRuns _ sequenceRuns+1; sequenceLength _ sequenceLength+length; }; FinishSequence: PROC ~ { SELECT sequenceType FROM sequenceString => DoString[self, text]; sequenceIdentifier => DoIdentifier[self, text]; sequenceInteger => DoCardinal[self, text]; sequenceRational => DoRational[self, text]; sequenceInsertFile => DoInsertFile[self, text]; sequenceComment => NULL; sequenceLargeVector => { rope: ROPE ~ RopeFromRuns[self.rope, runsHead, sequenceLength]; b: NAT ~ Rope.Fetch[rope, 0]-'\000; vector: IPMaster.Vector ~ IPInterpreter.VectorFromBytes[bytes: Rope.Substr[rope, 1], bytesPerElement: b, signed: TRUE]; IPInterpreter.PushVector[self, vector]}; sequencePackedPixelVector => { rope: ROPE ~ RopeFromRuns[self.rope, runsHead, sequenceLength]; bitsPerSample: [1..1] ~ Fetch16[rope, 0]; -- only one bit per sample supported here scanLength: NAT ~ Fetch16[rope, 2]; dataBitsPerLine: NAT ~ bitsPerSample*scanLength; padBitsPerLine: NAT ~ NAT[32 - (dataBitsPerLine MOD 32)] MOD 32; vector: IPMaster.Vector ~ IPInterpreter.VectorFromBits[bytes: Rope.Substr[rope, 4], dataBitsPerLine: dataBitsPerLine, padBitsPerLine: padBitsPerLine]; IPInterpreter.PushVector[self, vector]}; sequenceCompressedPixelVector => MasterWarning[$unimplemented, "Not implemented: sequenceCompressedPixelVector"]; sequenceAdaptivePixelVector => MasterWarning[$unimplemented, "Not implemented: sequenceAdaptivePixelVector"]; sequenceContinued => MasterWarning[$invalidEncoding, "Misplaced sequenceContinued"]; ENDCASE => MasterWarning[$invalidEncoding, IO.PutFR1["Invalid sequence type (%g)", IO.int[ORD[sequenceType]]]]; sequenceData _ nil; sequenceType _ nil; }; DO -- for each Token [token, self.index] _ IPMaster.GetToken[encoding: self.rope, start: self.index]; IF token.seq=sequenceContinued THEN { ExtendSequence[token.len]; LOOP }; self.context.token _ token; IF sequenceType=sequenceString THEN { done: BOOL _ TRUE; SELECT token.op FROM show => Imager.ShowText[context: self.imager, text: text]; showandxrel => Imager.ShowText[context: self.imager, text: text, xrel: TRUE]; ENDCASE => done _ FALSE; IF done THEN { sequenceData _ nil; sequenceType _ nil; LOOP }}; IF sequenceData#nil THEN FinishSequence[]; IF token.op=endBody THEN EXIT; SELECT token.type FROM op => IPInterpreter.Apply[self, IPMaster.OpFromEncodingValue[token.op]]; num => IPInterpreter.PushNum[self, [int[token.num]]]; seq => { BeginSequence[token.seq]; ExtendSequence[token.len] }; ENDCASE => ERROR; ENDLOOP }; BeginBody: PROC [self: IPInterpreter.Ref] RETURNS [INT] ~ { [self.context.token, self.index] _ IPMaster.GetToken[self.rope, self.index]; IF self.context.token.op # beginBody THEN MasterError[$missingBody, "Missing body"]; RETURN[self.index]; }; SkipInlineBody: PUBLIC PROC [self: IPInterpreter.Ref] ~ { self.index _ BeginBody[self]; self.index _ IPMaster.SkipToEndOfBody[self.rope, self.index]; }; GetInlineBody: PUBLIC PROC [self: IPInterpreter.Ref] RETURNS [IPMaster.Body] ~ { start, stop: INT _ 0; start _ self.index; self.index _ BeginBody[self]; stop _ self.index _ IPMaster.SkipToEndOfBody[self.rope, self.index]; RETURN[Rope.Substr[self.rope, start, stop-start]]; }; ExecuteInlineBody: PROC [self: IPInterpreter.Ref] ~ { self.index _ BeginBody[self]; DO error: BOOL _ FALSE; ExecuteToEndOfBody[self ! MarkRecovery => { error _ TRUE; CONTINUE }]; IF error THEN { -- do mark recovery marker: IPInterpreter.Marker ~ IPInterpreter.PopToActiveMark[self]; IF marker=self.context.marker THEN { token: IPMaster.Token; DO [token, self.index] _ IPMaster.GetToken[self.rope, self.index]; SELECT token.op FROM endBody => ERROR MarkRecovery; -- end of body beginBody => self.index _ IPMaster.SkipToEndOfBody[self.rope, self.index]; -- skip body literal unmark0 => EXIT; -- found UNMARK0 ENDCASE => NULL; IF token.type=seq THEN self.index _ IPMaster.SkipBytes[self.rope, self.index, token.len]; ENDLOOP} ELSE ERROR MarkRecovery; -- not this context's marker } ELSE EXIT; -- normal completion ENDLOOP; }; CallInlineBody: PUBLIC PROC [self: IPInterpreter.Ref, frame, env: IPMaster.Vector] ~ { action: PROC ~ { ExecuteInlineBody[self] }; Call[self: self, action: action, frame: frame, env: env]; }; CallBody: PROC [self: IPInterpreter.Ref, body: IPMaster.Body, frame: IPMaster.Vector, env: IPMaster.Vector] ~ { saveBody: ROPE ~ self.rope; saveIndex: INT ~ self.index; self.rope _ body; self.index _ 0; CallInlineBody[self: self, frame: frame, env: env ! UNWIND => {self.rope _ saveBody; self.index _ saveIndex}]; self.rope _ saveBody; self.index _ saveIndex; }; DoWithMarkProtection: PUBLIC PROC [self: IPInterpreter.Ref, action: PROC] ~ { error: BOOL _ FALSE; inner: PROC ~ { IPInterpreter.Mark[self, 0]; action[]; IPInterpreter.Unmark[self, 0] }; inner[! MarkRecovery => { error _ TRUE; CONTINUE}]; IF error THEN { -- do mark recovery marker: IPInterpreter.Marker ~ IPInterpreter.PopToActiveMark[self]; IF marker=self.context.marker THEN IPInterpreter.Unmark[self, 0] ELSE ERROR MarkRecovery; }; }; Do: PUBLIC PROC [self: IPInterpreter.Ref, op: IPInterpreter.Operator] ~ { op.class.do[op, self] }; composedClass: IPInterpreter.OperatorClass ~ NEW[IPInterpreter.OperatorClassRep _ [ type: $Composed, do: ComposedDo]]; ComposedData: TYPE ~ REF ComposedDataRep; ComposedDataRep: TYPE ~ RECORD[ frame: IPMaster.Vector, -- initial frame env: IPMaster.Vector, -- environment body: IPMaster.Body -- body of the operator ]; ComposedDo: PROC [op: IPInterpreter.Operator, state: IPInterpreter.Ref] ~ { data: ComposedData ~ NARROW[op.data]; CallBody[self: state, body: data.body, frame: data.frame, env: data.env]; }; MakeCO: PUBLIC PROC [frame, env: IPMaster.Vector, body: IPMaster.Body] RETURNS [IPInterpreter.Operator] ~ { data: ComposedData ~ NEW[ComposedDataRep _ [frame: frame, env: env, body: body]]; RETURN[NEW[IPInterpreter.OperatorRep _ [class: composedClass, data: data]]]; }; CallPreamble: PUBLIC PROC [self: IPInterpreter.Ref, preamble: IPMaster.Preamble, frame, env: IPMaster.Vector] ~ { IF preamble # NIL THEN { preambleProc: PROC ~ { IPInterpreter.Mark[self, 0]; ExecuteInlineBody[self]; IF IPInterpreter.Count[self]<1 THEN IPInterpreter.PushVector[self, Env[self]]; IF IPInterpreter.Count[self]<2 THEN IPInterpreter.PushVector[self, Frame[self]]; IPInterpreter.Unmark[self, 2]}; IF preamble.initialFrame = NIL THEN { oldSource: ROPE = self.rope; oldIndex: INT = self.index; self.rope _ preamble.source; self.index _ 0; self.topFrame _ frame; self.topEnv _ env; Call[self: self, action: preambleProc, frame: frame, env: env]; self.rope _ oldSource; self.index _ oldIndex; preamble.initialFrame _ self.topFrame} ELSE self.topFrame _ preamble.initialFrame} ELSE ERROR; }; CallNode: PUBLIC PROC [self: IPInterpreter.Ref, node: Node, frame, env: IPMaster.Vector] ~ { WITH node SELECT FROM node: REF NodeRep.body => { self.rope _ node.body; self.index _ 0; CallInlineBody[self: self, frame: frame, env: env]}; -- May have to save old self values ENDCASE => ERROR; }; Master: TYPE ~ Interpress.Master; MasterRep: TYPE ~ Interpress.MasterRep; MasterImpl: TYPE ~ REF MasterImplRep; MasterImplRep: PUBLIC TYPE ~ RECORD [ -- exported to Interpress skeleton: IPMaster.Skeleton, interpreter: IPInterpreter.Ref ]; LogProc: TYPE ~ Interpress.LogProc; Error: SIGNAL [class: INT, code: ATOM, explanation: ROPE] ~ CODE; ReportError: PUBLIC PROC [class: INT, code: ATOM, explanation: ROPE] ~ { SIGNAL Error[class: class, code: code, explanation: explanation]; IF class=Interpress.classMasterError THEN ERROR MarkRecovery; }; MasterError: PUBLIC PROC [code: ATOM, explanation: ROPE] ~ { ReportError[class: Interpress.classMasterError, code: code, explanation: explanation]; }; MasterWarning: PUBLIC PROC [code: ATOM, explanation: ROPE _] ~ { ReportError[class: Interpress.classMasterWarning, code: code, explanation: explanation]; }; DoTopAction: PUBLIC PROC [self: IPInterpreter.Ref, action: PROC, log: LogProc] ~ { protect: PROC ~ { DoWithMarkProtection[self, action] }; call: PROC ~ { Call[self, protect, IPInterpreter.ZeroVec[0], IPInterpreter.ZeroVec[0]] }; save: PROC ~ { IF self.imager=NIL THEN call[] ELSE DoSaveAll[self, call] }; save[! Error => { IF log#NIL THEN {log[class, code, explanation]; RESUME} ELSE REJECT }]; }; Open: PUBLIC PROC [fileName: ROPE, log: LogProc, credentials: Interpress.Credentials _ NIL, instructionsHandle: Interpress.Instructions _ NIL] RETURNS [Master] ~ { RETURN [FromStream[FS.StreamOpen[fileName], log]]; }; FromStream: PUBLIC PROC [stream: STREAM, log: LogProc, credentials: Interpress.Credentials _ NIL, instructionsHandle: Interpress.Instructions _ NIL] RETURNS [Master] ~ { skeleton: IPMaster.Skeleton _ NEW[IPMaster.SkeletonRecord _ IPMaster.GetSkeleton[master: RopeFile.FromStream[stream], start: 0]]; self: IPInterpreter.Ref ~ NEW[IPInterpreter.Rep -- _ [stream: stream] --]; impl: MasterImpl ~ NEW[MasterImplRep _ [skeleton: skeleton, interpreter: self]]; master: Master ~ NEW[MasterRep _ [pages: skeleton.topBlock.totalPlates, impl: impl]]; self.buffer _ NEW[TEXT[200]]; self.stackArray _ NEW[IPInterpreter.StackArrayRep _ ALL[[zero[]]]]; self.stackCountMax _ IPExecute.defaultMaxStackLength; RETURN[master]; }; BlockForPage: PROC [skeleton: IPMaster.Skeleton, page: INT] RETURNS [block: Block] ~ { FindBlock: PROC [block: Block, page: INT] RETURNS [blockFound: Block _ NIL] ~ { currentPage: INT _ block.startingPlateNumber+1; IF block.startingPlateNumber > page-1 THEN ERROR; IF block.startingPlateNumber+block.totalPlates < page THEN RETURN; FOR i: NAT IN [0..block.size) DO node: Node = block[i]; WITH node SELECT FROM node: REF NodeRep.body => IF currentPage = page THEN RETURN [block] ELSE currentPage _ currentPage+1; node: REF NodeRep.block => IF (blockFound _ FindBlock[node.block, page]) # NIL THEN RETURN ELSE currentPage _ currentPage+node.block.totalPlates; ENDCASE => ERROR; ENDLOOP; ERROR; -- Should never get here }; RETURN [FindBlock[block: skeleton.topBlock, page: page]] }; NodeForPage: PROC [block: Block, page: INT] RETURNS [node: Node] ~ { FindNode: PROC [block: Block, page: INT] RETURNS [nodeFound: Node _ NIL] ~ { currentPage: INT _ block.startingPlateNumber+1; IF block.startingPlateNumber > page-1 THEN ERROR; IF block.startingPlateNumber+block.totalPlates < page THEN RETURN; FOR i: NAT IN [0..block.size) DO node: Node = block[i]; WITH node SELECT FROM node: REF NodeRep.body => IF currentPage = page THEN RETURN [node] ELSE currentPage _ currentPage+1; node: REF NodeRep.block => IF (nodeFound _ FindNode[node.block, page]) # NIL THEN RETURN ELSE currentPage _ currentPage+node.block.totalPlates; ENDCASE => ERROR; ENDLOOP; ERROR; -- Should never get here }; RETURN [FindNode[block: block, page: page]] }; DoPage: PUBLIC PROC [master: Master, page: INT, context: Imager.Context, log: LogProc, copy: INT _ 1] ~ { IF page IN[1..master.pages] THEN { impl: MasterImpl ~ master.impl; block: Block ~ BlockForPage[impl.skeleton, page]; node: Node ~ NodeForPage[block, page]; self: IPInterpreter.Ref ~ impl.interpreter; action: PROC ~ { CallNode[self: self, node: node, frame: self.topFrame, env: self.topEnv] }; self.imager _ context; self.topFrame _ block.preamble.initialFrame; self.topEnv _ block.preamble.environment; DoTopAction[self, action, log]; self.imager _ NIL}; }; Close: PUBLIC PROC [master: Master] ~ { }; }. ΔIPExecImpl.mesa Copyright Σ 1984, 1985, 1986 by Xerox Corporation. All rights reserved. Michael Plass, November 26, 1986 9:35:38 am PST Doug Wyatt, December 3, 1986 5:38:45 pm PST Allan H. Wax December 3, 1986 5:48:11 pm PST Allan Wax: February 4, 1987 10:50:11 am PST Someday, this might worry about pools other than the Imager pool Someday, this might worry about pools other than the Imager pool node: REF NodeRep.block => { block: Block ~ node.block; pageFrame, pageEnv: Vector; CallPreamble[self, block.preamble, frame, env]; pageFrame _ PopVector[self]; pageEnv _ PopVector[self]; FOR i: NAT IN[0..block.size) DO CallNode[self, block[i], pageFrame, pageEnv]; ENDLOOP; }; DoPreamble: PROC [master: Master, log: LogProc] ~ { impl: MasterImpl ~ master.impl; self: IPInterpreter.Ref ~ impl.interpreter; block: Block ~ impl.skeleton.topBlock; action: PROC ~ { CallPreamble[self: self, preamble: block.preamble, frame: iPExecute.topFrame, env: iPExecute.topEnv]; self.topFrame _ IPInterpreter.PopVector[self]; self.topEnv _ IPInterpreter.PopVector[self]; }; DoTopAction[self, action, log]; }; self.imager _ imager; -- -- dummy imager context DoPreamble[master, log]; *** Already done by GetSkeleton *** The requested page is contained within this block The requested page is contained within this block Eventually will use the new structure for the Master which includes a list of SIF/SIM files referenced and delete/flush them after all RopeFile references to them have been un-made. This will preclude using up the cache on Cedar and is necessary for the NS version of the product. ObtainExternalInstructions: PROC [self: Ref] RETURNS [Vector] ~ { RETURN[VectorFromAny[GetP[Env[self], $externalInstructions]]]; }; AddInstructionDefaults: PROC [self: Ref, computedInstructions, externalInstructions: Vector] RETURNS [Vector] ~ { RETURN[computedInstructions] }; ExecuteInstructionsBody: PROC [self: Ref, externalInstructions: Vector] RETURNS [Vector] ~ { body: Index ~ self.skeleton.preamble.instructions; IF body=nullIndex THEN RETURN[externalInstructions] ELSE { reader: Reader ~ NARROW[self.reader]; PushVector[self, externalInstructions]; reader.SetIndex[body]; DoBody[self, NoPool[], initialTopFrame, $saveAll]; WHILE Count[self]>1 DO Apply[self, $mergeprop] ENDLOOP; RETURN[PopVector[self]]; }; }; ComputePrintingInstructions: PROC [self: Ref] ~ { externalInstructions: Vector ~ ObtainExternalInstructions[self]; instructions: Vector _ iPExecute.emptyVector; Mark[self, 0]; instructions _ ExecuteInstructionsBody[self, externalInstructions ! Error => CONTINUE]; Unmark0[self]; instructions _ AddInstructionDefaults[self, instructions, externalInstructions]; self.media _ GetP[instructions, $media]; self.copySelect _ GetP[instructions, $copySelect]; self.pageSelect _ GetP[instructions, $pageSelect]; self.onSimplex _ GetP[instructions, $onSimplex]; self.mediaSelect _ GetP[instructions, $mediaSelect]; self.copyName _ GetP[instructions, $copyName]; self.instructions _ instructions; }; Κj˜codešœ…Οkœ)™΄Kšœ)™,Kšœ+™+—K˜š ˜ Kšœœ˜Kšœœ4˜@Kšœ œ˜(Kšœ œn˜~Kšœœœ˜Kšœ œ˜(KšœœΓ˜ΦKšœ œœΕ˜ζKšœœ˜Kšœœ+œ˜IKšœ œ˜K˜—šΟn œœ˜KšœœœF˜TKšœ%˜,K˜K˜Kšœœœ˜Kšœœœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœ œ˜!Kšœœ œ˜K˜Kšž œœœœ˜"Kšžœœœœ˜K˜Kšœœ˜K˜šž œœœ%˜Yšœœ˜!K˜K˜"K˜0—Kšœ œ˜.K˜—K˜šž œœ>˜Ošœ+œ˜3K˜"Kšœœ˜Kšœœ˜Kšœœ˜K˜K˜1—K˜—K˜šžœœœ"œ"˜YK˜4˜=Kšœ'œ ˜6—K˜!K˜Kšœ œC˜RKšœœ>˜ZKšœœ˜K˜—K˜šžœœœœ˜HK˜.Kšœœœœ˜6Kšœœ/˜:K˜—K˜šžœœœ5œ˜dK˜.Kšœœœœ,˜LKšœ/œ˜WK˜—K˜šžœœœN˜_K˜.KšœœœE˜^K˜NK˜—K˜Kš žœœœœœ˜`K˜šžœœœ"œ˜>Kšœ@™@K˜#K˜—K˜šž œœœ"œ˜AKšœ@™@K˜&K˜—K˜Kšœœœ œ˜$Kšœ œœœ˜K˜šžœœ!œœ˜Kšœœ˜šœœ˜Kšœœ&˜.K˜(—šœ˜Kšœœ'˜0K˜*—K˜—K˜šž œœ!œœ˜>Kšœœ˜Kšœœ ˜K˜šœ œ˜KšœœA˜GKšœœD˜JKšœœœœœœœ4˜YKšœ#œœ˜:—šœ˜KšœœB˜IKšœœE˜LK˜*K˜—šœœ!˜8Kšœ0œ ˜@—K˜—K˜šž œœ!œœ˜@K˜LK˜—K˜š žœœœ œœœ˜AKšœœ%˜1Kšœœ'˜3Kšœ ˜K˜—K˜šž œœ œœœœœœœ˜kš œœœœœ˜2K˜KšœE˜EKšœ˜—Kšœ"œœ˜/K˜—K˜šžœœ˜6K˜,K˜*Kšœœ˜Kšœœ˜Kšœœœœ˜Kšœœœ˜Kšœœœœ˜&K˜K˜šž œœ!˜4šœ˜K˜IK˜9K˜‚Kšœ˜—šœ˜K˜+Kšœ œ˜&Kšœ˜—K˜K˜—K˜šžœœ œ˜&šœ˜˜K˜?K˜@—˜ Kšœœ ˜Kšœ$œ(˜RK•StartOfExpansionM[buffer: REF TEXT, rope: ROPE, start: INT _ 0, len: INT _ 2147483647]šœR˜RKšœ?Οcœ˜_—˜ Kšœ œœ˜!Kšœ œ#˜2Kšœ œœœ˜GK˜@—K˜GKšœœ˜—K˜K˜'K˜—K˜šžœœ˜šœ˜K˜'K˜/K˜*K˜+K˜/Kšœœ˜K˜˜Kšœœ5˜?Kšœœ˜#Kšœqœ˜wK˜(K˜—˜Kšœœ5˜?Kšœ*Ÿ)˜SKšœ œ˜#Kšœœ˜0Kš œœœœœ˜@K˜–K˜(K˜—Kšœq˜qK˜Kšœm˜mK˜KšœT˜TK˜Kšœ$œ&œœ˜oK˜—K˜K˜K˜—K˜šœŸ˜K˜QKšœœœ˜HK˜šœœ˜%Kšœœœ˜šœ ˜K˜:KšœGœ˜MKšœ œ˜—Kšœœ+œ˜?—Kšœœ˜*Kšœœœ˜šœ ˜KšœH˜HK˜5K˜?Kšœœ˜—Kš˜—K˜—K˜šž œœœœ˜;K˜MKšœ#œ+˜TKšœ ˜K˜—K˜šžœœœ˜9Kšœ˜K˜=K˜—K˜šž œœœœ˜PKšœ œ˜K˜K˜K˜DKšœ,˜2K˜—K˜šžœœ˜5Kšœ˜šœœœ˜Kšœ4œœ˜FšœœŸ˜#K˜Cšœœ˜$K˜š˜K˜?šœ ˜Kšœ œŸ˜-KšœKŸ˜_Kšœ œŸ˜!Kšœœ˜—KšœœC˜YKšœ˜——KšœœŸ˜5K˜—KšœœŸ˜Kšœ˜—Kšœ˜—K˜šžœœœ;˜VKšœœ˜+K˜9K˜—K˜šžœœa˜oKšœ œ ˜Kšœ œ˜Kšœ˜K˜šœ1˜1Kšœœ4˜<—Kšœ˜Kšœ˜K˜—K˜šžœœœ#œ˜MKšœœœ˜KšœœL˜WKšœ"œœ˜3šœœŸ˜#K˜CKšœœ˜@Kšœœ˜K˜—K˜—K˜KšžœœœS˜bšœ-œ#˜SK˜"—K˜Kšœœœ˜)šœœœ˜KšœŸ˜(KšœŸ˜$KšœŸ˜+K˜—K˜šž œœ;˜KKšœœ ˜%K˜IK˜—K˜Kšžœœœ4˜Gšœ˜$Kšœœ9˜QKšœœB˜LK˜—K˜šž œœœX˜qšœ œœ˜šœœ˜K˜K˜Kšœœ+˜NKšœœ-˜PK˜—K˜šœœœ˜%Kšœ œ ˜Kšœ œ˜K˜K˜K˜K˜K˜K˜K˜?K˜K˜K˜K˜Kšœ&˜&—Kšœ'˜+—Kšœœ˜ K˜—K˜šžœœœG˜\šœœ˜šœœ˜K˜K˜Kšœ5Ÿ#˜X—Kšœœ™Kšœ™Kšœ™Kšœ/™/Kšœ™Kšœ™Kšœœœ™Kšœ-™-Kšœ™Kšœ™Kšœœ˜—K˜—K˜Kšœœ˜!Kšœ œ˜'Kšœ œœ˜%šœœœœŸ˜?K˜K˜K˜—Kšœ œ˜#K˜Kš žœœ œœœœ˜AK˜š ž œœœ œœœ˜HKšœ;˜AKšœ#œœ˜=K˜—K˜š ž œœœœœ˜Kšœ™K™Kšžœœ@™\Kšœ ™Kšœ™Kšœ™K™Kšžœœ+œ ™\Kšœ2™2Kšœœœ™3Kšœ™Kšœœ™%Kšœ'™'Kšœ™Kšœ2™2Kšœœœ™7Kšœ™Kšœ™Kšœ™K™Kšžœœ™1Kšœ@™@Kšœ-™-K™Kšœ™KšœMœ™WKšœ™K™KšœP™PK™Kšœ(™(Kšœ2™2Kšœ2™2Kšœ0™0Kšœ4™4Kšœ.™.Kšœ!™!Kšœ™K™K˜—…—Kl4