JaMIOImpl.mesa
Stone, February 14, 1985 6:42:18 pm PST
Last edited by:
Doug Wyatt, November 21, 1983 1:12 pm
Maureen Stone January 9, 1985 4:19:29 pm PST
DIRECTORY
Basics USING [LowByte, LowHalf],
FS USING [Error, StreamOpen, OpenFile, Open],
IO USING [Close, EndOf, GetChar, int, Put, PutChar, PutRope, real, refAny],
JaM USING [AGet, Any, Array, AtomToRope, Command, Dict, Error, ExecuteRope, Mark, Op, Pop, PopBool, PopInt, PopStream, PopRope, PushBool, PushInt, PushStream, ROPE, RopeToAtom, State, Stop, STREAM, TryToLoad, LineComplete],
JaMPrimitives USING [],
Loader USING [Error, Instantiate, Start],
PrincOps USING [ControlModule],
FileNames USING [FileWithSearchRules],
RopeIO USING [FromFile];
JaMIOImpl: CEDAR PROGRAM
IMPORTS Basics, FS, IO, JaM, RopeIO, FileNames, Loader
EXPORTS JaMPrimitives
= BEGIN OPEN JaM;
BYTE: TYPE = [0..256);
IntToChar:
PROC[i:
INT]
RETURNS[
CHAR] =
INLINE {
RETURN[LOOPHOLE[Basics.LowByte[Basics.LowHalf[i]]]] };
CharToInt:
PROC[c:
CHAR]
RETURNS[
INT] =
INLINE {
RETURN[LOOPHOLE[c, BYTE]] };
NotFound: SIGNAL = CODE;
FullName:
PROC [name, extension:
ROPE, self: State]
RETURNS [fullName:
ROPE] = {
rules: REF ANY;
found: BOOLEAN;
[found, rules] ← TryToLoad[self, RopeToAtom[".searchrules"]];
IF ~found THEN rules ← NIL;
[fullName,] ← FileNames.FileWithSearchRules[root: name, defaultExtension: extension, requireExtension: FALSE, requireExact: TRUE, searchRules: rules];
IF fullName=NIL THEN SIGNAL NotFound ELSE RETURN[fullName];
};
OpenStream:
PROC[name:
ROPE, write:
BOOL ←
FALSE]
RETURNS[
STREAM] = {
msg: ROPE;
stream:
STREAM =
FS.StreamOpen[
fileName: name,
accessOptions: (
IF write
THEN $create
ELSE $read) !
FS.Error => IF error.group = user THEN msg ← error.explanation];
IF msg=NIL THEN RETURN[stream] ELSE ERROR Error[OpenFailed, msg];
};
Intrinsics
ApplyRun:
PUBLIC
PROC[self: State] = {
file: ROPE = PopRope[self];
rope:
ROPE = RopeIO.FromFile[FullName[file, ".jam", self !
NotFound => GOTO NotFound]];
IF JaM.LineComplete[rope] THEN ExecuteRope[self, rope ! Stop => CONTINUE]
ELSE ERROR JaM.Error[OpenFailed, "Missing ) or }\n"];
EXITS NotFound => ERROR Error[OpenFailed, "file not found"];
};
ApplyLoadBCD:
PUBLIC
PROC[self: State] = {
filename: ROPE ← PopRope[self];
msg: ROPE;
TRUSTED {
--extra block for TRUSTED and EXITS
file: FS.OpenFile;
prog: PrincOps.ControlModule;
filename ← FullName[filename, ".bcd", self ! NotFound => GOTO NotFound];
file ←
FS.Open[filename !
FS.Error => {IF error.group = user THEN msg ← error.explanation; GOTO FSError}];
[prog,] ← Loader.Instantiate[file: file !
Loader.Error => {msg ← message; GOTO LoadFailed}];
Loader.Start[prog];
EXITS
NotFound => ERROR Error[OpenFailed, "file not found"];
FSError => ERROR Error[OpenFailed, msg];
LoadFailed => ERROR Error[LoadFailed, msg];
};
};
ApplyStream:
PUBLIC
PROC[self: State] = {
write: BOOL = PopBool[self];
name: ROPE = PopRope[self];
stream:
STREAM = OpenStream[FullName[name,
NIL, self !
NotFound => GOTO NotFound], write];
PushStream[self, stream];
EXITS NotFound => ERROR Error[OpenFailed, "file not found"];
};
ApplyReadItem:
PUBLIC
PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOLEAN ← NOT stream.EndOf[];
IF ok THEN PushInt[self, CharToInt[stream.GetChar[]]]
ELSE stream.Close[];
PushBool[self, ok];
};
ApplyWriteItem:
PUBLIC
PROC[self: State] = {
item: INT = PopInt[self];
stream: STREAM = PopStream[self];
stream.PutChar[IntToChar[item]];
};
ApplyReadLine: PUBLIC PROC[self: State] = {
stream: STREAM ← PopStream[self];
s: StreamHandle ← GetStream[stream];
localline: STRING ← [256];
line: TextObject ← TextNew[localline];
found: BOOLEAN ← FALSE; string: String;
{ ENABLE UNWIND => TextFree[@line];
UNTIL s.endof[s] DO
c: CHARACTER ← s.get[s];
TextPut[@line,c]; found ← TRUE;
IF c=Ascii.CR THEN EXIT;
ENDLOOP;
IF found THEN string ← MakeString[TextRead[@line]];
};
TextFree[@line];
IF found THEN Push[self,string] ELSE KillStream[stream];
PushBoolean[self,found];
};
ApplyWriteBytes:
PUBLIC
PROC[self: State] = {
string: ROPE = PopRope[self];
stream: STREAM = PopStream[self];
stream.PutRope[string];
};
ApplyKillStream:
PUBLIC
PROC[self: State] = {
stream: STREAM = PopStream[self];
stream.Close[];
};
Print:
PROC[self: State, x: Any] = {
out: STREAM = self.out;
WITH x
SELECT
FROM
x: REF INT => out.Put[IO.int[x^]];
x: REF REAL => out.Put[IO.real[x^]];
x: ROPE => out.PutRope[x];
x: ATOM => out.PutRope[AtomToRope[x]];
x: STREAM => out.PutRope["<stream>"];
x: Command => out.PutRope["<cmd>"];
x: Op => out.PutRope["<op>"];
x: Array => PrintArray[self, x];
x: Dict => out.PutRope["<dict>"];
x: Mark => out.PutRope["<mark>"];
x: LIST OF REF ANY => PrintList[self, x];
x: LIST OF ROPE => LoopholePrintList[self, x];
x: LIST OF REF INT => LoopholePrintList[self, x];
x: LIST OF REF REAL => LoopholePrintList[self, x];
x: LIST OF LIST OF ATOM => LoopholePrintList[self, x];
ENDCASE => out.Put[IO.refAny[x]];
};
PrintArray:
PROC[self: State, array: Array] = {
out: STREAM = self.out;
out.PutRope["{ "];
FOR i:
INT
IN[0..array.length)
DO
Print[self, AGet[array, i]];
out.PutRope[" "];
ENDLOOP;
out.PutRope["}"];
};
LoopholePrintList:
PROC[self: State, list:
REF
ANY] =
TRUSTED {
--to force "general" lists
PrintList[self: self, list: LOOPHOLE[list]];
};
PrintList:
PROC[self: State, list:
LIST
OF
REF
ANY] = {
x: Any = Pop[self];
self.out.PutRope["LIST["];
FOR each:
LIST
OF
REF
ANY ← list, each.rest
WHILE each #
NIL
DO
Print[self, each.first];
IF each.rest#NIL THEN self.out.PutRope[ ", "];
ENDLOOP;
self.out.PutRope["]"];
};
ApplyPrint:
PUBLIC
PROC[self: State] = {
x: Any = Pop[self];
Print[self, x];
};
END.