Warning: code here only implements downward (2nd class) continuations on some 16 bit compilers for MS-DOS.
For a more general example of coroutines in C, see http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html.
For C/asm folks, here's a C [CeeLanguage] version I just wrote for various nefarious purposes. I'd explain how it works, but that isn't any fun. It should be obvious. If it isn't, I'll explain what's going on.
/* except.c -- Demonstrates continuations in C. * -------- * Written by Sunir Shah. Placed into the public domain. * * It only works on x86 systems right now. * * USE AT YOUR OWN RISK. */ #include <stdio.h> typedef struct { void *pin; } Continuation; int exception( Continuation *continuation, void (*pfn)( Continuation * ) ) { short difference; if( pfn ) { continuation->pin = &difference; pfn(continuation); return 0; } difference = (unsigned char *)continuation->pin - (unsigned char*)(&difference); _asm add bp, difference return 1; } void bar( Continuation *continuation, int count ) { int test; printf( "bar #%d\n", count ); if( 5 == count ) exception( continuation, NULL ); if( count ) bar(continuation, --count); } void foo( Continuation *continuation ) { printf( "foo\n" ); bar(continuation, 20); printf( "end foo\n" ); } main() { Continuation continuation; printf( "Entering call\n" ); if( exception( &continuation, foo ) ) { printf( "Exception when calling foo\n" ); } else { printf( "Safe\n" ); } return 0; }This is like setjmp(), except it doesn't store all the non-volatile register values in the continuation. It may be useful for old compilers that don't have setjmp/longjmp implemented.
Contributors: SunirShah, StephanHouben, ClarkEvans, JonathanTang