private BoundExpression BindBinaryExpression(BinaryExpressionSyntax syntax) { var boundLeft = BindExpression(syntax.Left); var boundRight = BindExpression(syntax.Right); if (boundLeft.Type == TypeSymbol.Error || boundRight.Type == TypeSymbol.Error) { return(new BoundErrorExpression()); } var boundOperator = BoundBinaryOperator.Bind(syntax.OperatorToken.Kind, boundLeft.Type, boundRight.Type); if (boundOperator == null) { _diagnostics.ReportUndefinedBinaryOperator(syntax.OperatorToken.Span, syntax.OperatorToken.Text, boundLeft.Type, boundRight.Type); return(new BoundErrorExpression()); } return(new BoundBinaryExpression(boundLeft, boundOperator, boundRight)); }
public BoundCompoundAssignmentExpression(SyntaxNode syntax, VariableSymbol variable, BoundBinaryOperator op, BoundExpression expression) : base(syntax) { Variable = variable; Op = op; Expression = expression; }
public BoundBinaryExpression(BoundExpression left, BoundBinaryOperator @operator, BoundExpression right) { Left = left; Operator = @operator; Right = right; }
public BoundBinaryExpression(BoundExpression left, BoundBinaryOperator op, BoundExpression right) { Left = left; Op = op; Right = right; }
public static BoundBinaryExpression Binary(SyntaxNode syntax, BoundExpression left, BoundBinaryOperator op, BoundExpression right) { return(new BoundBinaryExpression(syntax, left, op, right)); }
public static BoundBinaryExpression Binary(SyntaxNode syntax, BoundExpression left, SyntaxKind kind, BoundExpression right) { var op = BoundBinaryOperator.Bind(kind, left.Type, right.Type) !; return(Binary(syntax, left, op, right)); }
public BoundCompoundAssignmentExpression(VariableSymbol variable, BoundBinaryOperator op, BoundExpression expression) { Variable = variable; Op = op; Expression = expression; }
public static BoundConstant?Fold(BoundExpression left, BoundBinaryOperator op, BoundExpression right) { var leftConstant = left.ConstantValue; var rightConstant = right.ConstantValue; // Special case && and || because there are cases where only one // side needs to be known. if (op.Kind == BoundBinaryOperatorKind.LogicalAnd) { if (leftConstant != null && !(bool)leftConstant.Value || rightConstant != null && !(bool)rightConstant.Value) { return(new BoundConstant(false)); } } if (op.Kind == BoundBinaryOperatorKind.LogicalOr) { if (leftConstant != null && (bool)leftConstant.Value || rightConstant != null && (bool)rightConstant.Value) { return(new BoundConstant(true)); } } if (leftConstant == null || rightConstant == null) { return(null); } var l = leftConstant.Value; var r = rightConstant.Value; switch (op.Kind) { case BoundBinaryOperatorKind.Addition: if (left.Type == TypeSymbol.Int) { return(new BoundConstant((int)l + (int)r)); } else { return(new BoundConstant((string)l + (string)r)); } case BoundBinaryOperatorKind.Subtraction: return(new BoundConstant((int)l - (int)r)); case BoundBinaryOperatorKind.Multiplication: return(new BoundConstant((int)l * (int)r)); case BoundBinaryOperatorKind.Division: return(new BoundConstant((int)l / (int)r)); case BoundBinaryOperatorKind.BitwiseAnd: if (left.Type == TypeSymbol.Int) { return(new BoundConstant((int)l & (int)r)); } else { return(new BoundConstant((bool)l & (bool)r)); } case BoundBinaryOperatorKind.BitwiseOr: if (left.Type == TypeSymbol.Int) { return(new BoundConstant((int)l | (int)r)); } else { return(new BoundConstant((bool)l | (bool)r)); } case BoundBinaryOperatorKind.BitwiseXor: if (left.Type == TypeSymbol.Int) { return(new BoundConstant((int)l ^ (int)r)); } else { return(new BoundConstant((bool)l ^ (bool)r)); } case BoundBinaryOperatorKind.LogicalAnd: return(new BoundConstant((bool)l && (bool)r)); case BoundBinaryOperatorKind.LogicalOr: return(new BoundConstant((bool)l || (bool)r)); case BoundBinaryOperatorKind.Equals: return(new BoundConstant(Equals(l, r))); case BoundBinaryOperatorKind.NotEquals: return(new BoundConstant(!Equals(l, r))); case BoundBinaryOperatorKind.Less: return(new BoundConstant((int)l < (int)r)); case BoundBinaryOperatorKind.LessOrEquals: return(new BoundConstant((int)l <= (int)r)); case BoundBinaryOperatorKind.Greater: return(new BoundConstant((int)l > (int)r)); case BoundBinaryOperatorKind.GreaterOrEquals: return(new BoundConstant((int)l >= (int)r)); default: throw new Exception($"Unexpected binary operator {op.Kind}"); } }