/* Copyright (c) 2006, Sriram Srinivasan
*
* You may distribute this software under the terms of the license
* specified in the file "License"
*/
package kilim;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* A Generator, from the caller's perspective, looks like a normal iterator
* that produces values. Because a standard iterator's next() method
* must return every time, the programmer is forced to manage the stack
* explicitly. The Generator class instead allows one to write a
* task with an automatically managed stack and couple it to an
* iterator interface.
*
* For example:
*
* <pre>
* class StringGenerator extends Generator<String>{
* public void execute() throws Pausable {
* while (!done) {
* String s = getNextWord(); // this can pause
* yield(s);
* }
* }
* private String getNextWord() throws Pausable {
* }
* }
*
*
* </pre>
* @see kilim.examples.Fib, kilim.examples.Tree
*/
public class Generator<T> extends Task implements Iterator<T>, Iterable<T> {
T nextVal;
public boolean hasNext() {
if (nextVal == null) {
if (isDone())
return false;
_runExecute(null);
return nextVal != null;
} else {
return true;
}
}
public T next() {
T ret;
if (nextVal != null) {
ret = nextVal;
nextVal = null;
return ret;
}
if (isDone()) {
throw new NoSuchElementException();
}
_runExecute(null);
ret = nextVal;
nextVal = null;
return ret;
}
public void remove() {
throw new AssertionError("Not Supported");
}
public Iterator<T> iterator() {
return this;
}
public void yield(T val) throws Pausable {
nextVal = val;
Task.yield();
}
}