// Copyright (c) 2010 Guillaume Lathoud
// MIT License
//
// tailtramp.js
// 
// Implement full tail-call optimization in Javascript through a
// trampoline.

/*jslint evil:false */

function tailtramp(g) {
    function TailCall(arr) {
        this.arr = arr;
    }
    return (function (n) {

        return function()
        {
            var arr = [g, this, arguments], ret;

            if (n>5) {  // Jump off a small Empire State Building
                return new TailCall(arr);
            }
            
            while (true)
            {
                n++;
                ret = arr[0].apply(arr[1], arr[2]);
                n--;
                
                if ((n>0) || (!(ret instanceof TailCall))) {
                    return ret;
                }
                
                // Hit 33rd Street and bounce again
                arr = ret.arr;
            }
        };

    })(0);
}
