All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.aviator.BaseExpression Maven / Gradle / Ivy

There is a newer version: 5.4.3
Show newest version
package com.googlecode.aviator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import com.googlecode.aviator.lexer.SymbolTable;
import com.googlecode.aviator.lexer.token.Variable;
import com.googlecode.aviator.runtime.FunctionArgument;
import com.googlecode.aviator.utils.Env;


/**
 * Base expression
 *
 * @author dennis
 *
 */
public abstract class BaseExpression implements Expression {

  public static final String FUNC_PARAMS_VAR = "__funcs_args__";
  private final List varNames;
  private final List varFullNames;
  private String expression;
  protected AviatorEvaluatorInstance instance;
  private Env compileEnv;
  private Map> funcsArgs = Collections.emptyMap();
  protected SymbolTable symbolTable;

  public BaseExpression(final AviatorEvaluatorInstance instance, final List varNames,
      final SymbolTable symbolTable) {
    super();
    this.symbolTable = symbolTable;
    this.varFullNames = varNames;
    this.instance = instance;
    LinkedHashSet tmp = new LinkedHashSet<>(varNames.size());
    // process nested names
    for (String name : varNames) {
      if (name.contains(".")) {
        name = name.substring(0, name.indexOf("."));
      }
      tmp.add(name);
    }
    this.varNames = new ArrayList(tmp);
  }

  private class SymbolHashMap extends HashMap {

    private static final long serialVersionUID = 5951510458689965590L;

    public SymbolHashMap(final int initialCapacity) {
      super(initialCapacity);
    }

    @Override
    public Object put(String key, final Object value) {
      Variable var = null;
      if (BaseExpression.this.symbolTable != null
          && (var = BaseExpression.this.symbolTable.getVariable(key)) != null) {
        key = var.getLexeme();
      }
      return super.put(key, value);
    }

  }

  @Override
  public Map newEnv(final Object... args) {
    if (args != null && args.length % 2 != 0) {
      throw new IllegalArgumentException("Expect arguments number is even.");
    }
    Map env = new SymbolHashMap(args != null ? args.length : 10);
    if (args != null) {
      for (int i = 0; i < args.length; i += 2) {
        String key = (String) args[i];
        env.put(key, args[i + 1]);
      }
    }
    return env;
  }

  public abstract Object executeDirectly(final Map env);

  @Override
  public Object execute(Map map) {
    if (map == null) {
      map = Collections.emptyMap();
    }
    Env env = genTopEnv(map);
    return executeDirectly(env);
  }


  public void setFuncsArgs(final Map> funcsArgs) {
    if (funcsArgs != null) {
      this.funcsArgs = Collections.unmodifiableMap(funcsArgs);
    }
  }


  public Env getCompileEnv() {
    return this.compileEnv;
  }


  public void setCompileEnv(final Env compileEnv) {
    this.compileEnv = compileEnv;
  }


  /**
   * Returns the expression string when turn on {@link Options#TRACE_EVAL} option, else returns
   * null.
   *
   * @return expression in string.
   */
  public String getExpression() {
    return this.expression;
  }

  public void setExpression(final String expression) {
    this.expression = expression;
  }


  @Override
  public String addSymbol(final String name) {
    if (this.symbolTable != null) {
      return this.symbolTable.reserve(name).getLexeme();
    } else {
      return name;
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see com.googlecode.aviator.IExpression#execute()
   */
  @Override
  public Object execute() {
    return this.execute(null);
  }


  @Override
  public List getVariableFullNames() {
    return this.varFullNames;
  }


  /*
   * (non-Javadoc)
   *
   * @see com.googlecode.aviator.IExpression#getVariableNames()
   */
  @Override
  public List getVariableNames() {
    return this.varNames;
  }

  protected Env newEnv(final Map map, final boolean direct) {
    Env env;
    if (direct) {
      env = new Env(map, map == Collections.EMPTY_MAP ? new HashMap() : map);
    } else {
      env = new Env(map);
    }
    env.setInstance(this.instance);
    return env;
  }

  protected Env genTopEnv(final Map map) {
    if (map instanceof Env) {
      ((Env) map).setInstance(this.instance);
    }
    Env env =
        newEnv(map, this.instance.getOptionValue(Options.USE_USER_ENV_AS_TOP_ENV_DIRECTLY).bool);

    if (this.compileEnv != null && !this.compileEnv.isEmpty()) {
      env.putAll(this.compileEnv);
    }
    if (!this.funcsArgs.isEmpty()) {
      env.override(FUNC_PARAMS_VAR, this.funcsArgs);
    }
    return env;
  }

  protected Env newEnv(final Map map) {
    return newEnv(map, false);
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy