DIRECTORY
Atom USING [MakeAtom, PutProp],
Basics USING [LowByte],
Convert USING [RealFromRope, RopeFromReal],
FS USING [Error, StreamOpen],
IO,
PascalBasic,
PascalNoviceFiles,
PrincOpsUtils USING [LongCopy],
Real USING [DefaultSinglePrecision],
RefText USING [TrustTextAsRope],
Rope USING [Cat, Equal, Fetch, FromChar, Length],
ViewerIO USING [CreateViewerStreams];
PascalNoviceFilesImpl:
CEDAR
PROGRAM
IMPORTS Atom, Basics, Convert, FS, IO, PascalBasic, PrincOpsUtils, RefText, Rope, ViewerIO
EXPORTS PascalNoviceFiles =
BEGIN OPEN PascalBasic, PascalNoviceFiles;
V A R I A B L E S (all private)
Control: PascalTextFile;
Input: PUBLIC PascalTextFile;
Output: PUBLIC PascalTextFile;
Tty: PUBLIC PascalTextFile;
openFiles: MesaFilePtr ← NIL;
nilStream:
IO.
STREAM ←
IO.CreateStream[
streamProcs:
IO.CreateStreamProcs[
variety: inputOutput,
class: $NilStream,
getChar: NilGetChar, putChar: NilPutChar, endOf: NilEndOf,
unsafeGetBlock: NilUnsafeGetBlock,
unsafePutBlock: NilUnsafePutBlock,
close: NilClose],
streamData: NIL];
anonNo, ttyNo: PascalInteger ← 0;
P R O C E D U R E S
PrepareForTextRead:
UNSAFE
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
IF file.baseFile =
NIL
OR file.baseFile.in =
NIL
THEN
PascalAttachFile[file: @file.baseFile, dir: in, type: text];
END;
PrepareForTextWrite:
UNSAFE
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
IF file.baseFile =
NIL
OR file.baseFile.out =
NIL
THEN
PascalAttachFile[file: @file.baseFile, dir: out, type: text];
END;
PascalTextBREAK:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
NULL; -- !! Should do some sort of flush
END;
PascalTextGET:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
IF NOT file.validElement THEN PascalTextFinishGet[file];
file.validElement ← FALSE;
END;
PascalTextElement:
PUBLIC
PROCEDURE [file: PascalTextFilePtr]
RETURNS [PascalChar] =
TRUSTED BEGIN
IF NOT file.validElement THEN PascalTextFinishGet[file];
RETURN[file.element];
END;
PascalTextFinishGet:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
PrepareForTextRead[file];
file.element ← file.baseFile.in.GetChar[ !
IO.EndOfStream => GOTO EOF];
file.eoln ← FALSE;
SELECT file.element
FROM
IN ['A..'Z] =>
IF
NOT file.control.readUpperCase
THEN
file.element ← file.element - 'A + 'a;
IN ['a..'z] =>
IF
NOT file.control.readLowerCase
THEN
file.element ← file.element - 'a + 'A;
'\N
--CR-- => {
file.eoln ← TRUE; file.lineNo ← file.lineNo + 1; file.element ← ' };
IN [0C..' ) =>
IF NOT file.control.readAllControlChars THEN file.element ← ' ;
'Z - 100B --Ctrl-Z-- => GOTO EOF;
ENDCASE => NULL;
file.validElement ← TRUE;
EXITS
EOF => {
file.baseFile.eof ← file.eoln ← file.validElement ← TRUE;
file.element ← ' };
END;
PascalTextPUT:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
c: PascalChar;
PrepareForTextWrite[file];
SELECT file.element
FROM
IN ['A..'Z] =>
IF NOT file.control.writeUpperCase THEN c ← file.element - 'A + 'a;
IN ['a..'z] =>
IF NOT file.control.writeLowerCase THEN c ← file.element - 'a + 'A;
'\N --CR-- => c ← file.element;
IN [0C..' ) =>
IF NOT file.control.writeAllControlChars THEN file.element ← ' ;
ENDCASE => c ← file.element;
file.baseFile.out.PutChar[c];
END;
PascalTextRESET:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
PrepareForTextRead[file];
file.baseFile.in.Reset[];
file.baseFile.eof ← FALSE;
file.eoln ← TRUE;
file.lineNo ← 1;
file.element ← ' ;
file.validElement ← FALSE;
END;
PascalTextREWRITE:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
PrepareForTextWrite[file];
file.baseFile.out.Reset[];
file.baseFile.out.SetLength[0 !
IO.Error =>
{IF ec = NotImplementedForThisStream THEN CONTINUE}];
file.baseFile.eof ← file.baseFile.in # nilStream;
END;
PascalTextPAGE:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
BEGIN
PascalWriteLn[file: file];
PascalWriteChar[file: file, item: '\F --form feed--];
PascalWriteLn[file: file]
END;
PascalTextEOF:
PUBLIC
PROCEDURE [file: PascalTextFilePtr]
RETURNS [
BOOLEAN] =
TRUSTED BEGIN
IF NOT file.validElement THEN PascalTextFinishGet[file];
RETURN[file.baseFile.eof]
END;
PascalTextEOLN:
PUBLIC
PROCEDURE [file: PascalTextFilePtr]
RETURNS [
BOOLEAN] =
TRUSTED BEGIN
IF NOT file.validElement THEN PascalTextFinishGet[file];
RETURN[file.eoln]
END;
PascalBREAK:
PUBLIC
PROCEDURE [
file: PascalFilePtr, length: CARDINAL,
element: LONG POINTER] = {NULL}; -- !! Should be some form of Flush
PascalGET:
PUBLIC
UNSAFE
PROCEDURE [
file: PascalFilePtr, length: CARDINAL,
element: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED --] =
UNCHECKED BEGIN
PrepareForRead[file];
IF length = 1
THEN
element^ ← file.in.GetChar[ ! IO.EndOfStream => {file.eof ← TRUE; CONTINUE}]
ELSE
IF length # file.in.UnsafeGetBlock[[base: element, startIndex: 0,
count: length]] THEN file.eof ← TRUE;
END;
PascalPUT:
PUBLIC
PROCEDURE [
file: PascalFilePtr, length: CARDINAL,
element: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED --] =
TRUSTED BEGIN
PrepareForWrite[file];
IF length = 1
THEN
file.out.PutChar[LOOPHOLE[Basics.LowByte[LOOPHOLE[element^]]]]
ELSE file.out.UnsafePutBlock[[base: element, startIndex: 0, count: length]];
END;
PascalRESET:
PUBLIC
UNSAFE
PROCEDURE [
file: PascalFilePtr, length: CARDINAL,
element: LONG POINTER -- TO ARRAY[0..length) OF UNSPECIFIED --] =
UNCHECKED BEGIN
PrepareForRead[file];
file.in.SetIndex[0];
file.eof ← FALSE;
PascalGET[file, length, element];
END;
PascalREWRITE:
PUBLIC
PROCEDURE [
file: PascalFilePtr, length: CARDINAL ← 0,
element: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED -- ← NIL] =
TRUSTED BEGIN
PrepareForWrite[file];
file.out.Reset[];
file.out.SetLength[0 !
IO.Error =>
{IF ec = NotImplementedForThisStream THEN CONTINUE}];
file.eof ← TRUE;
END;
PascalRead,
PascalReadLong:
PUBLIC
UNSAFE
PROCEDURE [
file: PascalFilePtr, length: CARDINAL,
element: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED --,
item: LONG POINTER -- TO ARRAY[0..length/2) OF UNSPECIFIED --] =
UNCHECKED BEGIN
IF length = 1
THEN item^ ← element^
ELSE PrincOpsUtils.LongCopy[from: element, nwords: length/2, to: item];
PascalGET[file: file, length: length, element: element];
END;
PascalWrite,
PascalWriteLong:
PUBLIC
UNSAFE
PROCEDURE [
file: PascalFilePtr, length: CARDINAL,
element: LONG POINTER TO -- ARRAY[0..length/2) OF -- UNSPECIFIED,
item: LONG POINTER TO -- ARRAY[0..length/2) OF -- UNSPECIFIED] =
UNCHECKED BEGIN
IF length = 1
THEN element^ ← item^
ELSE PrincOpsUtils.LongCopy[from: item, nwords: length/2, to: element];
PascalPUT[file: file, length: length, element: element];
END;
PascalEOF:
PUBLIC
PROCEDURE [file: PascalFilePtr]
RETURNS [
BOOLEAN] =
TRUSTED {
RETURN[IF file^ = NIL THEN TRUE ELSE file.eof]};
PascalReadLn:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
WHILE NOT PascalTextEOLN[file] DO PascalTextGET[file] ENDLOOP;
PascalTextGET[file];
END;
PascalWriteLn:
PUBLIC
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
PrepareForTextWrite[file];
file.baseFile.out.PutChar[('\N -- CR -- )];
IF file.baseFile.in = nilStream THEN file.element ← ' ;
END;
PascalReadInteger:
PUBLIC
PROCEDURE [file: PascalTextFilePtr]
RETURNS [PascalInteger] =
TRUSTED BEGIN
PrepareForTextRead[file];
SkipBlanks[file];
SELECT file.element
FROM
'- => {PascalTextGET[file]; RETURN[-ReadDecimal[file].n]};
'+ => {PascalTextGET[file]; RETURN[ReadDecimal[file].n]};
ENDCASE => RETURN[ReadDecimal[file].n];
END;
SkipBlanks:
PROCEDURE [file: PascalTextFilePtr] =
TRUSTED BEGIN
WHILE
NOT PascalTextEOF[file]
AND
(
SELECT file.element
FROM
'-, '+, IN ['0..'9], '., IN ['a..'z], IN ['A..'Z] => FALSE,
ENDCASE => TRUE) DO PascalTextGET[file] ENDLOOP;
END;
ReadDecimal:
PROCEDURE [file: PascalTextFilePtr]
RETURNS [n, digitCount: PascalInteger] =
TRUSTED BEGIN
n ← 0;
digitCount ← 0;
IF
NOT PascalTextEOF[file]
AND file.element
NOT
IN ['0..'9]
THEN
SIGNAL NumericInputError;
WHILE file.element
IN ['0..'9]
DO
n ← 10*n + (file.element - '0);
digitCount ← digitCount + 1;
PascalTextFinishGet[file];
ENDLOOP;
END;
PascalWriteInteger:
PUBLIC
PROCEDURE [
file: PascalTextFilePtr, item: PascalInteger,
fieldMinLength: PascalInteger ← -1] =
TRUSTED BEGIN
sayMinus: BOOLEAN ← FALSE;
digits: ARRAY [0..15] OF [0..9];
nDigits: [0..15] ← 0;
i: PascalInteger;
stream: IO.STREAM;
PrepareForTextWrite[file];
stream ← file.baseFile.out;
IF NOT fieldMinLength IN [0..1] THEN stream.PutChar[' ];
IF sayMinus ← item < 0
THEN {
item ← -item; fieldMinLength ← fieldMinLength - 1};
IF item = 0 THEN {digits[0] ← 0; nDigits ← 1}
ELSE
WHILE item # 0
DO
digits[nDigits] ← item MOD 10;
nDigits ← nDigits + 1;
item ← item/10;
ENDLOOP;
FOR i IN [1..fieldMinLength - nDigits] DO stream.PutChar[' ] ENDLOOP;
IF sayMinus THEN stream.PutChar['-];
FOR i
DECREASING
IN [0..nDigits)
DO
stream.PutChar['0 + digits[i]] ENDLOOP;
IF file.baseFile.in = nilStream THEN file.element ← '0 + digits[0];
END;
PascalReadReal:
PUBLIC
PROCEDURE [file: PascalTextFilePtr]
RETURNS [PascalReal] =
TRUSTED BEGIN
s: REF TEXT ← NEW[TEXT[50]];
s.length ← 0;
PrepareForTextRead[file];
SkipBlanks[file];
WHILE
(
SELECT file.element
FROM
IN ['a..'z], IN ['A..'Z], '+, '-, '., IN ['0..'9] => TRUE,
ENDCASE => FALSE) DO
s[s.length] ← file.element;
s.length ← s.length + 1;
PascalTextFinishGet[file];
ENDLOOP;
RETURN[Convert.RealFromRope[RefText.TrustTextAsRope[s]]];
END;
PascalWriteReal:
PUBLIC
PROCEDURE [
file: PascalTextFilePtr, item: PascalReal,
fieldMinLength, fracLength: PascalInteger ← -1] =
TRUSTED BEGIN
shortFracLength: INTEGER ← fracLength;
PrepareForTextWrite[file];
IF
NOT fieldMinLength
IN [0..1]
THEN
file.baseFile.out.PutChar[' ];
PascalWriteString[file, Convert.RopeFromReal[
from: item,
precision:
IF fracLength < 0 THEN Real.DefaultSinglePrecision ELSE shortFracLength], fieldMinLength];
END;
PascalReadChar:
PUBLIC
PROCEDURE [file: PascalTextFilePtr]
RETURNS [PascalChar] =
TRUSTED BEGIN
c: PascalChar;
PrepareForTextRead[file];
c ← PascalTextElement[file];
PascalTextGET[file];
RETURN[c];
END;
PascalWriteChar:
PUBLIC
PROCEDURE [
file: PascalTextFilePtr, item: PascalChar,
fieldMinLength: PascalInteger ← -1] =
TRUSTED BEGIN
i: PascalInteger;
PrepareForTextWrite[file];
FOR i
IN [1..fieldMinLength)
DO
file.baseFile.out.PutChar[' ] ENDLOOP;
IF fieldMinLength#0
THEN
BEGIN
IF file.baseFile.in = nilStream THEN file.baseFile.out.PutChar[item];
file.element ← item;
END;
END;
PascalReadBoolean:
PUBLIC
PROCEDURE [file: PascalTextFilePtr]
RETURNS [PascalBoolean] =
TRUSTED BEGIN
b: PascalBoolean;
PrepareForTextRead[file];
SkipBlanks[file];
SELECT file.element
FROM
'T, 't => b ← TRUE;
'F, 'f => b ← FALSE;
ENDCASE => {SIGNAL NumericInputError; b ← FALSE};
WHILE
(
SELECT file.element
FROM
IN ['a..'z], IN ['A..'Z] => TRUE,
ENDCASE => FALSE) DO PascalTextFinishGet[file] ENDLOOP;
RETURN[b];
END;
PascalWriteBoolean:
PUBLIC
PROCEDURE [
file: PascalTextFilePtr, item: PascalBoolean,
fieldMinLength: PascalInteger ← -1] =
TRUSTED BEGIN
IF
NOT fieldMinLength
IN [0..1]
THEN
PascalWriteChar[file, ' ];
PascalWriteString[file, IF item THEN "TRUE" ELSE "FALSE", fieldMinLength];
END;
PascalReadArrayOfChar, PascalReadLongArrayOfChar:
PUBLIC UNSAFE PROCEDURE [
file: PascalTextFilePtr,
item: CharArrayPtr, arrayBound: PascalInteger] =
UNCHECKED BEGIN
v: CharArrayConcretePtr ← item;
i: PascalInteger;
PrepareForTextRead[file];
FOR i
IN [1..arrayBound]
DO
v[i] ← PascalTextElement[file]; PascalTextGET[file]; ENDLOOP;
END;
PascalWriteArrayOfChar, PascalWriteLongArrayOfChar:
PUBLIC PROCEDURE [
file: PascalTextFilePtr,
item: CharArrayPtr,
arrayBound: PascalInteger, fieldMinLength: PascalInteger ← -1] =
TRUSTED BEGIN
v: CharArrayConcretePtr ← LOOPHOLE[item];
i, arrayLim: PascalInteger;
PrepareForTextWrite[file];
FOR i
IN [arrayBound..fieldMinLength)
DO
file.baseFile.out.PutChar[' ] ENDLOOP;
arrayLim ←
IF fieldMinLength < 0 THEN arrayBound ELSE MIN[fieldMinLength, arrayBound];
FOR i
IN [1..arrayLim]
DO
file.baseFile.out.PutChar[v[i]] ENDLOOP;
IF file.baseFile.in =
NIL
AND
((fieldMinLength < 0 AND arrayLim > 0) OR fieldMinLength>0) THEN
file.element ← IF arrayLim > 0 THEN v[arrayLim] ELSE ' ;
END;
ReadString:
PRIVATE
PROCEDURE [file: PascalTextFilePtr]
RETURNS [r:
ROPE]=
TRUSTED BEGIN
PrepareForTextRead[file];
IF file.baseFile.in = NIL THEN PascalTextRESET[file];
r ← "";
WHILE
NOT PascalTextEOLN[file]
AND
NOT file.baseFile.eof
DO
r ← Rope.Cat[r, Rope.FromChar[file.element]];
PascalTextGET[file];
ENDLOOP;
END;
PascalWriteString,
PascalWriteLongString:
PUBLIC
PROCEDURE [
file: PascalTextFilePtr, item: ROPE, fieldMinLength: PascalInteger ← -1] =
TRUSTED BEGIN
i, len, stringLim: PascalInteger;
PrepareForTextWrite[file];
len ← item.Length[];
FOR i
IN [len..fieldMinLength)
DO
file.baseFile.out.PutChar[' ] ENDLOOP;
stringLim ← IF fieldMinLength < 0 THEN len ELSE MIN[fieldMinLength, len];
FOR i
IN [0..stringLim)
DO
file.baseFile.out.PutChar[Rope.Fetch[item, i]] ENDLOOP;
IF file.baseFile.in =
NIL
AND
((fieldMinLength < 0 AND stringLim > 0) OR fieldMinLength>0) THEN
file.element ← IF stringLim > 0 THEN Rope.Fetch[item, stringLim-1] ELSE ' ;
END;
PascalCleanupFiles:
PUBLIC
PROCEDURE [] =
BEGIN
ENABLE
IO.Error =>
{IF ec = NotImplementedForThisStream THEN CONTINUE};
FOR f: MesaFilePtr ← openFiles, f.openFileLink
WHILE f#
NIL
DO
IF f.in # NIL THEN f.in.Flush[];
IF f.out # NIL THEN f.out.Flush[];
IF f.inSource # NIL THEN f.inSource.Flush[];
IF f.inSource2 # NIL THEN f.inSource2.Flush[];
IF f.outDest # NIL THEN f.outDest.Flush[];
IF f.outDest2 # NIL THEN f.outDest2.Flush[];
ENDLOOP;
END;
CloseMesaFile:
PROCEDURE [f: MesaFilePtr] =
BEGIN
IF f.in # NIL THEN {f.in.Close[]; f.in ← NIL};
IF f.out # NIL THEN {f.out.Close[]; f.out ← NIL};
IF f.inSource # NIL THEN {f.inSource.Close[]; f.inSource ← NIL};
IF f.inSource2 # NIL THEN {f.inSource2.Close[]; f.inSource2 ← NIL};
IF f.outDest # NIL THEN {f.outDest.Close[]; f.outDest ← NIL};
IF f.outDest2 # NIL THEN {f.outDest2.Close[]; f.outDest2 ← NIL};
END;
PascalInventFileName:
PUBLIC
PROCEDURE [name:
ROPE ←
NIL]
RETURNS [PascalFile] =
BEGIN
openFiles ← z.NEW[MesaFile ← [name: name, openFileLink: openFiles]];
RETURN[LOOPHOLE[openFiles]];
END; -- end of PascalInventFileName
PascalAttachFile:
PUBLIC
PROCEDURE [
file: PascalFilePtr, dir: PascalFileDirection ← in,
type: PascalFileType ← text] =
TRUSTED BEGIN
name: ROPE ← NIL;
mFile: MesaFilePtr;
RequestFileName:
PROCEDURE[] =
TRUSTED BEGIN
PascalWriteLn[file: @Control];
PascalWriteString[file: @Control, item: "** File name = "];
name ← ReadString[file: @Control];
PascalReadLn[file: @Control];
END;
BEGIN -- for EXITS
IF file^ =
NIL
THEN {RequestFileName[]; file^ ← PascalInventFileName[name]}
ELSE name ← file.name;
As of this moment, file^ is a vaild non-NIL PascalFile. Unfortunately, we need
a REF to a MesaFile rather than a LONG POINTER, so that reference counting
will be turned on as we change the fields of this heap object. So, here we go. . .
mFile ← LOOPHOLE[file^];
Atom.PutProp[Atom.MakeAtom[name], $PascalFile, mFile];
CloseMesaFile[mFile];
SELECT
TRUE
FROM
Rope.Equal[s1: name, s2: "Tty", case:
FALSE] =>
BEGIN
h: IO.STREAM ← IO.ROS[];
h.Put[[rope["PascalTty"]], [integer[ttyNo]]];
name ← h.RopeFromROS[];
h.Close[];
ttyNo ← ttyNo+1;
GOTO UseWindow;
END;
Rope.Equal[s1: name, s2: "Nil", case:
FALSE] =>
{mFile.in ← mFile.out ← nilStream};
ENDCASE =>
BEGIN
IF Rope.Length[name]=0
THEN
BEGIN
h: IO.STREAM ← IO.ROS[];
h.Put[[rope["PascalAnonymous"]], [integer[anonNo]]];
name ← h.RopeFromROS[];
h.Close[];
anonNo ← anonNo+1;
GOTO UseWindow;
END;
SELECT dir
FROM
in, both =>
BEGIN
mFile.in ← FS.StreamOpen[name, $write !
FS.Error => IF error.group=user THEN GOTO UseWindow];
mFile.out ← nilStream;
--following code commented out due to laziness of Cedar 5.0 converter:
IF type = text THEN
BEGIN
mFile.inSource2 ← mFile.in;
[in: mFile.inSource, out: mFile.outDest] ←
ViewerIO.CreateViewerStreams[name];
mFile.in ← IO.CreateDribbleStream[stream: mFile.inSource2,
dribbleTo: mFile.outDest];
END;
END;
ENDCASE =>
-- out --
BEGIN
mFile.out ← FS.StreamOpen[name, $create !
FS.Error => IF error.group=user THEN GOTO UseWindow];
mFile.in ← nilStream;
--following code commented out due to laziness of Cedar 5.0 converter:
IF type = text THEN
BEGIN
mFile.outDest2 ← mFile.out;
[in: mFile.inSource, out: mFile.outDest] ←
ViewerIO.CreateViewerStreams[name];
mFile.out ← IO.CreateDribbleStream[stream: mFile.outDest2,
dribbleTo: mFile.outDest];
END;
END;
END;
EXITS
UseWindow =>
BEGIN
[in: mFile.in, out: mFile.out] ← ViewerIO.CreateViewerStreams[name: name];
END;
END;
END; -- of PascalAttachFile
PrepareForRead:
UNSAFE
PROCEDURE [file: PascalFilePtr] =
TRUSTED BEGIN
IF file^ =
NIL
OR file^.in =
NIL
THEN
PascalAttachFile[file: file, dir: in, type: binary];
END;
PrepareForWrite:
UNSAFE
PROCEDURE [file: PascalFilePtr] =
TRUSTED BEGIN
IF file^ =
NIL
OR file^.out =
NIL
THEN
PascalAttachFile[file: file, dir: out, type: binary];
END;
Stream operations
NilGetChar:
PROCEDURE [self:
IO.STREAM]
RETURNS [
CHARACTER] =
BEGIN
ERROR IO.EndOfStream[self];
END;
NilPutChar: PROCEDURE [self: IO.STREAM, char: CHARACTER] = {NULL};
NilEndOf:
PROCEDURE [self:
IO.STREAM]
RETURNS [
BOOLEAN] =
{RETURN[TRUE]};
NilUnsafeGetBlock:
PROCEDURE [self:
IO.STREAM,
block: IO.UnsafeBlock] RETURNS [INT] = {RETURN[0]};
NilUnsafePutBlock:
PROCEDURE [self:
IO.STREAM,
block: IO.UnsafeBlock] = {NULL};
NilClose:
PROCEDURE[self:
IO.STREAM, abort:
BOOLEAN ←
FALSE] =
{NULL};
Initialization
Input ← PascalTextFile[baseFile: PascalInventFileName[name: "PascalInput"]];
Output ← PascalTextFile[baseFile: PascalInventFileName[name: "PascalOutput"]];
Tty ← PascalTextFile[baseFile: PascalInventFileName[name: "Tty"]];
Control ← PascalTextFile[baseFile: PascalInventFileName[name: "PascalControl"]];
TRUSTED {[in: Control.baseFile.in, out: Control.baseFile.out] ←
ViewerIO.CreateViewerStreams[name: "PascalControl"]};
anonNo ← ttyNo ← 0;
TRUSTED {
PascalWriteString[file: @Control,
item: "Pascal Cedar Runtime of May 9, 1985"];
PascalWriteLn[file: @Control]};
END. -- PascalNoviceFilesImpl