protected override SyntaxToken VisitBinary(BinarySyntaxToken token) { SyntaxToken left = this.Visit(token.Left); SyntaxToken right = this.Visit(token.Right); BinaryOperationType type = token.Type; if (left.TokenType == SyntaxTokenType.Constant && right.TokenType == SyntaxTokenType.Constant) { return this.EvalBinary((ConstantSyntaxToken)left, (ConstantSyntaxToken)right, type); } // swap constant to the right if ((type == BinaryOperationType.Add || type == BinaryOperationType.Multiply) && (left.TokenType == SyntaxTokenType.Constant)) { SyntaxToken temp = right; right = left; left = temp; } // add if (type == BinaryOperationType.Add) { if (right.HasValue(0)) { return left; } } // subtract else if (type == BinaryOperationType.Subtract) { if (right.HasValue(0)) { return left; } if (SyntaxToken.Equals(left, right)) { return SyntaxToken.Constant(0); } } // multiply else if (type == BinaryOperationType.Multiply) { if (right.HasValue(0)) { return SyntaxToken.Constant(0); } if (right.HasValue(1)) { return left; } if (left.TokenType == SyntaxTokenType.Binary && right.TokenType == SyntaxTokenType.Binary) { BinarySyntaxToken bl = (BinarySyntaxToken)left; BinarySyntaxToken br = (BinarySyntaxToken)right; if (bl.Type == BinaryOperationType.Power && br.Type == BinaryOperationType.Power && SyntaxToken.Equals(bl.Left, br.Left)) { return this.Visit(SyntaxToken.Pow(bl.Left, SyntaxToken.Add(bl.Right, br.Right))); } } } // divide else if (type == BinaryOperationType.Divide) { if (left.HasValue(0)) { return SyntaxToken.Constant(0); } if (SyntaxToken.Equals(left, right)) { return SyntaxToken.Constant(1); } } // modulus else if (type == BinaryOperationType.Modulus) { if (left.HasValue(0)) { return SyntaxToken.Constant(0); } if (SyntaxToken.Equals(left, right)) { return SyntaxToken.Constant(0); } } // pow else if (type == BinaryOperationType.Power) { if (right.HasValue(0)) { return SyntaxToken.Constant(1); } if (right.HasValue(1)) { return left; } if (left.HasValue(0)) { return SyntaxToken.Constant(1); } if (left.TokenType == SyntaxTokenType.Binary) { BinarySyntaxToken bl = (BinarySyntaxToken)left; if (bl.Type == BinaryOperationType.Power) { return this.Visit(SyntaxToken.Pow(bl.Left, SyntaxToken.Multiply(bl.Right, right))); } } } return SyntaxToken.Binary(left, right, type); }