package carpet.script.value; import carpet.script.exception.InternalExpressionException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Locale; public abstract class LazyListValue extends AbstractListValue implements Iterator { public static LazyListValue range(long from, long to, long step) { return new LazyListValue() { { if (step == 0) throw new InternalExpressionException("Range will never end with a zero step"); this.start = from; this.current = this.start; this.limit = to; this.stepp = step; } private long start; private long current; private long limit; private long stepp; @Override public Value next() { Value val = new NumericValue(current); current += stepp; return val; } @Override public void reset() { current = start; } @Override public boolean hasNext() { return stepp > 0?(current < limit):(current > limit); } @Override public String getString() { return String.format(Locale.ROOT, "[%d, %d, ..., %d]",start, start+stepp, limit); } }; } @Override public String getString() { return "[...]"; } @Override public boolean getBoolean() { return hasNext(); } public abstract boolean hasNext(); public abstract Value next(); @Override public void fatality() {reset();} public abstract void reset(); @Override public Iterator iterator() {return this;} public List unroll() { List result = new ArrayList<>(); this.forEachRemaining(result::add); fatality(); return result; } @Override public Value slice(long from, long to) { if (to < 0) to = Integer.MAX_VALUE; if (from < 0) from = 0; if (from > to) return ListValue.of(); List result = new ArrayList<>(); int i; for (i = 0; i < from; i++) { if (hasNext()) next(); else { fatality(); return ListValue.wrap(result); } } for (i = (int)from; i < to; i++) { if (hasNext()) result.add(next()); else { fatality(); return ListValue.wrap(result); } } return ListValue.wrap(result); } @Override public Value add(Value other) { throw new InternalExpressionException("Cannot add to iterators"); } @Override public boolean equals(final Object o) { return false; } @Override public String getTypeString() { return "iterator"; } @Override public Object clone() { Object copy; try { copy = super.clone(); } catch (CloneNotSupportedException e) { throw new InternalExpressionException("Cannot copy iterators"); } ((LazyListValue)copy).reset(); return copy; } @Override public int hashCode() { return ("i"+getString()).hashCode(); } }