blob: 89d4bf5ea6d2d154d2229a17e4211376cd74650d [file] [edit]
import 'dart:collection';
abstract class Result {
bool moveNext(Flatten flatten);
}
class FromIterator extends Result {
var _iterator;
FromIterator(this._iterator);
bool moveNext(Flatten flatten) {
if(_iterator.moveNext()) {
flatten._stack.add(() => this);
flatten._current = _iterator.current;
return true;
} else {
return flatten.moveNext();
}
}
}
class Done extends Result {
bool moveNext(Flatten flatten) {
return flatten.moveNext();
}
}
class Single extends Result {
var _current, _moveNext;
Single(this._current, this._moveNext);
bool moveNext(Flatten flatten) {
flatten._stack.add(_moveNext);
flatten._current = _current;
return true;
}
}
class Nested extends Result {
var _current, _moveNext;
Nested(this._current, this._moveNext);
bool moveNext(Flatten flatten) {
flatten._stack.add(_moveNext);
// make sure that we have a SyncStar
flatten._stack.add(new SyncStar.fromIterable(_current)._iterator);
return flatten.moveNext();
}
}
class Tail extends Result {
var _current;
Tail(this._current);
bool moveNext(Flatten flatten) {
// make sure that we have a SyncStar
flatten._stack.add(new SyncStar.fromIterable(_current)._iterator);
return flatten.moveNext();
}
}
class SyncStar<E> extends IterableBase<E> {
var _iterator;
SyncStar(this._iterator);
factory SyncStar.fromIterable(Iterable<E> iterable) {
if(iterable is SyncStar) { return iterable; }
return new SyncStar(() => new FromIterator(iterable.iterator));
}
Iterator<E> get iterator => new Flatten(_iterator);
}
class Flatten extends Iterator {
Flatten(f){ _stack.add(f); }
var _stack = [];
var _current;
get current => _current;
bool moveNext() {
if(_stack.length == 0){ return false; }
var continuation = _stack.removeLast();
var result = continuation();
return result.moveNext(this);
}
void dispose() { _stack = []; _current = null; }
}