added custom context to be used in optimization evaluations that should expose all programmers issues, while allowing reporting errors to the error snooping entity. Fixes #875
This commit is contained in:
1 parent
deb4f78347
commit
f21897fab1
4 files changed
+76
-10
No files matched your search
@@ -1,5 +1,6 @@
|
||||
package carpet.script;
|
||||
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.value.Value;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -83,4 +84,63 @@ public class Context
|
||||
{
|
||||
return new Context(this.host);
|
||||
}
|
||||
public ScriptHost.ErrorSnooper getErrorSnooper()
|
||||
{
|
||||
return host.errorSnooper;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* immutable context only for reason on reporting access violations in evaluating expressions in optimizization
|
||||
* mode detecting any potential violations that may happen on the way
|
||||
*/
|
||||
public static class ContextForErrorReporting extends Context
|
||||
{
|
||||
public ScriptHost.ErrorSnooper optmizerEerrorSnooper;
|
||||
public ContextForErrorReporting(Context parent)
|
||||
{
|
||||
super(null);
|
||||
optmizerEerrorSnooper = parent.host.errorSnooper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptHost.ErrorSnooper getErrorSnooper()
|
||||
{
|
||||
return optmizerEerrorSnooper;
|
||||
}
|
||||
|
||||
public void badProgrammer()
|
||||
{
|
||||
throw new InternalExpressionException("Attempting to access the execution context while optimizing the code;" +
|
||||
" This is not the problem with your code, but the error cause by improper use of code compile optimizations" +
|
||||
"of scarpet authors. Please report this issue directly to the scarpet issue tracker");
|
||||
|
||||
}
|
||||
@Override
|
||||
public LazyValue getVariable(String name) { badProgrammer(); return null;}
|
||||
|
||||
@Override
|
||||
public void setVariable(String name, LazyValue lv) { badProgrammer(); }
|
||||
|
||||
@Override
|
||||
public void delVariable(String variable) { badProgrammer(); }
|
||||
|
||||
@Override
|
||||
public void removeVariablesMatching(String varname) { badProgrammer(); }
|
||||
|
||||
@Override
|
||||
public Context with(String variable, LazyValue lv) { badProgrammer(); return this; }
|
||||
|
||||
@Override
|
||||
public Set<String> getAllVariableNames() { badProgrammer(); return null;}
|
||||
|
||||
@Override
|
||||
public Context recreate() { badProgrammer(); return null;}
|
||||
|
||||
@Override
|
||||
protected void initialize() { badProgrammer();}
|
||||
|
||||
@Override
|
||||
public Context duplicate() { badProgrammer(); return null;}
|
||||
}
|
||||
}
|
||||
@@ -1072,6 +1072,7 @@ public class Expression
|
||||
if (!CarpetSettings.scriptsOptimization)
|
||||
return root.op;
|
||||
|
||||
Context optimizeOnlyContext = new Context.ContextForErrorReporting(context);
|
||||
CarpetScriptServer.LOG.info("Input code size for "+getModuleName()+": " + treeSize(root) + " nodes, " + treeDepth(root) + " deep");
|
||||
|
||||
boolean changed = true;
|
||||
@@ -1088,13 +1089,13 @@ public class Expression
|
||||
while (true) {
|
||||
int tree_size = treeSize(root);
|
||||
int tree_depth = treeDepth(root);
|
||||
boolean optimized = optimizeTree(context, root, Context.Type.NONE, 0);
|
||||
boolean optimized = optimizeTree(optimizeOnlyContext, root, Context.Type.NONE, 0);
|
||||
if (!optimized) break;
|
||||
changed = true;
|
||||
CarpetScriptServer.LOG.info("Optimized from " + tree_size + " nodes, " + tree_depth + " code depth to " + treeSize(root) + " nodes, " + treeDepth(root) + " code depth");
|
||||
}
|
||||
}
|
||||
return extractOp(context, root, Context.Type.NONE);
|
||||
return extractOp(optimizeOnlyContext, root, Context.Type.NONE);
|
||||
}
|
||||
|
||||
private int treeSize(ExpressionNode node)
|
||||
@@ -1222,25 +1223,25 @@ public class Expression
|
||||
Value val = ((LazyValue.Constant) arg.op).get();
|
||||
args.add((c, t) -> val);
|
||||
}
|
||||
else args.add((c, t) -> arg.op.evalValue(null, requestedType));
|
||||
else args.add((c, t) -> arg.op.evalValue(ctx, requestedType));
|
||||
} catch (NullPointerException npe) {
|
||||
throw new ExpressionException(ctx, this, node.token, "Attempted to evaluate context free expression");
|
||||
}
|
||||
}
|
||||
// applying argument unpacking
|
||||
args= AbstractLazyFunction.lazify(AbstractLazyFunction.unpackLazy(args, null, requestedType));
|
||||
args= AbstractLazyFunction.lazify(AbstractLazyFunction.unpackLazy(args, ctx, requestedType));
|
||||
Value result;
|
||||
if (operation instanceof ILazyFunction)
|
||||
{
|
||||
result = ((ILazyFunction) operation).lazyEval(null, expectedType, this, node.token, args).evalValue(null, expectedType);
|
||||
result = ((ILazyFunction) operation).lazyEval(ctx, expectedType, this, node.token, args).evalValue(null, expectedType);
|
||||
}
|
||||
else if (args.size() == 1)
|
||||
{
|
||||
result = ((ILazyOperator)operation).lazyEval(null, expectedType, this, node.token, args.get(0), null).evalValue(null, expectedType);
|
||||
result = ((ILazyOperator)operation).lazyEval(ctx, expectedType, this, node.token, args.get(0), null).evalValue(null, expectedType);
|
||||
}
|
||||
else // args == 2
|
||||
{
|
||||
result = ((ILazyOperator)operation).lazyEval(null, 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.token.morph(Tokenizer.Token.TokenType.CONSTANT, node.token.surface);
|
||||
|
||||
@@ -105,7 +105,12 @@ public abstract class ScriptHost
|
||||
|
||||
public final Module main;
|
||||
|
||||
public Fluff.TriFunction<Expression, Tokenizer.Token, String, List<String>> errorSnooper = null;
|
||||
@FunctionalInterface
|
||||
public interface ErrorSnooper
|
||||
{
|
||||
List<String> apply(Expression expression, Tokenizer.Token token, String message);
|
||||
}
|
||||
public ErrorSnooper errorSnooper = null;
|
||||
|
||||
protected ScriptHost(Module code, boolean perUser, ScriptHost parent)
|
||||
{
|
||||
|
||||
@@ -72,9 +72,9 @@ public class ExpressionException extends RuntimeException implements ResolvedExc
|
||||
|
||||
synchronized static String makeMessage(Context c, Expression e, Tokenizer.Token t, String message) throws ExpressionException
|
||||
{
|
||||
if (c.host.errorSnooper != null)
|
||||
if (c.getErrorSnooper() != null)
|
||||
{
|
||||
List<String> alternative = c.host.errorSnooper.apply(e, t, message);
|
||||
List<String> alternative = c.getErrorSnooper().apply(e, t, message);
|
||||
if (alternative!= null)
|
||||
{
|
||||
return String.join("\n", alternative);
|
||||
|
||||
Reference in new issue
Block a user