IPInterpreter.mesa
Copyright © 1984, 1985, 1986 by Xerox Corporation. All rights reserved.
Michael Plass, June 5, 1985 11:23:59 am PDT
Doug Wyatt, October 14, 1986 5:09:27 pm PDT
Allan H. Wax November 25, 1986 5:32:51 pm PST
Types and operations for the Interpress interpreter.
DIRECTORY
Basics USING [BITAND, BoundsCheckHighHalf, LowHalf, RawWords],
Imager USING [Color, Context, Font, PixelArray, Trajectory, Transformation],
ImagerBackdoor USING [Clipper],
ImagerFont USING [XChar, XCharProc, XStringProc],
IO USING [STREAM],
IPMaster USING [Body, Token, Op],
IPVector USING [Vector, VectorShape, Cardinal, Any],
PrincOps USING [BitAddress, DstFunc, SrcFunc],
Rope USING [ROPE];
IPInterpreter: CEDAR DEFINITIONS
IMPORTS Basics
~ BEGIN
Types
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Op: TYPE ~ IPMaster.Op;
Body: TYPE ~ IPMaster.Body;
maxCardinal: INT ~ 77777777B; -- 2^24 - 1 = 16777215
maxVecSize: NAT ~ 30000; -- for result of MakeVec or MakeVecLU
topFrameSize: NAT ~ 50;
Any: TYPE ~ IPVector.Any;
TypeCode: TYPE ~ MACHINE DEPENDENT {
null(0),
number(1), identifier(2), vector(3), operator(4), -- Base types
transformation(5), pixelArray(6), color(7), trajectory(8), outline(9), -- Image types
font(10), clipper(11) -- more Image types
};
Cardinal: TYPE ~ IPVector.Cardinal;
BoundsCheckCardinal: PROC [i: INT] RETURNS [Cardinal]
~ INLINE { RETURN[Basics.BoundsCheckHighHalf[value: i, bound: 400B]] };
IF i IN[0..maxCardinal] THEN RETURN[i] ELSE ERROR RuntimeError.BoundsFault;
Even: PROC [i: Cardinal] RETURNS [BOOL]
~ INLINE { RETURN[Basics.BITAND[Basics.LowHalf[i], 1]=0] };
RETURN[(i MOD 2)=0]
Number: TYPE ~ REF NumberRep;
NumberRep: TYPE ~ RECORD[
SELECT tag: * FROM
zero => [zero: Cardinal ← 0],
int => [int: INT],
real => [real: REAL],
rational => [n, d: INTEGER],
ENDCASE
];
Identifier: TYPE ~ ROPE;
Marker: TYPE ~ LONG CARDINAL; -- a unique mark value associated with a context
nullMarker: Marker ~ 0;
VectorShape: TYPE ~ IPVector.VectorShape; -- Upper bound "u" = lowerBound+size-1.
Vector: TYPE ~ IPVector.Vector;
Operator: TYPE ~ REF OperatorRep;
OperatorRep: TYPE ~ RECORD[class: OperatorClass, data: REF];
OperatorClass: TYPE ~ REF OperatorClassRep;
OperatorClassRep: TYPE ~ RECORD[
type: ATOM, -- $Composed, $Char, $Decompressor, $ColorOperator, ...
do: PROC [op: Operator, state: Ref]
];
Transformation: TYPE ~ Imager.Transformation;
PixelArray: TYPE ~ Imager.PixelArray;
Color: TYPE ~ Imager.Color;
Trajectory: TYPE ~ Imager.Trajectory;
Outline: TYPE ~ REF OutlineRep;
OutlineRep: TYPE ~ RECORD [oddWrap: BOOL, seq: SEQUENCE size: NAT OF Trajectory];
Font: TYPE ~ Imager.Font;
Clipper: TYPE ~ ImagerBackdoor.Clipper;
XChar: TYPE ~ ImagerFont.XChar;
XCharProc: TYPE ~ ImagerFont.XCharProc;
XStringProc: TYPE ~ ImagerFont.XStringProc;
Array: TYPE ~ REF ArrayRep; -- a mutable array of values, such as a frame
ArrayRep: TYPE ~ RECORD[
lowerBound: Cardinal, -- lower bound, as in VectorShape
array: SEQUENCE size: [0..maxVecSize] OF Any
];
Context: TYPE ~ REF ContextRep; -- an execution context
ContextRep: TYPE ~ RECORD[
caller: Context, -- caller's context
marker: Marker, -- unique mark for this context
token: IPMaster.Token, -- token currently being executed
initialFrame: Vector, -- initial frame
frame: Array, -- current frame (NIL if unchanged from initial frame)
env: Vector -- environment
];
stackArraySize: NAT ~ 8;
StackArray: TYPE ~ REF StackArrayRep;
StackArrayRep: TYPE ~ ARRAY[0..stackArraySize) OF NumberRep;
StackList: TYPE ~ LIST OF Any;
StackMark: TYPE ~ REF StackMarkRep;
StackMarkRep: TYPE ~ RECORD [
rest: StackMark ← NIL,
count: INT ← 0,
marker: Marker ← nullMarker
];
Ref: TYPE ~ REF Rep; -- an Interpress interpreter instance
Rep: TYPE ~ RECORD[
rope: ROPENIL, -- the rope containing the encoding to be interpreted
index: INT ← 0, -- current position in the rope
buffer: REF TEXTNIL, -- text buffer for sequence data
topFrame: Vector ← NIL, -- initial frame for the top level block
topEnv: Vector ← NIL, -- environment for the top level block
lastMarker: Marker ← nullMarker, -- last mark value used
context: Context ← NIL, -- the current context
contextFree: Context ← NIL, -- list of a few free contexts
contextFreeCount: INT ← 0, -- number of contexts on free list
stackArray: StackArray ← NIL, -- a few numbers on top of the stack
stackArrayCount: [0..stackArraySize] ← 0, -- number of elements in stackArray
stackList: StackList ← NIL, -- the rest of the stack
stackCount: INT ← 0, -- number of stack elements above the top mark
stackCountMax: INT ← 0, -- maximum count permitted above the top mark
stackMark: StackMark ← NIL, -- the top mark on the stack
stackMarkFree: StackMark ← NIL, -- list of a few free marks
stackMarkFreeCount: INT ← 0, -- number of marks on free list
imager: Imager.Context ← NIL -- imager state
];
Operations
Bug: ERROR;
MarkRecovery: ERROR;
ReportError: PROC [class: INT, code: ATOM, explanation: ROPE];
MasterError: PROC [code: ATOM, explanation: ROPE];
MasterWarning: PROC [code: ATOM, explanation: ROPE];
CardinalFromReal: PROC [REAL] RETURNS [Cardinal];
CardinalFromNum: PROC [NumberRep] RETURNS [Cardinal];
RealFromNum: PROC [NumberRep] RETURNS [REAL];
CardinalFromAny: PROC [Any] RETURNS [Cardinal];
RealFromAny: PROC [Any] RETURNS [REAL];
NumberFromAny: PROC [Any] RETURNS [Number];
IdentifierFromAny: PROC [Any] RETURNS [Identifier];
VectorFromAny: PROC [Any] RETURNS [Vector];
OperatorFromAny: PROC [Any] RETURNS [Operator];
Eq: PROC [a, b: Any] RETURNS [BOOL];
EqName: PROC [a, b: Any] RETURNS [BOOL];
Type: PROC [a: Any] RETURNS [TypeCode];
Get: PROC [v: Vector, i: Cardinal] RETURNS [Any];
GetCardinal: PROC [v: Vector, i: Cardinal] RETURNS [Cardinal];
GetReal: PROC [v: Vector, i: Cardinal] RETURNS [REAL];
Shape: PROC [v: Vector] RETURNS [VectorShape];
ZeroVec: PROC [n: Cardinal] RETURNS [Vector];
Creates a Vector with n elements, all zero.
MakeVec: PROC [n: Cardinal, pop: PROC RETURNS [Any]] RETURNS [Vector];
MakeVecLU: PROC [l, u: Cardinal, pop: PROC RETURNS [Any]] RETURNS [Vector];
Creates a Vector with the specified shape.
Calls pop shape.n times to get the elements, last element first.
MergeProp: PROC [v1, v2: Vector] RETURNS [Vector];
PropProc: TYPE ~ PROC [v: Vector, j: Cardinal] RETURNS [quit: BOOLFALSE];
MapProp: PROC [v: Vector, action: PropProc] RETURNS [BOOL];
GetProp: PROC [v: Vector, propName: Any] RETURNS [found: BOOL, value: Any];
GetP: PROC [v: Vector, propName: Any] RETURNS [Any];
GetPropR: PROC [v: Vector, rope: ROPE] RETURNS [found: BOOL, value: Any];
GetPR: PROC [v: Vector, rope: ROPE] RETURNS [Any];
GetPropC: PROC [v: Vector, card: Cardinal] RETURNS [found: BOOL, value: Any];
GetPC: PROC [v: Vector, card: Cardinal] RETURNS [Any];
RunSize: PROC [r: Vector] RETURNS [Cardinal];
RunGet: PROC [r: Vector, i: Cardinal] RETURNS [Any];
VectorFromArray: PROC [Array] RETURNS [Vector];
Creates a Vector with the same shape and elements as the Array.
The result contains a copy of the Array; it does not share the original.
ArrayFromVector: PROC [Vector] RETURNS [Array];
Creates an Array with the same shape and elements as the Vector.
The result is a new, mutable copy; it shares nothing with the Vector.
VectorFromString: PROC [string: XStringProc] RETURNS [Vector];
Makes a Vector of Cardinal from the characters of the string.
StringFromVector: PROC [v: Vector, charAction: XCharProc];
Calls charAction for each element of v in order.
Error if any element is not an integer that fits in an XChar.
VectorFromRope: PROC [ROPE] RETURNS [Vector];
RopeFromVector: PROC [Vector] RETURNS [ROPE];
These use VectorFromString and StringFromVector to convert between Vectors and ROPEs.
The rope uses the encoding scheme in the Xerox Character Code Standard.
VectorFromName: PROC [ROPE] RETURNS [Vector];
NameFromVector: PROC [Vector] RETURNS [ROPE];
Conversion between slash-notation names (like "a/b/c") and Vectors of Identifiers.
VectorFromBytes: PROC [bytes: ROPE, bytesPerElement: NAT, signed: BOOL] RETURNS [Vector];
VectorFromBits: PROC [bytes: ROPE, dataBitsPerLine, padBitsPerLine: NAT] RETURNS [Vector];
UnsafeGetElements: UNSAFE PROC [vector: Vector, buffer: LONG POINTER TO Basics.RawWords, start: INT, count: NAT];
No sign extension is done.
UnsafeGetBits: UNSAFE PROC [vector: Vector, dst: PrincOps.BitAddress, start: INT, count: NAT, srcFunc: PrincOps.SrcFunc ← null, dstFunc: PrincOps.DstFunc ← null];
start and count deal in bits
PushAny: PROC [self: Ref, val: Any];
PushNum: PROC [self: Ref, val: NumberRep];
PushBool: PROC [self: Ref, val: BOOL];
PushCardinal: PROC [self: Ref, val: Cardinal];
PushReal: PROC [self: Ref, val: REAL];
PushIdentifier: PROC [self: Ref, val: Identifier];
PushVector: PROC [self: Ref, val: Vector];
PushOperator: PROC [self: Ref, val: Operator];
PopAny: PROC [self: Ref] RETURNS [Any];
PopNum: PROC [self: Ref] RETURNS [NumberRep];
PopBool: PROC [self: Ref] RETURNS [BOOL];
PopCardinal: PROC [self: Ref] RETURNS [Cardinal];
PopReal: PROC [self: Ref] RETURNS [REAL];
PopIdentifier: PROC [self: Ref] RETURNS [Identifier];
PopVector: PROC [self: Ref] RETURNS [Vector];
PopOperator: PROC [self: Ref] RETURNS [Operator];
TopType: PROC [self: Ref] RETURNS [TypeCode];
Pop: PROC [self: Ref];
Copy: PROC [self: Ref, depth: Cardinal];
Roll: PROC [self: Ref, depth, moveFirst: Cardinal];
Mark: PROC [self: Ref, n: Cardinal];
Unmark: PROC [self: Ref, n: Cardinal];
Count: PROC [self: Ref] RETURNS [Cardinal];
PopToActiveMark: PROC [self: Ref] RETURNS [Marker];
Call: PROC [self: Ref, action: PROC, frame: Vector, env: Vector];
Executes the action in a new context with specified frame and environment.
Frame: PROC [self: Ref] RETURNS [Vector];
FGet: PROC [self: Ref, i: Cardinal] RETURNS [Any];
FSet: PROC [self: Ref, x: Any, i: Cardinal];
Env: PROC [self: Ref] RETURNS [Vector];
DoSave: PROC [self: Ref, action: PROC];
Executes the action, then restores non-persistent imager variables.
DoSaveAll: PROC [self: Ref, action: PROC];
Executes the action, then restores all imager variables.
DoWithMarkProtection: PROC [self: Ref, action: PROC];
Executes < 0 MARK action UNMARK0 >, with mark recovery if necessary.
Apply: PROC [self: Ref, op: Op];
Executes a primitive.
Do: PROC [self: Ref, op: Operator];
Executes an Operator.
GetInlineBody: PROC [self: Ref] RETURNS [Body];
Reads a body from the master, recording it for later use.
SkipInlineBody: PROC [self: Ref];
Skips over a body in the master.
CallInlineBody: PROC [self: Ref, frame: Vector, env: Vector];
Executes a body in a new context.
MakeCO: PROC [frame: Vector, env: Vector, body: Body] RETURNS [Operator];
END.