/* public int fact( int m ) {
 * 	Marker 'A':
 * 	if (n == 0)
 * 		return 1;
 * 	else {
 * 		int f = fact(n-1);
 * 		Marker 'B':
 * 		return n*f;
 * 	}
 */
public class StackFact {

	private static class FactFrame {
		int n;
		char nextInstruction;
		int f;
		public FactFrame(int n, char next) {
			this.n = n;
			this.nextInstruction = next;
			this.f = 0;
		}
	}
	
	static int stackFact(int n) {
		Stack<FactFrame> stack = new Stack<FactFrame>();
		char nextInstruction = 'A';
		int returnValue=0;
		stack.push( new FactFrame(n, 'Z'));
		
		while (nextInstruction != 'Z') {
			FactFrame top = stack.top();
			if (nextInstruction == 'A') {
				if (top.n == 0) {
					nextInstruction = top.nextInstruction;
					returnValue = 1;
					stack.pop();
				}
				else {
					stack.push( new FactFrame(top.n-1, 'B'));
					nextInstruction = 'A';
				}
			}
			else  if (nextInstruction == 'B') {
				top.f = returnValue;
				nextInstruction = top.nextInstruction;
				returnValue = top.f*top.n;
				stack.pop();
			}
		}
		return returnValue;
		
	}
	
	public static void main(String[] args) {
		for (int i = 0; i < 10; i++)
			System.out.printf( "%d: %d\n", i, stackFact(i));
	}

}
