range now handles better long long chains, as well as float values.

This commit is contained in:
gnembon committed 2020-12-13 06:29:42 -04:00
1 parent 34ee6784a4
commit 7bacea1810
5 files changed
+71 -17

No files matched your search

+2
View File
@@ -215,6 +215,8 @@ map(range(10),_*_) => [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce(range(10),_a+_, 0) => 45 reduce(range(10),_a+_, 0) => 45
range(5,10) => [5, 6, 7, 8, 9] range(5,10) => [5, 6, 7, 8, 9]
range(20, 10, -2) => [20, 18, 16, 14, 12] range(20, 10, -2) => [20, 18, 16, 14, 12]
range(-0.3, 0.3, 0.1) => [-0.3, -0.2, -0.1, 0, 0.1, 0.2]
range(0.3, -0.3, -0.1) => [0.3, 0.2, 0.1, -0, -0.1, -0.2]
</pre> </pre>
## Map operations ## Map operations
@@ -135,23 +135,25 @@ public class DataStructures {
expression.addFunction("range", (lv) -> expression.addFunction("range", (lv) ->
{ {
long from = 0; NumericValue from = Value.ZERO;
long to = 0; NumericValue to;
long step = 1; NumericValue step = Value.ONE;
int argsize = lv.size(); int argsize = lv.size();
if (argsize == 0 || argsize > 3) if (argsize == 0 || argsize > 3)
throw new InternalExpressionException("'range' accepts from 1 to 3 arguments, not "+argsize); throw new InternalExpressionException("'range' accepts from 1 to 3 arguments, not "+argsize);
to = NumericValue.asNumber(lv.get(0)).getLong(); to = NumericValue.asNumber(lv.get(0));
if (lv.size() > 1) if (lv.size() > 1)
{ {
from = to; from = to;
to = NumericValue.asNumber(lv.get(1)).getLong(); to = NumericValue.asNumber(lv.get(1));
if (lv.size() > 2) if (lv.size() > 2)
{ {
step = NumericValue.asNumber(lv.get(2)).getLong(); step = NumericValue.asNumber(lv.get(2));
} }
} }
return LazyListValue.range(from, to, step); return (from.isInteger() && to.isInteger() && step.isInteger())
? LazyListValue.rangeLong(from.getLong(), to.getLong(), step.getLong())
: LazyListValue.rangeDouble(from.getDouble(), to.getDouble(), step.getDouble());
}); });
expression.addLazyFunction("m", -1, (c, t, llv) -> expression.addLazyFunction("m", -1, (c, t, llv) ->
@@ -11,7 +11,7 @@ import java.util.Locale;
public abstract class LazyListValue extends AbstractListValue implements Iterator<Value> public abstract class LazyListValue extends AbstractListValue implements Iterator<Value>
{ {
public static LazyListValue range(long from, long to, long step) public static LazyListValue rangeDouble(double from, double to, double step)
{ {
return new LazyListValue() return new LazyListValue()
{ {
@@ -23,10 +23,10 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
this.limit = to; this.limit = to;
this.stepp = step; this.stepp = step;
} }
private long start; private final double start;
private long current; private double current;
private long limit; private final double limit;
private long stepp; private final double stepp;
@Override @Override
public Value next() public Value next()
{ {
@@ -50,7 +50,50 @@ public abstract class LazyListValue extends AbstractListValue implements Iterato
@Override @Override
public String getString() public String getString()
{ {
return String.format(Locale.ROOT, "[%d, %d, ..., %d)",start, start+stepp, limit); 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(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 final long start;
private long current;
private final long limit;
private final 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, "[%s, %s, ..., %s)",NumericValue.of(start).getString(), NumericValue.of(start+stepp).getString(), NumericValue.of( limit).getString());
} }
}; };
} }
@@ -308,4 +308,9 @@ public class NumericValue extends Value
if (longValue != null) return new NumericValue(-longValue); if (longValue != null) return new NumericValue(-longValue);
return new NumericValue(-value); return new NumericValue(-value);
} }
public boolean isInteger()
{
return longValue!= null || getDouble() == (double)getLong();
}
} }
+6 -4
View File
@@ -13,10 +13,12 @@ import java.util.regex.PatternSyntaxException;
public abstract class Value implements Comparable<Value>, Cloneable public abstract class Value implements Comparable<Value>, Cloneable
{ {
public static Value FALSE = new NumericValue(0); public static NumericValue FALSE = new NumericValue(0);
public static Value TRUE = new NumericValue(1); public static NumericValue TRUE = new NumericValue(1);
public static Value ZERO = FALSE; public static NumericValue ZERO = FALSE;
public static Value NULL = new NullValue(); public static NumericValue ONE = TRUE;
public static NullValue NULL = new NullValue();
public String boundVariable; public String boundVariable;