Skip to content

Instantly share code, notes, and snippets.

@gilbert
Last active September 29, 2017 04:50
Show Gist options
  • Save gilbert/b8d7a8e8506c7443da479ffaff3730d1 to your computer and use it in GitHub Desktop.
Save gilbert/b8d7a8e8506c7443da479ffaff3730d1 to your computer and use it in GitHub Desktop.
Pipeline op code
var inc = (x) => x + 1;
var double = (x) => x * 2;
var x = 10 |> inc |> double;
var y = 10 |> inc;
var _tmp;
var inc = x => x + 1;
var double = x => x * 2;
var x = (_tmp = 10, _tmp = inc(_tmp), double(_tmp));
var y = (_tmp = 10, inc(_tmp));
import syntaxPipelines from "babel-plugin-syntax-pipelines";
export default function({ types: t }) {
return {
inherits: syntaxPipelines,
visitor: {
BinaryExpression(path) {
if (path.node.operator === "|>") {
//
// Transform the pipeline!
//
const tempVar = getTempId(path.scope);
const assignments = pipe(t, tempVar, path.node.left).concat([
t.callExpression(
path.node.right,
[tempVar]
)
]);
path.replaceWith( t.sequenceExpression(assignments) );
}
},
},
};
}
//
// Limits the variable generation to one per scope
//
function getTempId(scope) {
let id = scope.path.getData("pipelineOp");
if (id) return id;
id = scope.generateDeclaredUidIdentifier("tmp");
return scope.path.setData("pipelineOp", id);
}
//
// Converts:
// 10 |> obj.f |> g;
// To:
// (_x = 10, _x = obj.f(_x), _x = g(_x));
//
function pipe(t, tempVar, node) {
if (node.operator === "|>" && node.type === "BinaryExpression") {
const decl = t.assignmentExpression(
'=',
tempVar,
t.callExpression( node.right, [tempVar]),
);
return pipe(t, tempVar, node.left).concat([decl]);
} else {
return [t.assignmentExpression('=', tempVar, node)];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment