cprint { sclass VStack implements Steppable { new L stack; void subCompute(Computable computation) { computation.stack = this; stack.add(computation); } public bool step() { if (empty(stack)) false; if (last(stack).returned) popLast(stack); else last(stack).run(); true; } } asclass Computable implements Runnable { VStack stack; bool returned; Runnable continuation; } sclass f_ackermann extends Computable { BigInt a, b; BigInt returnValue; *(BigInt *a, BigInt *b) {} record noeq JustReturn(f_ackermann subComputation) implements Runnable { run { returnValue = subComputation.returnValue; set returned; } } record noeq Step2(f_ackermann subComputation) implements Runnable { run { f_ackermann subComputation2 = new(minus(a, BigInt.ONE), subComputation.returnValue); continuation = new JustReturn(subComputation2); stack.subCompute(subComputation2); } } run { if (continuation != null) ret with continuation.run(); if (a.equals(BigInt.ZERO)) { returnValue = plus(b, BigInt.ONE); ret with set returned; } if (b.equals(BigInt.ZERO)) { f_ackermann subComputation = new(a.subtract(BigInt.ONE), BigInt.ONE); continuation = new JustReturn(subComputation); stack.subCompute(subComputation); ret; } f_ackermann subComputation = new(a, minus(b, BigInt.ONE)); continuation = new Step2(subComputation); stack.subCompute(subComputation); } } start-thread { new VStack stack; f_ackermann ack = new(bigInt(2), bigInt(2)); stack.subCompute(ack); stepAllWithStats(stack); print("Result: " + ack.returnValue); } }