Last active
December 2, 2019 11:18
-
-
Save jlongster/8f6fed214ef8ea8d1851f318a135aa6a to your computer and use it in GitHub Desktop.
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
// Example code, see below for run/yield implementation. Note how we | |
// can even do yields across the stack, so this implements something | |
// more like coroutines than generators. | |
function foo() { | |
var x = Yield(); | |
return x + 1; | |
} | |
var process = Run(function() { | |
console.log(Yield()); | |
console.log(foo()); | |
}); | |
process.send("hello"); | |
process.send(5); | |
// Output: | |
// hello | |
// 6 | |
// run/yield implementation | |
var yieldStack = []; | |
function currentContinuation() { | |
return callCC(function(cont) { | |
cont(cont); | |
}); | |
} | |
function Run(fn) { | |
let c = currentContinuation(); | |
let y; | |
if(c) { | |
y = { | |
suspend: c, | |
send: function(val) { | |
let c = currentContinuation(); | |
if(c) { | |
y.suspend = c; | |
y.resume(val); | |
} | |
} | |
}; | |
yieldStack.push(y); | |
fn(); | |
yieldStack.pop(y); | |
// A final suspend will jump back to the last place where we | |
// should be (either the last thing that sent a value or, if | |
// nothing was ever sent, ourselves) | |
y.suspend(); | |
} | |
return y; | |
} | |
function Yield() { | |
if(yieldStack.length > 0) { | |
var c = currentContinuation(); | |
var y = yieldStack[yieldStack.length - 1]; | |
if(typeof c === 'function') { | |
y.resume = c; | |
y.suspend(); | |
} | |
else { | |
y.resume = null; | |
return c; | |
} | |
} | |
throw new Error("Yield outside of Run"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment