src/main/java/org/mvel2/compiler/AbstractParser.java
protected int arithmeticFunctionReduction(int operator) {
    ASTNode tk;
    int operator2;

    /**
     * If the next token is an operator, we check to see if it has a higher
     * precdence.
     */
    if ((tk = nextToken()) != null) {
      if (isArithmeticOperator(operator2 = tk.getOperator()) && PTABLE[operator2] > PTABLE[operator]) {
        stk.xswap();
        /**
         * The current arith. operator is of higher precedence the last.
         */

        tk = nextToken();

        /**
         * Check to see if we're compiling or executing interpretively.  If we're compiling, we really
         * need to stop if this is not a literal.
         */
        if (compileMode && !tk.isLiteral()) {
          splitAccumulator.push(tk, new OperatorNode(operator2, expr, st, pCtx));
          return OP_OVERFLOW;
        }

        dStack.push(operator = operator2, tk.getReducedValue(ctx, ctx, variableFactory));

        while (true) {
          ASTNode previousToken = tk;
          // look ahead again
          if ((tk = nextToken()) != null && (operator2 = tk.getOperator()) != -1
              && operator2 != END_OF_STMT && PTABLE[operator2] > PTABLE[operator]) {
            // if we have back to back operations on the stack, we don't xswap

            if (dStack.isReduceable()) {
              stk.copyx2(dStack);
            }

            /**
             * This operator is of higher precedence, or the same level precedence.  push to the RHS.
             */
            ASTNode nextToken = nextToken();
            if (compileMode && !nextToken.isLiteral()) {
              splitAccumulator.push(nextToken, new OperatorNode(operator2, expr, st, pCtx));
              return OP_OVERFLOW;
            }
            dStack.push(operator = operator2, nextToken.getReducedValue(ctx, ctx, variableFactory));

            continue;
          }
          else if (tk != null && operator2 != -1 && operator2 != END_OF_STMT) {
            if (PTABLE[operator2] == PTABLE[operator]) {
              if (!dStack.isEmpty()) dreduce();
              else {
                while (stk.isReduceable()) {
                  stk.xswap_op();
                }
              }

              /**
               * This operator is of the same level precedence.  push to the RHS.
               */

              dStack.push(operator = operator2, nextToken().getReducedValue(ctx, ctx, variableFactory));

              continue;
            }
            else {
              /**
               * The operator doesn't have higher precedence. Therfore reduce the LHS.
               */
              while (dStack.size() > 1) {
                dreduce();
              }

              operator = tk.getOperator();
              // Reduce the lesser or equal precedence operations.
              while (stk.size() != 1 && stk.peek2() instanceof Integer &&
                  ((operator2 = (Integer) stk.peek2()) < PTABLE.length) &&
                  PTABLE[operator2] >= PTABLE[operator]) {
                stk.xswap_op();
              }
            }
          }
          else {
            /**
             * There are no more tokens.
             */

            if (dStack.size() > 1) {
              dreduce();
            }

            if (stk.isReduceable()) stk.xswap();

            break;
          }

          if ((tk = nextToken()) != null) {
            switch (operator) {
              case AND: {
                if (!(stk.peekBoolean())) return OP_TERMINATE;
                else {
                  splitAccumulator.add(tk);
                  return AND;
                }
              }
              case OR: {
                if ((stk.peekBoolean())) return OP_TERMINATE;
                else {
                  splitAccumulator.add(tk);
                  return OR;
                }
              }

              default:
                if (compileMode && !tk.isLiteral()) {
                  stk.push(operator, tk);
                  return OP_NOT_LITERAL;
                }
                stk.push(operator, tk.getReducedValue(ctx, ctx, variableFactory));
            }
          }
        }
      }
      else if (!tk.isOperator()) {
        throw new CompileException("unexpected token: " + tk.getName(), expr, st);
      }
      else {
        reduce();
        splitAccumulator.push(tk);
      }
    }

    // while any values remain on the stack
    // keep XSWAPing and reducing, until there is nothing left.
    if (stk.isReduceable()) {
      while (true) {
        reduce();
        if (stk.isReduceable()) {
          stk.xswap();
        }
        else {
          break;
        }
      }
    }

    return OP_RESET_FRAME;
  }
/**
   * Reduce the current operations on the stack.
   *
   * @param operator the operator
   * @return a stack control code
   */
