MtasFunctionParserFunctionBasic.java

  1. package mtas.parser.function.util;

  2. import java.io.IOException;
  3. import java.util.ArrayList;

  4. import mtas.codec.util.CodecUtil;
  5. import mtas.parser.function.ParseException;

  6. /**
  7.  * The Class MtasFunctionParserFunctionBasic.
  8.  */
  9. public class MtasFunctionParserFunctionBasic
  10.     extends MtasFunctionParserFunction {

  11.   /** The first type. */
  12.   private String firstType;

  13.   /** The first id. */
  14.   private int firstId;

  15.   /** The tmp parser longs. */
  16.   private ArrayList<MtasFunctionParserFunction> tmpParserLongs = new ArrayList<>();

  17.   /** The tmp parser doubles. */
  18.   private ArrayList<MtasFunctionParserFunction> tmpParserDoubles = new ArrayList<>();

  19.   /** The tmp constant longs. */
  20.   private ArrayList<Long> tmpConstantLongs = new ArrayList<>();

  21.   /** The tmp constant doubles. */
  22.   private ArrayList<Double> tmpConstantDoubles = new ArrayList<>();

  23.   /** The number. */
  24.   private int number;

  25.   /** The operator list. */
  26.   private String[] operatorList;

  27.   /** The type list. */
  28.   private String[] typeList;

  29.   /** The id list. */
  30.   private int[] idList;

  31.   /** The tmp operator list. */
  32.   private ArrayList<String> tmpOperatorList = new ArrayList<>();

  33.   /** The tmp type list. */
  34.   private ArrayList<String> tmpTypeList = new ArrayList<>();

  35.   /** The tmp id list. */
  36.   private ArrayList<Integer> tmpIdList = new ArrayList<>();

  37.   /** The Constant BASIC_OPERATOR_ADD. */
  38.   public static final String BASIC_OPERATOR_ADD = "add";

  39.   /** The Constant BASIC_OPERATOR_SUBTRACT. */
  40.   public static final String BASIC_OPERATOR_SUBTRACT = "subtract";

  41.   /** The Constant BASIC_OPERATOR_MULTIPLY. */
  42.   public static final String BASIC_OPERATOR_MULTIPLY = "multiply";

  43.   /** The Constant BASIC_OPERATOR_DIVIDE. */
  44.   public static final String BASIC_OPERATOR_DIVIDE = "divide";

  45.   /** The Constant BASIC_OPERATOR_POWER. */
  46.   public static final String BASIC_OPERATOR_POWER = "power";

  47.   /**
  48.    * Instantiates a new mtas function parser function basic.
  49.    *
  50.    * @param item the item
  51.    * @throws ParseException the parse exception
  52.    */
  53.   public MtasFunctionParserFunctionBasic(MtasFunctionParserItem item)
  54.       throws ParseException {
  55.     sumRule = true;
  56.     String type = item.getType();
  57.     MtasFunctionParserFunction parser;
  58.     firstType = type;
  59.     degree = item.getDegree();
  60.     switch (type) {
  61.     case MtasFunctionParserItem.TYPE_N:
  62.       firstId = 0;
  63.       dataType = CodecUtil.DATA_TYPE_LONG;
  64.       needPositions = true;
  65.       break;
  66.     case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  67.       firstId = tmpConstantLongs.size();
  68.       dataType = CodecUtil.DATA_TYPE_LONG;
  69.       tmpConstantLongs.add(item.getValueLong());
  70.       break;
  71.     case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  72.       firstId = tmpConstantDoubles.size();
  73.       dataType = CodecUtil.DATA_TYPE_DOUBLE;
  74.       tmpConstantDoubles.add(item.getValueDouble());
  75.       break;
  76.     case MtasFunctionParserItem.TYPE_ARGUMENT:
  77.       firstType = type;
  78.       firstId = item.getId();
  79.       dataType = CodecUtil.DATA_TYPE_LONG;
  80.       needArgument.add(item.getId());
  81.       break;
  82.     case MtasFunctionParserItem.TYPE_PARSER_LONG:
  83.       parser = item.getParser();
  84.       parser.close();
  85.       if (parser.getType().equals(CodecUtil.DATA_TYPE_LONG)) {
  86.         firstId = tmpParserLongs.size();
  87.         tmpParserLongs.add(parser);
  88.         sumRule = parser.sumRule();
  89.         dataType = CodecUtil.DATA_TYPE_LONG;
  90.         needPositions = needPositions ? needPositions : parser.needPositions();
  91.         needArgument.addAll(parser.needArgument);
  92.       } else {
  93.         throw new ParseException("incorrect dataType");
  94.       }
  95.       break;
  96.     case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  97.       parser = item.getParser();
  98.       parser.close();
  99.       if (parser.getType().equals(CodecUtil.DATA_TYPE_DOUBLE)) {
  100.         firstId = tmpParserDoubles.size();
  101.         tmpParserDoubles.add(parser);
  102.         sumRule = parser.sumRule();
  103.         dataType = CodecUtil.DATA_TYPE_DOUBLE;
  104.         needPositions = needPositions ? needPositions : parser.needPositions();
  105.         needArgument.addAll(parser.needArgument);
  106.       } else {
  107.         throw new ParseException("incorrect dataType");
  108.       }
  109.       break;
  110.     default:
  111.       throw new ParseException("unknown type");
  112.     }
  113.   }

  114.   /*
  115.    * (non-Javadoc)
  116.    *
  117.    * @see mtas.parser.function.util.MtasFunctionParserFunction#close()
  118.    */
  119.   @Override
  120.   public void close() throws ParseException {
  121.     if (!defined()) {
  122.       super.close();
  123.       if (!tmpParserLongs.isEmpty()) {
  124.         parserLongs = new MtasFunctionParserFunction[tmpParserLongs.size()];
  125.         parserLongs = tmpParserLongs.toArray(parserLongs);
  126.       }
  127.       if (!tmpParserDoubles.isEmpty()) {
  128.         parserDoubles = new MtasFunctionParserFunction[tmpParserDoubles.size()];
  129.         parserDoubles = tmpParserDoubles.toArray(parserDoubles);
  130.       }
  131.       if (!tmpConstantLongs.isEmpty()) {
  132.         constantLongs = new long[tmpConstantLongs.size()];
  133.         for (int i = 0; i < tmpConstantLongs.size(); i++) {
  134.           constantLongs[i] = tmpConstantLongs.get(i);
  135.         }
  136.       }
  137.       if (!tmpConstantDoubles.isEmpty()) {
  138.         constantDoubles = new Double[tmpConstantDoubles.size()];
  139.         for (int i = 0; i < tmpConstantDoubles.size(); i++) {
  140.           constantDoubles[i] = tmpConstantDoubles.get(i);
  141.         }
  142.       }
  143.       if (firstType == null) {
  144.         throw new ParseException("incorrect definition: no firstType");
  145.       }
  146.       if (!tmpOperatorList.isEmpty()) {
  147.         number = tmpOperatorList.size();
  148.         if ((tmpTypeList.size() != number) || (tmpIdList.size() != number)) {
  149.           throw new ParseException("incorrect definition additional items");
  150.         } else {
  151.           operatorList = new String[number];
  152.           operatorList = tmpOperatorList.toArray(operatorList);
  153.           typeList = new String[number];
  154.           typeList = tmpTypeList.toArray(typeList);
  155.           idList = new int[number];
  156.           for (int i = 0; i < number; i++) {
  157.             idList[i] = tmpIdList.get(i).intValue();
  158.           }
  159.         }
  160.       } else {
  161.         number = 0;
  162.         operatorList = null;
  163.         typeList = null;
  164.         idList = null;
  165.       }
  166.     }
  167.   }

  168.   /**
  169.    * Adds the.
  170.    *
  171.    * @param item the item
  172.    * @throws ParseException the parse exception
  173.    */
  174.   public void add(MtasFunctionParserItem item) throws ParseException {
  175.     basic(BASIC_OPERATOR_ADD, item);
  176.   }

  177.   /**
  178.    * Subtract.
  179.    *
  180.    * @param item the item
  181.    * @throws ParseException the parse exception
  182.    */
  183.   public void subtract(MtasFunctionParserItem item) throws ParseException {
  184.     basic(BASIC_OPERATOR_SUBTRACT, item);
  185.   }

  186.   /**
  187.    * Multiply.
  188.    *
  189.    * @param item the item
  190.    * @throws ParseException the parse exception
  191.    */
  192.   public void multiply(MtasFunctionParserItem item) throws ParseException {
  193.     basic(BASIC_OPERATOR_MULTIPLY, item);
  194.   }

  195.   /**
  196.    * Divide.
  197.    *
  198.    * @param item the item
  199.    * @throws ParseException the parse exception
  200.    */
  201.   public void divide(MtasFunctionParserItem item) throws ParseException {
  202.     basic(BASIC_OPERATOR_DIVIDE, item);
  203.   }

  204.   /**
  205.    * Power.
  206.    *
  207.    * @param item the item
  208.    * @throws ParseException the parse exception
  209.    */
  210.   public void power(MtasFunctionParserItem item) throws ParseException {
  211.     basic(BASIC_OPERATOR_POWER, item);
  212.   }

  213.   /**
  214.    * Basic.
  215.    *
  216.    * @param operator the operator
  217.    * @param item the item
  218.    * @throws ParseException the parse exception
  219.    */
  220.   private void basic(String operator, MtasFunctionParserItem item)
  221.       throws ParseException {
  222.     if (!defined()) {
  223.       String type = item.getType();
  224.       MtasFunctionParserFunction parser;
  225.       tmpOperatorList.add(operator);
  226.       if (operator.equals(BASIC_OPERATOR_DIVIDE)) {
  227.         dataType = CodecUtil.DATA_TYPE_DOUBLE;
  228.       }
  229.       switch (type) {
  230.       case MtasFunctionParserItem.TYPE_N:
  231.         tmpTypeList.add(type);
  232.         tmpIdList.add(0);
  233.         needPositions = true;
  234.         if (sumRule && degree != null) {
  235.           if (operator.equals(BASIC_OPERATOR_ADD)
  236.               || operator.equals(BASIC_OPERATOR_SUBTRACT)) {
  237.             if (degree < 0) {
  238.               sumRule = false;
  239.               degree = null;
  240.             } else if (degree > 0) {
  241.               sumRule = false;
  242.             }
  243.           } else if (operator.equals(BASIC_OPERATOR_POWER) && (degree != 0)) {
  244.             sumRule = false;
  245.             degree = null;
  246.           }
  247.         }
  248.         break;
  249.       case MtasFunctionParserItem.TYPE_ARGUMENT:
  250.         tmpTypeList.add(type);
  251.         tmpIdList.add(item.getId());
  252.         needArgument.add(item.getId());
  253.         if (sumRule && degree != null) {
  254.           if (operator.equals(BASIC_OPERATOR_ADD)
  255.               || operator.equals(BASIC_OPERATOR_SUBTRACT)) {
  256.             if (degree != 1) {
  257.               sumRule = false;
  258.             }
  259.             if (degree >= 0) {
  260.               degree = Math.max(degree, 1);
  261.             } else {
  262.               degree = null;
  263.             }
  264.           } else if (operator.equals(BASIC_OPERATOR_MULTIPLY)) {
  265.             if (degree != 0) {
  266.               sumRule = false;
  267.             }
  268.             degree += 1;
  269.           } else if (operator.equals(BASIC_OPERATOR_DIVIDE)) {
  270.             sumRule = false;
  271.             degree -= 1;
  272.           } else if (operator.equals(BASIC_OPERATOR_POWER)) {
  273.             sumRule = false;
  274.             degree = null;
  275.           }
  276.         }
  277.         break;
  278.       case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  279.         tmpTypeList.add(type);
  280.         tmpIdList.add(tmpConstantLongs.size());
  281.         tmpConstantLongs.add(item.getValueLong());
  282.         if (sumRule && degree != null) {
  283.           if (operator.equals(BASIC_OPERATOR_ADD)
  284.               || operator.equals(BASIC_OPERATOR_SUBTRACT)) {
  285.             if (degree < 0) {
  286.               sumRule = false;
  287.               degree = null;
  288.             } else if (degree > 0) {
  289.               sumRule = false;
  290.             }
  291.           } else if (operator.equals(BASIC_OPERATOR_POWER) && (degree != 0)) {
  292.             sumRule = false;
  293.             degree = null;
  294.           }
  295.         }
  296.         break;
  297.       case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  298.         tmpTypeList.add(type);
  299.         tmpIdList.add(tmpConstantDoubles.size());
  300.         dataType = CodecUtil.DATA_TYPE_DOUBLE;
  301.         tmpConstantDoubles.add(item.getValueDouble());
  302.         if (sumRule && degree != null) {
  303.           if (operator.equals(BASIC_OPERATOR_ADD)
  304.               || operator.equals(BASIC_OPERATOR_SUBTRACT)) {
  305.             if (degree < 0) {
  306.               sumRule = false;
  307.               degree = null;
  308.             } else if (degree > 0) {
  309.               sumRule = false;
  310.             }
  311.           } else if (operator.equals(BASIC_OPERATOR_POWER) && (degree != 0)) {
  312.             sumRule = false;
  313.             degree = null;
  314.           }
  315.         }
  316.         break;
  317.       case MtasFunctionParserItem.TYPE_PARSER_LONG:
  318.         tmpTypeList.add(type);
  319.         tmpIdList.add(tmpParserLongs.size());
  320.         parser = item.getParser();
  321.         parser.close();
  322.         tmpParserLongs.add(parser);
  323.         sumRule = sumRule ? parser.sumRule() : false;
  324.         needPositions = needPositions ? needPositions : parser.needPositions();
  325.         needArgument.addAll(parser.needArgument);
  326.         if (sumRule && degree != null) {
  327.           if (operator.equals(BASIC_OPERATOR_ADD)
  328.               || operator.equals(BASIC_OPERATOR_SUBTRACT)) {
  329.             if (!parser.degree.equals(degree)) {
  330.               sumRule = false;
  331.               if (degree < 0) {
  332.                 degree = null;
  333.               } else {
  334.                 degree = Math.max(degree, parser.degree);
  335.               }
  336.             }
  337.           } else if (operator.equals(BASIC_OPERATOR_MULTIPLY)) {
  338.             if (degree != 0 || parser.degree != 0) {
  339.               sumRule = false;
  340.             }
  341.             degree += parser.degree;
  342.           } else if (operator.equals(BASIC_OPERATOR_POWER) && (degree != 0)) {
  343.             sumRule = false;
  344.             degree = null;
  345.           }
  346.         }
  347.         break;
  348.       case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  349.         tmpTypeList.add(type);
  350.         tmpIdList.add(tmpParserDoubles.size());
  351.         dataType = CodecUtil.DATA_TYPE_DOUBLE;
  352.         parser = item.getParser();
  353.         parser.close();
  354.         tmpParserDoubles.add(parser);
  355.         sumRule = sumRule ? parser.sumRule() : false;
  356.         needPositions = needPositions ? needPositions : parser.needPositions();
  357.         needArgument.addAll(parser.needArgument);
  358.         if (sumRule && degree != null) {
  359.           if (operator.equals(BASIC_OPERATOR_ADD)
  360.               || operator.equals(BASIC_OPERATOR_SUBTRACT)) {
  361.             if (!parser.degree.equals(degree)) {
  362.               sumRule = false;
  363.               if (degree < 0) {
  364.                 degree = null;
  365.               } else {
  366.                 degree = Math.max(degree, parser.degree);
  367.               }
  368.             }
  369.           } else if (operator.equals(BASIC_OPERATOR_MULTIPLY)) {
  370.             if (degree != 0 || parser.degree != 0) {
  371.               sumRule = false;
  372.             }
  373.             degree += parser.degree;
  374.           } else if (operator.equals(BASIC_OPERATOR_POWER) && (degree != 0)) {
  375.             sumRule = false;
  376.             degree = null;
  377.           }
  378.         }
  379.         break;
  380.       default:
  381.         throw new ParseException("incorrect type");
  382.       }
  383.     } else {
  384.       throw new ParseException("already defined");
  385.     }
  386.   }

  387.   /*
  388.    * (non-Javadoc)
  389.    *
  390.    * @see
  391.    * mtas.parser.function.util.MtasFunctionParserFunction#getValueDouble(long[],
  392.    * long)
  393.    */
  394.   @Override
  395.   public double getValueDouble(long[] args, long n) throws IOException {
  396.     double sum;
  397.     switch (firstType) {
  398.     case MtasFunctionParserItem.TYPE_ARGUMENT:
  399.       sum = args[firstId];
  400.       break;
  401.     case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  402.       sum = parserDoubles[firstId].getValueDouble(args, n);
  403.       break;
  404.     case MtasFunctionParserItem.TYPE_PARSER_LONG:
  405.       sum = parserLongs[firstId].getValueLong(args, n);
  406.       break;
  407.     case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  408.       sum = constantDoubles[firstId];
  409.       break;
  410.     case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  411.       sum = constantLongs[firstId];
  412.       break;
  413.     case MtasFunctionParserItem.TYPE_N:
  414.       sum = n;
  415.       break;
  416.     default:
  417.       throw new IOException("no first value");
  418.     }
  419.     for (int i = 0; i < number; i++) {
  420.       switch (operatorList[i]) {
  421.       case BASIC_OPERATOR_ADD:
  422.         switch (typeList[i]) {
  423.         case MtasFunctionParserItem.TYPE_ARGUMENT:
  424.           sum += args[idList[i]];
  425.           break;
  426.         case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  427.           sum += parserDoubles[idList[i]].getValueDouble(args, n);
  428.           break;
  429.         case MtasFunctionParserItem.TYPE_PARSER_LONG:
  430.           sum += parserLongs[idList[i]].getValueLong(args, n);
  431.           break;
  432.         case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  433.           sum += constantDoubles[idList[i]];
  434.           break;
  435.         case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  436.           sum += constantLongs[idList[i]];
  437.           break;
  438.         case MtasFunctionParserItem.TYPE_N:
  439.           sum += n;
  440.           break;
  441.         default:
  442.           throw new IOException("unknown type");
  443.         }
  444.         break;
  445.       case BASIC_OPERATOR_SUBTRACT:
  446.         switch (typeList[i]) {
  447.         case MtasFunctionParserItem.TYPE_ARGUMENT:
  448.           sum -= args[idList[i]];
  449.           break;
  450.         case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  451.           sum -= parserDoubles[idList[i]].getValueDouble(args, n);
  452.           break;
  453.         case MtasFunctionParserItem.TYPE_PARSER_LONG:
  454.           sum -= parserLongs[idList[i]].getValueLong(args, n);
  455.           break;
  456.         case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  457.           sum -= constantDoubles[idList[i]];
  458.           break;
  459.         case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  460.           sum -= constantLongs[idList[i]];
  461.           break;
  462.         case MtasFunctionParserItem.TYPE_N:
  463.           sum -= n;
  464.           break;
  465.         default:
  466.           throw new IOException("unknown type");
  467.         }
  468.         break;
  469.       case BASIC_OPERATOR_MULTIPLY:
  470.         switch (typeList[i]) {
  471.         case MtasFunctionParserItem.TYPE_ARGUMENT:
  472.           sum *= args[idList[i]];
  473.           break;
  474.         case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  475.           sum *= parserDoubles[idList[i]].getValueDouble(args, n);
  476.           break;
  477.         case MtasFunctionParserItem.TYPE_PARSER_LONG:
  478.           sum *= parserLongs[idList[i]].getValueLong(args, n);
  479.           break;
  480.         case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  481.           sum *= constantDoubles[idList[i]];
  482.           break;
  483.         case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  484.           sum *= constantLongs[idList[i]];
  485.           break;
  486.         case MtasFunctionParserItem.TYPE_N:
  487.           sum *= n;
  488.           break;
  489.         default:
  490.           throw new IOException("unknown type");
  491.         }
  492.         break;
  493.       case BASIC_OPERATOR_DIVIDE:
  494.         double v;
  495.         switch (typeList[i]) {
  496.         case MtasFunctionParserItem.TYPE_ARGUMENT:
  497.           v = args[idList[i]];
  498.           break;
  499.         case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  500.           v = parserDoubles[idList[i]].getValueDouble(args, n);
  501.           break;
  502.         case MtasFunctionParserItem.TYPE_PARSER_LONG:
  503.           v = parserLongs[idList[i]].getValueLong(args, n);
  504.           break;
  505.         case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  506.           v = constantDoubles[idList[i]];
  507.           break;
  508.         case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  509.           v = constantLongs[idList[i]];
  510.           break;
  511.         case MtasFunctionParserItem.TYPE_N:
  512.           v = n;
  513.           break;
  514.         default:
  515.           throw new IOException("unknown type");
  516.         }
  517.         if (v != 0) {
  518.           sum /= v;
  519.         } else {
  520.           throw new IOException("division by zero");
  521.         }
  522.         break;
  523.       case BASIC_OPERATOR_POWER:
  524.         switch (typeList[i]) {
  525.         case MtasFunctionParserItem.TYPE_ARGUMENT:
  526.           sum = Math.pow(sum, args[idList[i]]);
  527.           break;
  528.         case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  529.           sum = Math.pow(sum, parserDoubles[idList[i]].getValueDouble(args, n));
  530.           break;
  531.         case MtasFunctionParserItem.TYPE_PARSER_LONG:
  532.           sum = Math.pow(sum, parserLongs[idList[i]].getValueLong(args, n));
  533.           break;
  534.         case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  535.           sum = Math.pow(sum, constantDoubles[idList[i]]);
  536.           break;
  537.         case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  538.           sum = Math.pow(sum, constantLongs[idList[i]]);
  539.           break;
  540.         case MtasFunctionParserItem.TYPE_N:
  541.           sum = Math.pow(sum, n);
  542.           break;
  543.         default:
  544.           throw new IOException("unknown type");
  545.         }
  546.         break;
  547.       default:
  548.         throw new IOException("unknown operator");
  549.       }
  550.     }
  551.     return sum;
  552.   }

  553.   /*
  554.    * (non-Javadoc)
  555.    *
  556.    * @see
  557.    * mtas.parser.function.util.MtasFunctionParserFunction#getValueLong(long[],
  558.    * long)
  559.    */
  560.   @Override
  561.   public long getValueLong(long[] args, long n) throws IOException {
  562.     try {
  563.       long sum;
  564.       switch (firstType) {
  565.       case MtasFunctionParserItem.TYPE_ARGUMENT:
  566.         sum = args[firstId];
  567.         break;
  568.       case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  569.         sum = (long) parserDoubles[firstId].getValueDouble(args, n);
  570.         break;
  571.       case MtasFunctionParserItem.TYPE_PARSER_LONG:
  572.         sum = parserLongs[firstId].getValueLong(args, n);
  573.         break;
  574.       case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  575.         sum = constantDoubles[firstId].longValue();
  576.         break;
  577.       case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  578.         sum = constantLongs[firstId];
  579.         break;
  580.       case MtasFunctionParserItem.TYPE_N:
  581.         sum = n;
  582.         break;
  583.       default:
  584.         throw new IOException("no first value");
  585.       }
  586.       for (int i = 0; i < number; i++) {
  587.         switch (operatorList[i]) {
  588.         case BASIC_OPERATOR_ADD:
  589.           switch (typeList[i]) {
  590.           case MtasFunctionParserItem.TYPE_ARGUMENT:
  591.             sum += args[idList[i]];
  592.             break;
  593.           case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  594.             sum += (long) parserDoubles[idList[i]].getValueDouble(args, n);
  595.             break;
  596.           case MtasFunctionParserItem.TYPE_PARSER_LONG:
  597.             sum += parserLongs[idList[i]].getValueLong(args, n);
  598.             break;
  599.           case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  600.             sum += constantDoubles[idList[i]].longValue();
  601.             break;
  602.           case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  603.             sum += constantLongs[idList[i]];
  604.             break;
  605.           case MtasFunctionParserItem.TYPE_N:
  606.             sum += n;
  607.             break;
  608.           default:
  609.             throw new IOException("unknown type");
  610.           }
  611.           break;
  612.         case BASIC_OPERATOR_SUBTRACT:
  613.           switch (typeList[i]) {
  614.           case MtasFunctionParserItem.TYPE_ARGUMENT:
  615.             sum -= args[idList[i]];
  616.             break;
  617.           case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  618.             sum -= (long) parserDoubles[idList[i]].getValueDouble(args, n);
  619.             break;
  620.           case MtasFunctionParserItem.TYPE_PARSER_LONG:
  621.             sum -= parserLongs[idList[i]].getValueLong(args, n);
  622.             break;
  623.           case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  624.             sum -= constantDoubles[idList[i]].longValue();
  625.             break;
  626.           case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  627.             sum -= constantLongs[idList[i]];
  628.             break;
  629.           case MtasFunctionParserItem.TYPE_N:
  630.             sum -= n;
  631.             break;
  632.           default:
  633.             throw new IOException("unknown type");
  634.           }
  635.           break;
  636.         case BASIC_OPERATOR_MULTIPLY:
  637.           switch (typeList[i]) {
  638.           case MtasFunctionParserItem.TYPE_ARGUMENT:
  639.             sum *= args[idList[i]];
  640.             break;
  641.           case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  642.             sum *= (long) parserDoubles[idList[i]].getValueDouble(args, n);
  643.             break;
  644.           case MtasFunctionParserItem.TYPE_PARSER_LONG:
  645.             sum *= parserLongs[idList[i]].getValueLong(args, n);
  646.             break;
  647.           case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  648.             sum *= constantDoubles[idList[i]].longValue();
  649.             break;
  650.           case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  651.             sum *= constantLongs[idList[i]];
  652.             break;
  653.           case MtasFunctionParserItem.TYPE_N:
  654.             sum *= n;
  655.             break;
  656.           default:
  657.             throw new IOException("unknown type");
  658.           }
  659.           break;
  660.         case BASIC_OPERATOR_DIVIDE:
  661.           long v;
  662.           switch (typeList[i]) {
  663.           case MtasFunctionParserItem.TYPE_ARGUMENT:
  664.             v = args[idList[i]];
  665.             break;
  666.           case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  667.             v = (long) parserDoubles[idList[i]].getValueDouble(args, n);
  668.             break;
  669.           case MtasFunctionParserItem.TYPE_PARSER_LONG:
  670.             v = parserLongs[idList[i]].getValueLong(args, n);
  671.             break;
  672.           case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  673.             v = constantDoubles[idList[i]].longValue();
  674.             break;
  675.           case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  676.             v = constantLongs[idList[i]];
  677.             break;
  678.           case MtasFunctionParserItem.TYPE_N:
  679.             v = n;
  680.             break;
  681.           default:
  682.             throw new IOException("unknown type");
  683.           }
  684.           if (v != 0) {
  685.             sum /= v;
  686.           } else {
  687.             throw new IOException("division by zero");
  688.           }
  689.           break;
  690.         case BASIC_OPERATOR_POWER:
  691.           switch (typeList[i]) {
  692.           case MtasFunctionParserItem.TYPE_ARGUMENT:
  693.             sum = sum ^ args[idList[i]];
  694.             break;
  695.           case MtasFunctionParserItem.TYPE_PARSER_DOUBLE:
  696.             sum = sum ^ (long) parserDoubles[idList[i]].getValueDouble(args, n);
  697.             break;
  698.           case MtasFunctionParserItem.TYPE_PARSER_LONG:
  699.             sum = sum ^ parserLongs[idList[i]].getValueLong(args, n);
  700.             break;
  701.           case MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE:
  702.             sum = sum ^ constantDoubles[idList[i]].longValue();
  703.             break;
  704.           case MtasFunctionParserItem.TYPE_CONSTANT_LONG:
  705.             sum = sum ^ constantLongs[idList[i]];
  706.             break;
  707.           case MtasFunctionParserItem.TYPE_N:
  708.             sum = sum ^ n;
  709.             break;
  710.           default:
  711.             throw new IOException("unknown type");
  712.           }
  713.           break;
  714.         default:
  715.           throw new IOException("unknown operator");
  716.         }
  717.       }
  718.       return sum;
  719.     } catch (java.lang.ArithmeticException e) {
  720.       throw new IOException(e);
  721.     }
  722.   }

  723.   /*
  724.    * (non-Javadoc)
  725.    *
  726.    * @see java.lang.Object#toString()
  727.    */
  728.   @Override
  729.   public String toString() {
  730.     if (firstType != null) {
  731.       StringBuilder text = new StringBuilder(toString(firstType, firstId));
  732.       for (int i = 0; i < tmpOperatorList.size(); i++) {
  733.         String operator = tmpOperatorList.get(i);
  734.         if (operator.equals(BASIC_OPERATOR_ADD)) {
  735.           text.append(" + ");
  736.         } else if (operator.equals(BASIC_OPERATOR_SUBTRACT)) {
  737.           text.append(" - ");
  738.         } else if (operator.equals(BASIC_OPERATOR_MULTIPLY)) {
  739.           text.append(" * ");
  740.         } else if (operator.equals(BASIC_OPERATOR_DIVIDE)) {
  741.           text.append(" / ");
  742.         } else if (operator.equals(BASIC_OPERATOR_POWER)) {
  743.           text.append(" ^ ");
  744.         } else {
  745.           text.append(" ? ");
  746.         }
  747.         text.append(toString(tmpTypeList.get(i), tmpIdList.get(i)));
  748.       }
  749.       return text.toString();
  750.     } else {
  751.       return "?";
  752.     }
  753.   }

  754.   /**
  755.    * To string.
  756.    *
  757.    * @param type the type
  758.    * @param id the id
  759.    * @return the string
  760.    */
  761.   private String toString(String type, int id) {
  762.     if (type.equals(MtasFunctionParserItem.TYPE_CONSTANT_LONG)) {
  763.       return tmpConstantLongs.get(id).toString();
  764.     } else if (type.equals(MtasFunctionParserItem.TYPE_CONSTANT_DOUBLE)) {
  765.       return tmpConstantDoubles.get(id).toString();
  766.     } else if (type.equals(MtasFunctionParserItem.TYPE_PARSER_LONG)) {
  767.       return "(" + tmpParserLongs.get(id).toString() + ")";
  768.     } else if (type.equals(MtasFunctionParserItem.TYPE_PARSER_DOUBLE)) {
  769.       return "(" + tmpParserDoubles.get(id).toString() + ")";
  770.     } else if (type.equals(MtasFunctionParserItem.TYPE_ARGUMENT)) {
  771.       return "$q" + id;
  772.     } else if (type.equals(MtasFunctionParserItem.TYPE_N)) {
  773.       return "$n";
  774.     } else {
  775.       return "..";
  776.     }
  777.   }

  778. }