From 1006e0ac40c6f28abee71ce9b5403fa81c65ce87 Mon Sep 17 00:00:00 2001 From: gnembon Date: Sat, 5 Sep 2020 02:06:59 -0300 Subject: [PATCH] commands return integer value if possible, fixes #408 handle infinite values as infinities. --- .../java/carpet/commands/ScriptCommand.java | 19 +++++---- .../java/carpet/script/CarpetExpression.java | 6 +-- .../java/carpet/script/CarpetScriptHost.java | 42 ++++++++++++------- .../carpet/script/CarpetScriptServer.java | 18 ++++---- .../java/carpet/script/value/NullValue.java | 5 +++ .../carpet/script/value/NumericValue.java | 5 ++- src/main/java/carpet/script/value/Value.java | 2 + 7 files changed, 63 insertions(+), 34 deletions(-) diff --git a/src/main/java/carpet/commands/ScriptCommand.java b/src/main/java/carpet/commands/ScriptCommand.java index 2d850986..529156fd 100644 --- a/src/main/java/carpet/commands/ScriptCommand.java +++ b/src/main/java/carpet/commands/ScriptCommand.java @@ -11,6 +11,7 @@ import carpet.script.ScriptHost; import carpet.script.Tokenizer; import carpet.script.exception.CarpetExpressionException; import carpet.script.value.FunctionValue; +import carpet.script.value.Value; import carpet.settings.SettingsManager; import carpet.utils.Messenger; import com.mojang.brigadier.CommandDispatcher; @@ -390,13 +391,13 @@ public class ScriptCommand return 1; } - public static void handleCall(ServerCommandSource source, CarpetScriptHost host, Supplier call) + public static int handleCall(ServerCommandSource source, CarpetScriptHost host, Supplier call) { try { host.setChatErrorSnooper(source); long start = System.nanoTime(); - String result = call.get(); + Value result = call.get(); long time = ((System.nanoTime()-start)/1000); String metric = "\u00B5s"; if (time > 5000) @@ -409,12 +410,18 @@ public class ScriptCommand time /= 1000; metric = "s"; } - Messenger.m(source, "wi = ", "wb "+result, "gi ("+time+metric+")"); + Messenger.m(source, "wi = ", "wb "+result.getString(), "gi ("+time+metric+")"); + return (int)result.readInteger(); } catch (CarpetExpressionException e) { host.handleErrorWithStack("Error while evaluating expression", e); } + catch (ArithmeticException ae) + { + host.handleErrorWithStack("Math doesn't compute", ae); + } + return 0; //host.resetErrorSnooper(); // lets say no need to reset the snooper in case something happens on the way } @@ -442,8 +449,7 @@ public class ScriptCommand } //if (!(args.trim().isEmpty())) // arguments.addAll(Arrays.asList(args.trim().split("\\s+"))); - handleCall(source, host, () -> host.call(source, call, positions, args)); - return 1; + return handleCall(source, host, () -> host.call(source, call, positions, args)); } @@ -451,11 +457,10 @@ public class ScriptCommand { ServerCommandSource source = context.getSource(); CarpetScriptHost host = getHost(context); - handleCall(source, host, () -> { + return handleCall(source, host, () -> { CarpetExpression ex = new CarpetExpression(host.main, expr, source, new BlockPos(0, 0, 0)); return ex.scriptRunCommand(host, new BlockPos(source.getPosition())); }); - return 1; } private static int scriptScan(CommandContext context, BlockPos origin, BlockPos a, BlockPos b, String expr) diff --git a/src/main/java/carpet/script/CarpetExpression.java b/src/main/java/carpet/script/CarpetExpression.java index 19bc38fe..b481df3e 100644 --- a/src/main/java/carpet/script/CarpetExpression.java +++ b/src/main/java/carpet/script/CarpetExpression.java @@ -3653,10 +3653,10 @@ public class CarpetExpression } } - public String scriptRunCommand(ScriptHost host, BlockPos pos) + public Value scriptRunCommand(ScriptHost host, BlockPos pos) { if (CarpetServer.scriptServer.stopAll) - return "SCRIPTING PAUSED"; + throw new CarpetExpressionException("SCRIPTING PAUSED", null); try { Context context = new CarpetContext(host, source, origin). @@ -3674,7 +3674,7 @@ public class CarpetExpression Value playerValue = new EntityValue(e).bindTo("p"); context.with("p", (cc, tt) -> playerValue); } - return this.expr.eval(context).getString(); + return this.expr.eval(context); } catch (ExpressionException e) { diff --git a/src/main/java/carpet/script/CarpetScriptHost.java b/src/main/java/carpet/script/CarpetScriptHost.java index 92da9ed7..83d84770 100644 --- a/src/main/java/carpet/script/CarpetScriptHost.java +++ b/src/main/java/carpet/script/CarpetScriptHost.java @@ -82,6 +82,11 @@ public class CarpetScriptHost extends ScriptHost host.resetErrorSnooper(); return null; } + catch (ArithmeticException ae) + { + host.handleErrorWithStack("Math doesn't compute", ae); + return null; + } } return host; } @@ -180,7 +185,7 @@ public class CarpetScriptHost extends ScriptHost return host; } - public String handleCommand(ServerCommandSource source, String call, List coords, String arg) + public Value handleCommand(ServerCommandSource source, String call, List coords, String arg) { try { @@ -189,17 +194,22 @@ public class CarpetScriptHost extends ScriptHost catch (CarpetExpressionException exc) { handleErrorWithStack("Error while running custom command", exc); - return ""; + return Value.NULL; + } + catch (ArithmeticException ae) + { + handleErrorWithStack("Math doesn't compute", ae); + return Value.NULL; } } - public String call(ServerCommandSource source, String call, List coords, String arg) + public Value call(ServerCommandSource source, String call, List coords, String arg) { if (CarpetServer.scriptServer.stopAll) - return "SCARPET PAUSED"; + throw new CarpetExpressionException("SCARPET PAUSED", null); FunctionValue function = getFunction(call); if (function == null) - return "UNDEFINED"; + throw new CarpetExpressionException("UNDEFINED", null); List argv = new ArrayList<>(); if (coords != null) for (Integer i: coords) @@ -230,7 +240,8 @@ public class CarpetScriptHost extends ScriptHost } catch (NumberFormatException exception) { - return "Fail: "+sign+tok.surface+" seems like a number but it is not a number. Use quotes to ensure its a string"; + throw new CarpetExpressionException("Fail: "+sign+tok.surface+" seems like a number but it is" + + " not a number. Use quotes to ensure its a string", null); } break; case HEX_LITERAL: @@ -242,7 +253,8 @@ public class CarpetScriptHost extends ScriptHost } catch (NumberFormatException exception) { - return "Fail: "+sign+tok.surface+" seems like a number but it is not a number. Use quotes to ensure its a string"; + throw new CarpetExpressionException("Fail: "+sign+tok.surface+" seems like a number but it is" + + " not a number. Use quotes to ensure its a string", null); } break; case OPERATOR: @@ -253,16 +265,18 @@ public class CarpetScriptHost extends ScriptHost } else { - return "Fail: operators, like " + tok.surface + " are not allowed in invoke"; + throw new CarpetExpressionException("Fail: operators, like " + tok.surface + " are not " + + "allowed in invoke", null); } break; case FUNCTION: - return "Fail: passing functions like "+tok.surface+"() to invoke is not allowed"; + throw new CarpetExpressionException("Fail: passing functions like "+tok.surface+"() to invoke is " + + "not allowed", null); case OPEN_PAREN: case COMMA: case CLOSE_PAREN: case MARKER: - return "Fail: "+tok.surface+" is not allowed in invoke"; + throw new CarpetExpressionException("Fail: "+tok.surface+" is not allowed in invoke", null); } } List args = function.getArguments(); @@ -273,7 +287,7 @@ public class CarpetScriptHost extends ScriptHost { error += (i "+(i function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv), context, Context.VOID - ).getString(); + ); } catch (ExpressionException e) { @@ -491,11 +505,11 @@ public class CarpetScriptHost extends ScriptHost super.resetErrorSnooper(); } - public void handleErrorWithStack(String intro, CarpetExpressionException exception) + public void handleErrorWithStack(String intro, Exception exception) { if (responsibleSource != null) { - exception.printStack(responsibleSource); + if (exception instanceof CarpetExpressionException) ((CarpetExpressionException) exception).printStack(responsibleSource); String message = exception.getMessage(); Messenger.m(responsibleSource, "r "+intro+(message.isEmpty()?"":": "+message)); } diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java index f9e5d765..f7015c30 100644 --- a/src/main/java/carpet/script/CarpetScriptServer.java +++ b/src/main/java/carpet/script/CarpetScriptServer.java @@ -221,10 +221,10 @@ public class CarpetScriptServer requires((player) -> modules.containsKey(hostName)). executes( (c) -> { - String response = modules.get(hostName).retrieveForExecution(c.getSource()). + Value response = modules.get(hostName).retrieveForExecution(c.getSource()). handleCommand(c.getSource(),"__command", null, ""); - if (!response.isEmpty()) Messenger.m(c.getSource(), "gi "+response); - return 1; + if (!response.isNull()) Messenger.m(c.getSource(), "gi "+response.getString()); + return (int)response.readInteger(); }); for (String function : host.globaFunctionNames(host.main, s -> !s.startsWith("_")).sorted().collect(Collectors.toList())) @@ -233,17 +233,17 @@ public class CarpetScriptServer then(literal(function). requires((player) -> modules.containsKey(hostName) && modules.get(hostName).getFunction(function) != null). executes( (c) -> { - String response = modules.get(hostName).retrieveForExecution(c.getSource()). + Value response = modules.get(hostName).retrieveForExecution(c.getSource()). handleCommand(c.getSource(), function,null,""); - if (!response.isEmpty()) Messenger.m(c.getSource(),"gi "+response); - return 1; + if (!response.isNull()) Messenger.m(c.getSource(),"gi "+response.getString()); + return (int)response.readInteger(); }). then(argument("args...", StringArgumentType.greedyString()). executes( (c) -> { - String response = modules.get(hostName).retrieveForExecution(c.getSource()). + Value response = modules.get(hostName).retrieveForExecution(c.getSource()). handleCommand(c.getSource(), function,null, StringArgumentType.getString(c, "args...")); - if (!response.isEmpty()) Messenger.m(c.getSource(), "gi "+response); - return 1; + if (!response.isNull()) Messenger.m(c.getSource(), "gi "+response.getString()); + return (int)response.readInteger(); }))); } Messenger.m(source, "gi "+hostName+" app "+loaded+" with /"+hostName+" command"); diff --git a/src/main/java/carpet/script/value/NullValue.java b/src/main/java/carpet/script/value/NullValue.java index eb0897cd..95df97c9 100644 --- a/src/main/java/carpet/script/value/NullValue.java +++ b/src/main/java/carpet/script/value/NullValue.java @@ -68,4 +68,9 @@ public class NullValue extends NumericValue // TODO check nonsingleton code { return JsonNull.INSTANCE; } + + @Override + public boolean isNull() { + return true; + } } diff --git a/src/main/java/carpet/script/value/NumericValue.java b/src/main/java/carpet/script/value/NumericValue.java index 61157dfe..6ba47604 100644 --- a/src/main/java/carpet/script/value/NumericValue.java +++ b/src/main/java/carpet/script/value/NumericValue.java @@ -44,11 +44,13 @@ public class NumericValue extends Value } try { + if (value.isInfinite()) return "INFINITY"; + if (value.isNaN()) return "NaN"; return BigDecimal.valueOf(value).stripTrailingZeros().toPlainString(); } catch (NumberFormatException exc) { - throw new ArithmeticException("Incorrect number format for "+value); + throw new InternalExpressionException("Incorrect number format for "+value); } } @@ -121,6 +123,7 @@ public class NumericValue extends Value } public Value divide(Value v) { + //if (1+2==3) throw new ArithmeticException("Booyah"); if (v instanceof NumericValue) { return new NumericValue(getDouble() / ((NumericValue) v).getDouble() ); diff --git a/src/main/java/carpet/script/value/Value.java b/src/main/java/carpet/script/value/Value.java index e22b914c..2e355da6 100644 --- a/src/main/java/carpet/script/value/Value.java +++ b/src/main/java/carpet/script/value/Value.java @@ -213,4 +213,6 @@ public abstract class Value implements Comparable, Cloneable { return new JsonPrimitive(getString()); } + + public boolean isNull() { return false; } }