/*
VStack-Computable Quick HowTo
(more up-to-date version here: https://wiki.gaz.ai/doku.php?id=vstack_computation_how-to)
To make a function that can be run on a virtual (reified) stack, do this:
(This is the "with step" method where you automatically get an int step counter to use.)
-Subclass VStackComputableWithStep (with A being your function's return type - or Void)
-Override void step(VStack stack)
-In step(), check the step field.
0 is step 1 of your function, 1 is step 2 etc.
After you have run the right code for the current step, update the
step field e.g. by step++.
-To return from the function, don't use ret normally, but write
"ret with stack.ret(myReturnValue);".
-To call a subroutine, write "ret with stack.push(new Subroutine(someArgs));".
(Note that the subroutine is also an object implementing
VStack.Computable.) Before this line, make sure you update the step
field to the piece of code that is to be run when the subroutine is
complete.
-stack.call(...) is a synonym for stack.push(...).
-To get the result of a subroutine call, call result() aka subResult().
You will have to cast the object to the correct type, there was no way
to provide a generic signature in this instance.
-A special form of calling a subroutine is:
ret with stack.tailCall(new Subroutine(...));
This calls the subroutine and passes its return value directly to the
current function's caller. Well, you know, tail calls. You don't have
to care about the step field in this case since a tail call means the
function is exiting anyway.
-Catching exceptions is currently not possible in VStack computations.
The simplest way to run your VStack-computable function is to call the
global function vStackCompute on it. This one does have a proper return
type thanks to the type parameter you provided right at the beginning…
*/
srecord noeq ForEach_vstack(Iterable l, IVF1 body) extends VStackComputableWithStep {
Iterator it;
void step(VStack stack) {
if (step == 0) {
if (l == null) ret with stack.ret();
it = iterator(l);
++step;
}
if (!it.hasNext())
ret with stack.ret();
body.get(it.next());
}
}