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: BOOLEAN _ FALSE; 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: BOOL _ FALSE] = { 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: BOOLEAN _ FALSE] = { 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 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 by Teitelman December 3, 1982 2:15 pm miscellaneous 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  Κ– "Cedar" style˜J˜JšΟc,™,šΟk ˜ Jšœžœ ˜Jšœžœ ˜Jš žœžœ(žœžœžœ˜ZJšœžœ3˜@Jšœžœžœ ˜J˜J˜—J˜JšΠbl œžœž˜J˜Jšžœžœ˜)J˜Jšžœžœ˜ J˜Jšœžœžœžœ˜J˜š Οnœžœžœ žœ!ž˜CJ˜J˜J˜Jšžœ ˜ —J˜š œ œžœžœ žœžœžœ ž˜DJš žœžœžœžœžœž˜:šž˜Jšœ˜Jšžœ˜—Jšžœ˜—J˜š  œžœžœž œ˜Qš   œž œ žœžœžœžœž ˜KJ˜HJšžœ˜—š   œž œ žœžœž ˜>Jšžœžœžœ˜.Jšžœ,˜0Jšžœ˜—š   œž œ žœžœžœž œ ˜PJšžœžœžœžœ˜šžœžœžœžœ˜'J˜Jšžœ˜—Jšžœ˜—š   œž œ žœžœžœž œ˜GJš  œžœž œžœ˜FJ˜9Jšžœ˜—š   œž œ žœžœžœž œ˜GJš  œžœž œžœ˜DJ˜˜fJ˜——J˜Jšžœ˜J˜J˜DJ˜J˜w˜Jšœ;žœžœ˜R—Jšœ<žœžœ˜SJš œ.žœžœNžœžœžœ˜˜J˜uJ˜J˜iJ˜J˜^J˜[™.J™KJšœ Οr œ‘œ‘ œ‘™7—J™—…—κω