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 101 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 11533x 11533x 11533x 11533x 1x 1x 1215735x 42759x 42759x 42759x 1215735x 1215735x 11533x 11533x 11533x 1204202x 1204202x 1204202x 1204202x 1204202x 1204202x 1x 1x 228024x 228024x 1x 1x 228024x 228024x 1x 1x 1x 1x 1x 1x 2199x 2199x 2199x 2199x 1x 1x 12x 12x 12x 12x 1x 1x 2431470x 23066x 2431470x 23066x 23066x 2385338x 2385338x 1x 1x 1444105x 1444105x 34320x 34320x 1409785x 1409785x 1x 1x 1215735x 1215735x 34563x 34563x 1181172x 1181172x 1x 1x 219840x 219840x 219840x 1x 1x 11533x 11533x 1x 1x 1444105x 1444105x 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;
}
}
|