org.snapscript.tree.collection.Range Maven / Gradle / Ivy
package org.snapscript.tree.collection;
import java.util.Iterator;
import org.snapscript.core.Evaluation;
import org.snapscript.core.Scope;
import org.snapscript.core.Value;
import org.snapscript.core.ValueType;
import org.snapscript.tree.operation.SignedNumber;
public class Range implements Evaluation {
private final SignedNumber start;
private final SignedNumber finish;
public Range(SignedNumber start, SignedNumber finish) {
this.start = start;
this.finish = finish;
}
@Override
public Value evaluate(Scope scope, Object left) throws Exception {
Iterable range = create(scope, left);
return ValueType.getTransient(range);
}
private Iterable create(Scope scope, Object left) throws Exception {
Value first = start.evaluate(scope, left);
Value last = finish.evaluate(scope, left);
Long firstNumber = first.getLong();
Long lastNumber = last.getLong();
return new RangeIterable(firstNumber, lastNumber);
}
private static class RangeIterable implements Iterable {
private final long first;
private final long last;
public RangeIterable(Long first, Long last) {
this.first = first;
this.last = last;
}
@Override
public Iterator iterator() {
if(first > last) {
return new ReverseIterator(first, last);
}
return new ForwardIterator(first, last);
}
}
private static class ForwardIterator implements Iterator {
private long first;
private long last;
public ForwardIterator(Long first, Long last) {
this.first = first;
this.last = last;
}
@Override
public boolean hasNext() {
return first <= last;
}
@Override
public Number next() {
if(first <= last) {
return first++;
}
return null;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Illegal modification of range");
}
}
private static class ReverseIterator implements Iterator {
private long first;
private long last;
public ReverseIterator(Long first, Long last) {
this.first = first;
this.last = last;
}
@Override
public boolean hasNext() {
return first >= last;
}
@Override
public Number next() {
if(first >= last) {
return first--;
}
return null;
}
@Override
public void remove() {
throw new UnsupportedOperationException("Illegal modification of range");
}
}
}