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 11317x 11317x 11317x 11317x 1x 1x 1190339x 41635x 41635x 41635x 1190339x 1190339x 11317x 11317x 11317x 1179022x 1179022x 1179022x 1179022x 1179022x 1179022x 1x 1x 223319x 223319x 1x 1x 223319x 223319x 1x 1x 1x 1x 1x 1x 2153x 2153x 2153x 2153x 1x 1x 12x 12x 12x 12x 1x 1x 2380678x 22634x 2380678x 22634x 22634x 2335410x 2335410x 1x 1x 1414004x 1414004x 33673x 33673x 1380331x 1380331x 1x 1x 1190339x 1190339x 33916x 33916x 1156423x 1156423x 1x 1x 215246x 215246x 215246x 1x 1x 11317x 11317x 1x 1x 1414004x 1414004x 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;
}
}
|