<<>> <> <> <> <> <<>> DIRECTORY Commander USING [CommandProc, Register], IO, RefText USING [AppendChar], Rope USING [FromRefText, ROPE], TJaM USING [Any, AtomFromRope, CommandProc, CvX, Def, ExecuteAtom, ExecuteRope, Exit, Frame, LineComplete, NewFrame, Number, Pop, Register, RopeFromAtom, Stop]; TJaMDriverImpl: CEDAR PROGRAM IMPORTS Commander, IO, RefText, Rope, TJaM ~ BEGIN OPEN TJaM; ROPE: TYPE ~ Rope.ROPE; STREAM: TYPE ~ IO.STREAM; Ref: TYPE ~ REF Rep; Rep: TYPE ~ RECORD[ frame: Frame, in, out: STREAM ¬ NIL ]; refKey: ATOM ~ $JaMInterpreter; promptKey: ATOM ~ AtomFromRope[".prompt"]; promptRope: ROPE ~ "(*) .print"; promptVal: Any ~ CvX[promptRope]; printKey: ATOM ~ AtomFromRope[".print"]; quitKey: ATOM ~ AtomFromRope[".quit"]; GetRef: SIGNAL RETURNS [Ref]; ApplyPrint: CommandProc ~ { self: Ref ~ SIGNAL GetRef[]; x: REF ~ Pop[frame]; WITH x SELECT FROM x: Number => WITH n: x SELECT FROM int => IO.Put1[self.out, IO.int[n.int]]; real => IO.Put1[self.out, IO.real[n.real]]; ENDCASE => ERROR; x: ATOM => IO.PutRope[self.out, RopeFromAtom[x]]; x: ROPE => IO.PutRope[self.out, x]; ENDCASE => IO.Put1[self.out, IO.refAny[x]]; }; Quit: ERROR ~ CODE; ApplyQuit: CommandProc ~ { ERROR Quit; }; AppendLine: PROC[text: REF TEXT, stream: STREAM] RETURNS[REF TEXT] ~ { DO char: CHAR ~ IO.GetChar[stream]; text ¬ RefText.AppendChar[text, char]; IF char='\n THEN EXIT; ENDLOOP; RETURN[text]; }; JaMInterpreterProcess: PROC[self: Ref] ~ { frame: Frame ~ self.frame; inner: PROC ~ { buffer: REF TEXT ~ NEW[TEXT[500]]; DO command: ROPE ¬ NIL; text: REF TEXT ¬ buffer; text.length ¬ 0; ExecuteAtom[frame, promptKey]; { DO text ¬ AppendLine[text, self.in]; command ¬ Rope.FromRefText[text]; IF LineComplete[command] THEN EXIT; ENDLOOP; ExecuteRope[frame: frame, rope: command ! Stop => CONTINUE; Exit => RESUME; Quit => EXIT; ]; }; ENDLOOP; }; Register[frame, AtomFromRope[".print"], ApplyPrint]; Register[frame, AtomFromRope[".quit"], ApplyQuit]; Def[frame, promptKey, promptVal]; inner[]; }; Run: Commander.CommandProc ~ { self: Ref ~ NEW[Rep ¬ [frame: NewFrame[]]]; self.in ¬ cmd.in; self.out ¬ cmd.out; JaMInterpreterProcess[self ! GetRef => RESUME [self]]; }; Commander.Register["TJaM", Run, "TJaM read-eval-print loop"]; END.