Created
May 9, 2015 06:20
-
-
Save aholmes/8f6bee6334ddb849b751 to your computer and use it in GitHub Desktop.
Trampoline (indirect jump) implementation in TypeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Trampoline = (function () | |
{ | |
function Trampoline(func, baseConditionReachedFunc) | |
{ | |
var _this = this; | |
this.func = func; | |
this.baseConditionReachedFunc = baseConditionReachedFunc; | |
if (typeof func !== 'function') throw new Error('Wrong type'); | |
this.wrappedFunc = function () | |
{ | |
var args = []; | |
for (var _i = 0; _i < arguments.length; _i++) | |
{ | |
args[_i - 0] = arguments[_i]; | |
} | |
return (args instanceof Array) | |
? func.apply(_this.func, args) | |
: func.call(_this.func, args); | |
}; | |
} | |
Trampoline.prototype.Execute = function () | |
{ | |
var args = []; | |
for (var _i = 0; _i < arguments.length; _i++) | |
{ | |
args[_i - 0] = arguments[_i]; | |
} | |
var func = this.wrappedFunc; | |
// Because the base condition test function signifies that the | |
// iterative state has reached what will trigger the base condition, | |
// the recursive method needs to be called so that it can do what | |
// it needs to do when that base condition has been met. | |
// That is why the base condition test is checked first, and then | |
// the recursive method is called. | |
var baseConditionReachedOnNextCall = false; | |
do | |
{ | |
baseConditionReachedOnNextCall = args instanceof Array | |
? this.baseConditionReachedFunc.apply(this.baseConditionReachedFunc, args) | |
: this.baseConditionReachedFunc.call(this.baseConditionReachedFunc, args); | |
args = args instanceof Array | |
? func.apply(this.func, args) | |
: func.call(this.func, args); | |
} while (!baseConditionReachedOnNextCall); | |
return args; | |
}; | |
return Trampoline; | |
})(); | |
// fibonacci | |
var t = new Trampoline( | |
function (n, a, b) { return n > 0 ? [n - 1, b || 1, (a || 0) + (b || 1)] : a; }, | |
function (n, a, b) { return n === 0; } | |
); | |
t.Execute(50); | |
t.Execute(100); | |
t.Execute(1000); | |
t.Execute(500000); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Trampoline | |
{ | |
private wrappedFunc: (...args: any[]) => any; | |
constructor(private func: (...args: any[]) => any, private baseConditionReachedFunc: (...args: any[]) => boolean) | |
{ | |
if (typeof func !== 'function') throw new Error('Wrong type'); | |
this.wrappedFunc = (...args: any[]) => | |
{ | |
return (args instanceof Array) | |
? func.apply(this.func, args) | |
: func.call(this.func, args); | |
}; | |
} | |
public Execute(...args: any[]) | |
{ | |
let func = this.wrappedFunc; | |
// Because the base condition test function signifies that the | |
// iterative state has reached what will trigger the base condition, | |
// the recursive method needs to be called so that it can do what | |
// it needs to do when that base condition has been met. | |
// That is why the base condition test is checked first, and then | |
// the recursive method is called. | |
let baseConditionReachedOnNextCall = false; | |
do | |
{ | |
baseConditionReachedOnNextCall = args instanceof Array | |
? this.baseConditionReachedFunc.apply(this.baseConditionReachedFunc, args) | |
: this.baseConditionReachedFunc.call(this.baseConditionReachedFunc, args); | |
args = args instanceof Array | |
? func.apply(this.func, args) | |
: func.call(this.func, args); | |
} while (!baseConditionReachedOnNextCall) | |
return args; | |
} | |
} | |
// fibonacci | |
var t = new Trampoline( | |
(n, a, b) => n > 0 ? [n - 1, b || 1, (a || 0) + (b || 1)] : a, | |
(n, a, b) => n === 0 | |
); | |
t.Execute(50); | |
t.Execute(100); | |
t.Execute(1000); | |
t.Execute(500000); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment