Last active
November 29, 2020 07:40
-
-
Save yelouafi/13ad4335f92e448f625930bb390da532 to your computer and use it in GitHub Desktop.
callcc with javascript generators
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
function*example() { | |
const x = 10 | |
const y = yield callcc(function*(k) { | |
// ... | |
yield k(20) | |
throw "Unreachable code" | |
}) | |
console.log(x + y) | |
} | |
stepGen(example()) |
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
function stepGen(gen, k = ()=>{}, arg) { | |
const {value, done} = gen.next(arg) | |
if(done) { | |
return k(value) | |
} | |
else if(typeof value.next === 'function') { | |
return stepGen(value, v => stepGen(gen, k, v)) | |
} | |
else { | |
return value(x => stepGen(gen, k, x)) | |
} | |
} | |
function callcc(gf) { | |
return k => { | |
const gen = gf(result => _ => k(result)) | |
stepGen(gen, k) | |
} | |
} |
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
let threads = [] | |
function* exit() { | |
if(threads.length > 0) { | |
const nextK = threads.shift() | |
yield nextK() | |
} | |
} | |
function fork(fn, ...args) { | |
threads.push(() => k => stepGen(fn(...args), k)) | |
return k => k() | |
} | |
const next = callcc(function*(k) { | |
threads.push(k) | |
const nextK = threads.shift() | |
yield nextK() | |
}) | |
function* proc(id, n) { | |
for(let i = 0; i <= n; i++) { | |
console.log(`proc ${id}:`, i) | |
yield next | |
} | |
yield exit() | |
} | |
function* main() { | |
console.log('start main') | |
yield fork(proc, 1, 4) | |
yield fork(proc, 2, 4) | |
yield fork(proc, 3, 4) | |
yield next | |
console.log('end main') | |
yield exit() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment