JaMIOImpl.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Maureen Stone, February 14, 1985 6:42:18 pm PST
Doug Wyatt, March 18, 1985 2:57:19 pm PST
McCreight December 22, 1986 7:07:02 pm PST
Bier, September 15, 1992 4:40 pm PDT
DIRECTORY
Basics USING [LowByte, LowHalf],
FS USING [Error, StreamOpen],
IO USING [Close, EndOf, EndOfStream, Error, GetBool, GetCedarTokenRope, GetChar, GetInt, GetLineRope, GetReal, GetTokenRope, int, Put1, PutChar, PutRope, real, refAny],
JaM USING [AGet, Any, Array, AtomToRope, Command, Dict, Error, ExecuteRope, Mark, Op, Pop, PopBool, PopInt, PopStream, PopRope, PushBool, PushInt, PushReal, PushRope, PushStream, ROPE, RopeToAtom, State, Stop, STREAM, TryToLoad, LineComplete],
JaMPrimitives USING [],
Loader USING [Error, Instantiate, Start],
PrincOps USING [ControlModule],
FileNames USING [FileWithSearchRules],
PFS,
Rope USING [FromChar];
JaMIOImpl: CEDAR PROGRAM
IMPORTS Basics, FileNames, FS, IO, JaM, PFS, Rope
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: BOOL;
[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 = RopeFile.Create[
name: FullName[file, ".jam", self ! NotFound => GOTO NotFound],
raw: FALSE];
rope: ROPE = PFS.RopeOpen[
fileName: PFS.PathFromRope[FullName[file, ".jam", self ! NotFound => GOTO NotFound]],
includeFormatting: FALSE].rope;
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];
};
};
>> -- hard to do this in PCedar
ApplyStream: PUBLIC PROC[self: State] = {
stream: STREAM;
write: BOOL = PopBool[self];
name: ROPE = PopRope[self];
fullName: ROPE = IF write THEN name ELSE FullName[name, NIL, self ! NotFound => GOTO NotFound];
stream ¬ OpenStream[fullName, write];
PushStream[self, stream];
EXITS NotFound => ERROR Error[OpenFailed, "file not found"];
};
ApplyReadItem: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOL ¬ 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.Put1[IO.int[x­]];
x: REF REAL => out.Put1[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.Put1[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];
};
ApplyIOChar: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOLEAN ¬ NOT stream.EndOf[];
IF ok THEN PushRope[self, Rope.FromChar[stream.GetChar[ ! IO.EndOfStream, IO.Error => {ok ¬ FALSE; CONTINUE}]]]
ELSE stream.Close[];
PushBool[self, ok];
};
ApplyIOBool: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOLEAN ¬ NOT stream.EndOf[];
IF ok THEN PushBool[self, stream.GetBool[ ! IO.EndOfStream, IO.Error => {ok ¬ FALSE; CONTINUE}]]
ELSE stream.Close[];
PushBool[self, ok];
};
ApplyIOInt: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOLEAN ¬ NOT stream.EndOf[];
IF ok THEN PushInt[self, stream.GetInt[ ! IO.EndOfStream, IO.Error => {ok ¬ FALSE; CONTINUE}]]
ELSE stream.Close[];
PushBool[self, ok];
};
ApplyIOReal: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOLEAN ¬ NOT stream.EndOf[];
IF ok THEN PushReal[self, stream.GetReal[ ! IO.EndOfStream, IO.Error => {ok ¬ FALSE; CONTINUE}]]
ELSE stream.Close[];
PushBool[self, ok];
};
ApplyIOLine: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOLEAN ¬ NOT stream.EndOf[];
IF ok THEN PushRope[self, stream.GetLineRope[ ! IO.EndOfStream, IO.Error => {ok ¬ FALSE; CONTINUE}]]
ELSE stream.Close[];
PushBool[self, ok];
};
ApplyIOToken: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOLEAN ¬ NOT stream.EndOf[];
IF ok THEN PushRope[self, stream.GetTokenRope[ ! IO.EndOfStream, IO.Error => {ok ¬ FALSE; CONTINUE}].token]
ELSE stream.Close[];
PushBool[self, ok];
};
ApplyIOCedarToken: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
ok: BOOLEAN ¬ NOT stream.EndOf[];
IF ok THEN PushRope[self, stream.GetCedarTokenRope[ ! IO.EndOfStream, IO.Error => {ok ¬ FALSE; CONTINUE}].token]
ELSE stream.Close[];
PushBool[self, ok];
};
ApplyIOClose: PUBLIC PROC[self: State] = {
stream: STREAM = PopStream[self];
stream.Close[];
};
END.