TJaMTest.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Doug Wyatt, March 26, 1985 2:02:22 pm PST
DIRECTORY
Commander USING [CommandProc, Register],
EditedStream USING [DeliverWhenProc, Rubout, SetDeliverWhen],
FS USING [ExpandName],
IO USING [GetChar, int, Put1, PutRope, real, refAny, STREAM],
List USING [AList, Assoc, PutAssoc],
Process USING [Detach],
ProcessProps USING [AddPropList, GetPropList],
RefText USING [AppendChar],
Rope USING [Concat, FromRefText, ROPE, Size, Substr],
TJaM USING [Any, AtomFromRope, CommandProc, CvX, Def, ExecuteAtom, ExecuteRope, Exit, Frame, LineComplete, NewFrame, Number, Pop, Register, RopeFromAtom, Stop],
ViewerIO USING [CreateViewerStreams];
TJaMTest: CEDAR PROGRAM
IMPORTS Commander, EditedStream, FS, IO, List, Process, ProcessProps, RefText, Rope, TJaM, ViewerIO
~ BEGIN OPEN TJaM;
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Ref: TYPE ~ REF Rep;
Rep: TYPE ~ RECORD[
frame: Frame,
in, out: STREAMNIL
];
refKey: ATOM ~ $JaMInterpreter;
AddProps: PROC[ref: Ref, wDir: ROPE, inner: PROC] ~ {
propList: List.AList ← NIL;
propList ← List.PutAssoc[key: refKey, val: ref, aList: propList];
propList ← List.PutAssoc[key: $WorkingDirectory, val: wDir, aList: propList];
ProcessProps.AddPropList[propList, inner];
};
GetRef: PROC RETURNS[Ref] ~ {
propList: List.AList ~ ProcessProps.GetPropList[];
val: REF ~ List.Assoc[key: refKey, aList: propList];
WITH val SELECT FROM ref: Ref => RETURN[ref] ENDCASE;
RETURN[NIL];
};
JaMDeliverWhen: EditedStream.DeliverWhenProc ~ {
ok: BOOLFALSE;
IF char='\n THEN {
rope: ROPE ~ Rope.FromRefText[buffer];
ok ← LineComplete[rope];
};
RETURN[appendChar: TRUE, activate: ok];
};
promptKey: ATOM ~ AtomFromRope[".prompt"];
promptRope: ROPE ~ "(*) .print";
promptVal: Any ~ CvX[promptRope];
printKey: ATOM ~ AtomFromRope[".print"];
quitKey: ATOM ~ AtomFromRope[".quit"];
ApplyPrint: PROC[frame: Frame] ~ {
self: Ref ~ 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: PROC[frame: Frame] ~ {
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, wDir: ROPE] ~ {
frame: Frame ~ self.frame;
inner: PROC ~ {
buffer: REF TEXT ~ NEW[TEXT[500]];
DO
command: ROPENIL;
text: REF TEXT ← buffer;
text.length ← 0;
ExecuteAtom[frame, promptKey];
{
DO
text ← AppendLine[text, self.in ! EditedStream.Rubout => GOTO Del];
command ← Rope.FromRefText[text];
IF LineComplete[command] THEN EXIT;
ENDLOOP;
ExecuteRope[frame: frame, rope: command !
Stop => CONTINUE;
Exit => RESUME;
Quit => EXIT;
];
EXITS Del => IO.PutRope[self.out, " -- <del>\n"];
};
ENDLOOP;
};
EditedStream.SetDeliverWhen[self.in, JaMDeliverWhen];
Register[frame, AtomFromRope[".print"], ApplyPrint];
Register[frame, AtomFromRope[".quit"], ApplyQuit];
Def[frame, promptKey, promptVal];
AddProps[self, wDir, inner];
};
GetWorkingDirectory: PROC RETURNS[ROPE] ~ {
dummyName: ROPE ~ "*";
fullFName: ROPE ~ FS.ExpandName[dummyName].fullFName;
RETURN[Rope.Substr[base: fullFName, len: Rope.Size[fullFName]-Rope.Size[dummyName]]];
};
JaMCommand: Commander.CommandProc ~ {
self: Ref ~ NEW[Rep ← [frame: NewFrame[]]];
wDir: ROPE ~ GetWorkingDirectory[];
viewerName: ROPE ~ Rope.Concat["TJaM ", wDir];
[in: self.in, out: self.out] ← ViewerIO.CreateViewerStreams[viewerName];
TRUSTED { Process.Detach[FORK JaMInterpreterProcess[self, wDir]] };
};
Commander.Register["TJaM", JaMCommand];
END.