-
Notifications
You must be signed in to change notification settings - Fork 0
/
thunk.js
70 lines (64 loc) · 1.25 KB
/
thunk.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
var gcd = function (a, b) {
if (b === 0) {
return a;
} else {
return gcd(b, a % b);
}
}
var gcdCPS = function (a, b, cont) {
console.log('gcdCPS', a, b);
if (b === 0) {
console.log('final', a, b);
return cont(a);
} else {
var new_cont = function (v) {
console.log('cont', a, b, v);
return cont(v);
}
return gcdCPS(b, a % b, new_cont);
}
}
/*
console.log(gcdCPS(259, 111, function (v) {
console.log('answer', v);
return v;
}));
*/
var thunk = function (f, lst) {
return {
tag: 'thunk',
func: f,
args: lst
};
};
var thunkValue = function (x) {
console.log('value', x);
return {
tag: 'value',
val: x
};
};
var gcdThunk = function (a, b, cont) {
console.log('gcdThunk', a, b);
if (b === 0) {
console.log('final', a, b);
return thunk(cont, [a]);
} else {
var new_cont = function (v) {
console.log('cont', a, b, v);
return thunk(cont, [v]);
}
return thunk(gcdThunk, [b, a % b, new_cont]);
}
}
var trampoline = function (thk) {
while (true) {
if (thk.tag === 'value') {
return thk.val;
}
if (thk.tag === 'thunk') {
thk = thk.func.apply(null, thk.args);
}
}
};
console.log(trampoline(gcdThunk(259, 111, thunkValue)));