Skip to content
Oeiuwq Faith Blog OpenSource Porfolio

puffnfresh/brushtail

JS AST rewriter for tail call elimination

puffnfresh/brushtail.json
{
"createdAt": "2012-12-08T08:49:42Z",
"defaultBranch": "master",
"description": "JS AST rewriter for tail call elimination",
"fullName": "puffnfresh/brushtail",
"homepage": "http://brushtail.brianmckenna.org/",
"language": "JavaScript",
"name": "brushtail",
"pushedAt": "2013-07-24T07:58:14Z",
"stargazersCount": 135,
"topics": [],
"updatedAt": "2025-10-23T12:11:39Z",
"url": "https://github.com/puffnfresh/brushtail"
}

Tail call optimisation for JavaScript.

example.js:

function count(from, to) {
if(from >= to)
return from;
return count(from + 1, to);
}
console.log(count(0, 1000000));

Is rewritten into:

function count(from, to) {
var __tcor;
tco:
while (true) {
if (from >= to) {
__tcor = from;
break tco;
}
{
var __from = from + 1, __to = to;
from = __from;
to = __to;
continue tco;
}
}
return __tcor;
}
console.log(count(0, 1000000));

Using the command-line tool:

$ brushtail example.js | node
1000000

For comparison, without the command-line tool:

$ node example.js
brushtail/example.js:1
n (exports, require, module, __filename, __dirname) { function count(from, to)
^
RangeError: Maximum call stack size exceeded

Takes a JavaScript program as a String. Returns a String with a tail call optimised program.

Takes a Mozilla Parser AST and mutates away tail calls.

brushtail.optimizeFunction(functionDeclaration)

Section titled “brushtail.optimizeFunction(functionDeclaration)”

Takes a function declaration in Mozilla Parser AST form and mutates away tail calls.

MIT