All files / src/abap/1_lexer lexer_stream.ts

94% Statements 94/100
88.46% Branches 23/26
100% Functions 12/12
94% Lines 94/100

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 1011x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11766x 11766x 11766x 11766x 1x 1x 1247779x 43960x 43960x 43960x 1247779x 1247779x 11766x 11766x 11766x 1236013x 1236013x 1236013x 1236013x 1236013x 1236013x 1x 1x 234202x 234202x 1x 1x 234202x 234202x 1x 1x 1x 1x 1x 1x 2235x 2235x     2235x 2235x 1x 1x 12x 12x     12x 12x 1x 1x 2495558x 23532x 2495558x 23532x 23532x 2448494x 2448494x 1x 1x 1482327x 1482327x 35017x 35017x 1447310x 1447310x 1x 1x 1247779x 1247779x 35262x 35262x 1212517x 1212517x 1x 1x 225828x     225828x 225828x 1x 1x 11766x 11766x 1x 1x 1482327x 1482327x 1x  
const NL = 10;   // "\n"
const EOF = -1;  // no character (start/end of file)
 
export class LexerStream {
  private readonly raw: string;
  private offset = -1;
  private row: number;
  private col: number;
 
  public constructor(raw: string) {
    this.raw = raw;
    this.row = 0;
    this.col = 0;
  }
 
  public advance(): boolean {
    if (this.currentChar() === NL) {
      this.col = 1;
      this.row = this.row + 1;
    }
 
    if (this.offset === this.raw.length) {
      this.col = this.col - 1;
      return false;
    }
 
    this.col = this.col + 1;
 
    this.offset = this.offset + 1;
    return true;
  }
 
  public getCol(): number {
    return this.col;
  }
 
  public getRow(): number {
    return this.row;
  }
 
  // the *Char() accessors return character codes (charCodeAt) rather than
  // single character strings, to avoid allocating a string per input character
  // in the lexer hot loop. EOF (-1) is returned when the offset is out of range.
 
  public prevChar(): number {
    const o = this.offset - 1;
    if (o < 0) {
      return EOF;
    }
    return this.raw.charCodeAt(o);
  }
 
  public prevPrevChar(): number {
    const o = this.offset - 2;
    if (o < 0) {
      return EOF;
    }
    return this.raw.charCodeAt(o);
  }
 
  public currentChar(): number {
    if (this.offset < 0) {
      return NL; // simulate newline at start of file to handle star(*) comments
    } else if (this.offset >= this.raw.length) {
      return EOF;
    }
    return this.raw.charCodeAt(this.offset);
  }
 
  public nextChar(): number {
    const o = this.offset + 1;
    if (o >= this.raw.length) {
      return EOF;
    }
    return this.raw.charCodeAt(o);
  }
 
  public nextNextChar(): number {
    const o = this.offset + 2;
    if (o >= this.raw.length) {
      return EOF;
    }
    return this.raw.charCodeAt(o);
  }
 
  public charCodeAt(o: number): number {
    if (o < 0 || o >= this.raw.length) {
      return EOF;
    }
    return this.raw.charCodeAt(o);
  }
 
  public getRaw(): string {
    return this.raw;
  }
 
  public getOffset() {
    return this.offset;
  }
}