Skip to content

Instantly share code, notes, and snippets.

@DasBrain
Created June 30, 2020 18:13
Show Gist options
  • Save DasBrain/abfdaa44b44d898f5d3c3888619eb49b to your computer and use it in GitHub Desktop.
Save DasBrain/abfdaa44b44d898f5d3c3888619eb49b to your computer and use it in GitHub Desktop.
import java.util.Iterator;
public class Generator<T> implements Iterable<T> {
private final Runnable target;
public Generator(Runnable target) {
this.target = target;
}
@Override
public Iterator<T> iterator() {
return new Iter<>(target);
}
public static <T> void yield(T obj) {
Iter.yield0(obj);
}
static class Iter<T> extends Continuation implements Iterator<T> {
private static final ContinuationScope SCOPE = new ContinuationScope("generator");
private boolean hasNext = false;
Object next = null;
Iter(Runnable r) {
super(SCOPE, r);
}
static void yield0(Object obj) {
Iter<?> iter = (Iter<?>) getCurrentContinuation(SCOPE);
if (iter == null) {
throw new IllegalStateException("not inside a generator");
}
iter.hasNext = true;
iter.next = obj;
Continuation.yield(SCOPE);
}
@Override
public boolean hasNext() {
if (hasNext) return true;
if (isDone()) return false;
run();
return hasNext;
}
@SuppressWarnings("unchecked")
@Override
public T next() {
if (!hasNext()) {
throw new IllegalStateException("no more elements");
}
hasNext = false;
T result = (T) next;
next = null;
return result;
}
}
public static void main(String[] args) {
Generator<Integer> gen = new Generator<Integer>(() -> {
for (int i = 0; i < 10; i++) {
Generator.yield(i);
}
});
for (var j : gen) {
System.out.println(j);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment