Skip to content

Commit

Permalink
Parsing for pipe operator
Browse files Browse the repository at this point in the history
commit b10a5e48d1552ff389de314762e863197bc0da7e
Author: William C. Johnson <wcjohnson@oigroup.net>
Date:   Sun Jul 16 22:55:34 2017 -0400

    Fix associativity

commit 0fac7c226b9cd9cda94a5956a45a067a145e2976
Author: William C. Johnson <wcjohnson@oigroup.net>
Date:   Sun Jul 16 22:22:34 2017 -0400

    Parse pipe operator as subscript

commit b21acb2f12941d9d7d4279320de4c55c7ee3b50f
Author: William C. Johnson <wcjohnson@oigroup.net>
Date:   Sun Jul 16 21:17:17 2017 -0400

    Basic pipeCall parsing
  • Loading branch information
wcjohnson committed Jul 17, 2017
1 parent 70ee2c8 commit 6975053
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/parser/expression.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,13 @@ pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
node.callee = base;
const next = this.parseBangCall(node, "CallExpression");
if (next) base = next; else return node;
} else if (
!noCalls &&
this.hasPlugin("pipeCall") &&
this.match(tt.pipeCall)
) {
const node = this.startNodeAt(startPos, startLoc);
base = this.parsePipeCall(node, base);
} else if (!(this.hasPlugin("lightscript") && this.isNonIndentedBreakFrom(startPos)) && this.eat(tt.bracketL)) {
const node = this.startNodeAt(startPos, startLoc);
node.object = base;
Expand Down
26 changes: 26 additions & 0 deletions src/plugins/pipeCall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Parser from "../parser";
import { types as tt, TokenType } from "../tokenizer/types";
const pp = Parser.prototype;

export default function(parser) {
if (parser.__pipeCallPluginInstalled) return;
parser.__pipeCallPluginInstalled = true;

tt.pipeCall = new TokenType("|>");

pp.parsePipeCall = function(node, left) {
this.next();

node.left = left;

// Left-associative parsing of pipeCalls
const right = this.parseExprAtom();
if (this.match(tt.pipeCall)) {
node.right = right;
} else {
node.right = this.parseSubscripts(right, this.state.start, this.state.startLoc, true);
}

return this.finishNode(node, "PipeCallExpression");
};
}
4 changes: 4 additions & 0 deletions src/registerPlugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import bangCallPlugin from "./plugins/bangCall";
import significantWhitespacePlugin from "./plugins/significantWhitespace";
import enhancedComprehensionPlugin from "./plugins/enhancedComprehension";
import syntacticPlaceholderPlugin from "./plugins/syntacticPlaceholder";
import pipeCallPlugin from "./plugins/pipeCall";
import { matchCoreSyntax, match } from "./plugins/match";

function noncePlugin() {}
Expand Down Expand Up @@ -84,4 +85,7 @@ export default function registerPlugins(plugins, metadata) {
// Parse identifiers beginning with `_` or another user-chosen symbol
// as PlaceholderExpressions.
registerPlugin("syntacticPlaceholder", syntacticPlaceholderPlugin);

// |> infix operator for piped function calls
registerPlugin("pipeCall", pipeCallPlugin);
}
4 changes: 4 additions & 0 deletions src/tokenizer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,10 @@ export default class Tokenizer {
if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
if (next === 61) return this.finishOp(tt.assign, 2);
if (code === 124 && next === 125 && this.hasPlugin("flow")) return this.finishOp(tt.braceBarR, 2);
if (code === 124 && next === 62 && this.hasPlugin("pipeCall")) {
this.state.pos += 2;
return this.finishToken(tt.pipeCall, "|>");
}
return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
}

Expand Down
1 change: 1 addition & 0 deletions test/fixtures/pipe-call/basic/associativity/actual.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a |> b |> c
130 changes: 130 additions & 0 deletions test/fixtures/pipe-call/basic/associativity/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
{
"type": "File",
"start": 0,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 11
}
},
"program": {
"type": "Program",
"start": 0,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 11
}
},
"sourceType": "script",
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 11
}
},
"expression": {
"type": "PipeCallExpression",
"start": 0,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 1,
"column": 11
}
},
"left": {
"type": "PipeCallExpression",
"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"
},
"right": {
"type": "Identifier",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
},
"identifierName": "b"
},
"name": "b"
}
},
"right": {
"type": "Identifier",
"start": 10,
"end": 11,
"loc": {
"start": {
"line": 1,
"column": 10
},
"end": {
"line": 1,
"column": 11
},
"identifierName": "c"
},
"name": "c"
}
}
}
],
"directives": []
}
}
1 change: 1 addition & 0 deletions test/fixtures/pipe-call/basic/pipe/actual.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a |> b
98 changes: 98 additions & 0 deletions test/fixtures/pipe-call/basic/pipe/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"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": "PipeCallExpression",
"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"
},
"right": {
"type": "Identifier",
"start": 5,
"end": 6,
"loc": {
"start": {
"line": 1,
"column": 5
},
"end": {
"line": 1,
"column": 6
},
"identifierName": "b"
},
"name": "b"
}
}
}
],
"directives": []
}
}
8 changes: 8 additions & 0 deletions test/fixtures/pipe-call/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"alternatives": {
"default": {
"allPlugins": true,
"excludePlugins": ["estree"]
}
}
}

0 comments on commit 6975053

Please sign in to comment.