<> <> <> DIRECTORY Commander, EditedStream, IO, List, Menus, Misp, Process, ProcessProps, <> Rope, ViewerClasses, ViewerIO; MispAlone: CEDAR PROGRAM IMPORTS Commander, EditedStream, IO, List, Menus, Misp, Process, ProcessProps, --ReadEvalPrint,-- Rope, ViewerIO = BEGIN InterpreterData: TYPE = REF InterpreterDataRep; InterpreterDataRep: TYPE = RECORD [ process: UNSAFE PROCESS, stop: REF BOOL]; ReadEvalPrint: PROC [from, to: IO.STREAM, env: Misp.Environment, cwd: Rope.ROPE, stopRef: REF BOOL] = BEGIN InnerReadEvalPrint: PROC = { raw, cooked: REF ANY _ NIL; Flush: PROC = { to.PutRope[" ... flushing input ... "]; WHILE from.CharsAvail[] > 0 DO [] _ from.GetChar[] ENDLOOP; to.PutRope[" ... done flushing\n"]; }; DO { ENABLE ABORTED => GOTO Abort; to.PutF["%lMisp>%l ", IO.rope["b"], IO.rope["B"]]; raw _ from.GetRefAny[ ! IO.EndOfStream => EXIT; IO.Error => { IF ec = $StreamClosed THEN EXIT; to.PutRope["IO Error on input"]; Flush[]; LOOP; }; EditedStream.Rubout => { to.PutRope[" -- \n"]; LOOP; }; ]; cooked _ Misp.Eval[raw, env, NIL ! Misp.Stop => { to.PutF["Stopped, at stack = %g", IO.rope[Misp.PrintValRope[stack]]]; stopRef^ _ FALSE; Flush[]; LOOP; }; Misp.Error => { to.PutF["%g\n Stack: %g\n", IO.rope[msg], IO.rope[Misp.PrintValRope[stack]]]; LOOP; }; Misp.Throw => { to.PutF["Uncaught Throw -- signal: %g, value: %g\n Stack: %g\n", IO.atom[atom], IO.rope[Misp.PrintValRope[value]], IO.rope[Misp.PrintValRope[stack]]]; LOOP; }; ]; to.PutF["%g\n", IO.rope[Misp.PrintValRope[cooked]]]; EXITS Abort => { to.PutRope[" ... aborted"]; Flush[]; }; } ENDLOOP; cwd _ cwd; }; ProcessProps.AddPropList[List.PutAssoc[$WorkingDirectory, cwd, NIL], InnerReadEvalPrint]; cwd _ cwd; END; MispCommand: Commander.CommandProc = BEGIN in, out: IO.STREAM; v: ViewerClasses.Viewer; env: Misp.Environment; cwd: Rope.ROPE _ NARROW[ProcessProps.GetProp[$WorkingDirectory]]; id: InterpreterData _ NEW [InterpreterDataRep _ [ process: NIL, stop: NEW [BOOL _ FALSE] ]]; [in, out] _ ViewerIO.CreateViewerStreams[Rope.Cat["Misp Interpreter: WD = ", cwd]]; v _ ViewerIO.GetViewerFromStream[out]; Menus.AppendMenuEntry[v.menu, Menus.CreateEntry[name: "Stop", proc: Stop, clientData: id]]; Menus.AppendMenuEntry[v.menu, Menus.CreateEntry[name: "STOP!", proc: StopHard, clientData: id]]; env _ Misp.NewEnvironment[name: "Root", in: in, out: out, sizeGuess: 200, stop: [ShouldStop, id.stop]]; Misp.DefinePrimitives[env]; TRUSTED {Process.Detach[id.process _ FORK ReadEvalPrint[in, out, env, cwd, id.stop]]}; END; ShouldStop: PROC [data: REF] RETURNS [abort: BOOL _ FALSE] --Interpreter.AbortProc-- = { stop: REF BOOL _ NARROW[data]; abort _ stop # NIL AND stop^; }; Stop: PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift, control: BOOL _ FALSE] --Menus.ClickProc-- = { id: InterpreterData _ NARROW[clientData]; id.stop^ _ TRUE; }; StopHard: PROC [parent: REF ANY, clientData: REF ANY _ NIL, mouseButton: Menus.MouseButton _ red, shift, control: BOOL _ FALSE] --Menus.ClickProc-- = { id: InterpreterData _ NARROW[clientData]; TRUSTED {Process.Abort[id.process]}; }; <> <> <> <> <<>> <%l ", info: [name: "Misp Interpreter", iconic: FALSE]];>> <<>> <> <> <> <<>> <\n";>> <\n";>> <> <> <<>> <> <> <<>> <> <> <> < {>> <> <> <> <> <> <<}>> <<];>> <> <> <<};>> <<>> <> <<[h: ReadEvalPrint.Handle, command: ROPE] RETURNS [result: ROPE _ NIL]>> <<>> <> <> <> <<>> <> <> < EXIT;>> <<];>> <<>> <> <> <> <> <<};>> Commander.Register[ key: "Misp", proc: MispCommand, doc: "Opens a new viewer for interacting with the Misp interpreter"] END.