DIRECTORY AMEvents USING [Debugged, Debugging], IO USING [Close, ChangeDeliverWhen, CharProc, CharsAvail, DeliverWhenProc, EndOf, EndOfStream, Error, GetSequence, NewLine, PeekChar, PutF, PutRope, PutSignal, Reset, ResetUserAbort, rope, SetUserAbort, Signal, STREAM, SyntaxError, UserAborted], MBQueue USING [Create, CreateMenuEntry, Queue], Menus USING [InsertMenuEntry, MenuProc], Process USING [Detach], ReadEvalPrint, Rope USING [ROPE], TypeScript USING [Create], ViewerClasses USING [Viewer, ViewerRec], ViewerEvents USING [EventProc, RegisterEventProc], ViewerIO USING [CreateViewerStreams, NotAllowed], ViewerOps USING [AddProp, ComputeColumn, FetchProp]; ReadEvalPrintImpl: CEDAR MONITOR IMPORTS AMEvents, IO, MBQueue, Menus, Process, TypeScript, ViewerEvents, ViewerIO, ViewerOps EXPORTS ReadEvalPrint SHARES ViewerIO = BEGIN CreateViewerEvaluator: PUBLIC PROC [clientProc: ReadEvalPrint.ClientProc, prompt: Rope.ROPE _ NIL, info: ViewerClasses.ViewerRec _ [], edited: BOOL _ TRUE, deliverWhen: IO.DeliverWhenProc _ IsACR, clientData: REF ANY _ NIL] RETURNS [h: ReadEvalPrint.Handle] = { h _ NEW[ReadEvalPrint.RObject _ []]; h.clientProc _ clientProc; h.deliverWhenProc _ NIL; h.menuHitQueue _ MBQueue.Create[]; h.prompt _ prompt; h.viewer _ TypeScript.Create[info: info, paint: FALSE]; h.clientData _ clientData; ViewerOps.AddProp[h.viewer, $ReadEvalPrint, h]; [in: h.in, out: h.out] _ ViewerIO.CreateViewerStreams[name: NIL, viewer: h.viewer, editedStream: edited]; [] _ h.in.ChangeDeliverWhen[deliverWhen]; Menus.InsertMenuEntry[menu: h.viewer.menu, line: 0, entry: MBQueue.CreateMenuEntry[q: h.menuHitQueue, name: "STOP!", proc: StopHit, clientData: h]]; ViewerOps.ComputeColumn[column: info.column]; }; CreateStreamEvaluator: PUBLIC PROC [clientProc: ReadEvalPrint.ClientProc, prompt: Rope.ROPE _ NIL, in, out: IO.STREAM, deliverWhen: IO.DeliverWhenProc _ NIL, clientData: REF ANY _ NIL] RETURNS [h: ReadEvalPrint.Handle] = { h _ NEW[ReadEvalPrint.RObject _ []]; h.clientProc _ clientProc; h.deliverWhenProc _ deliverWhen; h.prompt _ prompt; h.in _ in; h.out _ out; h.clientData _ clientData; }; Stop: PUBLIC PROC [h: ReadEvalPrint.Handle] = { SetTerminateRequested[h]; }; MainLoop: PUBLIC PROC [h: ReadEvalPrint.Handle, forkAndDetach: BOOL _ TRUE] = { IF forkAndDetach THEN TRUSTED { Process.Detach[FORK MainLoopInternal[h]]; } ELSE MainLoopInternal[h]; }; MainLoopInternal: PROC [h: ReadEvalPrint.Handle] = { commandLine: Rope.ROPE _ NIL; result: Rope.ROPE _ NIL; rejectThisOne: BOOL _ FALSE; badRope: Rope.ROPE _ NIL; -- used to save for debugger inspection UNTIL WasTerminateRequested[h] DO { ENABLE ANY => { rejectThisOne _ FALSE; REJECT; }; {ENABLE {-- these catch phrases protect the input operation only AMEvents.Debugging, AMEvents.Debugged => REJECT; IO.UserAborted => { -- user typed ctrl-del s: IO.STREAM _ h.in; IF rejectThisOne THEN REJECT; WITH abortee SELECT FROM a: IO.STREAM => s _ a; ENDCASE; s.ResetUserAbort[ ! ANY => CONTINUE]; h.in.Reset[ ! ANY => CONTINUE]; h.out.PutF[IF h.readUserAbortedRope # NIL THEN h.readUserAbortedRope ELSE " XXX\n" ! ANY => CONTINUE]; GOTO DoLoop; }; ABORTED => { -- took a breakpoint and then aborted IF rejectThisOne THEN REJECT; h.in.ResetUserAbort[ ! ANY => CONTINUE]; h.in.Reset[ ! ANY => CONTINUE]; h.out.PutF[IF h.readABORTEDRope # NIL THEN h.readABORTEDRope ELSE " aborted\n" ! ANY => CONTINUE]; GOTO DoLoop; }; UNWIND => GOTO DoLoop; ANY => IF h.bulletProof THEN { -- otherwise reject Inform: PROCEDURE = { h.in.ResetUserAbort[ ! ANY => CONTINUE]; h.in.Reset[ ! ANY => CONTINUE]; h.out.NewLine[ ! ANY => CONTINUE]; h.out.PutSignal[ ! ANY => CONTINUE]; h.out.NewLine[ ! ANY => CONTINUE]; }; IF rejectThisOne THEN REJECT; Inform[! ANY => CONTINUE]; GOTO DoLoop; }; }; {ENABLE { IO.Error => { IF rejectThisOne THEN REJECT; IF ec = StreamClosed THEN { IF h.viewer = NIL OR h.viewer.destroyed THEN GOTO Destroyed }; -- user destroyed the viewer. }; IO.Signal => IF ec = Rubout THEN { IF rejectThisOne THEN REJECT; IF h.ruboutProc # NIL THEN h.ruboutProc[h] ELSE { h.in.ResetUserAbort[ ! ANY => CONTINUE]; h.in.Reset[ ! ANY => CONTINUE]; h.out.PutF[IF h.readIOSignalRope # NIL THEN h.readIOSignalRope ELSE " XXX\n" ! ANY => CONTINUE]; }; GOTO DoLoop; }; ViewerIO.NotAllowed => { IF rejectThisOne THEN REJECT; h.in.ResetUserAbort[ ! ANY => CONTINUE]; h.in.Reset[ ! ANY => CONTINUE]; h.out.PutRope[" ViewerIO.NotAllowed => XXX\n" ! ANY => CONTINUE]; GOTO DoLoop; }; IO.SyntaxError => { IF rejectThisOne THEN REJECT; h.in.ResetUserAbort[ ! ANY => CONTINUE]; h.in.Reset[ ! ANY => CONTINUE]; h.out.PutF["Syntax Error: %g", IO.rope[msg] ! ANY => CONTINUE]; GOTO DoLoop; }; IO.EndOfStream => GOTO Destroyed; }; MyCharProc: IO.CharProc = { b: BOOL _ h.deliverWhenProc[char: char, stream: h.in ! ANY => { rejectThisOne _ TRUE; REJECT; }]; RETURN[quit: b, include: TRUE]; }; AvailCharProc: IO.CharProc = { RETURN[quit: NOT h.in.CharsAvail[], include: TRUE]; }; h.out.NewLine[ ! ANY => CONTINUE]; IF result # NIL THEN h.out.PutF[result ! ANY => { badRope _ result; result _ NIL; rejectThisOne _ TRUE; REJECT}]; h.out.NewLine[ ! ANY => CONTINUE]; IF h.in.EndOf[! ANY => GOTO Destroyed] THEN GOTO Destroyed; h.out.PutF[h.prompt ! ANY => { badRope _ result; rejectThisOne _ TRUE; h.prompt _ NIL; REJECT}]; IF h.promptProc # NIL THEN h.promptProc[h ! ANY => { rejectThisOne _ TRUE; REJECT}]; IF h.deliverWhenProc # NIL THEN commandLine _ h.in.GetSequence[MyCharProc] ELSE { [] _ h.in.PeekChar[]; -- wait DeliverWhenProc to activate commandLine _ h.in.GetSequence[AvailCharProc]; }; } EXITS DoLoop => LOOP; }}; -- end of input block TRUSTED { result _ h.clientProc[h, commandLine ! ABORTED => {result _ IF h.evalABORTEDRope # NIL THEN h.evalABORTEDRope ELSE " ...Aborted\n"; CONTINUE}; IO.UserAborted => { s: IO.STREAM _ h.in; WITH abortee SELECT FROM a: IO.STREAM => s _ a; ENDCASE; s.ResetUserAbort[ ! ANY => CONTINUE]; h.in.Reset[ ! ANY => CONTINUE]; result _ NIL; IF h.evalUserAbortedRope # NIL THEN result _ h.evalUserAbortedRope ELSE h.out.PutF[" ...UserAbort %g\n", IO.rope[msg] ! ANY => CONTINUE]; CONTINUE; }; UNWIND => {result _ IF h.evalUNWINDRope # NIL THEN h.evalUNWINDRope ELSE " ...Unwound\n"; CONTINUE}; ]; }; ENDLOOP; EXITS Destroyed => NULL; }; IsACR: PUBLIC IO.DeliverWhenProc = { RETURN[char = '\n]; }; SetTerminateRequested: ENTRY PROC [h: ReadEvalPrint.Handle] = { ENABLE UNWIND => NULL; IF h.in # NIL THEN h.in.Close[! ANY => CONTINUE]; h.terminateRequested _ TRUE; }; WasTerminateRequested: ENTRY PROC [h: ReadEvalPrint.Handle] RETURNS [BOOL] = { ENABLE UNWIND => NULL; RETURN[h.terminateRequested]; }; StopHit: Menus.MenuProc = TRUSTED { in: IO.STREAM _ NARROW[clientData, ReadEvalPrint.Handle].in; in.SetUserAbort[]; }; ViewerEvent: ViewerEvents.EventProc = TRUSTED { SELECT event FROM destroy => { prop: REF _ ViewerOps.FetchProp[viewer, $ReadEvalPrint]; IF prop # NIL THEN { SetTerminateRequested[NARROW[prop, ReadEvalPrint.Handle]]; }; }; ENDCASE; }; Init: PROC = { [] _ ViewerEvents.RegisterEventProc[proc: ViewerEvent, event: destroy, filter: $Typescript]; }; Init[]; END. >ReadEvalPrintImpl.mesa A comman read-eval-print loop for use with viewers. Original version by P. Rovner March 30, 1983 3:34 pm Last Edited by L. Stewart, April 15, 1983 11:38 am Implementation private procedures [parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL] Initialization Ê d˜J™Jšœi™iJ™2J˜šÏk ˜ Jšœ œ˜%JšœœËœ˜õJšœœ"˜/Jšœœ˜(Jšœœ ˜Jšœ˜Jšœœœ˜Jšœ œ ˜Jšœœ˜(Jšœ œ ˜2Jšœ œ#˜1Jšœ œ%˜4—J˜Jšœœ˜ Jšœ œH˜\Jšœ˜Jšœ ˜Jš˜J˜šÏnœœœ5œœ.œœœ&œœœœ˜…Jšœœ˜$Jšœ˜Jšœœ˜Jšœ"˜"J˜Jšœ0œ˜7Jšœ˜Jšœ/˜/Jšœ<œ*˜iJšœ)˜)Jšœ”˜”Jšœ-˜-J˜—J™šžœœœ5œœ œœœœœœœœ˜ÞJšœœ˜$Jšœ˜Jšœ ˜ J˜J˜ J˜ Jšœ˜J˜—J˜šžœœœ˜/Jšœ˜J˜—J˜š žœœœ*œœ˜OJšœœœœ˜KJšœ˜J˜—J˜šžœœ˜4Jšœœœ˜Jšœ œœ˜Jšœœœ˜Jšœœ/˜AJ˜šœœ˜"šœœœ˜Jšœœ˜Jšœ˜J˜—šœœÏc7˜@Jšœ)œ˜0šœŸ˜*Jšœœœ˜Jšœœœ˜šœ œ˜Jšœœœ ˜Jšœ˜—Jšœœœ˜%Jšœœœ˜Jš œ œœœœ œœ˜hJšœ˜ J˜—šœŸ%˜3Jšœœœ˜Jšœœœ˜(Jšœœœ˜Jš œ œœœœœœ˜bJšœ˜ Jšœ˜—Jšœœ˜šœœœŸ˜3šžœ œ˜Jšœœœ˜(Jšœœœ˜Jšœœœ˜"Jšœœœ˜$Jšœœœ˜"J˜—Jšœœœ˜Jšœ œœ˜Jšœ˜ Jšœ˜—J˜šœœ˜ šœ ˜ Jšœœœ˜šœœ˜Jš œ œœœœ ˜;JšœŸ˜!—J˜—šœ œ œ˜"Jšœœœ˜Jšœœ˜*šœ˜Jšœœœ˜(Jšœœœ˜Jš œ œœœœ œœ˜`J˜—Jšœ˜ J˜—šœ˜Jšœœœ˜Jšœœœ˜(Jšœœœ˜Jšœ0œœ˜CJšœ˜ Jšœ˜—šœ˜Jšœœœ˜Jšœœœ˜(Jšœœœ˜Jšœœ œœ˜?Jšœ˜ Jšœ˜—Jšœœ ˜!Jšœ˜—šœ œ ˜šœœ0œ˜?Jšœœ˜Jšœ˜J˜—Jšœœ˜J˜—šœœ ˜Jšœœœ˜3J˜—Jšœœœ˜"šœ œœœ˜1Jšœ˜Jšœ œ˜ Jšœœ˜Jšœ˜ —Jšœœœ˜"Jš œœœ œœ ˜;šœœ˜Jšœ˜Jšœœ˜Jšœ œ˜Jšœ˜ —šœœœœ˜4Jšœœ˜Jšœ˜ —Jšœœœ+˜Jšœ˜JšœŸ#˜:Jšœ.˜.J˜—Jšœ˜—š˜Jšœ œ˜—JšœŸ˜Jšœ˜ šœ&˜&Jš œœœœœœ˜gšœ˜Jšœœœ˜šœ œ˜Jšœœœ ˜Jšœ˜—Jšœœœ˜%Jšœœœ˜Jšœ œ˜Jšœœœ˜BJšœ"œœœ˜GJšœ˜ Jšœ˜—Jš œœœœœœ˜dJ˜—J˜Jšœ˜—š˜Jšœ œ˜—Jšœ˜—J˜Jšœœœœ˜;J˜J™!J™šžœœœ˜?Jšœœœ˜Jš œœœœœ˜1Jšœœ˜Jšœ˜J˜—š žœœœœœ˜NJšœœœ˜Jšœ˜Jšœ˜—J˜šÏbœœ˜#JšœN™NJšœœœœ&˜