/* * /// <summary> * /// Binds a simple identifier. * /// </summary> * private BoundExpression BindIdentifier(SimpleNameSyntax node, bool invoked) * { * } */ private BoundExpression BindSimpleBinaryOperator(BinaryExpressionSyntax node, BindingDiagnosticBag diagnostics) { // The simple binary operators are left-associative, and expressions of the form // a + b + c + d .... are relatively common in machine-generated code. The parser can handle // creating a deep-on-the-left syntax tree no problem, and then we promptly blow the stack during // semantic analysis. Here we build an explicit stack to handle the left-hand recursion. Debug.Assert(IsSimpleBinaryOperator(node.Kind)); var expressions = new Stack <BoundExpression>(); var syntaxNodes = new Stack <BinaryExpressionSyntax>(); ExpressionSyntax current = node; while (IsSimpleBinaryOperator(current.Kind)) { var binOp = (BinaryExpressionSyntax)current; syntaxNodes.Push(binOp); expressions.Push(BindValue(binOp.Right, diagnostics, BindValueKind.RValue)); current = binOp.Left; } BoundExpression leftMost = BindExpression(current, diagnostics); expressions.Push(leftMost); Debug.Assert(syntaxNodes.Count + 1 == expressions.Count); int compoundStringLength = 0; while (syntaxNodes.Count > 0) { BinaryExpressionSyntax syntaxNode = syntaxNodes.Pop(); BoundExpression left = expressions.Pop(); BoundExpression right = expressions.Pop(); left = CheckValue(left, BindValueKind.RValue); BoundExpression boundOp = BindSimpleBinaryOperator(syntaxNode, diagnostics, left, right, ref compoundStringLength); expressions.Push(boundOp); } Debug.Assert(expressions.Count == 1); var result = expressions.Peek(); return(result); }
protected BoundExpression BindExpression(ExpressionSyntax node, BindingDiagnosticBag diagnostics, bool invoked, bool indexed) { BoundExpression expr = BindExpressionInternal(node, diagnostics, invoked, indexed); return(expr); }
public BoundExpression BindExpression(ExpressionSyntax node, BindingDiagnosticBag diagnostics) { return(BindExpression(node, diagnostics, invoked: false, indexed: false)); }
/// <summary> /// Bind the expression and verify the expression matches the combination of lvalue and /// rvalue requirements given by valueKind. If the expression was bound successfully, but /// did not meet the requirements, the return value will be a <see cref="BoundBadExpression"/> that /// (typically) wraps the subexpression. /// </summary> internal BoundExpression BindValue(ExpressionSyntax node, BindingDiagnosticBag diagnostics, BindValueKind valueKind) { var result = BindExpression(node, diagnostics, invoked: false, indexed: false); return(CheckValue(result, valueKind)); }
private BoundExpression BindSimpleBinaryOperator(BinaryExpressionSyntax node, BindingDiagnosticBag diagnostics, BoundExpression left, BoundExpression right, ref int compoundStringLength) { BinaryOperatorKind kind = SyntaxKindToBinaryOperatorKind(node.Kind); TypeSymbol leftType = left.Type; TypeSymbol rightType = right.Type; /* Perform binary operator overload resoluton */ BinaryOperatorSignature signature; BinaryOperatorAnalysisResult best; bool foundOperator = BindSimpleBinaryOperatorParts(node, diagnostics, left, right, kind, out signature, out best); if (!foundOperator) { ReportBinaryOperatorError(node, diagnostics, node.OperatorToken, left, right); } BoundExpression resultLeft = left; BoundExpression resultRight = right; BinaryOperatorKind resultOperatorKind = signature.Kind; TypeSymbol resultType = signature.ReturnType; return(new BoundBinaryOperator( node, resultOperatorKind, resultLeft, resultRight, resultType)); }
internal static void Error(BindingDiagnosticBag diagnostics, ErrorCode code, SyntaxNode syntax, params object[] args) { var diagnostic = new SlothDiagnostic(new DiagnosticInfo(code, args), syntax.Location); diagnostics.Add(diagnostic); }