Reduce the current operations on the stack.
@param operator the operator
@return a stack control code
Reduce the current operations on the stack . @param operator the operator @return a stack control code
protected int arithmeticFunctionReduction(int operator) {
    ASTNode tk;
    int operator2;
    /**
     * If the next token is an operator, we check to see if it has a higher
     * precdence.
     */
    if ((tk = nextToken()) != null) {
      if (isArithmeticOperator(operator2 = tk.getOperator()) && PTABLE[operator2] > PTABLE[operator]) {
        stk.xswap();
        /**
         * The current arith. operator is of higher precedence the last.
         */
        tk = nextToken();
        /**
         * Check to see if we're compiling or executing interpretively.  If we're compiling, we really
         * need to stop if this is not a literal.
         */
        if (compileMode && !tk.isLiteral()) {
          splitAccumulator.push(tk, new OperatorNode(operator2, expr, st, pCtx));
          return OP_OVERFLOW;
        }
        dStack.push(operator = operator2, tk.getReducedValue(ctx, ctx, variableFactory));
        while (true) {
          ASTNode previousToken = tk;
          if ((tk = nextToken()) != null && (operator2 = tk.getOperator()) != -1
              && operator2 != END_OF_STMT && PTABLE[operator2] > PTABLE[operator]) {
            if (dStack.isReduceable()) {
              stk.copyx2(dStack);
            }
            /**
             * This operator is of higher precedence, or the same level precedence.  push to the RHS.
             */
            ASTNode nextToken = nextToken();
            if (compileMode && !nextToken.isLiteral()) {
              splitAccumulator.push(nextToken, new OperatorNode(operator2, expr, st, pCtx));
              return OP_OVERFLOW;
            }
            dStack.push(operator = operator2, nextToken.getReducedValue(ctx, ctx, variableFactory));
            continue;
          }
          else if (tk != null && operator2 != -1 && operator2 != END_OF_STMT) {
            if (PTABLE[operator2] == PTABLE[operator]) {
              if (!dStack.isEmpty()) dreduce();
              else {
                while (stk.isReduceable()) {
                  stk.xswap_op();
                }
              }
              /**
               * This operator is of the same level precedence.  push to the RHS.
               */
              dStack.push(operator = operator2, nextToken().getReducedValue(ctx, ctx, variableFactory));
              continue;
            }
            else {
              /**
               * The operator doesn't have higher precedence. Therfore reduce the LHS.
               */
              while (dStack.size() > 1) {
                dreduce();
              }
              operator = tk.getOperator();
              while (stk.size() != 1 && stk.peek2() instanceof Integer &&
                  ((operator2 = (Integer) stk.peek2()) < PTABLE.length) &&
                  PTABLE[operator2] >= PTABLE[operator]) {
                stk.xswap_op();
              }
            }
          }
          else {
            /**
             * There are no more tokens.
             */
            if (dStack.size() > 1) {
              dreduce();
            }
            if (stk.isReduceable()) stk.xswap();
            break;
          }
          if ((tk = nextToken()) != null) {
            switch (operator) {
              case AND: {
                if (!(stk.peekBoolean())) return OP_TERMINATE;
                else {
                  splitAccumulator.add(tk);
                  return AND;
                }
              }
              case OR: {
                if ((stk.peekBoolean())) return OP_TERMINATE;
                else {
                  splitAccumulator.add(tk);
                  return OR;
                }
              }
              default:
                if (compileMode && !tk.isLiteral()) {
                  stk.push(operator, tk);
                  return OP_NOT_LITERAL;
                }
                stk.push(operator, tk.getReducedValue(ctx, ctx, variableFactory));
            }
          }
        }
      }
      else if (!tk.isOperator()) {
        throw new CompileException("unexpected token: " + tk.getName(), expr, st);
      }
      else {
        reduce();
        splitAccumulator.push(tk);
      }
    }
    if (stk.isReduceable()) {
      while (true) {
        reduce();
        if (stk.isReduceable()) {
          stk.xswap();
        }
        else {
          break;
        }
      }
    }
    return OP_RESET_FRAME;
  }
