home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d512 / m2pascal.lha / M2Pascal / src / OutModule.mod < prev    next >
Text File  |  1991-07-20  |  7KB  |  250 lines

  1. IMPLEMENTATION MODULE OutModule;
  2.  (*
  3.    This module is used primarily for the output ( object ) file. It consists
  4.    of mostly internal text maintenance operations like word wrapping if
  5.    the data is too long for the output line and indenting the line from
  6.    the left side to match the original.
  7.    
  8.    This module also handles some string related procedures like comparing.
  9.  
  10.    BUGS: Tabs are not handled correctly.
  11.  *)
  12.  
  13. FROM scan    IMPORT IndentArray,          STRING,              write,       
  14.                     EOLN,                 ReadAheadSymbol,
  15.                     ReadSymbol,           SymbolType,          SPACE,
  16.                     TAB,                  rewind,              Q2;
  17. FROM Strings IMPORT StringLength,         ConcatString,        CompareString,
  18.                     Relation;
  19. FROM errors  IMPORT CleanUp;
  20.  
  21. FROM InOut   IMPORT WriteString,  WriteCard;
  22.  
  23. FROM options IMPORT OptionsRec;
  24.  
  25.  (* All global data below is for a SINGLE output file.
  26.  *)
  27. CONST
  28.         COLMAX   =   80;
  29.  
  30. VAR
  31.         ColWrite      :    CARDINAL;  (*  col we're about to write to  *)
  32.         InFileSymbol  :    STRING;
  33.         SymbolClass   :    SymbolType;
  34.         r_par         :    INTEGER;   (* paranth. matching *)
  35.  
  36.  
  37. (* Determine if symbol is too long for current line and should be placed
  38.    on next line.
  39. *)
  40. PROCEDURE WordWrap ( length : CARDINAL ) : BOOLEAN;
  41. BEGIN
  42.   RETURN  ( ( COLMAX - ColWrite + 1 ) < length );
  43. END WordWrap;
  44.  
  45.  
  46.  
  47.  
  48.  (* dump the data which produces the original margin.
  49.  *)
  50. PROCEDURE  WriteIndent ( indent : IndentArray );
  51.  VAR i : CARDINAL;  ch : CHAR;   good : BOOLEAN;
  52. BEGIN
  53.    i    :=  1;
  54.    ch   :=  indent [ i ];     (* Tab or Space character *)
  55.    INC  ( i );
  56.    good :=  TRUE;
  57.  
  58.    WHILE  (  ( ch <> 0C  ) AND good ) DO
  59.          write ( ch );
  60.          INC ( ColWrite , 1 );
  61.  
  62.          ch   := indent [ i ];
  63.          INC ( i        , 1 );
  64.    END;
  65. END WriteIndent;
  66.  
  67.  
  68.  (* A tab will merely increment ColWrite by 1. This in undesirable in
  69.     some circumstances.
  70.   *)
  71. PROCEDURE output ( indent     : IndentArray  ;   
  72.                    word       : STRING );
  73.  VAR   i : INTEGER;    ch  : CHAR;      good : BOOLEAN;
  74. BEGIN
  75.         i    := 0;
  76.         ch   := word [ i ];
  77.         good := TRUE;
  78.  
  79.  
  80.         IF ( (WordWrap ( StringLength ( word ) )) AND ( ch <> EOLN ) ) THEN
  81.             write ( EOLN );
  82.             ColWrite := 1;
  83.             WriteIndent ( indent );
  84.         END;
  85.  
  86.         WHILE  ( (  ch <> 0C  ) AND good ) DO
  87.                 write ( ch );
  88.  
  89.                 INC ( i        , 1 );
  90.                         
  91.                   (* reset ColWrite if a line feed exists *)
  92.                 IF ( ch <> EOLN ) THEN
  93.                         INC ( ColWrite , 1 );
  94.                 ELSE
  95.                         ColWrite := 1;
  96.                 END;
  97.  
  98.                 ch := word [ i ];
  99.         END;
  100.  
  101.         IF NOT good THEN CleanUp (); END;        (* HALT *)
  102.  
  103. END output;
  104.  
  105.  
  106.  (* Put the string "begin" in the output file either on the same line
  107.     we've been using or on the next line according to the default 
  108.     parameters. A space is inserted before "begin".
  109.  *)
  110. PROCEDURE PutBEGIN ( indent  : IndentArray );
  111.  VAR good : BOOLEAN;  len  : CARDINAL;
  112. BEGIN
  113.  len := 6;   (* " begin"   note spc at begining   *)
  114.  
  115.   (* same line if possible *)
  116.  IF ( ( OptionsRec.BeginNewLine = FALSE ) AND ( NOT WordWrap ( len )  ) ) THEN
  117.     output ( indent, " begin" );
  118.   (* next line *)
  119.  ELSE
  120.         write ( EOLN );
  121.     ColWrite :=  1;  WriteIndent ( indent );
  122.         output ( indent , "begin" ); 
  123.  END;
  124.  
  125. END PutBEGIN;
  126.  
  127.  
  128.  
  129.  
  130. (*****************String related support below********************************)
  131.  
  132.  
  133.  (* If there blanks in the InFile that are about to be read then
  134.     tack them onto the end of the string.
  135.    BUG: This procedure is the reason why INC(i) doesn't work but INC ( i ) does
  136.  
  137.  *)
  138. PROCEDURE AddBlanks ( VAR symbol   : STRING      );
  139. BEGIN
  140.     ReadAheadSymbol ( InFileSymbol, SymbolClass );
  141. (*
  142.     rewind          ( InFile ) ; (* Next read-ahead returns the abve line *)
  143. *)
  144.     IF ( SymbolClass = blanks ) THEN
  145.         ReadSymbol ( InFileSymbol, SymbolClass );
  146.         ConcatString ( symbol, InFileSymbol );
  147.     END;
  148. END AddBlanks;
  149.  
  150.  
  151.  
  152.  
  153.   (* compare two strings. This probably doesn't belong in here...
  154.   *)
  155. PROCEDURE identical ( s1 , s2 : STRING ) : BOOLEAN;
  156. BEGIN
  157.  RETURN CompareString ( s1, s2 ) = equal;
  158. END identical;
  159.  
  160.  
  161.  (* Increase or decrease global variable "r_par" depending if s = ) or (
  162.  *)
  163. PROCEDURE SetParCount ( s : STRING );
  164. BEGIN
  165.      IF identical ( s , ")" ) THEN
  166.           INC ( r_par );
  167.      ELSIF identical ( s , "(" ) THEN
  168.           DEC ( r_par );
  169.      END;
  170. END SetParCount;
  171.  
  172.  
  173. PROCEDURE LastPar () : BOOLEAN;
  174. BEGIN
  175.      IF r_par = 1 THEN
  176.           RETURN TRUE;
  177.      ELSE
  178.           RETURN FALSE;
  179.      END;
  180. END LastPar;
  181.  
  182.  (* Read first options of a one or two option command like so:
  183.               INC ( i , 1 )   OR  INC ( i )
  184.                    ^^^                 ^^^      -> returned value
  185.                        |                  |     -> ptr to next char.
  186.  
  187.                   The comma is read and thrown out in the first case.
  188.  *)
  189.  
  190. PROCEDURE FirstOption ( VAR  RetSymbol : STRING );
  191. BEGIN
  192.      RetSymbol := "\0";
  193.      
  194.       (* blanks between parenthesis and first option *)
  195.      AddBlanks ( RetSymbol );
  196.  
  197.       (* Read first option ( until comma or right parenthesis )   *)
  198.      ReadAheadSymbol ( InFileSymbol, SymbolClass );
  199.  
  200.      WHILE ( NOT identical ( InFileSymbol , "," ) AND
  201.            ( NOT identical ( InFileSymbol , ")" )   ))  DO
  202.           ConcatString    ( RetSymbol, InFileSymbol );          
  203.           ReadSymbol      ( InFileSymbol, SymbolClass );
  204.           ReadAheadSymbol ( InFileSymbol, SymbolClass );
  205.      END;
  206.  
  207.      IF ( identical ( InFileSymbol , "," )  ) THEN
  208.           ReadSymbol      ( InFileSymbol, SymbolClass );
  209.      END;
  210.      
  211.      (*
  212.     WriteString("FirstOption. |"); WriteString( RetSymbol ); WriteString("|\n");
  213.      *)
  214. END FirstOption; 
  215.  
  216.  
  217.  
  218.  (* Use to get retrieve a second option of a two option command. 
  219.     This is used after a call to FirstOption(). 
  220.     Here is a picture :
  221.              INC ( i , 1 ) ;   OR   INC ( i ) ;
  222.                       |                     |     -> start on entry
  223.                           |                  |    -> finish on exit
  224.  *)
  225. PROCEDURE SecondOption ( VAR RetSymbol : STRING);
  226.  VAR s : STRING;  
  227. BEGIN
  228.      RetSymbol := "\0";
  229.      r_par     := 0   ;  (* number of right ")" paranthesis *)
  230.  
  231.      ReadSymbol (  s, SymbolClass );
  232.      SetParCount ( s );
  233.      WHILE  NOT LastPar()  DO
  234.                 ConcatString    ( RetSymbol, s );
  235.                 ReadSymbol      ( s, SymbolClass );
  236.                 SetParCount     ( s );
  237.      END;
  238.      
  239.      (*
  240.    WriteString("SecondOption. |"); WriteString( RetSymbol ); WriteString("|\n");
  241.      *)
  242. END SecondOption;
  243.  
  244.  
  245.  
  246. BEGIN
  247.     ColWrite   := 1;
  248. END OutModule.
  249.  
  250.