move gamerule access out of expression, ranames
This commit is contained in:
1 parent
29e139794c
commit
6dd7bda6e4
3 files changed
+51
-37
No files matched your search
@@ -12,6 +12,7 @@ import carpet.script.api.WorldAccess;
|
|||||||
import carpet.script.exception.CarpetExpressionException;
|
import carpet.script.exception.CarpetExpressionException;
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
import carpet.script.external.Carpet;
|
import carpet.script.external.Carpet;
|
||||||
|
import carpet.script.external.Vanilla;
|
||||||
import carpet.script.value.BlockValue;
|
import carpet.script.value.BlockValue;
|
||||||
import carpet.script.value.EntityValue;
|
import carpet.script.value.EntityValue;
|
||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
@@ -20,6 +21,8 @@ import net.minecraft.commands.CommandSourceStack;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class CarpetExpression
|
public class CarpetExpression
|
||||||
{
|
{
|
||||||
private final CommandSourceStack source;
|
private final CommandSourceStack source;
|
||||||
@@ -86,7 +89,11 @@ public class CarpetExpression
|
|||||||
Value playerValue = new EntityValue(e).bindTo("p");
|
Value playerValue = new EntityValue(e).bindTo("p");
|
||||||
context.with("p", (cc, tt) -> playerValue);
|
context.with("p", (cc, tt) -> playerValue);
|
||||||
}
|
}
|
||||||
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context).getBoolean());
|
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.executeAndEvaluate(
|
||||||
|
context,
|
||||||
|
Vanilla.ScriptServer_scriptOptimizations(scriptServer.server),
|
||||||
|
Vanilla.ScriptServer_scriptDebugging(scriptServer.server) ? CarpetScriptServer.LOG::info : null
|
||||||
|
).getBoolean());
|
||||||
}
|
}
|
||||||
catch (ExpressionException e)
|
catch (ExpressionException e)
|
||||||
{
|
{
|
||||||
@@ -126,7 +133,11 @@ public class CarpetExpression
|
|||||||
Value playerValue = new EntityValue(e).bindTo("p");
|
Value playerValue = new EntityValue(e).bindTo("p");
|
||||||
context.with("p", (cc, tt) -> playerValue);
|
context.with("p", (cc, tt) -> playerValue);
|
||||||
}
|
}
|
||||||
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.eval(context));
|
return scriptServer.events.handleEvents.getWhileDisabled(() -> this.expr.executeAndEvaluate(
|
||||||
|
context,
|
||||||
|
Vanilla.ScriptServer_scriptOptimizations(scriptServer.server),
|
||||||
|
Vanilla.ScriptServer_scriptDebugging(scriptServer.server) ? CarpetScriptServer.LOG::info : null
|
||||||
|
));
|
||||||
}
|
}
|
||||||
catch (ExpressionException e)
|
catch (ExpressionException e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -829,7 +829,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
||||||
assertAppIntegrity(function.getModule());
|
assertAppIntegrity(function.getModule());
|
||||||
Context context = new CarpetContext(this, source);
|
Context context = new CarpetContext(this, source);
|
||||||
return scriptServer().events.handleEvents.getWhileDisabled(() -> function.getExpression().evalValue(
|
return scriptServer().events.handleEvents.getWhileDisabled(() -> function.getExpression().evaluatePartial(
|
||||||
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
||||||
context,
|
context,
|
||||||
Context.VOID
|
Context.VOID
|
||||||
@@ -862,7 +862,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
assertAppIntegrity(function.getModule());
|
assertAppIntegrity(function.getModule());
|
||||||
Context context = new CarpetContext(this, source);
|
Context context = new CarpetContext(this, source);
|
||||||
return function.getExpression().evalValue(
|
return function.getExpression().evaluatePartial(
|
||||||
() -> function.execute(context, Context.VOID, function.getExpression(), function.getToken(), argv, null),
|
() -> function.execute(context, Context.VOID, function.getExpression(), function.getToken(), argv, null),
|
||||||
context,
|
context,
|
||||||
Context.VOID
|
Context.VOID
|
||||||
@@ -899,7 +899,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
assertAppIntegrity(fun.getModule());
|
assertAppIntegrity(fun.getModule());
|
||||||
Context context = new CarpetContext(this, source, origin);
|
Context context = new CarpetContext(this, source, origin);
|
||||||
return fun.getExpression().evalValue(
|
return fun.getExpression().evaluatePartial(
|
||||||
() -> fun.execute(context, Context.VOID, fun.getExpression(), fun.getToken(), argv, null),
|
() -> fun.execute(context, Context.VOID, fun.getExpression(), fun.getToken(), argv, null),
|
||||||
context,
|
context,
|
||||||
Context.VOID);
|
Context.VOID);
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import carpet.script.exception.IntegrityException;
|
|||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.exception.ResolvedException;
|
import carpet.script.exception.ResolvedException;
|
||||||
import carpet.script.exception.ReturnStatement;
|
import carpet.script.exception.ReturnStatement;
|
||||||
import carpet.script.external.Vanilla;
|
|
||||||
import carpet.script.language.Arithmetic;
|
import carpet.script.language.Arithmetic;
|
||||||
import carpet.script.language.ControlFlow;
|
import carpet.script.language.ControlFlow;
|
||||||
import carpet.script.language.DataStructures;
|
import carpet.script.language.DataStructures;
|
||||||
@@ -36,7 +35,9 @@ import it.unimi.dsi.fastutil.Stack;
|
|||||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -45,6 +46,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.DoubleBinaryOperator;
|
import java.util.function.DoubleBinaryOperator;
|
||||||
import java.util.function.DoubleToLongFunction;
|
import java.util.function.DoubleToLongFunction;
|
||||||
import java.util.function.DoubleUnaryOperator;
|
import java.util.function.DoubleUnaryOperator;
|
||||||
@@ -1013,16 +1015,16 @@ public class Expression
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Value eval(Context c)
|
public Value executeAndEvaluate(Context c, boolean optimize, @Nullable Consumer<String> logger)
|
||||||
{
|
{
|
||||||
if (ast == null)
|
if (ast == null)
|
||||||
{
|
{
|
||||||
ast = getAST(c);
|
ast = getAST(c, optimize, logger);
|
||||||
}
|
}
|
||||||
return evalValue(() -> ast, c, Context.Type.NONE);
|
return evaluatePartial(() -> ast, c, Context.Type.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Value evalValue(Supplier<LazyValue> exprProvider, Context c, Context.Type expectedType)
|
public Value evaluatePartial(Supplier<LazyValue> exprProvider, Context c, Context.Type expectedType)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1181,7 +1183,7 @@ public class Expression
|
|||||||
return nodeStack.pop();
|
return nodeStack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LazyValue getAST(Context context)
|
private LazyValue getAST(Context context, boolean optimize, @Nullable Consumer<String> logger)
|
||||||
{
|
{
|
||||||
Tokenizer tokenizer = new Tokenizer(context, this, expression, allowComments, allowNewlineSubstitutions);
|
Tokenizer tokenizer = new Tokenizer(context, this, expression, allowComments, allowNewlineSubstitutions);
|
||||||
// stripping lousy but acceptable semicolons
|
// stripping lousy but acceptable semicolons
|
||||||
@@ -1190,21 +1192,22 @@ public class Expression
|
|||||||
List<Token> rpn = shuntingYard(context, cleanedTokens);
|
List<Token> rpn = shuntingYard(context, cleanedTokens);
|
||||||
validate(context, rpn);
|
validate(context, rpn);
|
||||||
ExpressionNode root = RPNToParseTree(rpn, context);
|
ExpressionNode root = RPNToParseTree(rpn, context);
|
||||||
if (!Vanilla.ScriptServer_scriptOptimizations(((CarpetScriptServer)context.scriptServer()).server))
|
if (!optimize)
|
||||||
{
|
{
|
||||||
return root.op;
|
return root.op;
|
||||||
}
|
}
|
||||||
|
|
||||||
Context optimizeOnlyContext = new Context.ContextForErrorReporting(context);
|
Context optimizeOnlyContext = new Context.ContextForErrorReporting(context);
|
||||||
optimizeTree(context, root, optimizeOnlyContext);
|
// flipping to full functional representation makes it little underperforming, might be related
|
||||||
|
// to the fact that operators are running from a bigger pool or function execution is slower
|
||||||
|
optimizeTree(root, optimizeOnlyContext, logger, false);
|
||||||
return extractOp(optimizeOnlyContext, root, Context.Type.NONE);
|
return extractOp(optimizeOnlyContext, root, Context.Type.NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void optimizeTree(Context context, ExpressionNode root, Context optimizeOnlyContext) {
|
private void optimizeTree(ExpressionNode root, Context optimizeOnlyContext, @Nullable Consumer<String> logger, boolean toFunctional) {
|
||||||
boolean scriptsDebugging = Vanilla.ScriptServer_scriptDebugging(((CarpetScriptServer) context.scriptServer()).server);
|
if (logger != null)
|
||||||
if (scriptsDebugging)
|
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info("Input code size for " + getModuleName() + ": " + treeSize(root) + " nodes, " + treeDepth(root) + " deep");
|
logger.accept("Input code size for " + getModuleName() + ": " + treeSize(root) + " nodes, " + treeDepth(root) + " deep");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defined out here to not need to conditionally assign them with debugging disabled
|
// Defined out here to not need to conditionally assign them with debugging disabled
|
||||||
@@ -1217,38 +1220,38 @@ public class Expression
|
|||||||
changed = false;
|
changed = false;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (scriptsDebugging)
|
if (logger != null)
|
||||||
{
|
{
|
||||||
prevTreeSize = treeSize(root);
|
prevTreeSize = treeSize(root);
|
||||||
prevTreeDepth = treeDepth(root);
|
prevTreeDepth = treeDepth(root);
|
||||||
}
|
}
|
||||||
boolean optimized = compactTree(root, Context.Type.NONE, 0, scriptsDebugging);
|
boolean optimized = compactTree(root, Context.Type.NONE, 0, logger, toFunctional);
|
||||||
if (!optimized)
|
if (!optimized)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
if (scriptsDebugging)
|
if (logger != null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info("Compacted from " + prevTreeSize + " nodes, " + prevTreeDepth + " code depth to " + treeSize(root) + " nodes, " + treeDepth(root) + " code depth");
|
logger.accept("Compacted from " + prevTreeSize + " nodes, " + prevTreeDepth + " code depth to " + treeSize(root) + " nodes, " + treeDepth(root) + " code depth");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (scriptsDebugging)
|
if (logger != null)
|
||||||
{
|
{
|
||||||
prevTreeSize = treeSize(root);
|
prevTreeSize = treeSize(root);
|
||||||
prevTreeDepth = treeDepth(root);
|
prevTreeDepth = treeDepth(root);
|
||||||
}
|
}
|
||||||
boolean optimized = optimizeConstantsAndPureFunctions(optimizeOnlyContext, root, Context.Type.NONE, 0, scriptsDebugging);
|
boolean optimized = optimizeConstantsAndPureFunctions(optimizeOnlyContext, root, Context.Type.NONE, 0, logger);
|
||||||
if (!optimized)
|
if (!optimized)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
changed = true;
|
changed = true;
|
||||||
if (scriptsDebugging)
|
if (logger != null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info("Optimized from " + prevTreeSize + " nodes, " + prevTreeDepth + " code depth to " + treeSize(root) + " nodes, " + treeDepth(root) + " code depth");
|
logger.accept("Optimized from " + prevTreeSize + " nodes, " + prevTreeDepth + " code depth to " + treeSize(root) + " nodes, " + treeDepth(root) + " code depth");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1271,7 +1274,7 @@ public class Expression
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean compactTree(ExpressionNode node, Context.Type expectedType, int indent, boolean scriptsDebugging)
|
private boolean compactTree(ExpressionNode node, Context.Type expectedType, int indent, @Nullable Consumer<String> logger, boolean toFunctional)
|
||||||
{
|
{
|
||||||
// ctx is just to report errors, not values evaluation
|
// ctx is just to report errors, not values evaluation
|
||||||
boolean optimized = false;
|
boolean optimized = false;
|
||||||
@@ -1291,7 +1294,7 @@ public class Expression
|
|||||||
Context.Type requestedType = operation.staticType(expectedType);
|
Context.Type requestedType = operation.staticType(expectedType);
|
||||||
for (ExpressionNode arg : node.args)
|
for (ExpressionNode arg : node.args)
|
||||||
{
|
{
|
||||||
if (compactTree(arg, requestedType, indent + 1, scriptsDebugging))
|
if (compactTree(arg, requestedType, indent + 1, logger, toFunctional))
|
||||||
{
|
{
|
||||||
optimized = true;
|
optimized = true;
|
||||||
}
|
}
|
||||||
@@ -1321,9 +1324,9 @@ public class Expression
|
|||||||
returnNode.token = returnNode.args.get(0).token;
|
returnNode.token = returnNode.args.get(0).token;
|
||||||
returnNode.range = returnNode.args.get(0).range;
|
returnNode.range = returnNode.args.get(0).range;
|
||||||
returnNode.args = returnNode.args.get(0).args;
|
returnNode.args = returnNode.args.get(0).args;
|
||||||
if (scriptsDebugging)
|
if (logger != null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info(" - Removed unnecessary tail return of " + returnNode.token.surface + " from function body at line " + (returnNode.token.lineno + 1) + ", node depth " + indent);
|
logger.accept(" - Removed unnecessary tail return of " + returnNode.token.surface + " from function body at line " + (returnNode.token.lineno + 1) + ", node depth " + indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1331,9 +1334,9 @@ public class Expression
|
|||||||
returnNode.op = LazyValue.ofConstant(Value.NULL);
|
returnNode.op = LazyValue.ofConstant(Value.NULL);
|
||||||
returnNode.token.morph(Token.TokenType.CONSTANT, "");
|
returnNode.token.morph(Token.TokenType.CONSTANT, "");
|
||||||
returnNode.args = Collections.emptyList();
|
returnNode.args = Collections.emptyList();
|
||||||
if (scriptsDebugging)
|
if (logger != null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info(" - Removed unnecessary tail return from function body at line " + (returnNode.token.lineno + 1) + ", node depth " + indent);
|
logger.accept(" - Removed unnecessary tail return from function body at line " + (returnNode.token.lineno + 1) + ", node depth " + indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1369,9 +1372,9 @@ public class Expression
|
|||||||
newargs.addAll(optimizedChild.args);
|
newargs.addAll(optimizedChild.args);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scriptsDebugging)
|
if (logger != null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info(" - " + symbol + "(" + node.args.size() + ") => " + function + "(" + newargs.size() + ") at line " + (node.token.lineno + 1) + ", node depth " + indent);
|
logger.accept(" - " + symbol + "(" + node.args.size() + ") => " + function + "(" + newargs.size() + ") at line " + (node.token.lineno + 1) + ", node depth " + indent);
|
||||||
}
|
}
|
||||||
node.token.morph(Token.TokenType.FUNCTION, function);
|
node.token.morph(Token.TokenType.FUNCTION, function);
|
||||||
node.args = newargs;
|
node.args = newargs;
|
||||||
@@ -1381,7 +1384,7 @@ public class Expression
|
|||||||
return optimized;
|
return optimized;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean optimizeConstantsAndPureFunctions(Context ctx, ExpressionNode node, Context.Type expectedType, int indent, boolean scriptsDebugging)
|
private boolean optimizeConstantsAndPureFunctions(Context ctx, ExpressionNode node, Context.Type expectedType, int indent, @Nullable Consumer<String> logger)
|
||||||
{
|
{
|
||||||
// ctx is just to report errors, not values evaluation
|
// ctx is just to report errors, not values evaluation
|
||||||
boolean optimized = false;
|
boolean optimized = false;
|
||||||
@@ -1403,7 +1406,7 @@ public class Expression
|
|||||||
Context.Type requestedType = operation.staticType(expectedType);
|
Context.Type requestedType = operation.staticType(expectedType);
|
||||||
for (ExpressionNode arg : node.args)
|
for (ExpressionNode arg : node.args)
|
||||||
{
|
{
|
||||||
if (optimizeConstantsAndPureFunctions(ctx, arg, requestedType, indent + 1, scriptsDebugging))
|
if (optimizeConstantsAndPureFunctions(ctx, arg, requestedType, indent + 1, logger))
|
||||||
{
|
{
|
||||||
optimized = true;
|
optimized = true;
|
||||||
}
|
}
|
||||||
@@ -1470,9 +1473,9 @@ public class Expression
|
|||||||
result = ((ILazyOperator) operation).lazyEval(ctx, expectedType, this, node.token, args.get(0), args.get(1)).evalValue(null, expectedType);
|
result = ((ILazyOperator) operation).lazyEval(ctx, expectedType, this, node.token, args.get(0), args.get(1)).evalValue(null, expectedType);
|
||||||
}
|
}
|
||||||
node.op = LazyValue.ofConstant(result);
|
node.op = LazyValue.ofConstant(result);
|
||||||
if (scriptsDebugging)
|
if (logger != null)
|
||||||
{
|
{
|
||||||
CarpetScriptServer.LOG.info(" - " + symbol + "(" + args.stream().map(a -> a.evalValue(null, requestedType).getString()).collect(Collectors.joining(", ")) + ") => " + result.getString() + " at line " + (node.token.lineno + 1) + ", node depth " + indent);
|
logger.accept(" - " + symbol + "(" + args.stream().map(a -> a.evalValue(null, requestedType).getString()).collect(Collectors.joining(", ")) + ") => " + result.getString() + " at line " + (node.token.lineno + 1) + ", node depth " + indent);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user