/// <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); }