puffnfresh/brushtail
JS AST rewriter for tail call elimination
{ "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"}Brushtail
Section titled “Brushtail”Tail call optimisation for JavaScript.
Examples
Section titled “Examples”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 | node1000000For comparison, without the command-line tool:
$ node example.js
brushtail/example.js:1n (exports, require, module, __filename, __dirname) { function count(from, to) ^RangeError: Maximum call stack size exceededbrushtail.tco(content)
Section titled “brushtail.tco(content)”Takes a JavaScript program as a String. Returns a String with a tail call optimised program.
brushtail.mutateAST(ast)
Section titled “brushtail.mutateAST(ast)”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.
License
Section titled “License”MIT