/* uglynode.p

Ugly print a node to a file

*/

DEFINE INPUT PARAMETER parser AS HANDLE NO-UNDO.
DEFINE INPUT PARAMETER nodehandle AS INTEGER NO-UNDO.
DEFINE INPUT PARAMETER filename AS CHARACTER NO-UNDO.

{proparse/api/proparse.i parser}

DEFINE VARIABLE indent     AS INTEGER   NO-UNDO INITIAL -8.
DEFINE VARIABLE indentby   AS INTEGER   NO-UNDO INITIAL 4.
DEFINE VARIABLE needline   AS LOGICAL   NO-UNDO.


OUTPUT TO VALUE(filename).
RUN displayNode(nodehandle).
OUTPUT CLOSE.
RETURN.

PROCEDURE displayNode:
  DEFINE INPUT PARAMETER theNode AS INTEGER NO-UNDO.

  DEFINE VARIABLE child AS INTEGER NO-UNDO.
  DEFINE VARIABLE grandchild AS INTEGER NO-UNDO.
  DEFINE VARIABLE sibling AS INTEGER NO-UNDO.
  DEFINE VARIABLE temp AS INTEGER NO-UNDO.
  DEFINE VARIABLE havenode AS LOGICAL NO-UNDO.
  ASSIGN child = parserGetHandle().
  ASSIGN grandchild = parserGetHandle().
  ASSIGN sibling = parserGetHandle().

  /* If we don't do something with operators here, then
   * we'll wind up with prefix notation like: + 1 2.
   * Do a little extra work to turn that into infix notation: 1 + 2.
   * See the Syntax Trees section of the documentation for some explanation.
   */
  IF parserAttrGet(theNode,"operator") = "t":U THEN DO:
    parserNodeFirstChild(theNode,child).
    parserNodeNextSibling(child,sibling).
    RUN displayNode(child).
    PUT UNFORMATTED " " parserGetNodeText(theNode).
    RUN displayNode(sibling).
  END.

  ELSE DO:

    ASSIGN indent = indent + indentby.
    IF needline THEN DO:
      IF indent > 0 THEN PUT UNFORMATTED SKIP FILL(" ",indent).
    END.
    ELSE
      IF indent > 0 THEN PUT UNFORMATTED FILL(" ",indent).
    ASSIGN needline = TRUE.

    PUT UNFORMATTED parserGetNodeText(theNode).
    ASSIGN havenode = parserNodeFirstChild(theNode,child) <> "".
    DO WHILE havenode:
      /* If this is a new node head, run displayNode with it */
      IF parserNodeFirstChild(child, grandchild) <> "" THEN DO:
        RUN displayNode (child).
        ASSIGN havenode = parserNodeNextSibling(child,child) <> "".
      END.
      ELSE DO:
        PUT UNFORMATTED " " + parserGetNodeText(child).
        ASSIGN
          havenode = parserNodeNextSibling(child, sibling) <> ""
          /* just keep flipping child and sibling handles */
          temp = child
          child = sibling
          sibling = temp.
      END.
    END.

    ASSIGN
      needline = FALSE
      indent = indent - indentby.
    PUT UNFORMATTED SKIP FILL(" ",indent).

  END.

  parserReleaseHandle(child).
  parserReleaseHandle(grandchild).
  parserReleaseHandle(sibling).
END.
