Cleaning
This commit is contained in:
parent
1961ac6249
commit
164f752338
6 changed files with 95 additions and 122 deletions
|
|
@ -202,6 +202,22 @@ export class Parser {
|
|||
return expr;
|
||||
}
|
||||
|
||||
private parseCommaSeparated<T>(closeToken: Token['kind'], parseItem: () => T): T[] {
|
||||
const items: T[] = [];
|
||||
let first = true;
|
||||
|
||||
while (this.current().kind !== closeToken) {
|
||||
if (!first) {
|
||||
this.expect('comma');
|
||||
if (this.current().kind === closeToken) break; // trailing commas
|
||||
}
|
||||
first = false;
|
||||
items.push(parseItem());
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private parseMatch(expr: AST): AST {
|
||||
const token = this.current();
|
||||
const cases: MatchCase[] = [];
|
||||
|
|
@ -288,23 +304,16 @@ export class Parser {
|
|||
// Record
|
||||
if (token.kind === 'open-brace') {
|
||||
this.advance();
|
||||
const fields: { [key: string]: Pattern } = {};
|
||||
let first = true;
|
||||
|
||||
while (this.current().kind !== 'close-brace') {
|
||||
if (!first) {
|
||||
this.expect('comma');
|
||||
if (this.current().kind === 'close-brace') break; // trailing commas
|
||||
}
|
||||
first = false;
|
||||
|
||||
const items = this.parseCommaSeparated('close-brace', () => {
|
||||
const keyToken = this.expect('ident');
|
||||
const key = (keyToken as { value: string }).value;
|
||||
this.expect('equals');
|
||||
fields[key] = this.parsePattern();
|
||||
}
|
||||
return { key, pattern: this.parsePattern() };
|
||||
});
|
||||
|
||||
this.expect('close-brace');
|
||||
const fields: { [key: string]: Pattern } = {};
|
||||
for (const item of items) fields[item.key] = item.pattern;
|
||||
return { kind: 'record', fields };
|
||||
}
|
||||
|
||||
|
|
@ -429,23 +438,17 @@ export class Parser {
|
|||
if (this.current().kind === 'open-brace') {
|
||||
// Record update
|
||||
this.advance();
|
||||
const updates: { [key: string]: AST } = {};
|
||||
let first = true;
|
||||
|
||||
while (this.current().kind !== 'close-brace') {
|
||||
if (!first) {
|
||||
this.expect('comma');
|
||||
if (this.current().kind === 'close-brace') break; // trailing commas
|
||||
}
|
||||
first = false;
|
||||
|
||||
const items = this.parseCommaSeparated('close-brace', () => {
|
||||
const keyToken = this.expect('ident');
|
||||
const key = (keyToken as { value: string }).value;
|
||||
this.expect('equals');
|
||||
updates[key] = this.parseExpression();
|
||||
}
|
||||
return { key, value: this.parseExpression() };
|
||||
});
|
||||
|
||||
this.expect('close-brace');
|
||||
const updates: { [key: string]: AST } = {};
|
||||
for (const item of items) updates[item.key] = item.value;
|
||||
expr = { kind: 'record-update', record: expr, updates, ...this.getPos(token) }
|
||||
|
||||
} else {
|
||||
|
|
@ -475,26 +478,15 @@ export class Parser {
|
|||
if (token.kind === 'open-bracket') {
|
||||
this.advance();
|
||||
|
||||
const items: AST[] = [];
|
||||
let first = true;
|
||||
|
||||
while (this.current().kind !== 'close-bracket') {
|
||||
if (!first) {
|
||||
this.expect('comma');
|
||||
if (this.current().kind === 'close-bracket') break; // trailing commas
|
||||
}
|
||||
first = false;
|
||||
|
||||
const items = this.parseCommaSeparated('close-bracket', () => {
|
||||
// Spread
|
||||
if (this.current().kind === 'dot-dot-dot') {
|
||||
const spreadToken = this.current();
|
||||
this.advance();
|
||||
const expr = this.parseExpression();
|
||||
items.push({ kind: 'list-spread', spread: expr, ...this.getPos(spreadToken) })
|
||||
} else {
|
||||
items.push(this.parseExpression());
|
||||
return { kind: 'list-spread' as const, spread: this.parseExpression(), ...this.getPos(spreadToken) };
|
||||
}
|
||||
}
|
||||
return this.parseExpression();
|
||||
});
|
||||
|
||||
this.expect('close-bracket');
|
||||
return { kind: 'list', elements: items, ...this.getPos(token) };
|
||||
|
|
@ -502,28 +494,16 @@ export class Parser {
|
|||
|
||||
if (token.kind === 'open-brace') {
|
||||
this.advance();
|
||||
|
||||
const entries: Array<{ kind: 'field', key: string, value: AST } | { kind: 'spread', expr: AST }> = [];
|
||||
let first = true;
|
||||
|
||||
while (this.current().kind !== 'close-brace') {
|
||||
if (!first) {
|
||||
this.expect('comma');
|
||||
if (this.current().kind === 'close-brace') break; // trailing commas
|
||||
}
|
||||
first = false;
|
||||
|
||||
const entries = this.parseCommaSeparated('close-brace', () => {
|
||||
if (this.current().kind === 'dot-dot-dot') {
|
||||
this.advance();
|
||||
const expr = this.parseExpression();
|
||||
entries.push({ kind: 'spread', expr });
|
||||
} else {
|
||||
const keyToken = this.expect('ident');
|
||||
const key = (keyToken as { value: string }).value;
|
||||
this.expect('equals');
|
||||
entries.push({ kind: 'field', key, value: this.parseExpression() });
|
||||
return { kind: 'spread' as const, expr: this.parseExpression() };
|
||||
}
|
||||
}
|
||||
const keyToken = this.expect('ident');
|
||||
const key = (keyToken as { value: string }).value;
|
||||
this.expect('equals');
|
||||
return { kind: 'field' as const, key, value: this.parseExpression() };
|
||||
});
|
||||
|
||||
this.expect('close-brace');
|
||||
return { kind: 'record', entries, ...this.getPos(token) };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue