/// <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)); } }
/// <summary> /// Unary subtraction (negation) operation of an expression. /// </summary> /// <param name="expr">Expression to be negated.</param> /// <returns>Returns a negated expression of the input expression.</returns> public static Expression operator -(Expression expr) => NegatedExpression.Build(expr);