public void AddUnaryOperation(IUnaryOperation operation) { if (!UnaryOperations.Contains(operation)) { UnaryOperations.Add(operation); } }
public void FactorialInputArgumentReturnedValue(int leftValue, int expectedValue) { var leftNumber = new Number() { Value = leftValue }; var result = UnaryOperations.Factorial(leftNumber); Assert.AreEqual(expectedValue, result.Value); }
/// <summary> /// Generate the operation expression /// </summary> /// <typeparam name="T">Type of the values to apply operation on</typeparam> /// <param name="member">Member to apply operation on</param> /// <param name="targetValues">Values to apply operation on</param> /// <returns>Operation expression</returns> public Expression GetExpression <T>(Expression member, List <T> targetValues) { var type = member.Type; // check if the member is a method call if (IsMethodCall) { // get method by name var method = type.GetMethod(MethodName); if (method == null) { throw new Exception($"There is no method named {this} in the type {type.Name}"); } // get parameters list var parameters = method.GetParameters().ToList(); // check if values match parameters count if (parameters.Count != targetValues.Count) { throw new Exception($"There is no method named {this} in the type {type.Name} taking the same count of input"); } // convert values to a list of ConstantExpressions var constants = parameters.Select(p => Expression.Constant(Convert.ChangeType(targetValues[parameters.IndexOf(p)], p.ParameterType))).ToList(); // generate a MethodCallExpression return(Expression.Call(member, method, constants)); } // if not a method call // then validate that the member type is one of the predefined operations if (Enum.TryParse(Type.ToString(), out ExpressionType expressionType)) { // check if it is in the binary operations if (BinaryOperations.Contains(Type)) { // convert value to ConstantExpression var constant = Expression.Constant(Convert.ChangeType(targetValues[0], type)); // generate a BinaryExpression return(Expression.MakeBinary(expressionType, member, constant)); } else if (UnaryOperations.Contains(Type)) { // generate a UnaryExpression return(Expression.MakeUnary(expressionType, member, typeof(bool))); } } // throw an exception if operation not found throw new Exception("Unknown Operation"); }
public void ExponentiationInputArgumentReturnedValue(int leftValue, int rightValue, int expectedValue) { var leftNumber = new Number() { Value = leftValue }; var rightNumber = new Number() { Value = rightValue }; var result = UnaryOperations.Exponentiation(leftNumber, rightNumber); Assert.AreEqual(expectedValue, result.Value); }
private static ExpressionType GetExpressionType(UnaryOperations op, out bool assign, out bool post) { assign = false; post = false; switch (op) { case UnaryOperations.Plus: return ExpressionType.UnaryPlus; case UnaryOperations.Minus: return ExpressionType.Negate; case UnaryOperations.Not: return ExpressionType.Not; case UnaryOperations.PostIncrement: assign = true; post = true; return ExpressionType.Increment; case UnaryOperations.PostDecrement: assign = true; post = true; return ExpressionType.Decrement; case UnaryOperations.PreIncrement: assign = true; return ExpressionType.Increment; case UnaryOperations.PreDecrement: assign = true; return ExpressionType.Decrement; default: throw Assert.Unreachable; } }
public UnaryExpressionNode(UnaryOperations operation, ExpressionNode value, SourceSpan sourceSpan) : base(sourceSpan) { this.operation = operation; this.value = value; }
public static UnaryOpNode FromSymbol(int line, string symbol) => new UnaryOpNode(line, symbol, UnaryOperations.UnaryFromSymbol(symbol));
/// <summary> /// Creates a new <see cref="UnaryOperationExpression"/> with the <paramref name="operation"/> and /// <paramref name="targetExpression"/> provided. /// </summary> /// <param name="operation">The operation referred to by the <see cref="UnaryOperationExpression"/>.</param> /// <param name="targetExpression">The <see cref="IExpression"/> which has the <paramref name="operation"/> applied to it.</param> public UnaryOperationExpression(UnaryOperations operation, IExpression targetExpression) { this.operation = operation; this.targetExpression = targetExpression; }
/// <summary> /// The calculation of the converted expression. /// </summary> /// <param name="inputExpression"> Input the converted expression. </param> /// <param name="firstNumber"> The first number. </param> /// <param name="secondNumber"> The second number. </param> /// <returns> Result of calculating the expression. </returns> public static Number Counting(string inputExpression, Number firstNumber, Number secondNumber) { if (string.IsNullOrWhiteSpace(inputExpression)) { throw new ArgumentNullException("The input expression cannot be empty.", nameof(inputExpression)); } double result = 0; var temp = new Stack <double>(); for (int i = 0; i < inputExpression.Length; i++) { if (char.IsDigit(inputExpression[i])) { string a = string.Empty; while (!IsDelimeter(inputExpression[i]) && !IsOperator(inputExpression[i])) { a += inputExpression[i]; i++; if (i == inputExpression.Length) { break; } } temp.Push(double.Parse(a, CultureInfo.InvariantCulture)); i--; } else if (IsOperator(inputExpression[i])) { if (inputExpression[i] == '!') { firstNumber = new Number { Value = temp.Pop() } } ; else { firstNumber = new Number { Value = temp.Pop() }; secondNumber = new Number { Value = temp.Pop() }; } switch (inputExpression[i]) { case '+': result = BinaryOperations.Addition(secondNumber, firstNumber).Value; break; case '-': result = BinaryOperations.Subsctraction(secondNumber, firstNumber).Value; break; case '*': result = BinaryOperations.Multiplication(secondNumber, firstNumber).Value; break; case '/': result = BinaryOperations.Division(secondNumber, firstNumber).Value; break; case '%': result = BinaryOperations.DivisionReaminder(secondNumber, firstNumber).Value; break; case '^': result = UnaryOperations.Exponentiation(secondNumber, firstNumber).Value; break; case '!': result = UnaryOperations.Factorial(firstNumber).Value; break; } temp.Push(result); } } return(new Number { Value = temp.Peek() }); }