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.