Skip to content

Commit 8891e77

Browse files
committed
Reduce bytes in parse function
1 parent 85e5e2c commit 8891e77

File tree

1 file changed

+53
-72
lines changed

1 file changed

+53
-72
lines changed

src/index.ts

Lines changed: 53 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -186,31 +186,31 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
186186
const { encodePath = NOOP_VALUE } = options;
187187
const chars = [...str];
188188
const tokens: Array<LexToken> = [];
189-
let i = 0;
190189
let index = 0;
190+
let pos = 0;
191191

192192
function name() {
193193
let value = "";
194194

195-
if (ID_START.test(chars[++i])) {
196-
value += chars[i];
197-
while (ID_CONTINUE.test(chars[++i])) {
198-
value += chars[i];
195+
if (ID_START.test(chars[index])) {
196+
value += chars[index];
197+
while (ID_CONTINUE.test(chars[++index])) {
198+
value += chars[index];
199199
}
200-
} else if (chars[i] === '"') {
201-
let pos = i;
200+
} else if (chars[index] === '"') {
201+
let pos = index;
202202

203-
while (i < chars.length) {
204-
if (chars[++i] === '"') {
205-
i++;
203+
while (index < chars.length) {
204+
if (chars[++index] === '"') {
205+
index++;
206206
pos = 0;
207207
break;
208208
}
209209

210-
if (chars[i] === "\\") {
211-
value += chars[++i];
210+
if (chars[index] === "\\") {
211+
value += chars[++index];
212212
} else {
213-
value += chars[i];
213+
value += chars[index];
214214
}
215215
}
216216

@@ -223,103 +223,84 @@ export function parse(str: string, options: ParseOptions = {}): TokenData {
223223

224224
if (!value) {
225225
throw new TypeError(
226-
errorMessage(`Missing parameter name at index ${i}`, str),
226+
errorMessage(`Missing parameter name at index ${index}`, str),
227227
);
228228
}
229229

230230
return value;
231231
}
232232

233-
while (i < chars.length) {
234-
const value = chars[i];
233+
while (index < chars.length) {
234+
const value = chars[index];
235235
const type = SIMPLE_TOKENS[value];
236236

237237
if (type) {
238-
tokens.push({ type, index: i++, value });
238+
tokens.push({ type, index: index++, value });
239239
} else if (value === "\\") {
240-
tokens.push({ type: "ESCAPED", index: i++, value: chars[i++] });
240+
tokens.push({ type: "ESCAPED", index: index++, value: chars[index++] });
241241
} else if (value === ":") {
242-
const value = name();
243-
tokens.push({ type: "PARAM", index: i, value });
242+
tokens.push({ type: "PARAM", index: index++, value: name() });
244243
} else if (value === "*") {
245-
const value = name();
246-
tokens.push({ type: "WILDCARD", index: i, value });
244+
tokens.push({ type: "WILDCARD", index: index++, value: name() });
247245
} else {
248-
tokens.push({ type: "CHAR", index: i, value: chars[i++] });
246+
tokens.push({ type: "CHAR", index: index++, value });
249247
}
250248
}
251249

252-
tokens.push({ type: "END", index: i, value: "" });
253-
254-
function peek(): LexToken {
255-
return tokens[index];
256-
}
257-
258-
function tryConsume(type: TokenType): string | undefined {
259-
const token = peek();
260-
if (token.type !== type) return;
261-
index++;
262-
return token.value;
263-
}
264-
265-
function consume(type: TokenType): string {
266-
const value = tryConsume(type);
267-
if (value !== undefined) return value;
268-
const { type: nextType, index } = peek();
269-
throw new TypeError(
270-
errorMessage(
271-
`Unexpected ${nextType} at index ${index}, expected ${type}`,
272-
str,
273-
),
274-
);
275-
}
276-
277-
function text(): string {
278-
let result = "";
279-
let value: string | undefined;
280-
while ((value = tryConsume("CHAR") || tryConsume("ESCAPED"))) {
281-
result += value;
282-
}
283-
return result;
284-
}
250+
tokens.push({ type: "END", index, value: "" });
285251

286252
function consumeUntil(endType: TokenType): Token[] {
287-
const tokens: Token[] = [];
253+
const output: Token[] = [];
288254

289255
while (true) {
290-
const path = text();
291-
if (path) tokens.push({ type: "text", value: encodePath(path) });
256+
const { type, value, index } = tokens[pos++];
257+
if (type === endType) break;
258+
259+
if (type === "CHAR" || type === "ESCAPED") {
260+
let path = value;
261+
while (true) {
262+
const next = tokens[pos];
263+
if (next.type !== "CHAR" && next.type !== "ESCAPED") break;
264+
pos++;
265+
path += next.value;
266+
}
267+
output.push({ type: "text", value: encodePath(path) });
268+
continue;
269+
}
292270

293-
const param = tryConsume("PARAM");
294-
if (param) {
295-
tokens.push({
271+
if (type === "PARAM") {
272+
output.push({
296273
type: "param",
297-
name: param,
274+
name: value,
298275
});
299276
continue;
300277
}
301278

302-
const wildcard = tryConsume("WILDCARD");
303-
if (wildcard) {
304-
tokens.push({
279+
if (type === "WILDCARD") {
280+
output.push({
305281
type: "wildcard",
306-
name: wildcard,
282+
name: value,
307283
});
308284
continue;
309285
}
310286

311-
const open = tryConsume("{");
312-
if (open) {
313-
tokens.push({
287+
if (type === "{") {
288+
output.push({
314289
type: "group",
315290
tokens: consumeUntil("}"),
316291
});
317292
continue;
318293
}
319294

320-
consume(endType);
321-
return tokens;
295+
throw new TypeError(
296+
errorMessage(
297+
`Unexpected ${type} at index ${index}, expected ${endType}`,
298+
str,
299+
),
300+
);
322301
}
302+
303+
return output;
323304
}
324305

325306
return new TokenData(consumeUntil("END"), str);

0 commit comments

Comments
 (0)