From 6f0faf991a2850a80fbecae5d58bdac9302ef64f Mon Sep 17 00:00:00 2001 From: gnembon Date: Mon, 12 Oct 2020 11:56:52 -0300 Subject: [PATCH] expanded long arithmetic --- .../scarpet/language/VariablesAndConstants.md | 6 ++- src/main/java/carpet/script/Expression.java | 2 +- .../carpet/script/language/Functions.java | 2 +- .../carpet/script/language/Operators.java | 4 +- .../carpet/script/value/NumericValue.java | 42 +++++++++++++++---- .../java/carpet/script/value/StringValue.java | 6 +++ 6 files changed, 48 insertions(+), 14 deletions(-) diff --git a/docs/scarpet/language/VariablesAndConstants.md b/docs/scarpet/language/VariablesAndConstants.md index 8256c550..2afb874d 100644 --- a/docs/scarpet/language/VariablesAndConstants.md +++ b/docs/scarpet/language/VariablesAndConstants.md @@ -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` diff --git a/src/main/java/carpet/script/Expression.java b/src/main/java/carpet/script/Expression.java index a042f822..3f68c110 100644 --- a/src/main/java/carpet/script/Expression.java +++ b/src/main/java/carpet/script/Expression.java @@ -339,7 +339,7 @@ public class Expression } }); } - public FunctionValue addContextFunction(Context context, String name, Expression expr, Tokenizer.Token token, List arguments, String varArgs, List outers, LazyValue code) + public FunctionValue createUserDefinedFunction(Context context, String name, Expression expr, Tokenizer.Token token, List arguments, String varArgs, List outers, LazyValue code) { if (functions.containsKey(name)) throw new ExpressionException(context, expr, token, "Function "+name+" would mask a built-in function"); diff --git a/src/main/java/carpet/script/language/Functions.java b/src/main/java/carpet/script/language/Functions.java index 0f4907f6..36566305 100644 --- a/src/main/java/carpet/script/language/Functions.java +++ b/src/main/java/carpet/script/language/Functions.java @@ -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; }); diff --git a/src/main/java/carpet/script/language/Operators.java b/src/main/java/carpet/script/language/Operators.java index 906001ff..b3548992 100644 --- a/src/main/java/carpet/script/language/Operators.java +++ b/src/main/java/carpet/script/language/Operators.java @@ -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 diff --git a/src/main/java/carpet/script/value/NumericValue.java b/src/main/java/carpet/script/value/NumericValue.java index 6ba47604..a93dfa3d 100644 --- a/src/main/java/carpet/script/value/NumericValue.java +++ b/src/main/java/carpet/script/value/NumericValue.java @@ -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); + } } diff --git a/src/main/java/carpet/script/value/StringValue.java b/src/main/java/carpet/script/value/StringValue.java index c494865d..61868c60 100644 --- a/src/main/java/carpet/script/value/StringValue.java +++ b/src/main/java/carpet/script/value/StringValue.java @@ -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() {