Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 33 additions & 31 deletions src/charstream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ export namespace CharUtil {
}
}

private withNewEndPos(newEndPos: number): CharStream {
const newHasEOF = newEndPos >= this.endpos && this.hasEOF;
return new CharStream(this.input, this.startpos, newEndPos, newHasEOF);
}

private withNewStartPos(newStartPos: number): CharStream {
return new CharStream(this.input, newStartPos, this.endpos, this.hasEOF);
}

/**
* Returns true of the end of the input has been reached.
*/
Expand All @@ -59,8 +68,7 @@ export namespace CharUtil {
if (this.startpos + num >= this.endpos) {
return this;
} else {
const newHasEOF = this.startpos + num == this.endpos && this.hasEOF;
return new CharStream(this.input, this.startpos, this.startpos + num, newHasEOF);
return this.withNewEndPos(this.startpos + num);
}
}

Expand All @@ -83,11 +91,10 @@ export namespace CharUtil {
*/
public seekWhile(pred: (char: string) => boolean): CharStream {
let pos = this.startpos;
let end = this.endpos;
while (pos < end && pred(this.input.charAt(pos))) {
while (pos < this.endpos && pred(this.input.charAt(pos))) {
pos++;
}
return new CharStream(this.input, pos, end, pos == end);
return this.withNewStartPos(pos);
}

/**
Expand All @@ -98,14 +105,10 @@ export namespace CharUtil {
*/
public seekWhileCharCode(okCodes: (n: number) => boolean): [CharStream, CharStream] {
let pos = this.startpos;
let end = this.endpos;
while (pos < end && okCodes(this.input.charCodeAt(pos))) {
while (pos < this.endpos && okCodes(this.input.charCodeAt(pos))) {
pos++;
}
return [
new CharStream(this.input, this.startpos, pos, pos == end),
new CharStream(this.input, pos, end, this.hasEOF),
];
return [this.withNewEndPos(pos), this.withNewStartPos(pos)];
}

/**
Expand All @@ -114,11 +117,8 @@ export namespace CharUtil {
* @param num
*/
public seek(num: number): CharStream {
if (this.startpos + num > this.endpos) {
return new CharStream(this.input, this.endpos, this.endpos, this.hasEOF);
} else {
return new CharStream(this.input, this.startpos + num, this.endpos, this.hasEOF);
}
const newStart = Math.min(this.startpos + num, this.endpos);
return this.withNewStartPos(newStart);
}

/**
Expand All @@ -127,12 +127,10 @@ export namespace CharUtil {
* empty.
*/
public head(): CharStream {
if (!this.isEmpty()) {
const newHasEOF = this.startpos + 1 == this.endpos && this.hasEOF;
return new CharStream(this.input, this.startpos, this.startpos + 1, newHasEOF);
} else {
if (this.isEmpty()) {
throw new Error('Cannot get the head of an empty string.');
}
return this.withNewEndPos(this.startpos + 1);
}

/**
Expand All @@ -141,11 +139,10 @@ export namespace CharUtil {
* empty.
*/
public tail(): CharStream {
if (!this.isEmpty()) {
return new CharStream(this.input, this.startpos + 1, this.endpos, this.hasEOF);
} else {
if (this.isEmpty()) {
throw new Error('Cannot get the tail of an empty string.');
}
return this.withNewStartPos(this.startpos + 1);
}

/**
Expand Down Expand Up @@ -175,7 +172,7 @@ export namespace CharUtil {
public substring(start: number, end: number): CharStream {
const start2 = this.startpos + start;
const end2 = this.startpos + end;
const newHasEOF = this.endpos == end2 && this.hasEOF;
const newHasEOF = end2 >= this.endpos && this.hasEOF;
return new CharStream(this.input, start2, end2, newHasEOF);
}

Expand All @@ -199,14 +196,19 @@ export namespace CharUtil {
*/
static concat(css: CharStream[]): CharStream {
if (css.length == 0) {
return new CharStream('', 0, 0, false);
} else {
let cs = css[0];
for (let i = 1; i < css.length; i++) {
cs = cs.concat(css[i]);
}
return cs;
return new CharStream('', 0, 0, true);
}

let s = '';
let hasEOF = true;
for (const cs of css) {
s += cs.toString();
// We only want the EOF of the last item so
// it's fine to keep overwriting it
hasEOF = cs.hasEOF;
}

return new CharStream(s, 0, s.length, hasEOF);
}
}
}
Loading