// closure conversion
// this version uses heap allocation of continuation closures.
#include <stdio.h>
#include <stdlib.h>
struct _cont;
typedef void (*factk)(int, struct _cont *);
// we'll just use this one type of continuation closure
typedef struct _cont {
factk fun;
struct _cont * k;
int n;
} cont;
static int the_result = 0;
static cont cont_heap[100];
static int cont_counter = 0;
static
cont *
get_cont()
{
return &cont_heap[cont_counter++];
}
// note that ret_cps ignores its continuation
static
void
ret_cps (int n, cont * k)
{
the_result = n;
}
static
void
factcps_3 (int f, cont * k) {
k->fun (k->n * f, k->k);
}
void
factcps (int n, cont * k)
{
if (n == 0) {
k->fun (1, k->k);
} else {
cont * k0 = get_cont();
k0->fun = factcps_3;
k0->k = k;
k0->n = n;
factcps (n-1, k0);
}
}
int
main (int argc, char * argv[])
{
cont k = { ret_cps, NULL, 1 };
//factcps (5, &k);
// use a random number so llvm doesn't try to unroll the loop.
factcps (getpid()%10, &k);
fprintf (stdout, "factcps(5)==%d\n", the_result);
return 0;
}