/* cps.c - factorial in continuation-passing style
 * takes the factorial of the arguments it is given
 * Chris Lu, 2008
 * gcc -o cps cps.c
 */

#include <stdio.h>
#include <stdlib.h>

typedef void(*cont_t)(long long);

void fact(long long num, cont_t k)
{
	if(!num)
		k(1);
	else {
		void newk(long long x)
		{
			k(num * x);
		}
		fact(num - 1, &newk);
	}
}

void printnum(long long num, cont_t k)
{
	printf("the factorial of %lld is", num);
	k(num);
}

void printres(long long num, cont_t k)
{
	printf(" %lld\n", num);
	k(num);
}

void atoik(char *str, cont_t k)
{
	k(atoi(str));
}

void iterfact(char** ptr, cont_t k)
{
	if(!(*ptr))
		k(0);
	else {
		void printcont1(long long x)
		{
			iterfact(ptr+1, k);
		}
		
		void factcont(long long x)
		{
			printres(x, &printcont1);
		}

		void printcont2(long long x)
		{
			fact(x, &factcont);
		}

		void atoicont(long long x)
		{
			printnum(x, &printcont2);
		}

		atoik(*ptr, &atoicont);
	}
}

int main(int argc, char **argv)
{
	void newk(long long x)
	{
		exit(x);
	}

	iterfact(argv+1, &newk);
	
	/* to keep gcc happy */
	return 0;
}

