protected override SyntaxToken VisitBinary(BinarySyntaxToken token) { SyntaxToken leftDiff = this.Visit(token.Left); SyntaxToken rightDiff = this.Visit(token.Right); switch (token.Type) { case BinaryOperationType.Add: return(leftDiff + rightDiff); case BinaryOperationType.Subtract: return(leftDiff - rightDiff); case BinaryOperationType.Multiply: return(leftDiff * token.Right + token.Left * rightDiff); case BinaryOperationType.Divide: return((leftDiff * token.Right - token.Left * rightDiff) / SyntaxToken.Pow(token.Right, SyntaxToken.Constant(2))); // TODO: implement case BinaryOperationType.Modulus: return(token); case BinaryOperationType.Power: if (!this.VarDetector.HasVariable(token.Right)) { return(token.Right * SyntaxToken.Pow(token.Left, token.Right - SyntaxToken.Constant(1))); } return(token * (leftDiff * token.Right / token.Left + rightDiff * SyntaxToken.Ln(token.Left))); default: throw new NotSupportedException(); } }
protected override SyntaxToken VisitBinary(BinarySyntaxToken token) { SyntaxToken st = this.Visit(token.Left); if (!(st is NullSyntaxToken)) { return(st); } return(this.Visit(token.Right)); }
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); }
protected abstract SyntaxToken VisitBinary(BinarySyntaxToken token);