Skip to content

Commit 5f5695f

Browse files
fix(parser): handle comma operator
1 parent 371cfb5 commit 5f5695f

4 files changed

Lines changed: 33 additions & 8 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ interface BinaryExpression extends Node {
685685

686686
```ts
687687
type BinaryOperator =
688+
| ','
688689
| '=='
689690
| '!='
690691
| '<'

src/ast.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ export interface BinaryExpression extends Node {
100100
}
101101

102102
export type BinaryOperator =
103+
| ','
103104
| '=='
104105
| '!='
105106
| '<'

src/parser.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const POSTFIX_OPERATOR_PRECEDENCE: Record<string, Precedence> = {
8383
}
8484

8585
const INFIX_OPERATOR_PRECEDENCE_LEFT: Record<string, Precedence> = {
86+
',': Precedence.COMMA,
8687
'||': Precedence.LOGICAL_OR,
8788
'^^': Precedence.LOGICAL_XOR,
8889
'&&': Precedence.LOGICAL_AND,
@@ -202,7 +203,7 @@ function parseExpression(tokens: Token[], minBindingPower: number = 0): Expressi
202203
const args: Expression[] = []
203204

204205
while (peek(tokens)?.value !== ')') {
205-
args.push(parseExpression(tokens, 0))
206+
args.push(parseExpression(tokens, Precedence.COMMA))
206207
if (peek(tokens)?.value !== ')') consume(tokens, ',')
207208
}
208209
consume(tokens, ')')
@@ -217,7 +218,7 @@ function parseExpression(tokens: Token[], minBindingPower: number = 0): Expressi
217218
const elements: Expression[] = []
218219

219220
while (peek(tokens)?.value !== ')') {
220-
elements.push(parseExpression(tokens, 0))
221+
elements.push(parseExpression(tokens, Precedence.COMMA))
221222
if (peek(tokens)?.value !== ')') consume(tokens, ',')
222223
}
223224
consume(tokens, ')')
@@ -321,7 +322,7 @@ function parseVariableDeclarator(
321322

322323
if (peek(tokens)?.value === '=') {
323324
consume(tokens, '=')
324-
init = parseExpression(tokens)
325+
init = parseExpression(tokens, Precedence.COMMA)
325326
}
326327

327328
return { type: 'VariableDeclarator', id, qualifiers, typeSpecifier, layout, init }
@@ -433,7 +434,7 @@ function parseIndeterminate(
433434
layout = {}
434435

435436
while (peek(tokens) && peek(tokens)!.value !== ')') {
436-
const expression = parseExpression(tokens)
437+
const expression = parseExpression(tokens, Precedence.COMMA)
437438

438439
if (
439440
expression.type === 'AssignmentExpression' &&
@@ -660,7 +661,7 @@ function parsePreprocessor(tokens: Token[]): PreprocessorStatement {
660661

661662
const args: Expression[] = []
662663
while (peek(tokens)?.value !== ')') {
663-
args.push(parseExpression(tokens, 0))
664+
args.push(parseExpression(tokens, Precedence.COMMA))
664665
if (peek(tokens)?.value !== ')') consume(tokens, ',')
665666
}
666667
consume(tokens, ')')
@@ -740,7 +741,8 @@ function parseStatement(tokens: Token[]): Statement {
740741
else if (token.value === '{') statement = parseBlock(tokens)
741742
else {
742743
const expression = parseExpression(tokens)
743-
consume(tokens, ';')
744+
if (peek(tokens)?.value === ',') consume(tokens, ';')
745+
else consume(tokens, ';')
744746
statement = { type: 'ExpressionStatement', expression }
745747
}
746748

tests/parser.test.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1242,7 +1242,28 @@ describe('parser', () => {
12421242
])
12431243
})
12441244

1245-
it.skip('can parse comma operator syntax', () => {
1246-
expect(() => parse('!b, uv3;')).not.toThrow()
1245+
it('parses the comma operator', () => {
1246+
expect(parse('!b, uv3;').body).toStrictEqual<[ExpressionStatement]>([
1247+
{
1248+
type: 'ExpressionStatement',
1249+
expression: {
1250+
type: 'BinaryExpression',
1251+
left: {
1252+
type: 'UnaryExpression',
1253+
argument: {
1254+
type: 'Identifier',
1255+
name: 'b',
1256+
},
1257+
operator: '!',
1258+
prefix: true,
1259+
},
1260+
operator: ',',
1261+
right: {
1262+
type: 'Identifier',
1263+
name: 'uv3',
1264+
},
1265+
},
1266+
},
1267+
])
12471268
})
12481269
})

0 commit comments

Comments
 (0)