<> <> <> DIRECTORY AMTypes, Commander, Interpreter, IO, List, PrintTV, Rope, StructuredStreams, SymTab, UnparserBuffer; PrettyPrintCommands: CEDAR PROGRAM IMPORTS Commander, Interpreter, IO, List, PrintTV, Rope, StructuredStreams, SymTab, UnparserBuffer = BEGIN ROPE: TYPE = Rope.ROPE; depth: INT _ 4; maxLength: INT _ 32; width: INT _ 60; verbose: BOOL _ FALSE; PrettyPrint: PROC [cmd: Commander.Handle] RETURNS [result: REF ANY _ NIL, msg: ROPE _ NIL]--Commander.CommandProc-- = BEGIN thisDepth: INT _ depth; thisMaxLength: INT _ maxLength; thisWidth: INT _ width; thisVerbose: BOOLEAN _ verbose; noResult: BOOL; exprRope: ROPE; val: AMTypes.TV; errRope: ROPE; in: IO.STREAM _ IO.RIS[cmd.commandLine]; out: IO.STREAM _ cmd.out; ubh: UnparserBuffer.Handle _ UnparserBuffer.NewInittedHandle[[output: [stream[out]]]]; put: IO.STREAM; symTab: SymTab.Ref; DO switch: CHAR; sticky: BOOLEAN _ FALSE; [] _ in.SkipWhitespace[]; IF in.EndOf[] THEN RETURN [NIL, "No expression to PrettyPrint"]; IF in.PeekChar[] # '/ THEN EXIT; IF in.GetChar[] # '/ THEN ERROR; IF in.EndOf[] THEN RETURN [NIL, "No switch after slash"]; IF in.PeekChar[] = '/ THEN BEGIN IF in.GetChar[] # '/ THEN ERROR; sticky _ TRUE; IF in.EndOf[] THEN RETURN [NIL, "No switch after double slash"]; END; switch _ in.GetChar[]; [] _ in.SkipWhitespace[]; IF (IF NOT in.EndOf[] THEN in.PeekChar[] = ': ELSE FALSE) THEN [] _ in.GetChar[]; IF Rope.Find["vVwWdDlL", Rope.FromChar[switch]] >= 0 THEN { IF in.EndOf[] THEN RETURN [NIL, "No value for switch"]; } ELSE RETURN [NIL, "Invalid switch"]; SELECT switch FROM 'v, 'V => {thisVerbose _ in.GetBool[]; IF sticky THEN verbose _ thisVerbose}; 'l, 'L => {thisMaxLength _ in.GetInt[]; IF sticky THEN maxLength _ thisMaxLength}; 'd, 'D => {thisDepth _ in.GetInt[]; IF sticky THEN depth _ thisDepth}; 'w, 'W => {thisWidth _ in.GetInt[]; IF sticky THEN width _ thisWidth}; ENDCASE => NULL; ENDLOOP; ubh.margin _ thisWidth; put _ StructuredStreams.Create[ubh]; exprRope _ in.GetLineRope[]; TRUSTED {symTab _ LOOPHOLE[List.Assoc[$SymTab, cmd.propertyList]]}; IF symTab = NIL THEN { symTab _ SymTab.Create[]; [] _ List.PutAssoc[key: $SymTab, val: symTab, aList: cmd.propertyList]; }; [val, errRope, noResult] _ Interpreter.Evaluate[rope: exprRope, symTab: symTab]; IF errRope.Length[] # 0 THEN out.PutRope[Rope.Cat["Error: ", errRope]] ELSE IF noResult THEN out.PutRope["(No result)"] ELSE PrintTV.Print[tv: val, put: put, depth: thisDepth, width: thisMaxLength, verbose: thisVerbose]; put.PutRope["\n"]; put.Close[]; END; Commander.Register[key: "PrettyPrint", proc: PrettyPrint, interpreted: FALSE, doc: " PrettyPrint (/v bool | /d int | /l int | /w int)* expression evaluates the expression and prettily prints it. The switches may give values for the verbosity (default FALSE), depth (default 4), maximum list length (default 32), and target width (default 60) of the printout. Doubling slash makes it sticky."]; END.