Пример #1
0
        /// <summary>
        /// Decode the token, is it an operator??
        /// Depending of the language, get the right operator.
        /// can be:
        ///     Logical, comparison, calculation or a setValue.
        /// </summary>
        /// <param name="token"></param>
        private bool DecodeTokenOperator(Stack <ExpressionBase> stack, ExprToken token)
        {
            //----is it a comparison operator?
            if (_exprEvalConfig.DictComparisonOperators.ContainsKey(token.Value.ToLower()))
            {
                OperatorComparisonCode operComp = _exprEvalConfig.DictComparisonOperators[token.Value.ToLower()];

                // empile le token opérateur
                ExprOperatorComparison exprOperatorComparison = new ExprOperatorComparison();
                exprOperatorComparison.Operator = operComp;
                exprOperatorComparison.Token    = token;
                stack.Push(exprOperatorComparison);
                return(true);
            }

            // is it a logical operator?
            if (_exprEvalConfig.DictLogicalOperators.ContainsKey(token.Value.ToLower()))
            {
                OperatorLogicalCode operLogical = _exprEvalConfig.DictLogicalOperators[token.Value.ToLower()];

                // is it the NOT operator?
                if (operLogical == OperatorLogicalCode.Not)
                {
                    // empile le token opérateur
                    ExprOperatorLogicalNot exprOperatorLogicalNot = new ExprOperatorLogicalNot();
                    exprOperatorLogicalNot.Token = token;
                    stack.Push(exprOperatorLogicalNot);
                    return(true);
                }

                // empile le token opérateur
                ExprOperatorLogical exprOperatorLogical = new ExprOperatorLogical();
                exprOperatorLogical.Operator = operLogical;
                exprOperatorLogical.Token    = token;
                stack.Push(exprOperatorLogical);
                return(true);
            }

            // is it a calculation operator?
            if (_exprEvalConfig.DictCalculationOperators.ContainsKey(token.Value.ToLower()))
            {
                OperatorCalculationCode operCalc = _exprEvalConfig.DictCalculationOperators[token.Value.ToLower()];

                // empile le token opérateur
                ExprOperatorCalculation exprOperatorCalc = new ExprOperatorCalculation();
                exprOperatorCalc.Operator = operCalc;
                exprOperatorCalc.Token    = token;
                stack.Push(exprOperatorCalc);
                return(true);
            }

            // the token is not an operator
            return(false);
        }
        /// <summary>
        /// Do the calculation of the multiplication/division expr comme l'add mais le rs va remplacer l'objet Mul dans le main add)
        ///
        /// </summary>
        /// <param name="execResult"></param>
        /// <param name="exprCalculation"></param>
        /// <param name="mainCalcAdd"></param>
        /// <param name="exprExecCalcResult"></param>
        /// <returns></returns>
        private bool DoCalculationExprMul(ExecResult execResult, ExprCalculation exprCalculation, ExprExecCalcMul execCalcMul, out ExprExecCalcValue execCalcValueResult)
        {
            // the temporary result, to start the addition calculation
            ExprExecValueInt resInt = new ExprExecValueInt();

            // the integer neutral value, the first calculation is 1*operand[0]
            resInt.Value = 1;
            ExpressionExecBase exprExecCalcResult = resInt;

            ExpressionExecBase exprExecTmpResult = null;
            int pos = 0;

            // scan addition expressions, two by two operands
            foreach (ExprExecCalcValue execCalcValue in execCalcMul.ListExprExecCalcValue)
            {
                // the item should be a number: an int or a double

                // get the operator
                ExprOperatorCalculation operatorCalc;

                // the first calc is special: res := 0 + firstOperand
                if (pos == 0)
                {
                    // put the default neutral operator: +
                    operatorCalc          = new ExprOperatorCalculation();
                    operatorCalc.Operator = OperatorCalculationCode.Multiplication;
                    //operatorCalc.Token = mainCalcAdd.ListOperator[0].Token;
                }
                else
                {
                    // there one operator less than operand
                    operatorCalc = execCalcMul.ListOperator[pos - 1];
                }

                // Do the calculation:   tmpRes := res +/- currentValue
                DoCalculationTwoOperands(execResult, exprCalculation, exprExecCalcResult, execCalcValue.ExprExecValue, operatorCalc, out exprExecTmpResult);

                // the current temporary result
                exprExecCalcResult = exprExecTmpResult;

                pos++;
            }

            // then replace the calc mul expr by the result
            execCalcValueResult = new ExprExecCalcValue();
            execCalcValueResult.ExprExecValue = exprExecTmpResult;
            //mainCalcAdd.ListExprExecCalc[posMulInMainAdd] = execCalcValueResult;

            return(true);
        }
        /// <summary>
        /// Execute/evaluate the addition main expression.
        /// </summary>
        /// <param name="execResult"></param>
        /// <param name="exprCalculation"></param>
        /// <param name="listCalcAdd"></param>
        /// <returns></returns>
        private bool DoCalculationMainExprAdditions(ExecResult execResult, ExprCalculation exprCalculation, ExprExecCalcAdd mainCalcAdd, out ExpressionExecBase exprExecCalcResult)
        {
            // the temporary result, to start the addition calculation
            ExprExecValueInt resInt = new ExprExecValueInt();

            // the integer neutral value, the first calculation is 0+operand[0]
            resInt.Value       = 0;
            exprExecCalcResult = resInt;

            ExpressionExecBase exprExecTmpResult;
            int pos = 0;

            // scan addition expressions, two by two operands
            foreach (ExprExecCalcBase execCalcBase in mainCalcAdd.ListExprExecCalc)
            {
                // the item should be a number: an int or a double
                ExprExecCalcValue execCalcValue = execCalcBase as ExprExecCalcValue;

                // get the operator
                ExprOperatorCalculation operatorCalc;

                // the first calc is special: res := 0 + firstOperand
                if (pos == 0)
                {
                    // put the default neutral operator: +
                    operatorCalc          = new ExprOperatorCalculation();
                    operatorCalc.Operator = OperatorCalculationCode.Plus;
                    if (mainCalcAdd.ListOperator.Count > 0)
                    {
                        operatorCalc.Token = mainCalcAdd.ListOperator[0].Token;
                    }
                }
                else
                {
                    // there one operator less than operand
                    operatorCalc = mainCalcAdd.ListOperator[pos - 1];
                }

                // Do the calculation:   tmpRes := res +/- currentValue
                DoCalculationTwoOperands(execResult, exprCalculation, exprExecCalcResult, execCalcValue.ExprExecValue, operatorCalc, out exprExecTmpResult);

                // the current temporary result
                exprExecCalcResult = exprExecTmpResult;

                pos++;
            }

            return(true);
        }
        /// <summary>
        /// Do the calculation: res := operandLeft operator operandRight.
        /// Both operand must be number, int or double.
        /// the operator can be: +, -, *, /.
        /// </summary>
        /// <param name="execResult"></param>
        /// <param name="exprExecBase"></param>
        /// <returns></returns>
        private bool DoCalculationTwoOperands(ExecResult execResult, ExprCalculation exprCalculation, ExpressionExecBase exprExecBaseLeft, ExpressionExecBase exprExecBaseRight, ExprOperatorCalculation operatorCalc, out ExpressionExecBase exprExecCalcResult)
        {
            exprExecCalcResult = null;

            CalcIntOrDouble calcIntOrDoubleLeft  = CalcIntOrDouble.NotDefined;
            CalcIntOrDouble calcIntOrDoubleRight = CalcIntOrDouble.NotDefined;

            int    valLeftInt     = 0;
            int    valRightInt    = 0;
            double valLeftDouble  = 0;
            double valRightDouble = 0;

            //---parse the left operand
            ExprExecValueInt exprExecValueLeftInt = exprExecBaseLeft as ExprExecValueInt;

            if (exprExecValueLeftInt != null)
            {
                valLeftInt          = exprExecValueLeftInt.Value;
                calcIntOrDoubleLeft = CalcIntOrDouble.IsInt;
            }
            else
            {
                ExprExecValueDouble exprExecValueLeftDouble = exprExecBaseLeft as ExprExecValueDouble;
                if (exprExecValueLeftDouble != null)
                {
                    valLeftDouble       = exprExecValueLeftDouble.Value;
                    calcIntOrDoubleLeft = CalcIntOrDouble.IsDouble;
                }
            }

            //---parse the right operand
            ExprExecValueInt exprExecValueRightInt = exprExecBaseRight as ExprExecValueInt;

            if (exprExecValueRightInt != null)
            {
                valRightInt          = exprExecValueRightInt.Value;
                calcIntOrDoubleRight = CalcIntOrDouble.IsInt;
            }
            else
            {
                ExprExecValueDouble exprExecValueRightDouble = exprExecBaseRight as ExprExecValueDouble;
                if (exprExecValueRightDouble != null)
                {
                    valRightDouble       = exprExecValueRightDouble.Value;
                    calcIntOrDoubleRight = CalcIntOrDouble.IsDouble;
                }
            }

            //----wrong type
            if (calcIntOrDoubleLeft == CalcIntOrDouble.NotDefined)
            {
                // other operators are not allowed on the boolean type (only bool)
                execResult.AddErrorExec(ErrorCode.ExprCalculationOperandTypeUnExcepted, "Position", exprExecBaseLeft.Expr.Token.Position.ToString(), "Operand", exprExecBaseLeft.Expr.Token.Value);

                return(false);
            }
            if (calcIntOrDoubleRight == CalcIntOrDouble.NotDefined)
            {
                // other operators are not allowed on the boolean type (only bool)
                execResult.AddErrorExec(ErrorCode.ExprCalculationOperandTypeUnExcepted, "Position", exprExecBaseRight.Expr.Token.Position.ToString(), "Operand", exprExecBaseRight.Expr.Token.Value);

                return(false);
            }

            // if one of both operand is an double, convert the other to a double
            if (calcIntOrDoubleLeft == CalcIntOrDouble.IsDouble || calcIntOrDoubleRight == CalcIntOrDouble.IsDouble)
            {
                if (calcIntOrDoubleLeft == CalcIntOrDouble.IsInt)
                {
                    valLeftDouble = (double)valLeftInt;
                }

                if (calcIntOrDoubleRight == CalcIntOrDouble.IsInt)
                {
                    valRightDouble = (double)valRightInt;
                }

                // used to define the calculation type
                calcIntOrDoubleLeft = CalcIntOrDouble.IsDouble;
            }

            //----calculate, depending on the operator: Plus
            if (operatorCalc.Operator == OperatorCalculationCode.Plus)
            {
                if (calcIntOrDoubleLeft == CalcIntOrDouble.IsDouble)
                {
                    ExprExecValueDouble resDouble = new ExprExecValueDouble();
                    resDouble.Value    = valLeftDouble + valRightDouble;
                    exprExecCalcResult = resDouble;
                    return(true);
                }

                ExprExecValueInt resInt = new ExprExecValueInt();
                resInt.Value       = valLeftInt + valRightInt;
                exprExecCalcResult = resInt;
                return(true);
            }

            //----calculate, depending on the operator: Minus
            if (operatorCalc.Operator == OperatorCalculationCode.Minus)
            {
                if (calcIntOrDoubleLeft == CalcIntOrDouble.IsDouble)
                {
                    ExprExecValueDouble resDouble = new ExprExecValueDouble();
                    resDouble.Value    = valLeftDouble - valRightDouble;
                    exprExecCalcResult = resDouble;
                    return(true);
                }

                ExprExecValueInt resInt = new ExprExecValueInt();
                resInt.Value       = valLeftInt - valRightInt;
                exprExecCalcResult = resInt;
                return(true);
            }

            //----calculate, depending on the operator: Multiplication
            if (operatorCalc.Operator == OperatorCalculationCode.Multiplication)
            {
                if (calcIntOrDoubleLeft == CalcIntOrDouble.IsDouble)
                {
                    ExprExecValueDouble resDouble = new ExprExecValueDouble();
                    resDouble.Value    = valLeftDouble * valRightDouble;
                    exprExecCalcResult = resDouble;
                    return(true);
                }

                ExprExecValueInt resInt = new ExprExecValueInt();
                resInt.Value       = valLeftInt * valRightInt;
                exprExecCalcResult = resInt;
                return(true);
            }

            //----calculate, depending on the operator: Division
            if (operatorCalc.Operator == OperatorCalculationCode.Division)
            {
                if (calcIntOrDoubleLeft == CalcIntOrDouble.IsDouble)
                {
                    ExprExecValueDouble resDouble = new ExprExecValueDouble();
                    resDouble.Value    = valLeftDouble / valRightDouble;
                    exprExecCalcResult = resDouble;
                    return(true);
                }

                // the result can be a double!
                double res  = (double)valLeftInt / (double)valRightInt;
                double res2 = res - Math.Truncate(res);

                if (res2 == 0)
                {
                    ExprExecValueInt resInt = new ExprExecValueInt();
                    resInt.Value       = valLeftInt / valRightInt;
                    exprExecCalcResult = resInt;
                    return(true);
                }
                else
                {
                    ExprExecValueDouble resDouble = new ExprExecValueDouble();
                    resDouble.Value    = res; // valLeftInt / valRightInt;
                    exprExecCalcResult = resDouble;
                    return(true);
                }
                return(true);
            }

            // operator not yet implemented
            execResult.AddErrorExec(ErrorCode.ExprCalculationOperatorNotYetImplemented, "Position", exprExecBaseLeft.Expr.Token.Position.ToString(), "Operand", exprExecBaseLeft.Expr.Token.Value);
            return(false);
        }