/// <summary> /// Comprueba si se ha encontrado un operador que indica el final de la operación /// </summary> private bool EndSearchOperator(ExpressionOperatorBase expression, ExpressionBase lastOperator) { if (lastOperator == null) // ... si no queda nada en la pila { return(true); } else if (lastOperator is ExpressionParenthesis parenthesis && parenthesis.Open) // ... si es un paréntesis de apertura { return(true); }
/// <summary> /// Calcula una operación de cadena /// </summary> private VariableModel ComputeString(ExpressionOperatorBase expression, VariableModel first, VariableModel second, out string error) { string firstValue = first.Value.ToString(); string secondValue = second.Value.ToString(); // Inicializa los argumentos de salida error = string.Empty; // Ejecuta la operación switch (expression) { case ExpressionOperatorMath operation: if (operation.Type == ExpressionOperatorMath.MathType.Sum) { return(new VariableModel("Result", firstValue + secondValue)); } break; case ExpressionOperatorLogical operation: int compare = NormalizeString(firstValue).CompareTo(NormalizeString(secondValue)); switch (operation.Type) { case ExpressionOperatorLogical.LogicalType.Distinct: return(new VariableModel("Result", compare != 0)); case ExpressionOperatorLogical.LogicalType.Equal: return(new VariableModel("Result", compare == 0)); case ExpressionOperatorLogical.LogicalType.Greater: return(new VariableModel("Result", compare > 0)); case ExpressionOperatorLogical.LogicalType.GreaterOrEqual: return(new VariableModel("Result", compare >= 0)); case ExpressionOperatorLogical.LogicalType.Less: return(new VariableModel("Result", compare < 0)); case ExpressionOperatorLogical.LogicalType.LessOrEqual: return(new VariableModel("Result", compare <= 0)); } break; } // Si ha llegado hasta aquí es porque no se puede ejecutar la operación error = "Cant execute this operation with a string"; return(null); }
/// <summary> /// Calcula una operación lógica /// </summary> private VariableModel ComputeBoolean(ExpressionOperatorBase expression, VariableModel first, VariableModel second, out string error) { bool firstValue = (bool)first.Value; bool secondValue = false; // Inicializa los argumentos de salida error = string.Empty; // Normaliza el segundo valor if (second.Value != null) { secondValue = (bool)second.Value; } // Ejecuta la operación switch (expression) { case ExpressionOperatorLogical logical: switch (logical.Type) { case ExpressionOperatorLogical.LogicalType.Distinct: return(new VariableModel("Result", firstValue != secondValue)); case ExpressionOperatorLogical.LogicalType.Equal: return(new VariableModel("Result", firstValue == secondValue)); } break; case ExpressionOperatorRelational relational: switch (relational.Type) { case ExpressionOperatorRelational.RelationalType.And: return(new VariableModel("Result", firstValue && secondValue)); case ExpressionOperatorRelational.RelationalType.Or: return(new VariableModel("Result", firstValue || secondValue)); } break; } // Si ha llegado hasta aquí es porque no se ha podido ejecutar la operación error = "Cant execute this operation with logic value"; return(null); }
/// <summary> /// Calcula una operación con dos valores /// </summary> private VariableModel ComputeBinary(ExpressionOperatorBase expression, VariableModel first, VariableModel second, out string error) { switch (first.Type) { case VariableModel.VariableType.Boolean: return(ComputeBoolean(expression, first, second, out error)); case VariableModel.VariableType.String: return(ComputeString(expression, first, second, out error)); case VariableModel.VariableType.Date: return(ComputeDate(expression, first, second, out error)); case VariableModel.VariableType.Numeric: return(ComputeNumeric(expression, first, second, out error)); default: error = "Unknow type"; return(null); } }
/// <summary> /// Calcula una operación de fecha /// </summary> private VariableModel ComputeDate(ExpressionOperatorBase expression, VariableModel first, VariableModel second, out string error) { DateTime firstValue = (DateTime)first.Value; // Inicializa los valores de salida error = string.Empty; // Dependiendo del tipo del segundo valor switch (second.Type) { case VariableModel.VariableType.Numeric: if (expression is ExpressionOperatorMath operation) { int interval = (int)second.Value; switch (operation.Type) { case ExpressionOperatorMath.MathType.Sum: return(new VariableModel("Result", ComputeDate(firstValue, true, interval, DateOperation.Day))); case ExpressionOperatorMath.MathType.Substract: return(new VariableModel("Result", ComputeDate(firstValue, false, interval, DateOperation.Day))); } } break; case VariableModel.VariableType.String: if (expression is ExpressionOperatorMath operationString) { (int interval, DateOperation dateOperation) = GetDateIncrement(second.Value?.ToString()); switch (operationString.Type) { case ExpressionOperatorMath.MathType.Sum: return(new VariableModel("Result", ComputeDate(firstValue, true, interval, dateOperation))); case ExpressionOperatorMath.MathType.Substract: return(new VariableModel("Result", ComputeDate(firstValue, false, interval, dateOperation))); } } break; case VariableModel.VariableType.Date: if (expression is ExpressionOperatorLogical logical) { DateTime secondValue = (DateTime)second.Value; switch (logical.Type) { case ExpressionOperatorLogical.LogicalType.Distinct: return(new VariableModel("Result", firstValue != secondValue)); case ExpressionOperatorLogical.LogicalType.Equal: return(new VariableModel("Result", firstValue == secondValue)); case ExpressionOperatorLogical.LogicalType.Greater: return(new VariableModel("Result", firstValue > secondValue)); case ExpressionOperatorLogical.LogicalType.GreaterOrEqual: return(new VariableModel("Result", firstValue >= secondValue)); case ExpressionOperatorLogical.LogicalType.Less: return(new VariableModel("Result", firstValue < secondValue)); case ExpressionOperatorLogical.LogicalType.LessOrEqual: return(new VariableModel("Result", firstValue <= secondValue)); } } break; } // Si ha llegado hasta aquí es porque no se ha podido evaluar la operación error = "Can execute this operation with a date"; return(null); }
/// <summary> /// Calcula una operación numérica /// </summary> private VariableModel ComputeNumeric(ExpressionOperatorBase expression, VariableModel first, VariableModel second, out string error) { // Inicializa los argumentos de salida error = string.Empty; // Si el segundo valor es una cadena, convierte y procesa con cadenas switch (second.Type) { case VariableModel.VariableType.String: return(ComputeString(expression, new VariableModel("Converted", first.Value.ToString()), second, out error)); case VariableModel.VariableType.Date: return(ComputeDate(expression, second, first, out error)); case VariableModel.VariableType.Numeric: double firstValue = (double?)first.Value ?? 0; double secondValue = (double?)second.Value ?? 0; switch (expression) { case ExpressionOperatorMath operation: switch (operation.Type) { case ExpressionOperatorMath.MathType.Sum: return(new VariableModel("Result", firstValue + secondValue)); case ExpressionOperatorMath.MathType.Substract: return(new VariableModel("Result", firstValue - secondValue)); case ExpressionOperatorMath.MathType.Multiply: return(new VariableModel("Result", firstValue * secondValue)); case ExpressionOperatorMath.MathType.Divide: if (secondValue == 0) { error = "Cant divide by zero"; } else { return(new VariableModel("Result", firstValue / secondValue)); } break; case ExpressionOperatorMath.MathType.Modulus: if (secondValue == 0) { error = "Cant compute a module by zero"; } else { return(new VariableModel("Result", firstValue % secondValue)); } break; } break; case ExpressionOperatorLogical operation: switch (operation.Type) { case ExpressionOperatorLogical.LogicalType.Distinct: return(new VariableModel("Result", firstValue != secondValue)); case ExpressionOperatorLogical.LogicalType.Equal: return(new VariableModel("Result", firstValue == secondValue)); case ExpressionOperatorLogical.LogicalType.Greater: return(new VariableModel("Result", firstValue > secondValue)); case ExpressionOperatorLogical.LogicalType.GreaterOrEqual: return(new VariableModel("Result", firstValue >= secondValue)); case ExpressionOperatorLogical.LogicalType.Less: return(new VariableModel("Result", firstValue < secondValue)); case ExpressionOperatorLogical.LogicalType.LessOrEqual: return(new VariableModel("Result", firstValue <= secondValue)); } break; } break; } // Si ha llegado hasta aquí es porque no se ha podido evaluar la operación if (string.IsNullOrEmpty(error)) { error = "Cant execute this operation with a numeric value"; } return(null); }