not quite. It is similar to longjmp except that this can jump down the stack. these labels can be jumped to even after the function returns
(And another way to do it is to simply allocate all your function call frames on the heap to begin with and not have a stack. Then call/cc is essentially free, but you need a really good incremental garbage collector because now every function call conses.)
> (let ((x 0)) (list (call/cc (lambda (f) (set! x 1) (f 2))) x))
(2 0) localhost:~/oort/examples% ../oort callcc2.nl
2
1
as expected since Oort uses heap allocated activation records.The Oort program:
typedef continuation_t = fn (p: int32) -> void;
call_cc (fun: fn(k: continuation_t) -> void) -> int32
{
retval: int32;
fun (fn (v: int32) -> void {
retval = v;
goto current_continuation;
});
// If fun returns without calling the continuation,
// then just return 0
return 0;
@current_continuation:
return retval;
}
x: int32 = 0;
print call_cc (fn (k: continuation_t) {
x = 1;
k (2);
});
print x;