TJaM.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last changed by Bill Paxton, 30-Jan-82 8:42:23
Michael Plass, February 14, 1985 10:26:01 am PST
Doug Wyatt, March 25, 1985 4:42:09 pm PST
DIRECTORY
Atom USING [PropList],
IO USING [STREAM],
RefTab USING [Ref],
Rope USING [ROPE];
TJaM: CEDAR DEFINITIONS
~
BEGIN
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Types
Any: TYPE ~ REF ANY;
Object:
TYPE ~ Any;
-- for compatibility
Number, ATOM, ROPE, STREAM, Cmd, Dict, Array, Mark, ...
Ob: TYPE ~ REF ObRep;
ObRep: TYPE ~ RECORD [tag: ObTag, body: Any];
ObTag: TYPE ~ {literal, executable};
TypeCode: TYPE ~ {nil, number, atom, rope, stream, cmd, dict, array, mark, other};
Number: TYPE ~ REF NumberRep;
NumberRep:
TYPE ~
RECORD [
SELECT tag: *
FROM
int => [int: INT],
real => [real: REAL],
ENDCASE
];
CommandProc:
TYPE ~
PROC [frame: Frame];
Cmd: TYPE ~ REF CmdRep;
CmdRep: TYPE ~ RECORD [proc: CommandProc, name: ATOM];
Dict: TYPE ~ REF DictRep;
DictRep: TYPE ~ RECORD [refTab: RefTab.Ref, attach: LIST OF Dict];
Array: TYPE ~ REF ArrayRep;
ArrayRep: TYPE ~ RECORD [base: Sequence, start, len: NAT];
Sequence: TYPE ~ REF SequenceRep;
SequenceRep: TYPE ~ RECORD [SEQUENCE size: NAT OF Object];
Mark: TYPE ~ REF MarkRep;
MarkRep: TYPE ~ RECORD [id: INT ← 0];
Frame: TYPE ~ REF FrameRep;
FrameRep:
TYPE ~
RECORD [
impl: REF FrameImplRep,
propList: Atom.PropList ← NIL
];
FrameImplRep: TYPE; -- see TJaMPrivate
Type attributes, conversion
Equal: PROC [a, b: Any] RETURNS [BOOL];
Length: PROC [x: Any] RETURNS [INT];
Type: PROC [x: Any] RETURNS [TypeCode];
IntFromReal: PROC [real: REAL] RETURNS [INT];
IntFromNum: PROC [n: NumberRep] RETURNS [INT];
RealFromNum: PROC [n: NumberRep] RETURNS [REAL];
IntFromAny: PROC [x: Any] RETURNS [INT];
RealFromAny: PROC [x: Any] RETURNS [REAL];
NumberFromAny: PROC [x: Any] RETURNS [Number];
AtomFromAny: PROC [x: Any] RETURNS [ATOM];
RopeFromAny: PROC [x: Any] RETURNS [ROPE];
StreamFromAny: PROC [x: Any] RETURNS [STREAM];
CmdFromAny: PROC [x: Any] RETURNS [Cmd];
ArrayFromAny: PROC [x: Any] RETURNS [Array];
DictFromAny: PROC [x: Any] RETURNS [Dict];
MarkFromAny: PROC [x: Any] RETURNS [Mark];
RopeFromAtom: PROC [ATOM] RETURNS [ROPE];
AtomFromRope: PROC [ROPE] RETURNS [ATOM];
CvX: PROC [x: Any] RETURNS [Any];
CvLit: PROC [x: Any] RETURNS [Any];
The Stack
Push: PROC [frame: Frame, val: Any];
PushBool: PROC [frame: Frame, val: BOOL];
PushInt: PROC [frame: Frame, val: INT];
PushReal: PROC [frame: Frame, val: REAL];
PushNum: PROC [frame: Frame, val: NumberRep];
PushAtom: PROC [frame: Frame, val: ATOM];
PushRope: PROC [frame: Frame, val: ROPE];
PushStream: PROC [frame: Frame, val: STREAM];
PushCmd: PROC [frame: Frame, val: Cmd];
PushArray: PROC [frame: Frame, val: Array];
PushDict: PROC [frame: Frame, val: Dict];
PushMark:
PROC [frame: Frame, val: Mark];
... push an object onto the operand stack
Pop: PROC [frame: Frame] RETURNS [Any];
PopBool: PROC [frame: Frame] RETURNS [BOOL];
PopInt: PROC [frame: Frame] RETURNS [INT];
PopReal: PROC [frame: Frame] RETURNS [REAL];
PopNum: PROC [frame: Frame] RETURNS [NumberRep];
PopAtom: PROC [frame: Frame] RETURNS [ATOM];
PopRope: PROC [frame: Frame] RETURNS [ROPE];
PopStream: PROC [frame: Frame] RETURNS [STREAM];
PopCmd: PROC [frame: Frame] RETURNS [Cmd];
PopArray: PROC [frame: Frame] RETURNS [Array];
PopDict: PROC [frame: Frame] RETURNS [Dict];
PopMark:
PROC [frame: Frame]
RETURNS [Mark];
... pop an object from the operand stack
Top:
PROC [frame: Frame]
RETURNS [Any];
... returns the object on top of the operand stack (does not pop)
! Error[stackunderflow] if the stack is empty
TopType:
PROC [frame: Frame]
RETURNS [TypeCode];
... returns the type of the object on top of the operand stack
! Error[stackunderflow] if the stack is empty
Copy: PROC [frame: Frame, n: INT];
Dup: PROC [frame: Frame];
Roll: PROC [frame: Frame, n, k: INT];
Exch:
PROC [frame: Frame];
ClearStack:
PROC [frame: Frame];
... pops the operand stack until it is empty
CountStack:
PROC [frame: Frame]
RETURNS [
INT];
... returns the number of elements on the operand stack
StackIsEmpty:
PROC [frame: Frame]
RETURNS [
BOOL];
... equivalent to CountStack[frame]=0, but faster
ClearToMark: PROC [frame: Frame];
CountToMark: PROC [frame: Frame] RETURNS [INT];
Index: PROC [frame: Frame, i: INT] RETURNS [Any];
Arrays
NewArray:
PROC [len:
INT]
RETURNS [Array];
... creates a new array with specified length
ACopy: PROC [array: Array, expand: INT ← 0] RETURNS [Array];
ASub: PROC [array: Array, start, len: INT] RETURNS [Array];
APut: PROC [array: Array, i: INT, val: Any];
AGet: PROC [array: Array, i: INT] RETURNS [Any];
AFind: PROC [array: Array, val: Any] RETURNS [INT]; -- returns -1 if not found
ABind:
PROC [array: Array, dict: Dict];
AnyAction:
TYPE ~
PROC [x: Any]
RETURNS [quit:
BOOL ←
FALSE];
ArrayForAll:
PROC [array: Array, action: AnyAction]
RETURNS [
BOOL];
... calls action for each array element in order; returns TRUE iff some action returns TRUE
AStore: PROC [frame: Frame, array: Array];
ALoad: PROC [frame: Frame, array: Array];
Dictionaries
NewDict:
PROC [mod:
NAT ← 17]
RETURNS [Dict];
... creates a new dictionary with suggested hash size
DictLength:
PROC [dict: Dict]
RETURNS [
INT];
... returns the number of entries in dict
TryToGet:
PROC [dict: Dict, key:
ATOM]
RETURNS [found:
BOOL, val: Any];
... looks up key in dict; returns [TRUE, val] if found, [FALSE, NIL] otherwise
Get:
PROC [dict: Dict, key:
ATOM]
RETURNS [val: Any];
... returns val associated with key in dict
! Error[undefkey] if not found
Put:
PROC [dict: Dict, key:
ATOM, val: Any];
... inserts (key, val) in dict; overwrites any previous definition
Del:
PROC [dict: Dict, key:
ATOM];
... removes key from dict
! Error[undefkey] if not found
ClrDict:
PROC [dict: Dict];
... removes all entries from dict (but not from attachments)
TupleAction:
TYPE ~
PROC [key:
ATOM, val: Any]
RETURNS [quit:
BOOL ←
FALSE];
DictForAll:
PROC [dict: Dict, action: TupleAction]
RETURNS [
BOOL];
... calls action for each tuple in dict (not including attachments)
AttachDict:
PROC [dict1, dict2: Dict];
... inserts dict2 at the head of dict1's attachment list; noop if already attached
! Error[attachmentcycle] if attachment would create a circularity
DetachDict:
PROC [dict1, dict2: Dict];
... removes dict2 from dict1's attachment list
! Error[notattached] if dict2 was not attached to dict1
DetachAll:
PROC [dict: Dict];
... removes all attachments from dict
DictAction:
TYPE ~
PROC [dict: Dict]
RETURNS [quit:
BOOL ←
FALSE];
AttachedForAll:
PROC [dict: Dict, action: DictAction]
RETURNS [
BOOL];
... calls action for each attachment in order (most recently attached first)
Where:
PROC [frame: Frame, key:
ATOM]
RETURNS [found:
BOOL, where: Dict];
... looks up key in frame, top dict first; if found, returns containing dict
TryToLoad:
PROC [frame: Frame, key:
ATOM]
RETURNS [found:
BOOL, val: Any];
... looks up key in frame, top dict first; returns [TRUE, val] if found, [FALSE, NIL] otherwise
Load:
PROC [frame: Frame, key:
ATOM]
RETURNS [val: Any];
... looks up key in frame, top dict first, returns corresponding val
! Error[undefkey] if not found
Def:
PROC [frame: Frame, key:
ATOM, val: Any];
... Puts (key, val) in frame's top dict
Store:
PROC [frame: Frame, key:
ATOM, val: Any];
... looks up key in frame, replaces val if found, else does a Def
Begin:
PROC [frame: Frame, dict: Dict];
... pushes dict onto the dictionary stack
End:
PROC [frame: Frame];
... pops the dictionary stack
DictTop:
PROC [frame: Frame]
RETURNS [Dict];
... returns the top of the dictionary stack (without popping)
Execution
Error: ERROR[error: ATOM];
Exit: SIGNAL;
Stop: ERROR;
ErrorType:
TYPE ~ {
nil, -- no error
undefinedKey, -- dictionary lookup failed to find key
wrongType, -- an object has the wrong type
boundsFault, -- an array index is out of bounds
invalidArgs, -- some operator was given invalid arguments
numericOverflow, -- a numerical operation or conversion overflowed
stackUnderflow, -- the operand stack underflowed
stackOverflow, -- the operand stack overflowed
dictionaryUnderflow, -- the dictionary stack underflowed
dictionaryOverflow, -- the dictionary stack overflowed
attachmentCycle, -- attaching dictionary would create a circularity
notAttached, -- tried to detach a dictionary not currently attached
syntaxError, -- the scanner detected bad syntax (probably in a string literal)
endOfStream, -- unexpected end of stream
bug -- some consistency check in the JaM implementation failed
};
ProduceError:
PROC [type: ErrorType];
... raises Error with a suitable ATOM for the specified error type.
ExecuteStream: PROC [frame: Frame, stream: STREAM, closeAtEnd: BOOL ← TRUE];
ExecuteRope: PROC [frame: Frame, rope: ROPE];
LineComplete: PROC [rope: ROPE] RETURNS [BOOL];
Execute: PROC [frame: Frame, x: Any];
ExecuteAtom: PROC [frame: Frame, atom: ATOM];
ExecuteArray: PROC [frame: Frame, array: Array];
NewFrame: PROC RETURNS [Frame];
Register:
PROC [frame: Frame, name:
ATOM, proc: CommandProc];
... defines a Command in frame's top dictionary (using Def).
RegisterPrimitive:
PROC [name:
ROPE, proc: CommandProc];
... defines a Command in a global dictionary of primitives.
END.