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 11212x 11212x 11212x 11212x 1x 1x 1173024x 40929x 40929x 40929x 1173024x 1173024x 11212x 11212x 11212x 1161812x 1161812x 1161812x 1161812x 1161812x 1161812x 1x 1x 220147x 220147x 1x 1x 220147x 220147x 1x 1x 1x 1x 1x 1x 2141x 2141x 2141x 2141x 1x 1x 12x 12x 12x 12x 1x 1x 2346048x 22424x 2346048x 22424x 22424x 2301200x 2301200x 1x 1x 1393516x 1393516x 33359x 33359x 1360157x 1360157x 1x 1x 1173024x 1173024x 33601x 33601x 1139423x 1139423x 1x 1x 212135x 212135x 212135x 1x 1x 11212x 11212x 1x 1x 1393516x 1393516x 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;
}
}
|