parser-core: Make readInputFrom return more rich
MODIFY
packages/@romejs/codec-json/parse.ts
packages/@romejs/codec-json/parse.ts
@@ -163,7 +163,7 @@ export default createParser(
// Line comment
if (char === '/' && nextChar === '/') {
const commentValueIndex = add(index, 2);
- const value = this.readInputFrom(commentValueIndex, isntNewline);
+ const [value] = this.readInputFrom(commentValueIndex, isntNewline);
// (comment content start + comment content length)
return this.finishValueToken(
'LineComment',
@@ -175,7 +175,7 @@ export default createParser(
// BlockComment
if (char === '/' && nextChar === '*') {
const commentValueIndex = add(index, 2);
- const value = this.readInputFrom(
+ const [value] = this.readInputFrom(
commentValueIndex,
isntBlockCommentEnd,
);
@@ -200,7 +200,7 @@ export default createParser(
// Single character token starters
switch (char) {
case '"':
- const value = this.readInputFrom(inc(index), isStringValueChar);
+ const [value] = this.readInputFrom(inc(index), isStringValueChar);
// Check for closed string (index is the current token index + string length + closing quote + 1 for the end char)
const end = add(add(index, value.length), 2);
@@ -284,7 +284,7 @@ export default createParser(
if (isDigit(char)) {
const value = this.removeUnderscores(
index,
- this.readInputFrom(index, isNumberChar),
+ this.readInputFrom(index, isNumberChar)[0],
);
const num = Number(value);
return this.finishValueToken('Number', num, add(index, value.length));
@@ -292,7 +292,7 @@ export default createParser(
// Word - boolean, undefined etc
if (isWordStartChar(char)) {
- const value = this.readInputFrom(index, isWordChar);
+ const [value] = this.readInputFrom(index, isWordChar);
return this.finishValueToken('Word', value, add(index, value.length));
}

MODIFY
packages/@romejs/codec-semver/parse.ts
packages/@romejs/codec-semver/parse.ts
@@ -97,7 +97,7 @@ const createSemverParser = createParser(
}
if (isDigit(char)) {
- const value = this.readInputFrom(index, isDigit);
+ const [value] = this.readInputFrom(index, isDigit);
return this.finishValueToken(
'Number',
Number(value),
@@ -106,7 +106,7 @@ const createSemverParser = createParser(
}
if (isAlpha(char)) {
- const value = this.readInputFrom(index, isAlpha);
+ const [value] = this.readInputFrom(index, isAlpha);
return this.finishValueToken('Word', value, add(index, value.length));
}

MODIFY
packages/@romejs/codec-spdx-license/parse.ts
packages/@romejs/codec-spdx-license/parse.ts
@@ -99,8 +99,7 @@ const createSPDXLicenseParser = createParser(
}
if (isWordChar(char)) {
- const value = this.readInputFrom(index, isWordChar);
- const end = add(index, value.length);
+ const [value, end] = this.readInputFrom(index, isWordChar);
if (value === 'AND') {
return this.finishToken('And', end);

MODIFY
packages/@romejs/parser-core/index.ts
packages/@romejs/parser-core/index.ts
@@ -31,6 +31,7 @@ import {
coerce0,
number0Neg1,
get0,
+ dec,
} from '@romejs/ob1';
import {escapeMarkup} from '@romejs/string-markup';
import {UnknownFilePath, createUnknownFilePath} from '@romejs/path';
@@ -465,19 +466,27 @@ export class ParserCore<Tokens extends TokensShape, State> {
readInputFrom(
index: Number0,
callback?: (char: string, index: Number0, input: string) => boolean,
- ): string {
+ ): [string, Number0, boolean] {
const {input} = this;
let value = '';
- while (
- get0(index) < input.length &&
- (callback === undefined || callback(input[get0(index)], index, input))
+ while (true) {
+ if (get0(index) >= input.length) {
+ return [value, index, true];
+ }
+
+ if (
+ callback === undefined ||
+ callback(input[get0(index)], index, input)
) {
value += input[get0(index)];
index = inc(index);
+ } else {
+ break;
+ }
}
- return value;
+ return [value, index, false];
}
// Get the string between the specified range

MODIFY
packages/@romejs/path-match/parse.ts
packages/@romejs/path-match/parse.ts
@@ -88,11 +88,11 @@ const createPathMatchParser = createParser(
return this.finishToken('Separator', add(index, 2));
}
- const value = this.readInputFrom(
+ const [value, end] = this.readInputFrom(
index,
this.isWordCharacter.bind(this),
);
- return this.finishValueToken('Word', value, add(index, value.length));
+ return this.finishValueToken('Word', value, end);
}
eatSeparators(): boolean {

MODIFY
packages/@romejs/string-markup/parse.ts
packages/@romejs/string-markup/parse.ts
@@ -138,28 +138,27 @@ const createStringMarkupParser = createParser(
}
if (isAlpha(char)) {
- const value = this.readInputFrom(index, isAlpha);
+ const [value, end] = this.readInputFrom(index, isAlpha);
return {
state,
- token: this.finishValueToken(
- 'Word',
- value,
- add(index, value.length),
- ),
+ token: this.finishValueToken('Word', value, end),
};
}
if (char === '"') {
- const value = this.readInputFrom(inc(index), isStringValueChar);
- const end = add(add(index, value.length), 2);
+ const [value, stringValueEnd, unclosed] = this.readInputFrom(
+ inc(index),
+ isStringValueChar,
+ );
- if (input[get0(end) - 1] !== '"') {
+ if (unclosed) {
throw this.unexpected({
message: 'Unclosed string',
- start: this.getPositionFromIndex(end),
+ start: this.getPositionFromIndex(stringValueEnd),
});
}
+ const end = add(stringValueEnd, 1);
return {
state,
token: this.finishValueToken('String', value, end),
@@ -186,14 +185,14 @@ const createStringMarkupParser = createParser(
}
// Keep eating text until we hit a <
- const value = this.readInputFrom(index, isTextChar);
+ const [value, end] = this.readInputFrom(index, isTextChar);
return {
state,
token: {
type: 'Text',
value: normalizeTextValue(value),
start: index,
- end: add(index, value.length),
+ end,
},
};
}

parser-core: Make readInputFrom return more rich