home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 15a / murutil.zip / PRETTYPR.PAS < prev    next >
Pascal/Delphi Source File  |  1986-11-11  |  42KB  |  1,232 lines

  1. PROGRAM PRETTYPRINT;
  2.  
  3.   (*  This Program was taken from PASCAL NEWS (PUG) and adapted for
  4.       VAX PASCAL by:
  5.  
  6.                   Francis J. Monaco
  7.                   Major, US ARMY
  8.                   Systems Manager, Computer Graphics Laboratory
  9.                   Department of Geography and Computer Science
  10.                   The United States Military Academy
  11.                   West Point, New York 10996
  12.                   914-938-2063
  13.  
  14.     Updated for Borland's "Turbo Pascal", which does not support the GET
  15.     and PUT primitive functions, by Harry M. Murphy,  March 1986.  *)
  16.  
  17.  
  18.                   CONST 
  19.                         SPECLENGTH = 65;
  20.                         (*  Length of a file specification. *)
  21.                         MAXSYMBOLSIZE = 200;
  22.                         (*  The maximum size (in characters) of a
  23.                             symbol scanned by the lexical scanner. *)
  24.                         MAXSTACKSIZE  = 100;
  25.                         (*  The maximum number of symbols causing
  26.                             indentation that may be stacked.  *)
  27.                         MAXKEYLENGTHY  =  10;
  28.                         (*  The maximum LENGTHY (in characters) of a
  29.                             Pascal reserved keyword. *)
  30.                         MAXLINESIZE   =  72;
  31.                         (*  The maximum size (in characters) of a
  32.                             line output by the PRETTYPRINTER. *)
  33.                         SLOFAIL1      =  36;
  34.                         (*  Up to this column position, each time
  35.                             "INDENTBYTAB" is invoked, the margin
  36.                             will be indented by "INDENT1".  *)
  37.                         SLOFAIL2      =  54;
  38.                         (*  Up to this column position, each time
  39.                             "INDENTBYTAB" is invoked, the margin
  40.                             will be indented by "INDENT2".  Beyond
  41.                             this, no indentation occurs. *)
  42.                         INDENT1       =   2;
  43.                         INDENT2       =   1;
  44.                         SPACE = ' ';
  45.  
  46.                   TYPE 
  47.                        FILESPEC = STRING[SPECLENGTH];
  48.                        FILESTAT = RECORD
  49.                                     FILECH: CHAR;
  50.                                     FILEEF: BOOLEAN;
  51.                                     FILEEL: BOOLEAN
  52.                                   END;
  53.                        KEYSYMBOL = (PROGSYM,    FUNCSYM,     PROCSYM,
  54.                                     LABELSYM,   CONSTSYM,    TYPESYM,
  55.                                     VARSYM,
  56.                                     BEGINSYM,   REPEATSYM,   RECORDSYM,
  57.                                     CASESYM,    CASEVARSYM,  OFSYM,
  58.                                     FORSYM,     WHILESYM,    WITHSYM,
  59.                                     DOSYM,
  60.                                     IFSYM,      THENSYM,     ELSESYM,
  61.                                     ENDSYM,     UNTILSYM,
  62.                                     BECOMES,    OPENCOMMENT,
  63.                                     CLOSECOMMENT,
  64.                                     SEMICOLON,  COLON,       EQUALS,
  65.                                     OPENPAREN,  CLOSEPAREN,  PERIOD,
  66.                                     ENDOFFILE,
  67.                                     OTHERSYM);
  68.                        OPTION = (CRSUPPRESS,
  69.                                  CRBEFORE,
  70.                                  BLANKLINEBEFORE,
  71.                                  DINDENTONKEYS,
  72.                                  DINDENT,
  73.                                  SPACEBEFORE,
  74.                                  SPACEAFTER,
  75.                                  GOBBLESYMBOLS,
  76.                                  INDENTBYTAB,
  77.                                  INDENTTOCLP,
  78.                                  CRAFTER);
  79.                        OPTIONSET = SET OF OPTION;
  80.                        KEYSYMSET = SET OF KEYSYMBOL;
  81.                        TABLEENTRY = RECORD
  82.                                      OPTIONSSELECTED : OPTIONSET;
  83.                                      DINDENTSYMBOLS  : KEYSYMSET;
  84.                                      GOBBLETERMINATORS: KEYSYMSET
  85.                                     END;
  86.                        OPTIONTABLE = ARRAY [KEYSYMBOL] OF TABLEENTRY;
  87.                        KEY = PACKED ARRAY [1..MAXKEYLENGTHY] OF CHAR;
  88.                        KEYWORDTABLE = ARRAY [PROGSYM..UNTILSYM] OF KEY;
  89.                        SPECIALCHAR = PACKED ARRAY [1..2] OF CHAR;
  90.                        DBLCHRSET = SET OF BECOMES..OPENCOMMENT;
  91.                        DBLCHARTABLE = ARRAY [BECOMES..OPENCOMMENT] OF
  92.                                       SPECIALCHAR;
  93.                        SGLCHARTABLE = ARRAY [SEMICOLON..PERIOD] OF CHAR;
  94.                        STRINGY = ARRAY [1..MAXSYMBOLSIZE] OF CHAR;
  95.                        SYMBOL = RECORD
  96.                                   NAME       : KEYSYMBOL;
  97.                                   VALUES      : STRINGY;
  98.                                   LENGTHY     : INTEGER;
  99.                                   SPACESBEFORE: INTEGER;
  100.                                   CRSBEFORE  : INTEGER
  101.                                 END;
  102.                        SYMBOLINFO = ^SYMBOL;
  103.                        CHARNAME = (LETTER,    DIGIT,    BLANK,    QUOTE,
  104.                                    ENDOFLINE, FILEMARK, OTHERCHAR);
  105.                        CHARINFO = RECORD
  106.                                     NAME: CHARNAME;
  107.                                     VALUES: CHAR
  108.                                   END;
  109.                        STACKENTRY = RECORD
  110.                                      INDENTSYMBOL: KEYSYMBOL;
  111.                                      PREVMARGIN : INTEGER
  112.                                     END;
  113.                        SYMBOLSTACK = ARRAY [1..MAXSTACKSIZE] OF
  114.                                      STACKENTRY;
  115.  
  116.                   VAR 
  117.                       FIN: TEXT;
  118.                       FINCH: CHAR;
  119.                       FINEF: BOOLEAN;
  120.                       FINEL: BOOLEAN;
  121.                       FINNAME: FILESPEC;
  122.                       FINSTAT: FILESTAT;
  123.                       FOUT: TEXT;
  124.                       OUTNAME: FILESPEC;
  125.                       SAWCOMOPEN, SAWCOMCLOSE, SAWQUOTEDSTRING,
  126.                       INACOMMENT   : BOOLEAN;
  127.                       RECORDSEEN: BOOLEAN;
  128.                       CURRCHAR,
  129.                       NEXTCHAR: CHARINFO;
  130.                       CURRSYM,
  131.                       NEXTSYM: SYMBOLINFO;
  132.                       CRPENDING: BOOLEAN;
  133.                       PPOPTION: OPTIONTABLE;
  134.                       KEYWORD: KEYWORDTABLE;
  135.                       DBLCHARS: DBLCHRSET;
  136.                       DBLCHAR: DBLCHARTABLE;
  137.                       SGLCHAR: SGLCHARTABLE;
  138.                       STACK: SYMBOLSTACK;
  139.                       TOP : INTEGER;
  140.                       STARTPOS, (* Starting position of last symbol
  141.                                    written. *)
  142.                       CURRLINEPOS,
  143.                       CURRMARGIN: INTEGER;
  144.                       I: INTEGER;
  145.  
  146.  
  147. PROCEDURE GETINPFIL(VAR INP: TEXT; VAR FINNAME: FILESPEC);
  148.  
  149. (*  This file gets an input file, either as the first parameter
  150.    on the command line or by requesting it from the user.
  151.  
  152.    Procedure by Harry M. Murphy,  22 February 1986.  *)
  153.  
  154.   VAR 
  155.       L: INTEGER;
  156.  
  157.   BEGIN
  158.     IF PARAMCOUNT = 0
  159.       THEN
  160.         BEGIN
  161.           WRITE('Input  file: ');
  162.           READLN(FINNAME)
  163.         END
  164.       ELSE
  165.         FINNAME := PARAMSTR(1);
  166.     FOR L:=1 TO LENGTH(FINNAME) DO FINNAME[L] := UPCASE(FINNAME[L]);
  167.     ASSIGN(INP,FINNAME);
  168.       (*$I-*) RESET(INP) (*$I+*);
  169.     IF IORESULT <> 0
  170.       THEN
  171.         BEGIN
  172.           CLOSE(INP);
  173.           WRITELN('ERROR!  Can''t find file ',FINNAME,'!');
  174.           HALT
  175.         END;
  176.   END (* Procedure GETINPFIL *);
  177.  
  178.  
  179. PROCEDURE GETOUTFIL(VAR OUT: TEXT; VAR OUTNAME: FILESPEC);
  180.  
  181. (*  This file gets an output file, either as the second parameter
  182.    on the command line or by requesting it from the user.
  183.  
  184.    Procedure by Harry M. Murphy,  22 February 1986.  *)
  185.  
  186.  VAR 
  187.      L: INTEGER;
  188.  
  189.   BEGIN
  190.     IF PARAMCOUNT < 2
  191.       THEN
  192.         BEGIN
  193.           WRITE('Output file: ');
  194.           READLN(OUTNAME)
  195.         END
  196.       ELSE
  197.         OUTNAME := PARAMSTR(2);
  198.     FOR L:=1 TO LENGTH(OUTNAME) DO OUTNAME[L] := UPCASE(OUTNAME[L]);
  199.     ASSIGN(OUT,OUTNAME);
  200.     (*$I-*) REWRITE(OUT) (*$I-*);
  201.     IF IORESULT <> 0
  202.       THEN
  203.         BEGIN
  204.           CLOSE(OUT);
  205.           WRITELN('ERROR!  Can''t open ',OUTNAME,'!');
  206.           HALT
  207.         END
  208.   END (* Procedure GETOUTFIL *);
  209.  
  210.  
  211. PROCEDURE GETFIN;
  212.  
  213. BEGIN
  214.   WITH FINSTAT DO
  215.     BEGIN
  216.       FINCH := FILECH;
  217.       FINEF := FILEEF;
  218.       FINEL := FILEEL;
  219.       FILECH := ' ';
  220.       FILEEF := EOF(FIN);
  221.       FILEEL := EOLN(FIN);
  222.       IF NOT FILEEF
  223.         THEN
  224.           IF FILEEL
  225.             THEN
  226.               READLN(FIN)
  227.             ELSE
  228.               READ(FIN,FILECH)
  229.       END
  230. END (* Procedure GETFIN *);
  231.  
  232.  
  233.    PROCEDURE GETCHAR(VAR NEXTCHAR :CHARINFO;
  234.                      VAR CURRCHAR :CHARINFO);
  235.    BEGIN (* GETCHAR *)
  236.      CURRCHAR := NEXTCHAR;
  237.      WITH NEXTCHAR DO
  238.        BEGIN
  239.          IF FINEF OR (FINCH=CHR(26))
  240.            THEN
  241.              NAME  := FILEMARK
  242.            ELSE
  243.              IF FINEL
  244.                THEN
  245.                  NAME  := ENDOFLINE
  246.                ELSE
  247.                  IF (((ORD(FINCH)) >= (ORD('a'))) AND
  248.                     ((ORD(FINCH)) <= (ORD('z'))) AND
  249.                     (NOT SAWQUOTEDSTRING)  AND
  250.                     (NOT INACOMMENT))
  251.                    THEN
  252.                      BEGIN
  253.                        FINCH := UPCASE(FINCH);
  254.                        NAME := LETTER
  255.                      END
  256.                    ELSE
  257.                      IF SAWCOMOPEN
  258.                        THEN
  259.                          BEGIN
  260.                            SAWCOMOPEN := FALSE;
  261.                            FINCH := '*';
  262.                            NAME := OTHERCHAR
  263.                          END
  264.                        ELSE
  265.                          IF SAWCOMCLOSE
  266.                            THEN
  267.                              BEGIN
  268.                                SAWCOMCLOSE := FALSE;
  269.                                FINCH := ')';
  270.                                NAME := OTHERCHAR
  271.                              END
  272.                            ELSE
  273.                              IF  ((FINCH = '{') AND (NOT SAWQUOTEDSTRING))
  274.                                THEN
  275.                                  BEGIN
  276.                                    SAWCOMOPEN := TRUE;
  277.                                    INACOMMENT := TRUE;
  278.                                    FINCH := '(';
  279.                                    NAME := OTHERCHAR
  280.                                  END
  281.                                ELSE
  282.                                  IF  ((FINCH = '}')  AND (NOT
  283.                                     SAWQUOTEDSTRING))
  284.                                    THEN
  285.                                      BEGIN
  286.                                       SAWCOMCLOSE := TRUE;
  287.                                       INACOMMENT := FALSE;
  288.                                       FINCH := '*';
  289.                                       NAME := OTHERCHAR
  290.                                      END
  291.                                    ELSE
  292.                                      IF FINCH IN ['A' .. 'Z', '_']
  293.                                       THEN
  294.                                        NAME  := LETTER
  295.                                       ELSE
  296.                                        IF FINCH IN ['0'..'9']
  297.                                         THEN
  298.                                          NAME  := DIGIT
  299.                                         ELSE
  300.                                          IF (FINCH = '''') AND (NOT
  301.                                             INACOMMENT)
  302.                                           THEN
  303.                                            IF SAWQUOTEDSTRING
  304.                                             THEN
  305.                                              BEGIN
  306.                                               NAME := QUOTE;
  307.                                               SAWQUOTEDSTRING := FALSE
  308.                                              END
  309.                                             ELSE
  310.                                              BEGIN
  311.                                               NAME := QUOTE;
  312.                                               SAWQUOTEDSTRING := TRUE
  313.                                              END
  314.                                           ELSE
  315.                                            IF FINCH = SPACE
  316.                                             THEN
  317.                                              NAME  := BLANK
  318.                                             ELSE
  319.                                              NAME := OTHERCHAR;
  320.          IF NAME IN [FILEMARK, ENDOFLINE]
  321.            THEN
  322.              VALUES := SPACE
  323.            ELSE
  324.              VALUES := FINCH;
  325.          IF (NAME <> FILEMARK) AND (NOT SAWCOMOPEN) AND (NOT SAWCOMCLOSE
  326.             )
  327.            THEN
  328.              GETFIN
  329.        END (* WITH *)
  330.    END; (* GETCHAR *)
  331.  
  332.   PROCEDURE STORENEXTCHAR(VAR LENGTHY:INTEGER;VAR CURRCHAR,
  333.                           NEXTCHAR: CHARINFO;VAR VALUES: STRINGY);
  334.    BEGIN (* STORENEXTCHAR *)
  335.      GETCHAR(NEXTCHAR,CURRCHAR);
  336.      IF LENGTHY < MAXSYMBOLSIZE
  337.        THEN
  338.          BEGIN
  339.            LENGTHY := LENGTHY + 1;
  340.            VALUES [LENGTHY] := CURRCHAR.VALUES
  341.          END
  342.    END; (* STORENEXTCHAR *)
  343.  
  344.   PROCEDURE SKIPSPACES(VAR CURRCHAR,NEXTCHAR: CHARINFO;VAR SPACESBEFORE,
  345.                        CRSBEFORE:INTEGER);
  346.    BEGIN (* SKIPSPACES *)
  347.      SPACESBEFORE := 0;
  348.      CRSBEFORE    := 0;
  349.      WHILE NEXTCHAR.NAME IN [BLANK, ENDOFLINE] DO
  350.        BEGIN
  351.          GETCHAR(NEXTCHAR,CURRCHAR);
  352.          CASE CURRCHAR.NAME OF
  353.            BLANK    : SPACESBEFORE := SPACESBEFORE + 1;
  354.            ENDOFLINE : 
  355.                        BEGIN
  356.                          CRSBEFORE    := CRSBEFORE + 1;
  357.                          SPACESBEFORE := 0
  358.                        END
  359.          END (* CASE *)
  360.        END (* WHILE *)
  361.    END; (* SKIPSPACES *)
  362.  
  363.   PROCEDURE GETCOMMENT(VAR CURRCHAR,NEXTCHAR:CHARINFO;VAR NAME:KEYSYMBOL
  364.                        ;VAR VALUES:STRINGY;VAR LENGTHY:INTEGER);
  365.    BEGIN (* GETCOMMENT *)
  366.      INACOMMENT := TRUE;
  367.      NAME := OPENCOMMENT;
  368.      WHILE NOT(((CURRCHAR.VALUES = '*') AND (NEXTCHAR.VALUES = ')'))
  369.            OR (NEXTCHAR.NAME = ENDOFLINE)
  370.            OR (NEXTCHAR.NAME = FILEMARK)) DO
  371.        STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES);
  372.      IF (CURRCHAR.VALUES = '*') AND (NEXTCHAR.VALUES = ')')
  373.        THEN
  374.          BEGIN
  375.            STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES);
  376.            NAME := CLOSECOMMENT;
  377.            INACOMMENT := FALSE
  378.          END
  379.    END; (* GETCOMMENT *)
  380.  
  381.   FUNCTION IDTYPE(VALUES : STRINGY; LENGTHY: INTEGER): KEYSYMBOL;
  382.  
  383.   VAR 
  384.       I: INTEGER;
  385.       KEYVALUES: KEY;
  386.       HIT: BOOLEAN;
  387.       THISKEY: KEYSYMBOL;
  388.    BEGIN (* IDTYPE *)
  389.      IDTYPE := OTHERSYM;
  390.      IF LENGTHY <= MAXKEYLENGTHY
  391.        THEN
  392.          BEGIN
  393.            FOR I := 1 TO LENGTHY DO KEYVALUES [I] := VALUES [I];
  394.            FOR I := LENGTHY+1 TO MAXKEYLENGTHY DO KEYVALUES [I] := SPACE;
  395.            THISKEY := PROGSYM;
  396.            HIT     := FALSE;
  397.            WHILE NOT(HIT OR (THISKEY = SUCC(UNTILSYM))) DO
  398.              IF KEYVALUES = KEYWORD [THISKEY]
  399.                THEN
  400.                  HIT := TRUE
  401.                ELSE
  402.                  THISKEY := SUCC(THISKEY);
  403.            IF HIT
  404.              THEN
  405.                IDTYPE := THISKEY
  406.          END;
  407.    END; (* IDTYPE *)
  408.  
  409.   PROCEDURE GETIDENTIFIER(VAR CURRCHAR,NEXTCHAR:CHARINFO;VAR NAME:
  410.                           KEYSYMBOL;VAR VALUES:STRINGY;VAR LENGTHY:
  411.                           INTEGER);
  412.    BEGIN (* GETIDENTIFIER *)
  413.      WHILE NEXTCHAR.NAME IN [LETTER, DIGIT] DO
  414.        STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES);
  415.      NAME := IDTYPE(VALUES,
  416.              LENGTHY);
  417.      IF NAME IN [RECORDSYM, CASESYM, ENDSYM]
  418.        THEN
  419.          CASE NAME OF
  420.            RECORDSYM: RECORDSEEN := TRUE;
  421.            CASESYM   : 
  422.                        IF RECORDSEEN
  423.                          THEN
  424.                            NAME := CASEVARSYM;
  425.            ENDSYM   : RECORDSEEN := FALSE
  426.          END (* CASE *)
  427.    END; (* GETIDENTIFIER *)
  428.  
  429.   PROCEDURE GETNUMBER(VAR CURRCHAR,NEXTCHAR:CHARINFO;VAR NAME:KEYSYMBOL;
  430.                       VAR VALUES:STRINGY;VAR LENGTHY:INTEGER);
  431.    BEGIN (* GETNUMBER *)
  432.      WHILE NEXTCHAR.NAME = DIGIT DO
  433.        STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES);
  434.      NAME := OTHERSYM
  435.    END; (* GETNUMBER *)
  436.  
  437.   PROCEDURE GETCHARLITERAL(VAR CURRCHAR,NEXTCHAR :CHARINFO;
  438.                            VAR NAME: KEYSYMBOL;VAR VALUES: STRINGY;VAR
  439.                            LENGTHY   :INTEGER);
  440.    BEGIN (* GETCHARLITERAL *)
  441.      WHILE NEXTCHAR.NAME = QUOTE DO
  442.        BEGIN
  443.          STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES);
  444.          WHILE NOT(NEXTCHAR.NAME IN [QUOTE, ENDOFLINE, FILEMARK]) DO
  445.            STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES);
  446.          IF NEXTCHAR.NAME = QUOTE
  447.            THEN
  448.              STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES)
  449.        END;
  450.      NAME := OTHERSYM
  451.    END; (* GETCHARLITERAL *)
  452.  
  453.   FUNCTION CHARTYPE(CURRCHAR,NEXTCHAR: CHARINFO): KEYSYMBOL;
  454.  
  455.   VAR 
  456.       NEXTTWOCHARS: SPECIALCHAR;
  457.       HIT: BOOLEAN;
  458.       THISCHAR: KEYSYMBOL;
  459.  
  460.    BEGIN (* CHARTYPE *)
  461.      NEXTTWOCHARS[1] := CURRCHAR.VALUES;
  462.      NEXTTWOCHARS[2] := NEXTCHAR.VALUES;
  463.      THISCHAR := BECOMES;
  464.      HIT      := FALSE;
  465.      WHILE NOT(HIT OR (THISCHAR = CLOSECOMMENT)) DO
  466.        IF NEXTTWOCHARS = DBLCHAR [THISCHAR]
  467.          THEN
  468.            HIT := TRUE
  469.          ELSE
  470.            THISCHAR := SUCC(THISCHAR);
  471.      IF NOT HIT
  472.        THEN
  473.          BEGIN
  474.            THISCHAR := SEMICOLON;
  475.            WHILE NOT(HIT OR (PRED(THISCHAR) = PERIOD)) DO
  476.              IF CURRCHAR.VALUES = SGLCHAR [THISCHAR]
  477.                THEN
  478.                  HIT := TRUE
  479.                ELSE
  480.                  THISCHAR := SUCC(THISCHAR)
  481.          END;
  482.      IF HIT
  483.        THEN
  484.          CHARTYPE := THISCHAR
  485.        ELSE
  486.          CHARTYPE := OTHERSYM
  487.    END; (* CHARTYPE *)
  488.  
  489.   PROCEDURE GETSPECIALCHAR(VAR CURRCHAR,NEXTCHAR :CHARINFO;
  490.                            VAR NAME     :KEYSYMBOL;VAR VALUES    :
  491.                            STRINGY;VAR LENGTHY   :INTEGER);
  492.    BEGIN (* GETSPECIALCHAR *)
  493.      STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES);
  494.      NAME := CHARTYPE(CURRCHAR,
  495.              NEXTCHAR);
  496.      IF NAME IN DBLCHARS
  497.        THEN
  498.          STORENEXTCHAR(LENGTHY,CURRCHAR,NEXTCHAR,VALUES)
  499.    END; (* GETSPECIALCHAR *)
  500.  
  501.   PROCEDURE GETNEXTSYMBOL(VAR CURRCHAR,NEXTCHAR:CHARINFO;VAR NAME:
  502.                           KEYSYMBOL;VAR VALUES:STRINGY;VAR LENGTHY:
  503.                           INTEGER);
  504.    BEGIN  (* GETNEXTSYMBOL *)
  505.      CASE NEXTCHAR.NAME OF
  506.        LETTER     : GETIDENTIFIER(CURRCHAR,NEXTCHAR,NAME,VALUES,LENGTHY)
  507.        ;
  508.        DIGIT      : GETNUMBER(CURRCHAR,NEXTCHAR,NAME,VALUES,LENGTHY);
  509.        QUOTE      : GETCHARLITERAL(CURRCHAR,NEXTCHAR,NAME,VALUES,LENGTHY
  510.                     );
  511.        OTHERCHAR: 
  512.                   BEGIN
  513.                     GETSPECIALCHAR(CURRCHAR,NEXTCHAR,NAME,VALUES,LENGTHY
  514.                     );
  515.                     IF NAME = OPENCOMMENT
  516.                       THEN
  517.                         GETCOMMENT(CURRCHAR,NEXTCHAR,NAME,VALUES,LENGTHY
  518.                         )
  519.                   END;
  520.        FILEMARK   : NAME := ENDOFFILE
  521.       END (* CASE *)
  522.    END; (* GETNEXTSYMBOL *)
  523.  
  524.   PROCEDURE GETSYMBOL(VAR NEXTSYM  :SYMBOLINFO;VAR CURRSYM  :SYMBOLINFO)
  525. ;
  526.  
  527.   VAR 
  528.       DUMMY: SYMBOLINFO;
  529.    BEGIN  (* GETSYMBOL *)
  530.      DUMMY   := CURRSYM;
  531.      CURRSYM := NEXTSYM;
  532.      NEXTSYM := DUMMY;
  533.      WITH NEXTSYM^ DO
  534.        BEGIN
  535.          SKIPSPACES(CURRCHAR,NEXTCHAR,SPACESBEFORE,CRSBEFORE);
  536.          LENGTHY := 0;
  537.          IF CURRSYM^.NAME = OPENCOMMENT
  538.            THEN
  539.              GETCOMMENT(CURRCHAR,NEXTCHAR,NAME,VALUES,LENGTHY)
  540.            ELSE
  541.              GETNEXTSYMBOL(CURRCHAR,NEXTCHAR,NAME,VALUES,LENGTHY)
  542.        END (* WITH *)
  543.    END; (* GETSYMBOL *)
  544.  
  545.   PROCEDURE INT2 (VAR TOPOFSTACK:INTEGER;
  546.                   VAR CURRLINEPOS,
  547.                   CURRMARGIN:INTEGER;
  548.                   VAR KEYWORD   :KEYWORDTABLE;
  549.                   VAR DBLCHARS  :DBLCHRSET;
  550.                   VAR DBLCHAR   :DBLCHARTABLE;
  551.                   VAR SGLCHAR   :SGLCHARTABLE;
  552.                   VAR RECORDSEEN:BOOLEAN;
  553.                   VAR CURRCHAR,
  554.                   NEXTCHAR  :CHARINFO;
  555.                   VAR CURRSYM,
  556.                   NEXTSYM   :SYMBOLINFO;
  557.                   VAR PPOPTION  :OPTIONTABLE);
  558.    BEGIN
  559.      WITH PPOPTION [OFSYM] DO
  560.        BEGIN
  561.          OPTIONSSELECTED   := [CRSUPPRESS,
  562.                               SPACEBEFORE];
  563.          DINDENTSYMBOLS    := [];
  564.          GOBBLETERMINATORS := []
  565.        END;
  566.      WITH PPOPTION [FORSYM] DO
  567.        BEGIN
  568.          OPTIONSSELECTED   := [SPACEAFTER,
  569.                               INDENTBYTAB,
  570.                               GOBBLESYMBOLS,
  571.                               CRAFTER];
  572.          DINDENTSYMBOLS    := [];
  573.          GOBBLETERMINATORS := [DOSYM]
  574.        END;
  575.      WITH PPOPTION [WHILESYM] DO
  576.        BEGIN
  577.          OPTIONSSELECTED   := [SPACEAFTER,
  578.                               INDENTBYTAB,
  579.                               GOBBLESYMBOLS,
  580.                               CRAFTER];
  581.          DINDENTSYMBOLS    := [];
  582.          GOBBLETERMINATORS := [DOSYM]
  583.        END;
  584.      WITH PPOPTION [WITHSYM] DO
  585.        BEGIN
  586.          OPTIONSSELECTED   := [SPACEAFTER,
  587.                               INDENTBYTAB,
  588.                               GOBBLESYMBOLS,
  589.                               CRAFTER];
  590.          DINDENTSYMBOLS    := [];
  591.          GOBBLETERMINATORS := [DOSYM]
  592.        END;
  593.      WITH PPOPTION [DOSYM] DO
  594.        BEGIN
  595.          OPTIONSSELECTED   := [CRSUPPRESS,
  596.                               SPACEBEFORE];
  597.          DINDENTSYMBOLS    := [];
  598.          GOBBLETERMINATORS := []
  599.        END;
  600.      WITH PPOPTION [IFSYM] DO
  601.        BEGIN
  602.          OPTIONSSELECTED   := [SPACEAFTER,
  603.                               INDENTBYTAB,
  604.                               GOBBLESYMBOLS,
  605.                               CRAFTER];
  606.          DINDENTSYMBOLS    := [];
  607.          GOBBLETERMINATORS := [THENSYM]
  608.        END;
  609.      WITH PPOPTION [THENSYM] DO
  610.        BEGIN
  611.          OPTIONSSELECTED   := [INDENTBYTAB,
  612.                               CRAFTER];
  613.          DINDENTSYMBOLS    := [];
  614.          GOBBLETERMINATORS := []
  615.        END;
  616.      WITH PPOPTION [ELSESYM] DO
  617.        BEGIN
  618.          OPTIONSSELECTED   := [CRBEFORE,
  619.                               DINDENTONKEYS,
  620.                               DINDENT,
  621.                               INDENTBYTAB,
  622.                               CRAFTER];
  623.          DINDENTSYMBOLS    := [IFSYM,
  624.                               ELSESYM];
  625.          GOBBLETERMINATORS := []
  626.        END;
  627.      WITH PPOPTION [ENDSYM] DO
  628.        BEGIN
  629.          OPTIONSSELECTED   := [CRBEFORE,
  630.                               DINDENTONKEYS,
  631.                               DINDENT,
  632.                               CRAFTER];
  633.          DINDENTSYMBOLS    := [IFSYM,
  634.                               THENSYM,
  635.                               ELSESYM,
  636.                               FORSYM,
  637.                               WHILESYM,
  638.                               WITHSYM,
  639.                               CASEVARSYM,
  640.                               COLON,
  641.                               EQUALS];
  642.          GOBBLETERMINATORS := []
  643.        END;
  644.      WITH PPOPTION [UNTILSYM] DO
  645.        BEGIN
  646.          OPTIONSSELECTED   := [CRBEFORE,
  647.                               DINDENTONKEYS,
  648.                               DINDENT,
  649.                               SPACEAFTER,
  650.                               GOBBLESYMBOLS,
  651.                               CRAFTER];
  652.          DINDENTSYMBOLS    := [IFSYM,
  653.                               THENSYM,
  654.                               ELSESYM,
  655.                               FORSYM,
  656.                               WHILESYM,
  657.                               WITHSYM,
  658.                               COLON,
  659.                               EQUALS];
  660.          GOBBLETERMINATORS := [ENDSYM,
  661.                               UNTILSYM,
  662.                               ELSESYM,
  663.                               SEMICOLON];
  664.        END;
  665.      WITH PPOPTION [BECOMES] DO
  666.        BEGIN
  667.          OPTIONSSELECTED   := [SPACEBEFORE,
  668.                               SPACEAFTER,
  669.                               GOBBLESYMBOLS];
  670.          DINDENTSYMBOLS    := [];
  671.          GOBBLETERMINATORS := [ENDSYM,
  672.                               UNTILSYM,
  673.                               ELSESYM,
  674.                               SEMICOLON]
  675.        END;
  676.      WITH PPOPTION [OPENCOMMENT] DO
  677.        BEGIN
  678.          OPTIONSSELECTED   := [CRSUPPRESS];
  679.          DINDENTSYMBOLS    := [];
  680.          GOBBLETERMINATORS := []
  681.        END;
  682.      WITH PPOPTION [CLOSECOMMENT] DO
  683.        BEGIN
  684.          OPTIONSSELECTED   := [CRSUPPRESS];
  685.          DINDENTSYMBOLS    := [];
  686.          GOBBLETERMINATORS := []
  687.        END;
  688.      WITH PPOPTION [SEMICOLON] DO
  689.        BEGIN
  690.          OPTIONSSELECTED   := [CRSUPPRESS,
  691.                               DINDENTONKEYS,
  692.                               CRAFTER];
  693.          DINDENTSYMBOLS    := [IFSYM,
  694.                               THENSYM,
  695.                               ELSESYM,
  696.                               FORSYM,
  697.                               WHILESYM,
  698.                               WITHSYM,
  699.                               COLON,
  700.                               EQUALS];
  701.          GOBBLETERMINATORS := []
  702.        END;
  703.      WITH PPOPTION [COLON] DO
  704.        BEGIN
  705.          OPTIONSSELECTED   := [SPACEAFTER,
  706.                               INDENTTOCLP];
  707.          DINDENTSYMBOLS    := [];
  708.          GOBBLETERMINATORS := []
  709.        END;
  710.      WITH PPOPTION [EQUALS] DO
  711.        BEGIN
  712.          OPTIONSSELECTED   := [SPACEBEFORE,
  713.                               SPACEAFTER,
  714.                               INDENTTOCLP];
  715.          DINDENTSYMBOLS    := [];
  716.          GOBBLETERMINATORS := []
  717.        END;
  718.      WITH PPOPTION [OPENPAREN] DO
  719.        BEGIN
  720.          OPTIONSSELECTED   := [GOBBLESYMBOLS];
  721.          DINDENTSYMBOLS    := [];
  722.          GOBBLETERMINATORS := [CLOSEPAREN]
  723.        END;
  724.      WITH PPOPTION [CLOSEPAREN] DO
  725.        BEGIN
  726.          OPTIONSSELECTED   := [];
  727.          DINDENTSYMBOLS    := [];
  728.          GOBBLETERMINATORS := []
  729.        END;
  730.      WITH PPOPTION [PERIOD] DO
  731.        BEGIN
  732.          OPTIONSSELECTED   := [CRSUPPRESS];
  733.          DINDENTSYMBOLS    := [];
  734.          GOBBLETERMINATORS := []
  735.        END;
  736.      WITH PPOPTION [ENDOFFILE] DO
  737.        BEGIN
  738.          OPTIONSSELECTED   := [];
  739.          DINDENTSYMBOLS    := [];
  740.          GOBBLETERMINATORS := []
  741.        END;
  742.      WITH PPOPTION [OTHERSYM] DO
  743.        BEGIN
  744.          OPTIONSSELECTED   := [];
  745.          DINDENTSYMBOLS    := [];
  746.          GOBBLETERMINATORS := []
  747.        END
  748.    END; (* INITIALIZE2 *)
  749.  
  750.   PROCEDURE INITIALIZE(VAR TOPOFSTACK:INTEGER;VAR CURRLINEPOS,
  751.                        CURRMARGIN:INTEGER;VAR KEYWORD:KEYWORDTABLE;
  752.                        VAR DBLCHARS:DBLCHRSET; VAR DBLCHAR:DBLCHARTABLE;
  753.                        VAR SGLCHAR:SGLCHARTABLE;VAR RECORDSEEN:BOOLEAN;
  754.                        VAR CURRCHAR,NEXTCHAR: CHARINFO;
  755.                        VAR CURRSYM,NEXTSYM:SYMBOLINFO;VAR PPOPTION:
  756.                        OPTIONTABLE);
  757.    BEGIN (* INITIALIZE *)
  758.      TOPOFSTACK  := 0;
  759.      CURRLINEPOS := 0;
  760.      CURRMARGIN  := 0;
  761.      KEYWORD [PROGSYM] := 'PROGRAM   ';
  762.      KEYWORD [FUNCSYM] := 'FUNCTION  ';
  763.      KEYWORD [PROCSYM] := 'PROCEDURE ';
  764.      KEYWORD [LABELSYM] := 'LABEL     ';
  765.      KEYWORD [CONSTSYM] := 'CONST     ';
  766.      KEYWORD [TYPESYM] := 'TYPE      ';
  767.      KEYWORD [VARSYM] := 'VAR       ';
  768.      KEYWORD [BEGINSYM] := 'BEGIN     ';
  769.      KEYWORD [REPEATSYM] := 'REPEAT    ';
  770.      KEYWORD [RECORDSYM] := 'RECORD    ';
  771.      KEYWORD [CASESYM] := 'CASE      ';
  772.      KEYWORD [CASEVARSYM] := 'CASE      ';
  773.      KEYWORD [OFSYM] := 'OF        ';
  774.      KEYWORD [FORSYM] := 'FOR       ';
  775.      KEYWORD [WHILESYM] := 'WHILE     ';
  776.      KEYWORD [WITHSYM] := 'WITH      ';
  777.      KEYWORD [DOSYM] := 'DO        ';
  778.      KEYWORD [IFSYM] := 'IF        ';
  779.      KEYWORD [THENSYM] := 'THEN      ';
  780.      KEYWORD [ELSESYM] := 'ELSE      ';
  781.      KEYWORD [ENDSYM] := 'END       ';
  782.      KEYWORD [UNTILSYM ] := 'UNTIL     ';
  783.      DBLCHARS := [BECOMES, OPENCOMMENT];
  784.      DBLCHAR [BECOMES]  := ':=';
  785.      DBLCHAR [OPENCOMMENT]  := '(*';
  786.      SGLCHAR [SEMICOLON]   := ';';
  787.      SGLCHAR [COLON]   := ':';
  788.      SGLCHAR [EQUALS]   := '=';
  789.      SGLCHAR [OPENPAREN]   := '(';
  790.      SGLCHAR [CLOSEPAREN]   := ')';
  791.      SGLCHAR [PERIOD]   := '.';
  792.      RECORDSEEN := FALSE;
  793.      SAWCOMOPEN := FALSE;
  794.      SAWCOMCLOSE := FALSE;
  795.      INACOMMENT := FALSE;
  796.      SAWQUOTEDSTRING := FALSE;
  797.      GETCHAR(NEXTCHAR,CURRCHAR);
  798.      NEW(CURRSYM);
  799.      NEW(NEXTSYM);
  800.      GETSYMBOL(NEXTSYM,CURRSYM);
  801.      WITH PPOPTION [PROGSYM] DO
  802.        BEGIN
  803.          OPTIONSSELECTED   := [BLANKLINEBEFORE,
  804.                               SPACEAFTER];
  805.          DINDENTSYMBOLS    := [];
  806.          GOBBLETERMINATORS := []
  807.        END;
  808.      WITH PPOPTION [FUNCSYM] DO
  809.        BEGIN
  810.          OPTIONSSELECTED   := [BLANKLINEBEFORE,
  811.                               DINDENTONKEYS,
  812.                               SPACEAFTER];
  813.          DINDENTSYMBOLS    := [LABELSYM,
  814.                               CONSTSYM,
  815.                               TYPESYM,
  816.                               VARSYM];
  817.          GOBBLETERMINATORS := []
  818.        END;
  819.      WITH PPOPTION [PROCSYM] DO
  820.        BEGIN
  821.          OPTIONSSELECTED   := [BLANKLINEBEFORE,
  822.                               DINDENTONKEYS,
  823.                               SPACEAFTER];
  824.          DINDENTSYMBOLS    := [LABELSYM,
  825.                               CONSTSYM,
  826.                               TYPESYM,
  827.                               VARSYM];
  828.          GOBBLETERMINATORS := []
  829.        END;
  830.      WITH PPOPTION [LABELSYM] DO
  831.        BEGIN
  832.          OPTIONSSELECTED   := [BLANKLINEBEFORE,
  833.                               SPACEAFTER,
  834.                               INDENTTOCLP,
  835.                               CRAFTER];
  836.          DINDENTSYMBOLS    := [];
  837.          GOBBLETERMINATORS := []
  838.        END;
  839.      WITH PPOPTION [CONSTSYM] DO
  840.        BEGIN
  841.          OPTIONSSELECTED   := [BLANKLINEBEFORE,
  842.                               DINDENTONKEYS,
  843.                               SPACEAFTER,
  844.                               INDENTTOCLP,
  845.                               CRAFTER];
  846.          DINDENTSYMBOLS    := [LABELSYM];
  847.          GOBBLETERMINATORS := []
  848.        END;
  849.      WITH PPOPTION [TYPESYM] DO
  850.        BEGIN
  851.          OPTIONSSELECTED   := [BLANKLINEBEFORE,
  852.                               DINDENTONKEYS,
  853.                               SPACEAFTER,
  854.                               INDENTTOCLP,
  855.                               CRAFTER];
  856.          DINDENTSYMBOLS    := [LABELSYM,
  857.                               CONSTSYM];
  858.          GOBBLETERMINATORS := []
  859.        END;
  860.      WITH PPOPTION [VARSYM] DO
  861.        BEGIN
  862.          OPTIONSSELECTED   := [BLANKLINEBEFORE,
  863.                               DINDENTONKEYS,
  864.                               SPACEAFTER,
  865.                               INDENTTOCLP,
  866.                               CRAFTER];
  867.          DINDENTSYMBOLS    := [LABELSYM,
  868.                               CONSTSYM,
  869.                               TYPESYM];
  870.          GOBBLETERMINATORS := []
  871.        END;
  872.      WITH PPOPTION [BEGINSYM] DO
  873.        BEGIN
  874.          OPTIONSSELECTED   := [DINDENTONKEYS,
  875.                               INDENTBYTAB,
  876.                               CRAFTER];
  877.          DINDENTSYMBOLS    := [LABELSYM,
  878.                               CONSTSYM,
  879.                               TYPESYM,
  880.                               VARSYM];
  881.          GOBBLETERMINATORS := []
  882.        END;
  883.      WITH PPOPTION [REPEATSYM] DO
  884.        BEGIN
  885.          OPTIONSSELECTED   := [INDENTBYTAB,
  886.                               CRAFTER];
  887.          DINDENTSYMBOLS    := [];
  888.          GOBBLETERMINATORS := []
  889.        END;
  890.      WITH PPOPTION [RECORDSYM] DO
  891.        BEGIN
  892.          OPTIONSSELECTED   := [INDENTBYTAB,
  893.                               CRAFTER];
  894.          DINDENTSYMBOLS    := [];
  895.          GOBBLETERMINATORS := []
  896.        END;
  897.      WITH PPOPTION [CASESYM] DO
  898.        BEGIN
  899.          OPTIONSSELECTED   := [SPACEAFTER,
  900.                               INDENTBYTAB,
  901.                               GOBBLESYMBOLS,
  902.                               CRAFTER];
  903.          DINDENTSYMBOLS    := [];
  904.          GOBBLETERMINATORS := [OFSYM]
  905.        END;
  906.      WITH PPOPTION [CASEVARSYM] DO
  907.        BEGIN
  908.          OPTIONSSELECTED   := [SPACEAFTER,
  909.                               INDENTBYTAB,
  910.                               GOBBLESYMBOLS,
  911.                               CRAFTER];
  912.          DINDENTSYMBOLS    := [];
  913.          GOBBLETERMINATORS := [OFSYM]
  914.        END;
  915.      INT2 (TOPOFSTACK, CURRLINEPOS, CURRMARGIN, KEYWORD, DBLCHARS,
  916.            DBLCHAR,
  917.            SGLCHAR, RECORDSEEN, CURRCHAR, NEXTCHAR, CURRSYM, NEXTSYM,
  918.            PPOPTION);
  919.    END;
  920.  
  921.   FUNCTION STACKEMPTY  : BOOLEAN;
  922.    BEGIN
  923.      STACKEMPTY:= (TOP=0)
  924.    END; (* STACKEMPTY *)
  925.  
  926.   FUNCTION STACKFULL  : BOOLEAN;
  927.    BEGIN
  928.      STACKFULL:= (TOP=MAXSTACKSIZE)
  929.    END; (* STACKFULL *)
  930.  
  931.   PROCEDURE POPSTACK(VAR INDENTSYMBOL:KEYSYMBOL;
  932.                      VAR PREVMARGIN  :INTEGER);
  933.    BEGIN (* POPSTACK *)
  934.      IF NOT STACKEMPTY
  935.        THEN
  936.          BEGIN
  937.            INDENTSYMBOL := STACK[TOP].INDENTSYMBOL;
  938.            PREVMARGIN   := STACK[TOP].PREVMARGIN;
  939.            TOP := TOP - 1
  940.          END
  941.        ELSE
  942.          BEGIN
  943.            INDENTSYMBOL := OTHERSYM;
  944.            PREVMARGIN   := 0
  945.          END
  946.    END; (* POPSTACK *)
  947.  
  948.   PROCEDURE PUSHSTACK(INDENTSYMBOL:KEYSYMBOL;
  949.                       PREVMARGIN  :INTEGER);
  950.    BEGIN (* PUSHSTACK *)
  951.      TOP := TOP + 1;
  952.      STACK[TOP].INDENTSYMBOL := INDENTSYMBOL;
  953.      STACK[TOP].PREVMARGIN   := PREVMARGIN
  954.    END; (* PUSHSTACK *)
  955.  
  956.   PROCEDURE WRITECRS(NUMBEROFCRS:INTEGER;VAR CURRLINEPOS:INTEGER);
  957.  
  958.   VAR 
  959.       I: INTEGER;
  960.    BEGIN (* WRITECRS *)
  961.      IF NUMBEROFCRS > 0
  962.        THEN
  963.          BEGIN
  964.            FOR I := 1 TO NUMBEROFCRS DO WRITELN(FOUT);
  965.            CURRLINEPOS := 0
  966.          END
  967.    END; (* WRITECRS *)
  968.  
  969.   PROCEDURE INSERTCR(VAR CURRSYM   :SYMBOLINFO);
  970.  
  971.   CONST 
  972.         ONCE = 1;
  973.    BEGIN (* INSERTCR *)
  974.      IF CURRSYM^.CRSBEFORE = 0
  975.        THEN
  976.          BEGIN
  977.            WRITECRS(ONCE,CURRLINEPOS);
  978.            CURRSYM^.SPACESBEFORE := 0
  979.          END
  980.    END; (* INSERTCR *)
  981.  
  982.   PROCEDURE INSERTBLANKLINE(VAR CURRSYM:SYMBOLINFO);
  983.  
  984.   CONST 
  985.         ONCE  = 1;
  986.         TWICE = 2;
  987.    BEGIN  (* INSERTBLANKLINE *)
  988.      IF CURRSYM^.CRSBEFORE = 0
  989.        THEN
  990.          BEGIN
  991.            IF CURRLINEPOS = 0
  992.              THEN
  993.                WRITECRS(ONCE,     CURRLINEPOS)
  994.              ELSE
  995.                WRITECRS(TWICE,     CURRLINEPOS);
  996.            CURRSYM^.SPACESBEFORE := 0
  997.          END
  998.        ELSE
  999.          IF CURRSYM^.CRSBEFORE = 1
  1000.            THEN
  1001.              IF CURRLINEPOS > 0
  1002.                THEN
  1003.                  WRITECRS(ONCE,     CURRLINEPOS)
  1004.    END; (* INSERTBLANKLINE *)
  1005.  
  1006.   PROCEDURE LSHIFTON(DINDENTSYMBOLS:KEYSYMSET);
  1007.  
  1008.   VAR 
  1009.       INDENTSYMBOL: KEYSYMBOL;
  1010.       PREVMARGIN  : INTEGER;
  1011.    BEGIN (* LSHIFTON *)
  1012.      IF NOT STACKEMPTY
  1013.        THEN
  1014.          BEGIN
  1015.            REPEAT
  1016.              POPSTACK(INDENTSYMBOL,
  1017.                       PREVMARGIN);
  1018.              IF INDENTSYMBOL IN DINDENTSYMBOLS
  1019.                THEN
  1020.                  CURRMARGIN := PREVMARGIN
  1021.            UNTIL NOT(INDENTSYMBOL IN DINDENTSYMBOLS)
  1022.                  OR (STACKEMPTY);
  1023.            IF NOT(INDENTSYMBOL IN DINDENTSYMBOLS)
  1024.              THEN
  1025.                PUSHSTACK(INDENTSYMBOL,
  1026.                          PREVMARGIN)
  1027.          END
  1028.    END; (* LSHIFTON *)
  1029.  
  1030.   PROCEDURE LSHIFT;
  1031.  
  1032.   VAR 
  1033.       INDENTSYMBOL: KEYSYMBOL;
  1034.       PREVMARGIN : INTEGER;
  1035.    BEGIN (* LSHIFT *)
  1036.      IF NOT STACKEMPTY
  1037.        THEN
  1038.          BEGIN
  1039.            POPSTACK(INDENTSYMBOL,
  1040.                     PREVMARGIN);
  1041.            CURRMARGIN := PREVMARGIN
  1042.          END
  1043.    END; (* LSHIFT *)
  1044.  
  1045.   PROCEDURE INSERTSPACE(VAR SYMBOL:SYMBOLINFO);
  1046.    BEGIN (* INSERTSPACE *)
  1047.      IF CURRLINEPOS < MAXLINESIZE
  1048.        THEN
  1049.          BEGIN
  1050.            WRITE(FOUT, SPACE);
  1051.            CURRLINEPOS := CURRLINEPOS + 1;
  1052.            WITH SYMBOL^ DO
  1053.              IF (CRSBEFORE = 0) AND (SPACESBEFORE > 0)
  1054.                THEN
  1055.                  SPACESBEFORE := SPACESBEFORE - 1
  1056.          END
  1057.    END; (* INSERTSPACE *)
  1058.  
  1059.   PROCEDURE MOVELINEPOS(NEWLINEPOS :INTEGER;
  1060.                         VAR CURRLINEPOS:INTEGER);
  1061.  
  1062.   VAR 
  1063.       I: INTEGER;
  1064.    BEGIN (* MOVELINEPOS *)
  1065.      FOR I := CURRLINEPOS+1 TO NEWLINEPOS DO WRITE(FOUT, SPACE);
  1066.      CURRLINEPOS := NEWLINEPOS
  1067.    END; (* MOVELINEPOS *)
  1068.  
  1069.   PROCEDURE PRINTSYMBOL(CURRSYM    :SYMBOLINFO;
  1070.                         VAR CURRLINEPOS:INTEGER);
  1071.  
  1072.   VAR 
  1073.       I: INTEGER;
  1074.    BEGIN (* PRINTSYMBOL *)
  1075.      WITH CURRSYM^ DO
  1076.        BEGIN
  1077.          FOR I := 1 TO LENGTHY DO
  1078.            BEGIN
  1079.              WRITE(FOUT, VALUES[I])
  1080.            END;
  1081.          STARTPOS := CURRLINEPOS (* Save start position for tabbing *);
  1082.          CURRLINEPOS := CURRLINEPOS + LENGTHY
  1083.        END (* WITH *)
  1084.    END; (* PRINTSYMBOL *)
  1085.  
  1086.   PROCEDURE PPSYMBOL(CURRSYM:SYMBOLINFO);
  1087.  
  1088.   CONST 
  1089.         ONCE  = 1;
  1090.  
  1091.   VAR 
  1092.       NEWLINEPOS: INTEGER;
  1093.    BEGIN (* PPSYMBOL *)
  1094.      WITH CURRSYM^ DO
  1095.        BEGIN
  1096.          WRITECRS(CRSBEFORE,CURRLINEPOS);
  1097.          IF (CURRLINEPOS + SPACESBEFORE > CURRMARGIN)
  1098.             OR (NAME IN [OPENCOMMENT, CLOSECOMMENT])
  1099.            THEN
  1100.              NEWLINEPOS := CURRLINEPOS + SPACESBEFORE
  1101.            ELSE
  1102.              NEWLINEPOS := CURRMARGIN;
  1103.          IF NEWLINEPOS + LENGTHY > MAXLINESIZE
  1104.            THEN
  1105.              BEGIN
  1106.                WRITECRS(ONCE,CURRLINEPOS);
  1107.                IF CURRMARGIN + LENGTHY <= MAXLINESIZE
  1108.                  THEN
  1109.                    NEWLINEPOS := CURRMARGIN
  1110.                  ELSE
  1111.                    IF LENGTHY < MAXLINESIZE
  1112.                      THEN
  1113.                        NEWLINEPOS := MAXLINESIZE - LENGTHY
  1114.                      ELSE
  1115.                        NEWLINEPOS := 0
  1116.              END;
  1117.          MOVELINEPOS( NEWLINEPOS,CURRLINEPOS);
  1118.          PRINTSYMBOL(CURRSYM,
  1119.                      CURRLINEPOS)
  1120.        END (* WITH *)
  1121.    END; (* PPSYMBOL *)
  1122.  
  1123.   PROCEDURE RSHIFTTOCLP(CURRSYM:KEYSYMBOL);
  1124.   FORWARD;
  1125.  
  1126.   PROCEDURE GOBBLE(TERMINATORS:KEYSYMSET;VAR CURRSYM,NEXTSYM    :
  1127.                    SYMBOLINFO);
  1128.    BEGIN (* GOBBLE *)
  1129.      RSHIFTTOCLP(CURRSYM^.NAME);
  1130.      WHILE NOT(NEXTSYM^.NAME IN (TERMINATORS + [ENDOFFILE])) DO
  1131.        BEGIN
  1132.          GETSYMBOL(NEXTSYM,CURRSYM);
  1133.          PPSYMBOL(CURRSYM)
  1134.        END; (* WHILE *)
  1135.      LSHIFT
  1136.    END; (* GOBBLE *)
  1137.  
  1138.   PROCEDURE RSHIFT(CURRSYM:KEYSYMBOL);
  1139.    BEGIN (* RSHIFT *)
  1140.      IF NOT STACKFULL
  1141.        THEN
  1142.          PUSHSTACK(CURRSYM,
  1143.                    CURRMARGIN);
  1144.      IF STARTPOS > CURRMARGIN
  1145.        THEN
  1146.          CURRMARGIN := STARTPOS;
  1147.      IF CURRMARGIN < SLOFAIL1
  1148.        THEN
  1149.          CURRMARGIN := CURRMARGIN + INDENT1
  1150.        ELSE
  1151.          IF CURRMARGIN < SLOFAIL2
  1152.            THEN
  1153.              CURRMARGIN := CURRMARGIN + INDENT2
  1154.    END; (* RSHIFT *)
  1155.  
  1156.   PROCEDURE RSHIFTTOCLP;
  1157.    BEGIN (* RSHIFTTOCLP *)
  1158.      IF NOT STACKFULL
  1159.        THEN
  1160.          PUSHSTACK(CURRSYM,
  1161.                    CURRMARGIN);
  1162.      CURRMARGIN := CURRLINEPOS
  1163.    END; (* RSHIFTTOCLP *)
  1164.  BEGIN  (* PRETTYPRINT *)
  1165.    LOWVIDEO;
  1166.    WRITELN
  1167.     ('This is the PASCAL User''s Group PASCAL Prettyprinter:');
  1168.    WRITELN;
  1169.    GETINPFIL(FIN,FINNAME);
  1170.    GETOUTFIL(FOUT,OUTNAME);
  1171.    WITH FINSTAT DO
  1172.      BEGIN
  1173.        FILECH := ' ';
  1174.        FILEEF := FALSE;
  1175.        FILEEL := FALSE
  1176.      END;
  1177.    GETFIN;
  1178.    INITIALIZE(TOP,        CURRLINEPOS,
  1179.               CURRMARGIN, KEYWORD,    DBLCHARS,    DBLCHAR,
  1180.               SGLCHAR,    RECORDSEEN, CURRCHAR,    NEXTCHAR,
  1181.               CURRSYM,    NEXTSYM,    PPOPTION);
  1182.    CRPENDING := FALSE;
  1183.    WHILE (NEXTSYM^.NAME <> ENDOFFILE) DO
  1184.      BEGIN
  1185.        GETSYMBOL(NEXTSYM,CURRSYM);
  1186.        WITH PPOPTION [CURRSYM^.NAME] DO
  1187.          BEGIN
  1188.            IF (CRPENDING AND NOT(CRSUPPRESS IN OPTIONSSELECTED))
  1189.               OR (CRBEFORE IN OPTIONSSELECTED)
  1190.              THEN
  1191.                BEGIN
  1192.                  INSERTCR(CURRSYM);
  1193.                  CRPENDING := FALSE
  1194.                END;
  1195.            IF BLANKLINEBEFORE IN OPTIONSSELECTED
  1196.              THEN
  1197.                BEGIN
  1198.                  INSERTBLANKLINE(CURRSYM);
  1199.                  CRPENDING := FALSE
  1200.                END;
  1201.            IF DINDENTONKEYS IN OPTIONSSELECTED
  1202.              THEN
  1203.                LSHIFTON(DINDENTSYMBOLS);
  1204.            IF DINDENT IN OPTIONSSELECTED
  1205.              THEN
  1206.                LSHIFT;
  1207.            IF SPACEBEFORE IN OPTIONSSELECTED
  1208.              THEN
  1209.                INSERTSPACE(CURRSYM);
  1210.            PPSYMBOL(CURRSYM);
  1211.            IF SPACEAFTER IN OPTIONSSELECTED
  1212.              THEN
  1213.                INSERTSPACE(NEXTSYM);
  1214.            IF INDENTBYTAB IN OPTIONSSELECTED
  1215.              THEN
  1216.                RSHIFT(CURRSYM^.NAME);
  1217.            IF INDENTTOCLP IN OPTIONSSELECTED
  1218.              THEN
  1219.                RSHIFTTOCLP(CURRSYM^.NAME);
  1220.            IF GOBBLESYMBOLS IN OPTIONSSELECTED
  1221.              THEN
  1222.                GOBBLE(GOBBLETERMINATORS,CURRSYM,NEXTSYM);
  1223.            IF CRAFTER IN OPTIONSSELECTED
  1224.              THEN
  1225.                CRPENDING := TRUE
  1226.          END (* WITH *)
  1227.      END; (* WHILE *)
  1228.    CLOSE(FIN);
  1229.    IF CRPENDING THEN WRITELN(FOUT);
  1230.    CLOSE (FOUT)
  1231.  END.
  1232.