<> <> <> <> <> <> DIRECTORY Process USING [priorityBackground, priorityNormal, SetPriority, Yield], TJaM, TJaMPrivate; TJaMExecImpl: CEDAR PROGRAM IMPORTS Process, TJaM EXPORTS TJaM ~ BEGIN OPEN TJaM, TJaMPrivate; FrameImplRep: PUBLIC TYPE ~ TJaMPrivate.FrameImplRep; RecursiveError: PUBLIC ERROR[error: ATOM] ~ CODE; Error: PUBLIC ERROR[error: ATOM] ~ CODE; Exit: PUBLIC SIGNAL ~ CODE; Stop: PUBLIC ERROR ~ CODE; ErrorAtom: TYPE ~ ATOM _; -- no default ErrorArray: TYPE ~ ARRAY ErrorType OF ErrorAtom; atomFromErrorType: REF ErrorArray ~ NEW[ErrorArray _ [ nil: AtomFromRope[".nil"], undefinedKey: AtomFromRope[".undefkey"], wrongType: AtomFromRope[".typechk"], boundsFault: AtomFromRope[".rangechk"], invalidArgs: AtomFromRope[".badargs"], numericOverflow: AtomFromRope[".overflow"], stackUnderflow: AtomFromRope[".stkundflw"], stackOverflow: AtomFromRope[".stkovrflw"], dictionaryUnderflow: AtomFromRope[".dictundflw"], dictionaryOverflow: AtomFromRope[".dictovrflw"], attachmentCycle: AtomFromRope[".attachmentcycle"], notAttached: AtomFromRope[".notattached"], syntaxError: AtomFromRope[".syntaxerr"], endOfStream: AtomFromRope[".endofstream"], bug: AtomFromRope[".bug"] ]]; ProduceError: PUBLIC PROC[type: ErrorType] ~ { atom: ATOM ~ atomFromErrorType[type]; ERROR Error[atom]; }; Execute: PUBLIC PROC[frame: Frame, x: Any] ~ { impl: FrameImpl ~ frame.impl; errorAtom: ATOM _ NIL; IF impl.abort THEN { impl.abort _ FALSE; ERROR Stop }; { ENABLE Error => { errorAtom _ error; CONTINUE }; WITH x SELECT FROM atom: ATOM => ExecuteAtom[frame, atom]; cmd: Cmd => cmd.proc[frame]; ob: Ob => SELECT ob.tag FROM literal => Push[frame, ob.body]; executable => ExecuteBody[frame, ob.body]; ENDCASE => ProduceError[bug]; ENDCASE => Push[frame, x]; }; IF errorAtom#NIL THEN { Push[frame, x]; ExecuteAtom[frame, errorAtom ! Error => IF error=errorAtom THEN ERROR RecursiveError[errorAtom] ]; }; Process.Yield[]; -- to help abort infinite loops }; undefName: ATOM ~ AtomFromRope[".undefname"]; ExecuteAtom: PUBLIC PROC[frame: Frame, atom: ATOM] ~ { found: BOOL; val: Any; [found, val] _ TryToLoad[frame, atom]; IF found THEN { Execute[frame, val]; RETURN }; [found, val] _ TryToLoad[frame, undefName]; IF found THEN { PushAtom[frame, atom]; Execute[frame, val] }; }; ExecuteArray: PUBLIC PROC[frame: Frame, array: Array] ~ { FOR i: NAT IN[0..array.len) DO Execute[frame, AGet[array, i]] ENDLOOP; }; ExecuteBody: PROC[frame: Frame, x: Any] ~ { WITH x SELECT FROM array: Array => ExecuteArray[frame, array]; rope: ROPE => ExecuteRope[frame, rope]; stream: STREAM => ExecuteStream[frame, stream]; ENDCASE => Execute[frame, x]; }; <<>> GetAbort: PUBLIC PROC[frame: Frame] RETURNS[BOOL] ~ { impl: FrameImpl ~ frame.impl; RETURN[impl.abort]; }; SetAbort: PUBLIC PROC[frame: Frame, b: BOOL] ~ { impl: FrameImpl ~ frame.impl; impl.abort _ b; }; ApplyStop: PUBLIC PROC[frame: Frame] ~ { ERROR Stop; }; ApplyExec: PUBLIC PROC[frame: Frame] ~ { x: Any ~ Pop[frame]; Execute[frame, x]; }; ApplyIf: PUBLIC PROC[frame: Frame] ~ { x: Any ~ Pop[frame]; b: BOOL ~ PopBool[frame]; IF b THEN Execute[frame, x]; }; ApplyIfElse: PUBLIC PROC[frame: Frame] ~ { xF: Any ~ Pop[frame]; xT: Any ~ Pop[frame]; b: BOOL ~ PopBool[frame]; Execute[frame, IF b THEN xT ELSE xF]; }; ApplyRept: PUBLIC PROC[frame: Frame] ~ { x: Any ~ Pop[frame]; n: INT ~ PopInt[frame]; THROUGH [0..n) DO Execute[frame, x ! Exit => EXIT] ENDLOOP; }; ApplyFor: PUBLIC PROC[frame: Frame] ~ { x: Any ~ Pop[frame]; k: INT ~ PopInt[frame]; j: INT ~ PopInt[frame]; i: INT ~ PopInt[frame]; IF j>=0 THEN FOR n: INT _ i, n+j UNTIL n>k DO PushInt[frame, n]; Execute[frame, x ! Exit => EXIT]; ENDLOOP ELSE FOR n: INT _ i, n+j UNTIL n EXIT]; ENDLOOP; }; ApplyLoop: PUBLIC PROC[frame: Frame] ~ { x: Any ~ Pop[frame]; DO Execute[frame, x ! Exit => EXIT] ENDLOOP; }; ApplyExit: PUBLIC PROC[frame: Frame] ~ { SIGNAL Exit; }; ApplyNicePriority: PUBLIC PROC[frame: Frame] ~ { nice: BOOL ~ PopBool[frame]; Process.SetPriority[IF nice THEN Process.priorityBackground ELSE Process.priorityNormal]; }; RegisterPrimitive[".if", ApplyIf]; RegisterPrimitive[".ifelse", ApplyIfElse]; RegisterPrimitive[".rept", ApplyRept]; RegisterPrimitive[".for", ApplyFor]; RegisterPrimitive[".loop", ApplyLoop]; RegisterPrimitive[".exit", ApplyExit]; RegisterPrimitive[".stop", ApplyStop]; RegisterPrimitive[".interrupt", ApplyStop]; RegisterPrimitive[".exec", ApplyExec]; RegisterPrimitive[".nice", ApplyNicePriority]; END.