edited by Teitelman December 3, 1982 2:15 pm
DIRECTORY
Atom USING [GetPName],
Convert USING [MapValue],
IO USING [GreenwichMeanTime, PutBlock, PutChar, ROPE, STREAM, TV, Type, UserAbort, Value],
PrintTV USING [Print, PrintRef, PrintType, PutClosure, PutProc],
Rope USING [ROPE, Text, Map]
;
OutputImpl: CEDAR PROGRAM
IMPORTS Atom, Convert, IO, Rope, PrintTV
EXPORTS IO
= BEGIN OPEN IO;
Put: PUBLIC PROC [stream: STREAM, v1, v2, v3: Value ← [null[]]] = {
Put1[v1, stream];
Put1[v2, stream];
Put1[v3, stream];
}; -- of Put
PutL, PutList: PUBLIC PROC [stream: STREAM, list: LIST OF Value] = {
FOR l: LIST OF READONLY Value ← list, l.rest UNTIL l = NIL
DO
Put1[l.first, stream];
ENDLOOP;
}; -- of PutList
Put1: PROC [v: Value, stream: STREAM] = TRUSTED { -- v is discriminated unsafely
PrintRefAny: PROCEDURE [stream: STREAM, ref: REF READONLY ANY] = CHECKED {
PrintTV.PrintRef[ref: ref, depth: 4, put: StreamToPutClosure[stream]];
}; -- of PrintRefAny
PrintAtom: PROCEDURE [stream: STREAM, atom: ATOM] = CHECKED {
IF atom = NIL THEN PrintRefText[stream, "NIL"]
ELSE PrintRopeText[stream, Atom.GetPName[atom]];
}; -- of PrintAtom
PrintString: PROCEDURE[stream: STREAM, str: LONG STRING] = TRUSTED { -- POINTER
IF str = NIL THEN RETURN;
FOR i: CARDINAL IN [0.. str.length) DO
stream.PutChar[str[i]];
ENDLOOP;
};-- of PrintString
PrintDecimal: PROCEDURE [stream: STREAM, n: LONG INTEGER] = CHECKED {
PrintDecimal1: PROC[char: CHARACTER] = CHECKED {stream.PutChar[char]};
Convert.MapValue[put: PrintDecimal1, value: [signed[n]]];
}; -- of PrintDecimal
PrintOctal: PROCEDURE [stream: STREAM, n: LONG CARDINAL] = CHECKED {
PrintOctal1: PROC[char: CHARACTER] = CHECKED {stream.PutChar[char]};
Convert.MapValue[put: PrintOctal1, value: [unsigned[n, 8]]];
IF n >= 8 THEN stream.PutChar['B];
}; -- of PrintOctal
PrintReal: PROCEDURE [stream: STREAM, r: REAL] = CHECKED {
periodSeen: BOOLEANFALSE;
PrintReal1: PROC[char: CHARACTER] = CHECKED {
IF char = '. THEN periodSeen ← TRUE;
stream.PutChar[char];
};
Convert.MapValue[put: PrintReal1, value: [real[r]]];
IF ~periodSeen THEN {stream.PutChar['.]; stream.PutChar['0]};
}; -- of PrintReal
PrintTime: PROC [stream: STREAM, t: GreenwichMeanTime] = CHECKED {
PrintTime1: PROC[char: CHARACTER] = CHECKED {stream.PutChar[char]};
Convert.MapValue[put: PrintTime1, value: [time[t]]];
}; -- of PrintTime
IF UserAbort[stream] THEN ERROR ABORTED;
WITH v SELECT FROM
null => NULL;
atom => PrintAtom[stream, value];
boolean => PrintRefText[stream, IF value THEN "TRUE" ELSE "FALSE"];
character => stream.PutChar[value];
cardinal => PrintDecimal[stream, value];
integer => PrintDecimal[stream, value];
real => PrintReal[stream, value];
refAny => PrintRefAny[stream, value];
rope => PutRope[stream, value];
string => PrintString[stream, value];
text => PrintRefText[stream, value];
time => PrintTime[stream, value];
tv => PutTV[stream, value];
type => PutType[stream, value];
ENDCASE;
}; -- of Put1
PutTV: PUBLIC PROC[stream: STREAM, tv: TV, depth: INT ← 4, width: INT ← 32, verbose: BOOLFALSE] = {
PrintTV.Print[tv: tv, depth: depth, width: width, verbose: verbose, put: StreamToPutClosure[stream]];
};
PutType: PUBLIC PROC[stream: STREAM, type: Type, depth: INT ← 4, width: INT ← 32, verbose: BOOLEANFALSE] = {
PrintTV.PrintType[type: type, put: StreamToPutClosure[stream], depth: depth, width: width, verbose: verbose];
};
PutRope: PUBLIC PROCEDURE [self: STREAM, r: Rope.ROPE] = {
WITH r SELECT FROM
t: Rope.Text => PrintRopeText[stream: self, text: t];
ENDCASE => -- rope is not flat. Must use Rope.Map
{PrintChar: PROC [char: CHAR] RETURNS [BOOL] = CHECKED
{self.PutChar[char]; RETURN[FALSE]};
[] ← Rope.Map[base: r, action: PrintChar];
};
}; -- of PutRope
miscellaneous
PrintRopeText: PROCEDURE [stream: STREAM, text: Rope.Text] = TRUSTED INLINE { -- LOOPHOLE
PrintRefText[stream, LOOPHOLE[text, REF READONLY TEXT]];
};
PrintRefText: PROCEDURE [stream: STREAM, text: REF READONLY TEXT] = CHECKED INLINE {
IF text # NIL THEN stream.PutBlock[text]};
StreamToPutClosure: PROC [stream: STREAM] RETURNS[PrintTV.PutClosure] = TRUSTED {
RETURN[PrintTV.PutClosure[proc: LOOPHOLE[stream.streamProcs.putChar, PrintTV.PutProc], data: stream]];
};
END.
8-Mar-82 23:59:55 added subrange, pointer, long pointer to PrintType
12-Mar-82 13:45:45 changed Put to come up for air, i.e. check userabort. Fixed PrintType to check BBFault.AddressFault.
6-Apr-82 13:12:24 changed PrintType to check for and print READONLY for REF types.
16-Apr-82 17:40:07 changed PrintType to check for and print READONLY for REF types.
24-Apr-82 20:42:58 added everyBodyKnowsThese, LIST OF TypeNames, for which unaesthetic /unnecessary to print their underType, e.g. REAL, ROPE, INT, etc.
June 29, 1982 11:54 am changed definition of PrintThisSignal to correspond to new way of handling signals in rttypes.
August 3, 1982 1:17 pm eliminated calls to AMBridge.RefFromTV by calling PrintTV rather than PrintRefAny.
August 26, 1982 10:25 am converted to use PrintTV rather than PrivateIO and hence TVStreamImpl
October 14, 1982 1:08 pm moved printproc stuff in here so tvstreamimpl could be eliminated.
Edited on April 30, 1983 1:02 am, by Teitelman
fixed putRope to insert \'s where appropriate. Stole code from PrintTVImpl.
changes to: PutEscape (local of PutRope) , PutRope