DIRECTORY IO USING [STREAM], Rope USING [ROPE]; JaM: CEDAR DEFINITIONS = BEGIN ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; State: TYPE = REF StateRep; StateRep: TYPE = RECORD[ aborted: BOOL _ FALSE, stack: Stack, -- the operand stack dictstk: LIST OF Dict, -- the dictionary stack out: STREAM -- output stream, for .print ]; Stack: TYPE = REF StackRep; StackRep: TYPE; Any: TYPE = REF ANY; Command: TYPE = REF CommandRep; CommandRep: TYPE = RECORD[name: ATOM, proc: PROC[State]]; Op: TYPE = REF OpRep; OpRep: TYPE = RECORD[body: Any]; Dict: TYPE = REF DictRep; DictRep: TYPE = RECORD[impl: REF DictImplRep, attach: LIST OF Dict]; DictImplRep: TYPE; Array: TYPE = REF ArrayRep; ArrayRep: TYPE = RECORD[start, length: NAT, seq: Sequence]; Sequence: TYPE = REF SequenceRep; SequenceRep: TYPE = RECORD[SEQUENCE size: NAT OF Any]; Mark: TYPE = REF MarkRep; MarkRep: TYPE = RECORD[m: INT]; Create: PROC[out: STREAM] RETURNS[State]; NewStack: PROC RETURNS[Stack]; Push: PROC[self: State, x: Any]; PushBool: PROC[self: State, x: BOOL]; PushInt: PROC[self: State, x: INT]; PushReal: PROC[self: State, x: REAL]; PushRope: PROC[self: State, x: ROPE] = INLINE { Push[self, x] }; PushStream: PROC[self: State, x: STREAM] = INLINE { Push[self, x] }; PushArray: PROC[self: State, x: Array] = INLINE { Push[self, x] }; PushDict: PROC[self: State, x: Dict] = INLINE { Push[self, x] }; Pop: PROC[self: State] RETURNS[Any]; PopBool: PROC[self: State] RETURNS[BOOL]; PopInt: PROC[self: State] RETURNS[INT]; PopReal: PROC[self: State] RETURNS[REAL]; PopRope: PROC[self: State] RETURNS[ROPE]; PopStream: PROC[self: State] RETURNS[STREAM]; PopArray: PROC[self: State] RETURNS[Array]; PopDict: PROC[self: State] RETURNS[Dict]; Copy: PROC[self: State, n: INT]; Roll: PROC[self: State, n, k: INT]; Index: PROC[self: State, i: INT] RETURNS[Any]; Count: PROC[self: State] RETURNS[INT]; PushMark: PROC[self: State, m: INT _ 0]; PopMark: PROC[self: State, m: INT _ 0]; CountToMark: PROC[self: State, m: INT _ 0] RETURNS[INT]; NewArray: PROC[length: INT] RETURNS[Array]; MakeArray: PROC[self: State, length: INT] RETURNS[Array]; SubArray: PROC[array: Array, start, length: INT] RETURNS[Array]; PutArray: PROC[from: Array, start: INT, into: Array]; APut: PROC[array: Array, i: INT, x: Any]; AGet: PROC[array: Array, i: INT] RETURNS[Any]; AFind: PROC[array: Array, x: Any] RETURNS[found: BOOL, i: INT]; ABind: PROC[array: Array, dict: Dict]; sysDict: Dict; NewDict: PROC[length: INT] RETURNS[Dict]; DictLength: PROC[dict: Dict] RETURNS[INT]; Put: PROC[dict: Dict, key, val: Any]; TryToGet: PROC[dict: Dict, key: Any] RETURNS[found: BOOL, val: Any]; Get: PROC[dict: Dict, key: Any] RETURNS[Any]; Del: PROC[dict: Dict, key: Any]; AttachDict: PROC[dict, adict: Dict]; DetachDict: PROC[dict, adict: Dict]; DetachAll: PROC[dict: Dict]; Def: PROC[self: State, key, val: Any]; Store: PROC[self: State, key, val: Any]; TryToLoad: PROC[self: State, key: Any] RETURNS[found: BOOL, val: Any]; Load: PROC[self: State, key: Any] RETURNS[Any]; Where: PROC[self: State, key: Any] RETURNS[found: BOOL, where: Dict]; Begin: PROC[self: State, dict: Dict]; End: PROC[self: State]; AtomToRope: PROC[ATOM] RETURNS[ROPE]; RopeToAtom: PROC[ROPE] RETURNS[ATOM]; Equal: PROC[a, b: Any] RETURNS[BOOL]; Eq: PROC[a, b: Any] RETURNS[BOOL] = INLINE { RETURN[IF a=b THEN TRUE ELSE Equal[a, b]] }; ExecuteRope: PROC[self: State, rope: ROPE]; LineComplete: PROC[text: ROPE] RETURNS[BOOL]; Execute: PROC[self: State, x: Any]; GetAbort: PROC[self: State] RETURNS[BOOL]; SetAbort: PROC[self: State, b: BOOL]; ErrorType: TYPE = {AttachmentCycle, BoundsFault, DictionaryUnderflow, InvalidArgs, LoadFailed, NotAttached, NumericOverflow, OpenFailed, StackOverflow, StackUnderflow, UndefinedKey, Unimplemented, WrongMark, WrongType}; Error: ERROR[type: ErrorType, msg: Rope.ROPE _ NIL]; Exit: ERROR; Stop: ERROR; RegisterInit: PROC[name: ROPE, init: PROC[State]]; Register: PROC[self: State, name: ROPE, proc: PROC[State]]; END. lJaM.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Maureen Stone January 26, 1984 5:40:32 pm PST Doug Wyatt, March 18, 1985 2:50:41 pm PST Types Creating a new interpreter Stack operations Array operations Dictionary operations Atoms Key comparison JaM will raise Error if any problems are encountered. The main execution loop converters these errors to ropes and prints them on the state.out stream since the main client of these procedures is the JaM typescript. It then raises the ERROR Stop. All clients of ExecuteRope and Execute may see the error Stop. If you are the top level procedure, it is adequate to immediately continue ie: Execute[state, any ! Stop => CONTINUE]. Scanning Execution Errors Registration (JaMControlImpl) There is a global list of names and initialization procedures kept in sysDict called .initprocs. Each program that wants to register commands with JaM should register an initialization procedure and a unique name (capitalization counts). There is a separate JaM dictionary for each typescript. To register commands in a particular dictionary execute (name) .callinit. This calls the named initialization proc with the correct JaM State. Note: you can create your own State independent of the typescripts by using JaM.Create. You can then register commands in that dictionary directly or simulate the typescript mechanism with ExecuteRope[state, "(name) .callinit \n"]; Register a name and an initialization proc that does all the calls to Register (below) Suggestion: make the name your module name put all your calls to Register in your initialization proc (above) Κ³˜codešœ™Kšœ Οmœ1™