245 lines
5.6 KiB
Java
245 lines
5.6 KiB
Java
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;
|
|
|
|
import net.minecraft.nbt.StringTag;
|
|
import net.minecraft.nbt.Tag;
|
|
|
|
public abstract class LazyListValue extends AbstractListValue implements Iterator<Value>
|
|
{
|
|
public static LazyListValue rangeDouble(final double from, final double to, final double 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 final double start;
|
|
private double current;
|
|
private final double limit;
|
|
private final double stepp;
|
|
|
|
@Override
|
|
public Value next()
|
|
{
|
|
final 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, "[%s, %s, ..., %s)", NumericValue.of(start).getString(), NumericValue.of(start + stepp).getString(), NumericValue.of(limit).getString());
|
|
}
|
|
};
|
|
}
|
|
|
|
public static LazyListValue rangeLong(final long from, final long to, final 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 final long start;
|
|
private long current;
|
|
private final long limit;
|
|
private final long stepp;
|
|
|
|
@Override
|
|
public Value next()
|
|
{
|
|
final 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, "[%s, %s, ..., %s)", NumericValue.of(start).getString(), NumericValue.of(start + stepp).getString(), NumericValue.of(limit).getString());
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public String getString()
|
|
{
|
|
return "[...]";
|
|
}
|
|
|
|
@Override
|
|
public boolean getBoolean()
|
|
{
|
|
return hasNext();
|
|
}
|
|
|
|
@Override
|
|
public void fatality()
|
|
{
|
|
reset();
|
|
}
|
|
|
|
public abstract void reset();
|
|
|
|
@Override
|
|
public Iterator<Value> iterator()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
public List<Value> unroll()
|
|
{
|
|
final List<Value> result = new ArrayList<>();
|
|
this.forEachRemaining(result::add);
|
|
fatality();
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public Value slice(long from, Long to)
|
|
{
|
|
if (to == null || to < 0)
|
|
{
|
|
to = (long) Integer.MAX_VALUE;
|
|
}
|
|
if (from < 0)
|
|
{
|
|
from = 0;
|
|
}
|
|
if (from > to)
|
|
{
|
|
return ListValue.of();
|
|
}
|
|
final List<Value> 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(final 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()
|
|
{
|
|
final Object copy;
|
|
try
|
|
{
|
|
copy = super.clone();
|
|
}
|
|
catch (final CloneNotSupportedException e)
|
|
{
|
|
throw new InternalExpressionException("Cannot copy iterators");
|
|
}
|
|
((LazyListValue) copy).reset();
|
|
return copy;
|
|
}
|
|
|
|
@Override
|
|
public Value fromConstant()
|
|
{
|
|
return (Value) clone();
|
|
}
|
|
|
|
@Override
|
|
public int hashCode()
|
|
{
|
|
return ("i" + getString()).hashCode();
|
|
}
|
|
|
|
@Override
|
|
public Tag toTag(final boolean force)
|
|
{
|
|
if (!force)
|
|
{
|
|
throw new NBTSerializableValue.IncompatibleTypeException(this);
|
|
}
|
|
return StringTag.valueOf(getString());
|
|
}
|
|
}
|