IMPLEMENTATION MODULE StreamLex;

FROM Streams IMPORT Stream, InputStream;
FROM YaflLex IMPORT LexicalAnalyzer;
IMPORT SYSTEM;

  CLASS StreamLex;
    INHERITS LexicalAnalyzer;
    VAR
      TheStream: InputStream;
      ExpandTabs: BOOLEAN;

    REDEFINE METHOD CREATE (KeepComments,
                            ExpandTabs: BOOLEAN;
                            Input: InputStream);
      BEGIN
      BASE(KeepComments);
      TheStream := Input;
      THIS.ExpandTabs := ExpandTabs;
      END CREATE;

    REDEFINE METHOD GetLine: ARRAY OF CHAR;
      VAR
         j, NewSize: INTEGER;
        a: ARRAY OF CHAR;
      CONST
        TabWidth = 8;
      BEGIN
      IF NOT TheStream.Eof THEN
        RESULT := TheStream.ReadLine;
        IF ExpandTabs THEN
          FOR i := 0 TO RESULT.SIZE - 1 DO
            NewSize := NewSize + 1;
            IF RESULT[i] = SYSTEM.CHR(SYSTEM.Tab) THEN
              NewSize := ((NewSize + TabWidth - 1) / TabWidth) * TabWidth;
              END; 
            END;
          IF NewSize <> RESULT.SIZE THEN
            a.CREATE (NewSize);
            FOR i := 0 TO RESULT.SIZE - 1 DO
              IF RESULT[i] = SYSTEM.CHR(SYSTEM.Tab) THEN
                a[j] := ' ';
                j := j + 1;
                WHILE j MOD 8 <> 0 DO
                  a[j] := ' ';
                  j := j + 1;
                  END;
               ELSE
                a[j] := RESULT[i];
                j := j + 1;
                END;
              END;
            RESULT := a;
            END;  
          END;
        END;
      END GetLine;

    END StreamLex;

END StreamLex;