protected int arithmeticFunctionReduction ( int operator ) { ASTNode tk ; int operator2 ; /**
     * If the next token is an operator, we check to see if it has a higher
     * precdence.
     */ if ( ( tk = nextToken ( ) ) != null ) { if ( isArithmeticOperator ( operator2 = tk . getOperator ( ) ) && PTABLE [ operator2 ] > PTABLE [ operator ] ) { stk . xswap ( ) ; /**
         * The current arith. operator is of higher precedence the last.
         */ tk = nextToken ( ) ; /**
         * Check to see if we're compiling or executing interpretively.  If we're compiling, we really
         * need to stop if this is not a literal.
         */ if ( compileMode && ! tk . isLiteral ( ) ) { splitAccumulator . push ( tk , new OperatorNode ( operator2 , expr , st , pCtx ) ) ; return OP_OVERFLOW ; } dStack . push ( operator = operator2 , tk . getReducedValue ( ctx , ctx , variableFactory ) ) ; while ( true ) { ASTNode previousToken = tk ; if ( ( tk = nextToken ( ) ) != null && ( operator2 = tk . getOperator ( ) ) != - 1 && operator2 != END_OF_STMT && PTABLE [ operator2 ] > PTABLE [ operator ] ) { if ( dStack . isReduceable ( ) ) { stk . copyx2 ( dStack ) ; } /**
             * This operator is of higher precedence, or the same level precedence.  push to the RHS.
             */ ASTNode nextToken = nextToken ( ) ; if ( compileMode && ! nextToken . isLiteral ( ) ) { splitAccumulator . push ( nextToken , new OperatorNode ( operator2 , expr , st , pCtx ) ) ; return OP_OVERFLOW ; } dStack . push ( operator = operator2 , nextToken . getReducedValue ( ctx , ctx , variableFactory ) ) ; continue ; } else if ( tk != null && operator2 != - 1 && operator2 != END_OF_STMT ) { if ( PTABLE [ operator2 ] == PTABLE [ operator ] ) { if ( ! dStack . isEmpty ( ) ) dreduce ( ) ; else { while ( stk . isReduceable ( ) ) { stk . xswap_op ( ) ; } } /**
               * This operator is of the same level precedence.  push to the RHS.
               */ dStack . push ( operator = operator2 , nextToken ( ) . getReducedValue ( ctx , ctx , variableFactory ) ) ; continue ; } else { /**
               * The operator doesn't have higher precedence. Therfore reduce the LHS.
               */ while ( dStack . size ( ) > 1 ) { dreduce ( ) ; } operator = tk . getOperator ( ) ; while ( stk . size ( ) != 1 && stk . peek2 ( ) instanceof Integer && ( ( operator2 = ( Integer ) stk . peek2 ( ) ) < PTABLE . length ) && PTABLE [ operator2 ] >= PTABLE [ operator ] ) { stk . xswap_op ( ) ; } } } else { /**
             * There are no more tokens.
             */ if ( dStack . size ( ) > 1 ) { dreduce ( ) ; } if ( stk . isReduceable ( ) ) stk . xswap ( ) ; break ; } if ( ( tk = nextToken ( ) ) != null ) { switch ( operator ) { case AND : { if ( ! ( stk . peekBoolean ( ) ) ) return OP_TERMINATE ; else { splitAccumulator . add ( tk ) ; return AND ; } } case OR : { if ( ( stk . peekBoolean ( ) ) ) return OP_TERMINATE ; else { splitAccumulator . add ( tk ) ; return OR ; } } default : if ( compileMode && ! tk . isLiteral ( ) ) { stk . push ( operator , tk ) ; return OP_NOT_LITERAL ; } stk . push ( operator , tk . getReducedValue ( ctx , ctx , variableFactory ) ) ; } } } } else if ( ! tk . isOperator ( ) ) { throw new CompileException ( "unexpected token: " + tk . getName ( ) , expr , st ) ; } else { reduce ( ) ; splitAccumulator . push ( tk ) ; } } if ( stk . isReduceable ( ) ) { while ( true ) { reduce ( ) ; if ( stk . isReduceable ( ) ) { stk . xswap ( ) ; } else { break ; } } } return OP_RESET_FRAME ; }
Reduce the current operations on the stack.
Reduce the current operations on the stack .
// look ahead again // if we have back to back operations on the stack, we don't xswap // Reduce the lesser or equal precedence operations. // while any values remain on the stack // keep XSWAPing and reducing, until there is nothing left.