#include void main () { int flag = 0; { int i=1; L: printf ("i = %d\n", i); if (flag) return; else { int i = 2; printf ("i = %d\n", i); flag = 1; goto L; } } } i = 1 i = 2 i = 1 structure K = SMLofNJ.Cont fun main _ = let val flag = ref false; in let val L : (unit K.cont option) ref = ref NONE; val i = 1; in callcc (fn k => L := SOME k); print((Int.toString i) ^ "\n"); if (!flag) then () else let val i = 2; val SOME k = !L in print((Int.toString i) ^ "\n"); flag := true; throw k () end end end; #include #include /* int setjump(jmp_buf env) The macro setjump saves state information in env for use by longjump. The return is zero from a direct call of setjump, and non-zero from a subsequent call of longjump. longjump restores the state by the most recent call to setjump, using the information saved in env, and execution resumes as if the setjump function had just executed and returned the non-zero value val. The function containing the setjump must not have terminated. Accessible objects have the values they had at the time longjump was called; values are not saved by stejump. */ jmp_buf k; /* a silly function that performs a few recursive calls, and then jumps to the point labelled with setjmp (which is in main) */ int f (int i) { if (i == 0) longjmp(k, 42); else return i*f(i-1); } void main () { int result = setjmp(k); switch (result) { case 0: f(5); break; /* normal execution goes here */ default: printf("f(5) = %d\n", result); break; /* we get here by longjmp */ } } f(5) = 42 structure K = SMLofNJ.Cont val globalk : (int K.cont option) ref = ref NONE; fun f i = let val SOME k = !globalk; in if (i = 0) then (throw k 42) else (i*f(i-1)) end; fun main _ = let val result = callcc (fn k => (globalk := SOME k; 0)); in case result of 0 => f(5) | x => (print("f(5)= " ^ (Int.toString (result)) ^"\n"); 99) end; #include segmentation violation jmp_buf k; int f (int i) { if (i == 0) return setjmp(k); else return i*f(i-1); } void main () { int result = f(5); longjmp(k,42); } does not terminate structure K = SMLofNJ.Cont val globalk : (int K.cont option) ref = ref NONE; fun f i = if (i = 0) then callcc (fn k => (globalk := SOME k; 0)) else i*f(i-1); fun main _ = let val flag = ref false; val result = f(5); in if (!flag) then (print ((Int.toString(result)) ^ "\n"); result) else let val SOME k = !globalk; in (print ((Int.toString(result)) ^ "\n"); flag := true; throw k 2 ) end end; 240 fun multlist (l: int list) : int = callcc (fn ret => let fun mult (nil) = 1 | mult (0::l)= throw ret 0 | mult (n::l)=n*mult l ; in mult l end ) fun multlist l = let fun mult (nil) ret = 1 | mult (0::l) ret = throw ret 0 | mult (n::l) ret =n*mult l ret ; in callcc (mult l) end fun cpsmult nil k = k 1 | cpsmult (n::l) k = cpsmult l (fn r => k (n*r)) fun mult l = cpsmult l (fn r => r) structure K = SMLofNJ.Cont datatype state = S of state cont; fun resume (S k : state ) : state = callcc (fn k' : state cont => throw k (S k')); val buf : int ref = ref 0; fun produce (n:int, cons: state) = (print("producer\n"); buf :=n ; produce (n+1, resume cons)); fun consume (prod: state) = (print("consumer \n"); print (Int.toString(!buf)); consume (resume prod)); fun run()= consume (callcc (fn k: state cont => produce (0, S k)));