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: BOOLFALSE];
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: BOOLFALSE];
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: BOOLFALSE];
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: BOOLTRUE];
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.