DIRECTORY AMEvents USING [Debugged, Debugging], EditedStream USING [DeliverWhenProc, SetDeliverWhen, Rubout, IsACR], IO USING [ Close, -- EndOf, --EndOfStream, Error, GetTokenRope, PeekChar, PutF, PutRope, Reset, STREAM, EndOf, BreakProc], List USING [AList], MBQueue USING [Create, CreateMenuEntry, Queue], Menus USING [InsertMenuEntry, MenuProc], Process USING [Detach, GetCurrent, Abort], ProcessProps USING [PushPropList], ReadEvalPrint, Rope USING [ROPE, Concat, Length, Fetch], RuntimeError USING [UNCAUGHT], TypeScript USING [Create], ViewerClasses USING [Viewer, ViewerRec], ViewerEvents USING [EventProc, RegisterEventProc], ViewerIO USING [CreateViewerStreams], ViewerOps USING [AddProp, ComputeColumn, FetchProp]; ReadEvalPrintImpl: CEDAR MONITOR IMPORTS AMEvents, EditedStream, IO, MBQueue, Menus, Process, ProcessProps, Rope, RuntimeError, TypeScript, ViewerEvents, ViewerIO, ViewerOps EXPORTS ReadEvalPrint = BEGIN CreateViewerEvaluator: PUBLIC PROC [clientProc: ReadEvalPrint.ClientProc, prompt: Rope.ROPE _ NIL, info: ViewerClasses.ViewerRec _ [], edited: BOOL _ TRUE, deliverWhen: EditedStream.DeliverWhenProc _ NIL, clientData: REF ANY _ NIL, topLevel: BOOL _ TRUE] RETURNS [h: ReadEvalPrint.Handle] = { h _ NEW[ReadEvalPrint.RObject _ []]; h.clientProc _ clientProc; IF deliverWhen = NIL THEN deliverWhen _ EditedStream.IsACR; h.deliverWhenProc _ deliverWhen; h.menuHitQueue _ MBQueue.Create[]; h.prompt _ prompt; h.viewer _ TypeScript.Create[info: info, paint: FALSE]; h.clientData _ clientData; h.topLevel _ topLevel; ViewerOps.AddProp[h.viewer, $ReadEvalPrint, h]; [in: h.in, out: h.out] _ ViewerIO.CreateViewerStreams[name: NIL, viewer: h.viewer, editedStream: edited]; IF edited THEN EditedStream.SetDeliverWhen[h.in, 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: EditedStream.DeliverWhenProc _ NIL, clientData: REF ANY _ NIL, topLevel: BOOL _ FALSE] RETURNS [h: ReadEvalPrint.Handle] = { h _ NEW[ReadEvalPrint.RObject _ []]; h.clientProc _ clientProc; IF deliverWhen = NIL THEN deliverWhen _ EditedStream.IsACR; h.deliverWhenProc _ deliverWhen; h.prompt _ prompt; h.in _ in; h.out _ out; h.clientData _ clientData; h.topLevel _ topLevel; }; Stop: PUBLIC ENTRY PROC [h: ReadEvalPrint.Handle] = { ENABLE UNWIND => NULL; IF h.in # NIL THEN h.in.Close[! RuntimeError.UNCAUGHT => CONTINUE]; h.terminateRequested _ TRUE; }; MainLoop: PUBLIC PROC [h: ReadEvalPrint.Handle, forkAndDetach: BOOL _ TRUE, properties: List.AList] = { IF forkAndDetach THEN TRUSTED { Process.Detach[FORK Base[props: properties, rep: h]]; } ELSE Base[props: properties, rep: h]; }; Base: PROC [props: List.AList, rep: ReadEvalPrint.Handle] = { inner: PROC = { MainLoopInternal[rep]; }; IF props # NIL THEN ProcessProps.PushPropList[props, inner] ELSE inner[]; }; 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 TRUSTED{h.mainLoopProcess _ LOOPHOLE[Process.GetCurrent[], SAFE PROCESS]}; UNTIL WasTerminateRequested[h] DO {--1--ENABLE RuntimeError.UNCAUGHT => {rejectThisOne _ FALSE; REJECT}; {--2--ENABLE {-- these catch phrases protect the input operation only AMEvents.Debugging, AMEvents.Debugged => REJECT; ABORTED => { -- took a breakpoint and then aborted IF rejectThisOne OR NOT h.topLevel THEN REJECT; GOTO HandleAborted; }; UNWIND => IF NOT h.topLevel THEN REJECT ELSE GOTO DoLoop; RuntimeError.UNCAUGHT => REJECT; }; -- end "these catch phrases protect the input operation only" {--3--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. ELSE IF ec = SyntaxError THEN { h.in.Reset[ ! RuntimeError.UNCAUGHT => CONTINUE]; h.out.PutRope["Input Syntax Error" ! RuntimeError.UNCAUGHT => CONTINUE]; GOTO DoLoop; }; -- user destroyed the viewer. }; EditedStream.Rubout => { IF rejectThisOne THEN REJECT; IF h.ruboutProc # NIL THEN h.ruboutProc[h] ELSE { h.in.Reset[ ! RuntimeError.UNCAUGHT => CONTINUE]; h.out.PutF[IF h.readIOSignalRope # NIL THEN h.readIOSignalRope ELSE " XXX\n" ! RuntimeError.UNCAUGHT => CONTINUE]; }; GOTO DoLoop; }; IO.EndOfStream => GOTO Destroyed; }; -- end "3" catch phrases IF result # NIL THEN { h.out.PutF[result ! RuntimeError.UNCAUGHT => { badRope _ result; result _ NIL; rejectThisOne _ TRUE; REJECT}]; h.out.PutRope["\n" ! RuntimeError.UNCAUGHT => CONTINUE]; result _ NIL; }; IF h.in.EndOf[ ! RuntimeError.UNCAUGHT => GOTO Destroyed] THEN GOTO Destroyed; h.out.PutF[h.prompt ! RuntimeError.UNCAUGHT => { badRope _ result; rejectThisOne _ TRUE; h.prompt _ NIL; REJECT}]; IF h.promptProc # NIL THEN h.promptProc[h ! RuntimeError.UNCAUGHT => { rejectThisOne _ TRUE; REJECT}]; [] _ h.in.PeekChar[]; {--4-- breakProc: IO.BreakProc = { IF h.deliverWhenProc[char, NIL, h.in, NIL].activate THEN RETURN[break] ELSE RETURN[other]; }; commandLine _ h.in.GetTokenRope[breakProc ! RuntimeError.UNCAUGHT => { rejectThisOne _ TRUE; REJECT; }].token; IF commandLine.Length[] # 1 OR NOT h.deliverWhenProc[commandLine.Fetch[0], NIL, h.in, NIL].activate THEN commandLine _ Rope.Concat[ commandLine, h.in.GetTokenRope[breakProc ! RuntimeError.UNCAUGHT => { rejectThisOne _ TRUE; REJECT; }].token]; }; -- end 4 }; -- end 3 EXITS DoLoop => LOOP; HandleAborted => { h.in.Reset[ ! RuntimeError.UNCAUGHT => CONTINUE]; h.out.PutF[IF h.readABORTEDRope # NIL THEN h.readABORTEDRope ELSE " aborted\n" ! RuntimeError.UNCAUGHT => CONTINUE]; LOOP; }; }; -- end 2 }; -- end of input block (1) TRUSTED { result _ h.clientProc[h, commandLine ! ABORTED => { IF NOT h.topLevel THEN REJECT ELSE { result _ IF h.evalABORTEDRope # NIL THEN h.evalABORTEDRope ELSE " ...Aborted\n"; CONTINUE; }; }; UNWIND => { IF NOT h.topLevel THEN REJECT ELSE { result _ IF h.evalUNWINDRope # NIL THEN h.evalUNWINDRope ELSE " ...Unwound\n"; CONTINUE; }; }; ]; }; ENDLOOP; EXITS Destroyed => NULL; }; -- end MainLoopInternal WasTerminateRequested: ENTRY PROC [h: ReadEvalPrint.Handle] RETURNS [BOOL] = { ENABLE UNWIND => NULL; RETURN[h.terminateRequested]; }; StopHit: Menus.MenuProc = TRUSTED { h: ReadEvalPrint.Handle _ NARROW[clientData, ReadEvalPrint.Handle]; in: IO.STREAM _ h.in; Process.Abort[h.mainLoopProcess]; }; ViewerEvent: ViewerEvents.EventProc = TRUSTED { SELECT event FROM destroy => { prop: REF _ ViewerOps.FetchProp[viewer, $ReadEvalPrint]; IF prop # NIL THEN { Stop[NARROW[prop, ReadEvalPrint.Handle]]; }; }; ENDCASE; }; Init: PROC = { [] _ ViewerEvents.RegisterEventProc[proc: ViewerEvent, event: destroy, filter: $Typescript]; }; Init[]; END. ZReadEvalPrintImpl.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, December 2, 1983 10:35 pm Russ Atkinson, September 26, 1983 11:16 pm Last Edited by Paul Rovner, November 29, 1983 8:44 am IF h.bulletProof THEN { -- otherwise reject Inform: PROCEDURE = { ENABLE RuntimeError.UNCAUGHT => GO TO localOut; h.in.Reset[]; h.out.PutRope["\n"]; AMIO.PutSignal[h.out]; h.out.PutRope["\n"]; EXITS localOut => {}; }; IF rejectThisOne THEN REJECT; Inform[! RuntimeError.UNCAUGHT => CONTINUE]; GOTO DoLoop; }; wait until there's stuff to read, else GetTokenRope will raise EndOfStream break char (e.g. CR) included; won't raise EndOfStream Implementation private procedures [parent: REF, clientData: REF, mouseButton: MouseButton, shift, control: BOOL] Initialization Ê ™˜J™Jšœi™iJ™4J™*J™5J˜šÏk ˜ Jšœ œ˜%Jšœ œ2˜Dšœœ˜ JšœÏc œBœ˜o—Jšœœ ˜Jšœœ"˜/Jšœœ˜(Jšœœ˜*Jšœ œ˜"Jšœ˜Jšœœœ˜)Jšœ œœ˜Jšœ œ ˜Jšœœ˜(Jšœ œ ˜2Jšœ œ˜%Jšœ œ%˜4—J˜šœœ˜ š˜Jšœœj˜„—Jšœ˜Jšœ˜—J˜šÏnœœœ5œœ.œœ.œœœœ œœœ˜¤Jšœœ˜$Jšœ˜Jšœœœ"˜;Jšœ ˜ Jšœ"˜"J˜Jšœ0œ˜7Jšœ˜J˜Jšœ/˜/šœ˜Jšœ%œ*˜R—Jšœœ0˜>šœ˜JšœP˜PJšœ/˜/—Jšœ-˜-J˜—J™šŸœœœ5œœ œœ.œœœœ œœœ˜€Jšœœ˜$Jšœ˜Jšœœœ"˜;Jšœ ˜ J˜J˜ J˜ Jšœ˜J˜J˜—J˜šŸœœœœ˜5Jšœœœ˜Jš œœœœœ˜CJšœœ˜J˜—J˜š Ÿœœœ*œœ˜gJšœœœœ$˜WJšœ!˜%J˜—J˜šŸœœ3˜=Jšœœ˜)Jšœ œœ(˜;Jšœ ˜ J˜J˜—šŸœœ˜4Jšœœœ˜Jšœ œœ˜Jšœœœ˜Jšœœœž'˜AJ˜Jšœœœœ˜JJ˜šœœ˜"Jš œžœœœœ˜Fšœžœž7˜EJšœ)œ˜0šœž%˜3Jš œœœ œœ˜/Jšœ˜Jšœ˜—Jšœœœ œœœœ˜9šœ œœ˜ šœœž™,šŸœ œ™Jšœœœœ ™/Jšœ ™ Jšœ™Jšœ™Jšœ™Jšœ™J™—Jšœœœ™Jšœœœ™,Jšœ™ Jšœ™——Jšœž=˜Ašœžœ˜šœ ˜ Jšœœœ˜šœœ˜Jš œ œœœœ ˜;Jšœž˜ —šœœœ˜Jšœœœ˜1Jšœ2œœ˜HJšœ˜ Jšœž˜!—J˜—šœ˜Jšœœœ˜Jšœœœ˜*šœ˜Jšœœœ˜1Jš œ œœœœœœ˜rJ˜—Jšœ˜ J˜—Jšœœ ˜!Jšœž˜—J˜šœ ˜šœ˜šœ˜šœœ˜Jšœ˜Jšœ œ˜ Jšœœ˜Jšœ˜ ——Jšœ"œœ˜8Jšœ œ˜ J˜——Jš œœœ œœ ˜Nšœ˜šœœ˜Jšœ˜Jšœœ˜Jšœ œ˜Jšœ˜ ——šœ˜šœ˜šœœ˜Jšœœ˜Jšœ˜ ———šœ˜JšœJ™J—šœž˜šœ œ˜šœœœ ˜3Jšœœœœ˜&—Jšœ˜—šœ)˜)šœœ˜Jšœœ˜Jšœ˜Jšœ ˜ ——šœ˜Jšœœ)œœ ˜Gšœ˜šœ ˜ šœ˜Jšœ ˜ šœ˜šœœ˜Jšœœ˜Jšœ˜Jšœ ˜ ———Jšœ6™6————Jšœž˜ Jšœž ˜—š˜Jšœ œ˜šœ˜šœ ˜ Jšœœœ˜%—š œ œœœœ ˜NJšœœœ˜%—Jšœ˜Jšœ˜——Jšœž ˜ Jšœž˜šœ˜ šœ&˜&šœ˜ Jšœœ œ˜šœ˜Jš œ œœœœ˜PJšœ˜ Jšœ˜—J˜—šœ˜ Jšœœ œ˜šœ˜Jš œ œœœœ˜NJšœ˜ J˜—Jšœ˜—J˜—J˜—Jšœ˜—š˜Jšœ œ˜—Jšœž˜—J˜J™!J™š Ÿœœœœœ˜NJšœœœ˜Jšœ˜Jšœ˜—J˜šÏbœœ˜#JšœN™NJšœœ#˜CJšœœœ˜Jšœ!˜!Jšœ˜—J˜š  œœ˜/šœ˜šœ ˜ Jšœœ/˜8šœœœ˜Jšœœ˜)J˜—Jšœ˜—Jšœ˜—Jšœ˜—J™šŸœœ˜Jšœ\˜\J˜J˜—J™J˜J˜Jšœ˜—…—)