#include <fstream.hfa>
#include <coroutine.hfa>
#include <stdlib.hfa>									// random
#include <unistd.h>										// getpid
coroutine Cons;											// forward
int delivery( Cons & cons, int p1, int p2 );
void stop( Cons & cons );

coroutine Prod {
	Cons & c;
	int N, money, receipt;
};
void main( Prod & prod ) with( prod ) {					// starter ::main
	// 1st resume starts here
	for ( i; N ) {										// N pairs of values
		int p1 = random( 100 ), p2 = random( 100 );
		sout | p1 | " " | p2;
		int status = delivery( c, p1, p2 );
		sout | " $" | money | nl | status;
		receipt += 1;
	}
	stop( c );
	sout | "prod stops";
}
int payment( Prod & prod, int m ) with(prod) {
	money = m;
	resume( prod );										// main 1st time, then
	return receipt;										// prod in delivery
}
void start( Prod & prod, int N, Cons &c ) {
	&prod.c = &c;
	prod.[N, receipt] = [N, 0];
	resume( prod );										// activate main
}
coroutine Cons {
	Prod & p;
	int p1, p2, status;
	bool done;
};
void ?{}( Cons & cons, Prod & p ) {
	&cons.p = &p;
	cons.[status, done ] = [0, false];
}
void ^?{}( Cons & cons ) {}
void main( Cons & cons ) with( cons ) {					// starter prod
	// 1st resume starts here
	int money = 1, receipt;
	for ( ; ! done; ) {
		sout | p1 | " " | p2 | nl | " $" | money;
		status += 1;
		receipt = payment( p, money );
		sout | " #" | receipt;
		money += 1;
	}
	sout | "cons stops";
}
int delivery( Cons & cons, int p1, int p2 ) {
	cons.[p1, p2] = [p1, p2];
	resume( cons );										// main 1st time, then
	return cons.status;									// cons in payment
}
void stop( Cons & cons ) {
	cons.done = true;
	resume( cons );										// activate payment
}
int main() {
	Prod prod;
	Cons cons = { prod };
	srandom( getpid() );
	start( prod, 5, cons );
}

// Local Variables: //
// tab-width: 4 //
// compile-command: "cfa ProdCons.cfa" //
// End: //
