示例#1
0
  /**
   * Return the Element which corresponds to the given variable name. It will first check local
   * variables and then the parent context. This method will return null if the variable doesn't
   * exist or the argument is null. Note that this will clone the final value, if it originated from
   * a global variable.
   *
   * @param name name of the variable to lookup
   * @param lookupOnly flag indicating if only a lookup should be done
   * @param terms values for dereferencing the given variable
   * @return Element value of the associated dereferenced variable
   */
  public Element dereferenceVariable(String name, boolean lookupOnly, Term[] terms)
      throws InvalidTermException {

    boolean duplicate = false;
    Element result = localVariables.get(name);

    // If the result is null, then try to look up a global variable.
    if (result == null) {
      duplicate = true;
      result = getGlobalVariable(name);
    }

    // Now actually dereference the given variable. The caller must deal
    // with any invalid term exceptions or evaluation exceptions. We just
    // pass those on.
    if (result != null) {
      if (!(result instanceof Undef)) {
        // FIXME: Determine if the result needs to be protected.
        result = result.rget(terms, 0, false, lookupOnly);
      } else {
        // Trying to dereference an undefined value. Therefore, the
        // value does not exist; return null to caller.
        result = null;
      }
    }

    // FIXME: This is inefficient and should be avoided. However, one must
    // ensure that global variables are protected against changes.

    // To ensure that global variables are not inadvertently modified via
    // copies in local variables, duplicate the result. Do this only AFTER
    // the dereference to limit the amount of potentially unnecessary
    // cloning.
    if (duplicate && result != null) {
      result = result.duplicate();
    }

    return result;
  }