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

Pipeline Operator proposal #742

Merged
merged 1 commit into from
Sep 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ require("babylon").parse("code", {
| `bigInt` ([proposal](https://github.com/tc39/proposal-bigint)) | `100n` |
| `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` |

### FAQ

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

Expand Down
7 changes: 7 additions & 0 deletions src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,13 @@ export default class ExpressionParser extends LValParser {

const startPos = this.state.start;
const startLoc = this.state.startLoc;

if (node.operator === "|>") {
this.expectPlugin("pipelineOperator");
// Support syntax such as 10 |> x => x + 1
this.state.potentialArrowAt = startPos;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the current draft spec has this logic. I couldn't figure out how to put it into the grammar. Right now, x |> y => z would be a syntax error. But it's clearly useful--i'll think more about the spec.

Copy link
Member Author

@hzoo hzoo Sep 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

node.right = this.parseExprOp(
this.parseMaybeUnary(),
startPos,
Expand Down
11 changes: 9 additions & 2 deletions src/tokenizer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,16 @@ export default class Tokenizer extends LocationParser {
const next = this.input.charCodeAt(this.state.pos + 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename the function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is ok now

if (next === code)
return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
if (code === 124) {
// '|>'
if (next === 62) {
return this.finishOp(tt.pipeline, 2);
} else if (next === 125 && this.hasPlugin("flow")) {
// '|}'
return this.finishOp(tt.braceBarR, 2);
}
}
if (next === 61) return this.finishOp(tt.assign, 2);
if (code === 124 && next === 125 && this.hasPlugin("flow"))
return this.finishOp(tt.braceBarR, 2);
return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
}

Expand Down
3 changes: 2 additions & 1 deletion src/tokenizer/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class TokenType {
this.isAssign = !!conf.isAssign;
this.prefix = !!conf.prefix;
this.postfix = !!conf.postfix;
this.binop = conf.binop || null;
this.binop = conf.binop === 0 ? 0 : conf.binop || null;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be nice with ?? :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, should be easy to add/use here (would be good to find this kind of code on github/codebase and then do a codemod)

this.updateContext = null;
}
}
Expand Down Expand Up @@ -131,6 +131,7 @@ export const types: { [name: string]: TokenType } = {
incDec: new TokenType("++/--", { prefix, postfix, startsExpr }),
bang: new TokenType("!", { beforeExpr, prefix, startsExpr }),
tilde: new TokenType("~", { beforeExpr, prefix, startsExpr }),
pipeline: new BinopTokenType("|>", 0),
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 @@
a |> b
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More examples, especially arrows.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

99 changes: 99 additions & 0 deletions test/fixtures/experimental/pipeline-operator/base/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"type": "File",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"program": {
"type": "Program",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"expression": {
"type": "BinaryExpression",
"start": 0,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 6
}
},
"left": {
"type": "Identifier",
"start": 0,
"end": 1,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 1
},
"identifierName": "a"
},
"name": "a"
},
"operator": "|>",
"right": {
"type": "Identifier",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
},
"identifierName": "b"
},
"name": "b"
}
}
}
],
"directives": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["pipelineOperator"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x => x |> inc |> double
170 changes: 170 additions & 0 deletions test/fixtures/experimental/pipeline-operator/chain/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
{
"type": "File",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 23
}
},
"program": {
"type": "Program",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 23
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 23
}
},
"expression": {
"type": "ArrowFunctionExpression",
"start": 0,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 23
}
},
"id": null,
"generator": false,
"expression": true,
"async": false,
"params": [
{
"type": "Identifier",
"start": 0,
"end": 1,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 1
},
"identifierName": "x"
},
"name": "x"
}
],
"body": {
"type": "BinaryExpression",
"start": 5,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 23
}
},
"left": {
"type": "BinaryExpression",
"start": 5,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 13
}
},
"left": {
"type": "Identifier",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
},
"identifierName": "x"
},
"name": "x"
},
"operator": "|>",
"right": {
"type": "Identifier",
"start": 10,
"end": 13,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 13
},
"identifierName": "inc"
},
"name": "inc"
}
},
"operator": "|>",
"right": {
"type": "Identifier",
"start": 17,
"end": 23,
"loc": {
"start": {
"line": 1,
"column": 17
},
"end": {
"line": 1,
"column": 23
},
"identifierName": "double"
},
"name": "double"
}
}
}
}
],
"directives": []
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"plugins": ["pipelineOperator"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
let result = "hello"
|> doubleSay
|> capitalize
|> exclaim;
Loading