/// <summary> /// Parses an addition expression. /// If the top-level expression is not an addition, /// the proper type of expression will be parsed and returned. /// </summary> /// <param name="tokens">Input list of tokens.</param> /// <param name="start">Index of first token of the expression.</param> /// <param name="length">Output variable for expression length (number of tokens used).</param> /// <returns>Returns the parsed expression.</returns> private static Expression ParseAddition(List <Token> tokens, int start, out int length) { // Create list for expressions belonging to this addition. List <Expression> parts = new List <Expression>() { // Read the first part / sub-expression of the addition. ParseMultiplication(tokens, start, out int firstLen) }; // Index of last processed token's end. int end = start + firstLen; // Keep going while sub-expressions are being added (or subtracted) // and while there are more tokens to process. while (end < tokens.Count && tokens[end] is SpecialToken special && (special.Addition || special.Subtraction)) { // Parse next part / sub-expression of the addition. Expression nextPart = ParseMultiplication(tokens, end + 1, out int nextLen); // Convert subtraction into addition of negated expression. parts.Add(special.Subtraction ? NegatedExpression.Build(nextPart) : nextPart); // Add the length of the operator and the sub-expression to the end token index. end += 1 + nextLen; } // Calculate the total length of the addition. length = end - start; return(AdditionExpression.Build(parts)); }
public static Expression Build(Expression expr) { if (expr is NegatedExpression negated) { return(negated.Expression); } else if (expr is ConstantExpression constant) { return(-constant.Value); } else if (expr is AdditionExpression addition) { return(AdditionExpression.Build(-addition.Constant, addition.VariableParts.Select(x => NegatedExpression.Build(x)))); } else if (expr is MultiplicationExpression multiplication) { return(MultiplicationExpression.Build(-multiplication.Coefficient, multiplication.VariableParts)); } else { return(new NegatedExpression(expr)); } }
public override Expression FindDerivative() => AdditionExpression.Build(VariableParts.Select(x => x.FindDerivative() * MultiplicationExpression.Build(VariableParts.Where(y => y != x)))) * Coefficient;
/// <summary> /// Binary subtraction of expressions. /// </summary> /// <param name="first">Left-side expression.</param> /// <param name="second">Right-side expression.</param> /// <returns>Returns the result of adding negated version of the second expression to the first expression.</returns> public static Expression operator -(Expression first, Expression second) => AdditionExpression.Build(first, -second);