Skip to content

Commit 10998a1

Browse files
committed
Adding TCO support
1 parent 14c4a18 commit 10998a1

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/BabelPlugin.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
function Plugin(babel) {
22
const t = babel.types;
3+
function markTailCall(retStmt) {
4+
if (retStmt.argument === null) return;
5+
if (retStmt.argument.type === "CallExpression") {
6+
retStmt.argument.isTailCall = true;
7+
} else if (retStmt.argument.type === "SequenceExpression" && retStmt.argument.expressions.length > 0) {
8+
const lastExp = retStmt.argument.expressions[retStmt.argument.expressions.length - 1];
9+
if (lastExp.type !== "CallExpression") return;
10+
lastExp.isTailCall = true;
11+
}
12+
}
313
// Function call without arguments
414
function hzCall(callee) {
515
return t.sequenceExpression([
@@ -190,7 +200,7 @@ function Plugin(babel) {
190200
t.variableDeclarator(
191201
funcDec.id,
192202
hzCoroutine(t.functionExpression(
193-
funcDec.id,
203+
null,
194204
funcDec.params,
195205
funcDec.body,
196206
true
@@ -204,7 +214,7 @@ function Plugin(babel) {
204214
t.variableDeclarator(
205215
funcDec.id,
206216
hzGenerator(t.functionExpression(
207-
funcDec.id,
217+
null,
208218
funcDec.params,
209219
funcDec.body,
210220
true
@@ -346,6 +356,7 @@ function Plugin(babel) {
346356
},
347357
exit: function (path) {
348358
//if (path.getFunctionParent().type === "Program") return;
359+
const isTailCall = "isTailCall" in path.node;
349360
if (path.node.callee.type === "MemberExpression") {
350361
if (path.node.arguments.length === 0) {
351362
path.replaceWith(hzCallMethod(
@@ -371,10 +382,16 @@ function Plugin(babel) {
371382
));
372383
}
373384
}
385+
if (isTailCall) {
386+
path.node.expressions[0].argument.arguments.push(t.booleanLiteral(true));
387+
}
374388
path.skip();
375389
}
376390
},
377391
"ReturnStatement": {
392+
enter: function (path) {
393+
markTailCall(path.node);
394+
},
378395
exit: function (path) {
379396
const parentPath = path.getFunctionParent();
380397
if (path.node.argument === null) path.node.argument = hzReturn();

0 commit comments

Comments
 (0)