/**
  * Get the value without forcing evaluation. Try to follow any indirection chains to their
  * conclusion.
  *
  * @return RTValue the value
  */
 @Override
 public RTValue getValue() {
   if (result == null) {
     return this;
   }
   return (result = result.getValue());
 }
 /**
  * Return the previous argument (until we reach the root)
  *
  * @return the previous argument
  */
 @Override
 public RTValue prevArg() {
   // Note:  In the normal course of graph reduction this method will not be
   // called before result is set.  An explicit check for a null result value
   // is omitted for performance reasons.
   return result.prevArg();
 }
 /** {@inheritDoc} */
 @Override
 public final DataType getDataType() {
   if (result != null) {
     return result.getDataType();
   } else {
     return DataType.OTHER;
   }
 }
  // WARNING: the implementation of this method must be kept compatible with unsynchronizedEvaluate
  private final synchronized RTValue synchronizedEvaluate(RTExecutionContext ec)
      throws CALExecutorException {
    if (!LECCMachineConfiguration.nonInterruptibleRuntime() && ec.isQuitRequested()) {
      throw RTValue.INTERRUPT_EXCEPTION;
    }

    RTValue newResult = result == null ? this : result;
    RTValue lastResult;

    // do not repeatedly poll the SourceGenerationConfiguration settings in the most performance
    // important common case
    // where we are not generating any runtime statistics

    if (RTResultFunction.HAS_RUNTIME_STATS) {

      // Attempt to reduce this result
      do {
        if (LECCMachineConfiguration.generateStatistics()) {
          ec.incrementNReductions();
        }

        lastResult = newResult;
        newResult = newResult.synchronizedReduce(ec);

      } while (lastResult != newResult);

    } else {

      // Attempt to reduce this result
      do {
        lastResult = newResult;
        newResult = newResult.synchronizedReduce(ec);
      } while (lastResult != newResult);
    }

    if (newResult != this) {
      setResult(newResult);
    }

    return newResult;
  }
 public final void setResult(RTValue res) {
   res = res.getValue();
   if (res != this) {
     result = res;
     if (parent == null) {
       if (res instanceof RTResultFunction) {
         ((RTResultFunction) res).setParent(this);
       }
     } else {
       parent.setResult(res);
     }
   }
 }
 /**
  * The method returns the argument value i.e. right hand branch of a general application node.
  *
  * @return the right hand branch as appropriate
  */
 @Override
 public RTValue getArgValue() {
   return result.getArgValue();
 }