IPInterpreter.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Michael Plass, June 5, 1985 11:23:59 am PDT
Doug Wyatt, November 22, 1985 2:48:11 pm PST
Types and operations for the Interpress interpreter.
DIRECTORY
Basics USING [BITAND, BoundsCheckHighHalf, LowHalf, RawWords],
Imager USING [Context],
ImagerFont USING [XCharProc, XStringProc],
IO USING [STREAM],
IPMaster USING [Body, Op, Token],
PrincOps USING [BitAddress, DstFunc, SrcFunc],
Rope USING [ROPE];
IPInterpreter: CEDAR DEFINITIONS
IMPORTS Basics
~ BEGIN
Types
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Body: TYPE ~ IPMaster.Body;
maxCardinal: INT ~ 77777777B; -- 2^24 - 1 = 16777215
maxVecSize: NAT ~ 32000; -- for result of MakeVec or MakeVecLU
topFrameSize: NAT ~ 50;
Any: TYPE ~ REF;
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.LAST) -- room for lots more
};
Cardinal: TYPE ~ INT--[0..maxCardinal]--;
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: INT] RETURNS [BOOL]
~ INLINE { RETURN[Basics.BITAND[Basics.LowHalf[LOOPHOLE[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 ~ RECORD [lowerBound: Cardinal, size: INT--[0..maxCardinal+1]--];
Upper bound "u" = lowerBound+size-1.
Vector: TYPE ~ REF VectorRep;
VectorRep: TYPE ~ RECORD [class: VectorClass, data: REF];
VectorClass: TYPE ~ REF VectorClassRep;
VectorClassRep: TYPE ~ RECORD [
type: ATOM, -- $Array, $Merged, $String, ...
shape: PROC [v: Vector] RETURNS [VectorShape],
get: PROC [v: Vector, i: Cardinal] RETURNS [Any],
getCardinal: PROC [v: Vector, i: Cardinal] RETURNS [Cardinal]
];
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]
];
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
];
Source: TYPE ~ REF SourceRep; -- a source of tokens
SourceRep: TYPE ~ RECORD [
caller: Source, -- calling source
stream: STREAM
];
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
frameV: Vector, -- frame vector (if NIL, use frameA)
frameA: Array, -- frame array (if NIL, use frameV)
env: Vector -- environment
];
stackArraySize: NAT ~ 8;
StackArray: TYPE ~ REF StackArrayRep;
StackArrayRep: TYPE ~ ARRAY [0..stackArraySize) OF NumberRep;
StackList: TYPE ~ LIST OF Any;
MarkItem: TYPE ~ RECORD [count: Cardinal, marker: Marker];
MarkArray: TYPE ~ REF MarkArrayRep;
MarkArrayRep: TYPE ~ RECORD [size: NAT, seq: SEQUENCE max: NAT OF MarkItem];
Ref: TYPE ~ REF Rep; -- an Interpress interpreter instance
Rep: TYPE ~ RECORD [
stream: STREAMNIL, -- input stream on the master being interpreted
buffer: REF TEXTNIL, -- buffer for short 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 execution context
contextFree: Context ← NIL, -- list of free execution contexts
contextCount: Cardinal ← 0, -- number of contexts allocated
stackCount: Cardinal ← 0, -- number of stack elements above the top mark
stackCountMax: Cardinal ← 0, -- maximum count permitted above the top mark
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
markArray: MarkArray ← NIL, -- marks on the stack
imager: Imager.Context ← NIL -- imager state
];
Operations
Bug: ERROR;
MarkRecovery: ERROR;
masterErrorCode: Cardinal ~ 0;
masterWarningCode: Cardinal ~ 10;
appearanceErrorCode: Cardinal ~ 50;
appearanceWarningCode: Cardinal ~ 60;
commentCode: Cardinal ~ 100;
ReportError: PROC [code: Cardinal, atom: ATOM, message: ROPE];
MasterError: PROC [atom: ATOM, message: ROPE];
MasterWarning: PROC [atom: ATOM, message: ROPE];
CardinalFromReal: PROC [REAL] RETURNS [Cardinal];
CardinalFromNum: PROC [NumberRep] RETURNS [Cardinal];
RealFromNum: PROC [NumberRep] RETURNS [REAL];
NumberFromCardinal: PROC [Cardinal] RETURNS [Number];
NumberFromReal: PROC [REAL] RETURNS [Number];
NumberFromNum: PROC [NumberRep] RETURNS [Number];
Conversion between Number representations.
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];
Type narrowing operations.
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: ImagerFont.XStringProc] RETURNS [Vector];
Makes a Vector of Cardinal from the characters of the string.
StringFromVector: PROC [v: Vector, charAction: ImagerFont.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];
These push an element on the stack.
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];
These pop an element from the stack.
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: IPMaster.Op];
Executes a primitive.
Do: PROC [self: Ref, op: Operator];
Executes an Operator.
MakeCO: PROC [frame: Vector, env: Vector, body: Body] RETURNS [Operator];
Makes a composed 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.
END.