Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

重载ADD运算符,运算式报错 #466

Closed
1633788059 opened this issue May 23, 2022 · 5 comments
Closed

重载ADD运算符,运算式报错 #466

1633788059 opened this issue May 23, 2022 · 5 comments
Labels

Comments

@1633788059
Copy link

1633788059 commented May 23, 2022

背景:进行表达式解析的时候,业务场景会出现 A+B的情形, a和b都是具体的业务含义
示例:重写ADD运算符的时候,返回类型为 AviatorRuntimeJavaType.valueOf(Maps.newHashMap())

demo:
public static void main(final String[] args) {

    AviatorEvaluator.getInstance().addOpFunction(OperatorType.ADD, new AbstractFunction() {

        @Override
        public AviatorObject call(final Map<String, Object> env, final AviatorObject arg1,
            final AviatorObject arg2) {
            Map<String, Object> test = Maps.newHashMap();
            test.put("test", "123");
            return AviatorRuntimeJavaType.valueOf(test);
        }

        @Override
        public String getName() {
            return OperatorType.ADD.getToken();
        }
    });

    Expression compiledExp3 = AviatorEvaluator.compile("10000+ 20000 ");
    System.out.println(compiledExp3.execute());
}

10000 和 20000 有实际的业务含义,所以才想着返回map类型出来

问题:执行过程报错
Exception in thread "main" com.googlecode.aviator.exception.CompileExpressionErrorException: Invalid operand:<JavaType, A_1, {}, java.util.HashMap>

想请教一下,怎么避免这个问题,使得能返回自定义的类型。
(是否有一些配置项之类的,谢谢了)

@1633788059
Copy link
Author

1633788059 commented May 23, 2022

改成 ‘10000’ + ‘20000’ 是可以出来想要的效果,
看了一下代码,是在compile的时候,判断是否要提前执行的逻辑,应该是做优化使用的。
代码在OptimizeCodeGenerator#executeOperator

 // if we can execute it on compile
    if (canExecute) {
      // arguments
      AviatorObject[] args = new AviatorObject[operandCount];
      int index = 0;
      for (int j = operandStartIndex; j < operatorIndex; j++) {
        token = this.tokenList.get(j);
        if (token.getType() == TokenType.Delegate) {
          this.tokenList.set(j, null);
          continue;
        }
        args[index++] = getAviatorObjectFromToken(token);
        // set argument token to null
        this.tokenList.set(j, null);

      }
      AviatorObject result = OperationRuntime.eval(getCompileEnv(), args, operatorType);
      // set result as token to tokenList for next executing
      this.tokenList.set(operatorIndex, getTokenFromOperand(operatorToken, result));
      return 1;
    }

问题:能否加一个配置项之类的,来决定是否在compile就计算结果,谢谢了

@killme2008
Copy link
Owner

关闭优化:

AviatorEvaluator.getInstance().setOption(Options.OPTIMIZE_LEVEL, AviatorEvaluator.COMPILE);

@killme2008
Copy link
Owner

不过这个算是个bug,先开着吧

@killme2008 killme2008 added the bug label May 23, 2022
@1633788059
Copy link
Author

1633788059 commented May 23, 2022

@killme2008 关闭优化 有什么其他方面的性能影响吗,想问一下这个有文档吗?谢谢了

@killme2008
Copy link
Owner

目前也只做了常量折叠的优化,理论上对运行时性能有少许影响

所有选项都在文档库有说明 https://www.yuque.com/boyan-avfmj/aviatorscript/yr1oau

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants