expanded long arithmetic

This commit is contained in:
gnembon committed 2020-10-12 11:56:52 -03:00
1 parent ff4c4431f4
commit 6f0faf991a
6 files changed
+48 -14

No files matched your search

@@ -17,8 +17,10 @@ block positions. All variables starting with `_` are read-only, and cannot be de
`scarpet` accepts numeric and string liters constants. Numbers look like `1, 2.5, -3e-7, 0xff,` and are internally
represented primarily as Java's `double` but `scarpet` will try to trim trailing zeros as much as possible so if you
need to use them as integers or even longs - you can. However any operation on a number even if it can be properly
represented as long, but not a double type, will make them round up to be doubles.
need to use them as integers or even longs - you can. Long values will also not loose their long precision in addition,
subtraction, negation and multiplication, however any other operation that is not guaranteed to return a long value
(like division) on a number even if it can be properly
represented as long, will make them convert to doubles.
Strings use single quoting, for multiple reasons, but primarily to allow for
easier use of strings inside doubly quoted command arguments (when passing a script as a parameter of `/script fill`
+1 -1
View File
@@ -339,7 +339,7 @@ public class Expression
}
});
}
public FunctionValue addContextFunction(Context context, String name, Expression expr, Tokenizer.Token token, List<String> arguments, String varArgs, List<String> outers, LazyValue code)
public FunctionValue createUserDefinedFunction(Context context, String name, Expression expr, Tokenizer.Token token, List<String> arguments, String varArgs, List<String> outers, LazyValue code)
{
if (functions.containsKey(name))
throw new ExpressionException(context, expr, token, "Function "+name+" would mask a built-in function");
@@ -108,7 +108,7 @@ public class Functions {
if (!(v1 instanceof FunctionSignatureValue))
throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
FunctionSignatureValue sign = (FunctionSignatureValue) v1;
Value result = expression.addContextFunction(c, sign.getName(), e, t, sign.getArgs(), sign.getVarArgs(), sign.getGlobals(), lv2);
Value result = expression.createUserDefinedFunction(c, sign.getName(), e, t, sign.getArgs(), sign.getVarArgs(), sign.getGlobals(), lv2);
return (cc, tt) -> result;
});
@@ -209,9 +209,9 @@ public class Operators {
return (cc, tt) -> lval;
});
expression.addUnaryOperator("-", false, (v) -> new NumericValue(-NumericValue.asNumber(v).getDouble()));
expression.addUnaryOperator("-", false, v -> NumericValue.asNumber(v).opposite());
expression.addUnaryOperator("+", false, (v) -> new NumericValue(NumericValue.asNumber(v).getDouble()));
expression.addUnaryOperator("+", false, NumericValue::asNumber);
expression.addLazyUnaryOperator("!", precedence.get("unary+-!"), false, (c, t, lv)-> lv.evalValue(c, Context.BOOLEAN).getBoolean() ? (cc, tt)-> Value.FALSE : (cc, tt) -> Value.TRUE); // might need context boolean
@@ -71,7 +71,7 @@ public class NumericValue extends Value
@Override
public boolean getBoolean()
{
return value != null && abs(value) > epsilon;
return abs(value) > epsilon;
}
public double getDouble()
{
@@ -98,14 +98,24 @@ public class NumericValue extends Value
{ // TODO test if definintn add(NumericVlaue) woud solve the casting
if (v instanceof NumericValue)
{
return new NumericValue(getDouble() + ((NumericValue) v).getDouble() );
NumericValue nv = (NumericValue)v;
if (longValue != null && nv.longValue != null)
{
return new NumericValue(longValue+nv.longValue);
}
return new NumericValue(value + nv.value);
}
return super.add(v);
}
public Value subtract(Value v) { // TODO test if definintn add(NumericVlaue) woud solve the casting
if (v instanceof NumericValue)
{
return new NumericValue(getDouble() - (((NumericValue) v).getDouble()));
NumericValue nv = (NumericValue)v;
if (longValue != null && nv.longValue != null)
{
return new NumericValue(longValue-nv.longValue);
}
return new NumericValue(value - nv.value);
}
return super.subtract(v);
}
@@ -113,7 +123,12 @@ public class NumericValue extends Value
{
if (v instanceof NumericValue)
{
return new NumericValue(getDouble() * ((NumericValue) v).getDouble() );
NumericValue nv = (NumericValue)v;
if (longValue != null && nv.longValue != null)
{
return new NumericValue(longValue*nv.longValue);
}
return new NumericValue(value * nv.value);
}
if (v instanceof ListValue)
{
@@ -146,7 +161,10 @@ public class NumericValue extends Value
}
if (o instanceof NumericValue)
{
return value.compareTo(((NumericValue) o).getDouble());
NumericValue no = (NumericValue)o;
if (longValue != null && no.longValue != null)
return longValue.compareTo(no.longValue);
return value.compareTo(no.value);
}
return getString().compareTo(o.getString());
}
@@ -159,7 +177,10 @@ public class NumericValue extends Value
}
if (o instanceof NumericValue)
{
return !this.subtract((Value) o).getBoolean();
NumericValue no = (NumericValue)o;
if (longValue != null && no.longValue != null)
return longValue.equals(no.longValue);
return !this.subtract(no).getBoolean();
}
return super.equals(o);
}
@@ -200,7 +221,7 @@ public class NumericValue extends Value
@Override
public int length()
{
return Integer.toString(value.intValue()).length();
return Long.toString(getLong()).length();
}
@Override
@@ -224,7 +245,7 @@ public class NumericValue extends Value
@Override
public int hashCode()
{
if (Math.abs(Math.floor(value + 0.5D)-value) < epsilon) // is sufficiently close to the integer value
if (longValue!= null || Math.abs(Math.floor(value + 0.5D)-value) < epsilon) // is sufficiently close to the integer value
return Long.hashCode(getLong());
return Double.hashCode(value);
}
@@ -268,4 +289,9 @@ public class NumericValue extends Value
return new JsonPrimitive(value);
}
}
public NumericValue opposite() {
if (longValue != null) return new NumericValue(-longValue);
return new NumericValue(-value);
}
}
@@ -28,6 +28,12 @@ public class StringValue extends Value
this.str = str;
}
public static Value of(String value)
{
if (value == null) return Value.NULL;
return new StringValue(value);
}
@Override
public String getTypeString()
{