Skip to content
This repository has been archived by the owner on May 19, 2018. It is now read-only.

Commit

Permalink
Implement nullish coalescing operator in parser (#761)
Browse files Browse the repository at this point in the history
* Implement nullish coalescing operator in parser

* Add ?? to AST
  • Loading branch information
azz authored and hzoo committed Oct 14, 2017
1 parent b5e6ba6 commit e53ce38
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ require("babylon").parse("code", {
| `optionalCatchBinding` ([proposal](https://github.com/babel/proposals/issues/7)) | `try {throw 0;} catch{do();}` |
| `throwExpressions` ([proposal](https://github.com/babel/proposals/issues/23)) | `() => throw new Error("")` |
| `pipelineOperator` ([proposal](https://github.com/babel/proposals/issues/29)) | `a \|> b` |
| `nullishCoalescingOperator` ([proposal](https://github.com/babel/proposals/issues/14)) | `a ?? b` |

### FAQ

Expand Down
1 change: 1 addition & 0 deletions ast/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@ enum BinaryOperator {
| "|" | "^" | "&" | "in"
| "instanceof"
| "|>"
| "??"
}
```

Expand Down
4 changes: 4 additions & 0 deletions src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ export default class ExpressionParser extends LValParser {
this.state.potentialArrowAt = startPos;
}

if (node.operator === "??") {
this.expectPlugin("nullishCoalescingOperator");
}

node.right = this.parseExprOp(
this.parseMaybeUnary(),
startPos,
Expand Down
5 changes: 4 additions & 1 deletion src/tokenizer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,10 @@ export default class Tokenizer extends LocationParser {
// '?'
const next = this.input.charCodeAt(this.state.pos + 1);
const next2 = this.input.charCodeAt(this.state.pos + 2);
if (next === 46 && !(next2 >= 48 && next2 <= 57)) {
if (next === 63) {
// '??'
this.finishOp(tt.nullishCoalescing, 2);
} else if (next === 46 && !(next2 >= 48 && next2 <= 57)) {
// '.' not followed by a number
this.state.pos += 2;
this.finishToken(tt.questionDot);
Expand Down
1 change: 1 addition & 0 deletions src/tokenizer/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export const types: { [name: string]: TokenType } = {
bang: new TokenType("!", { beforeExpr, prefix, startsExpr }),
tilde: new TokenType("~", { beforeExpr, prefix, startsExpr }),
pipeline: new BinopTokenType("|>", 0),
nullishCoalescing: new BinopTokenType("??", 1),
logicalOR: new BinopTokenType("||", 1),
logicalAND: new BinopTokenType("&&", 2),
bitwiseOR: new BinopTokenType("|", 3),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
foo ?? 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"type": "File",
"start": 0,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 9
}
},
"program": {
"type": "Program",
"start": 0,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 9
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 9
}
},
"expression": {
"type": "BinaryExpression",
"start": 0,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 8
}
},
"left": {
"type": "Identifier",
"start": 0,
"end": 3,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 3
},
"identifierName": "foo"
},
"name": "foo"
},
"operator": "??",
"right": {
"type": "NumericLiteral",
"start": 7,
"end": 8,
"loc": {
"start": {
"line": 1,
"column": 7
},
"end": {
"line": 1,
"column": 8
}
},
"extra": {
"rawValue": 1,
"raw": "1"
},
"value": 1
}
}
}
],
"directives": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["nullishCoalescingOperator"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
foo ?? 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"throws": "This experimental syntax requires enabling the parser plugin: 'nullishCoalescingOperator' (1:7)"
}

0 comments on commit e53ce38

Please sign in to comment.