本文整理汇总了C#中BoundBinaryOperator类的典型用法代码示例。如果您正苦于以下问题:C# BoundBinaryOperator类的具体用法?C# BoundBinaryOperator怎么用?C# BoundBinaryOperator使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
BoundBinaryOperator类属于命名空间,在下文中一共展示了BoundBinaryOperator类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: RewriteStringConcatenation
private BoundNode RewriteStringConcatenation(BoundBinaryOperator node)
{
// UNDONE: We need to make this more sophisticated. For example, we should
// UNDONE: be rewriting (M() + "A") + ("B" + N()) as
// UNDONE: String.Concat(M(), "AB", N()).
// UNDONE: We have many overloads of String.Concat to choose from: that
// UNDONE: take one, two, three, four strings, that take params arrays
// UNDONE: in strings and objects, and so on. See the native compiler
// UNDONE: string rewriter for details.
// UNDONE: For now, just to get this going let's do it the easy way;
// UNDONE: we'll just generate calls to String.Concat(string, string)
// UNDONE: or String.Concat(object, object) as appropriate.
Debug.Assert(node != null);
Debug.Assert(node.ConstantValueOpt == null);
SpecialMember member = (node.OperatorKind == BinaryOperatorKind.StringConcatenation) ?
SpecialMember.System_String__ConcatStringString :
SpecialMember.System_String__ConcatObjectObject;
var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member);
// UNDONE: Handle the bizarre error case where we don't have the expected string concat methods.
Debug.Assert(method != null);
return Visit(BoundCall.SynthesizedCall(null, method, node.Left, node.Right));
}
示例2: EmitBinaryOperatorExpression
private void EmitBinaryOperatorExpression(BoundBinaryOperator expression, bool used)
{
var operatorKind = expression.OperatorKind;
if (operatorKind.EmitsAsCheckedInstruction())
{
EmitBinaryOperator(expression);
}
else
{
// if operator does not have side-effects itself and is not short-circuiting
// we can simply emit side-effects from the first operand and then from the second one
if (!used && !operatorKind.IsLogical() && !OperatorHasSideEffects(operatorKind))
{
EmitExpression(expression.Left, false);
EmitExpression(expression.Right, false);
return;
}
if (IsConditional(operatorKind))
{
EmitBinaryCondOperator(expression, true);
}
else
{
EmitBinaryOperator(expression);
}
}
EmitPopIfUnused(used);
}
示例3: RewriteDelegateOperation
private BoundNode RewriteDelegateOperation(BoundBinaryOperator node, SpecialMember member)
{
Debug.Assert(node != null);
var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member);
// UNDONE: Handle the bizarre error case where we don't have the expected methods.
Debug.Assert(method != null);
BoundExpression call = BoundCall.SynthesizedCall(null, method, node.Left, node.Right);
BoundExpression result = method.ReturnType.SpecialType == SpecialType.System_Delegate ?
BoundConversion.SynthesizedConversion(call, ConversionKind.ExplicitReference, node.Type) :
call;
return Visit(result);
}
示例4: RewriteStringEquality
private BoundNode RewriteStringEquality(BoundBinaryOperator node, SpecialMember member)
{
Debug.Assert(node != null);
Debug.Assert(node.ConstantValueOpt == null);
if (node.Left.ConstantValue == ConstantValue.Null || node.Right.ConstantValue == ConstantValue.Null)
{
return base.VisitBinaryOperator(node);
}
var method = (MethodSymbol)this.compilation.Assembly.GetSpecialTypeMember(member);
Debug.Assert(method != null);
return Visit(BoundCall.SynthesizedCall(null, method, node.Left, node.Right));
}
示例5: VisitBinaryOperator
public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
{
Debug.Assert(node != null);
BoundExpression left = (BoundExpression)this.Visit(node.Left);
BoundExpression right = (BoundExpression)this.Visit(node.Right);
if (node.Type.SpecialType == SpecialType.System_Decimal)
{
return RewriteDecimalArithmeticBinaryOperator(node.OperatorKind, node.Syntax, left, right);
}
else if (node.Left.Type.SpecialType == SpecialType.System_Decimal && node.Left.Type.SpecialType == SpecialType.System_Decimal)
{
return RewriteDecimalComparisonOperator(node.OperatorKind, node.Syntax, left, right);
}
return node.Update(node.OperatorKind, left, right, node.ConstantValueOpt, node.MethodOpt, node.ResultKind, node.Type);
}
示例6: EmitBinaryCondOperator
//NOTE: The result of this should be a boolean on the stack.
private void EmitBinaryCondOperator(BoundBinaryOperator binOp, bool sense)
{
bool andOrSense = sense;
int opIdx;
switch (binOp.OperatorKind.OperatorWithLogical())
{
case BinaryOperatorKind.LogicalOr:
Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);
// Rewrite (a || b) as ~(~a && ~b)
andOrSense = !andOrSense;
// Fall through
goto case BinaryOperatorKind.LogicalAnd;
case BinaryOperatorKind.LogicalAnd:
Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);
// ~(a && b) is equivalent to (~a || ~b)
if (!andOrSense)
{
// generate (~a || ~b)
EmitShortCircuitingOperator(binOp, sense, sense, true);
}
else
{
// generate (a && b)
EmitShortCircuitingOperator(binOp, sense, !sense, false);
}
return;
case BinaryOperatorKind.And:
Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);
EmitBinaryCondOperatorHelper(ILOpCode.And, binOp.Left, binOp.Right, sense);
return;
case BinaryOperatorKind.Or:
Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);
EmitBinaryCondOperatorHelper(ILOpCode.Or, binOp.Left, binOp.Right, sense);
return;
case BinaryOperatorKind.Xor:
Debug.Assert(binOp.Left.Type.SpecialType == SpecialType.System_Boolean);
Debug.Assert(binOp.Right.Type.SpecialType == SpecialType.System_Boolean);
// Xor is equivalent to not equal.
if (sense)
EmitBinaryCondOperatorHelper(ILOpCode.Xor, binOp.Left, binOp.Right, true);
else
EmitBinaryCondOperatorHelper(ILOpCode.Ceq, binOp.Left, binOp.Right, true);
return;
case BinaryOperatorKind.NotEqual:
// neq is emitted as !eq
sense = !sense;
goto case BinaryOperatorKind.Equal;
case BinaryOperatorKind.Equal:
var constant = binOp.Left.ConstantValue;
var comparand = binOp.Right;
if (constant == null)
{
constant = comparand.ConstantValue;
comparand = binOp.Left;
}
if (constant != null)
{
if (constant.IsDefaultValue)
{
if (!constant.IsFloating)
{
if (sense)
{
EmitIsNullOrZero(comparand, constant);
}
else
{
// obj != null/0 for pointers and integral numerics is emitted as cgt.un
EmitIsNotNullOrZero(comparand, constant);
}
return;
}
}
else if (constant.IsBoolean)
{
// treat "x = True" ==> "x"
EmitExpression(comparand, true);
EmitIsSense(sense);
return;
}
}
//.........这里部分代码省略.........
示例7: EmitShortCircuitingOperator
private void EmitShortCircuitingOperator(BoundBinaryOperator condition, bool sense, bool stopSense, bool stopValue)
{
// we generate:
//
// gotoif (a == stopSense) fallThrough
// b == sense
// goto labEnd
// fallThrough:
// stopValue
// labEnd:
// AND OR
// +- ------ -----
// stopSense | !sense sense
// stopValue | 0 1
object lazyFallThrough = null;
EmitCondBranch(condition.Left, ref lazyFallThrough, stopSense);
EmitCondExpr(condition.Right, sense);
// if fall-through was not initialized, no-one is going to take that branch
// and we are done with Right on stack
if (lazyFallThrough == null)
{
return;
}
var labEnd = new object();
_builder.EmitBranch(ILOpCode.Br, labEnd);
// if we get to fallThrough, we should not have Right on stack. Adjust for that.
_builder.AdjustStack(-1);
_builder.MarkLabel(lazyFallThrough);
_builder.EmitBoolConstant(stopValue);
_builder.MarkLabel(labEnd);
}
示例8: CodeForJump
/// <summary>
/// Produces opcode for a jump that corresponds to given operation and sense.
/// Also produces a reverse opcode - opcode for the same condition with inverted sense.
/// </summary>
private static ILOpCode CodeForJump(BoundBinaryOperator op, bool sense, out ILOpCode revOpCode)
{
int opIdx;
switch (op.OperatorKind.Operator())
{
case BinaryOperatorKind.Equal:
revOpCode = !sense ? ILOpCode.Beq : ILOpCode.Bne_un;
return sense ? ILOpCode.Beq : ILOpCode.Bne_un;
case BinaryOperatorKind.NotEqual:
revOpCode = !sense ? ILOpCode.Bne_un : ILOpCode.Beq;
return sense ? ILOpCode.Bne_un : ILOpCode.Beq;
case BinaryOperatorKind.LessThan:
opIdx = 0;
break;
case BinaryOperatorKind.LessThanOrEqual:
opIdx = 1;
break;
case BinaryOperatorKind.GreaterThan:
opIdx = 2;
break;
case BinaryOperatorKind.GreaterThanOrEqual:
opIdx = 3;
break;
default:
throw ExceptionUtilities.UnexpectedValue(op.OperatorKind.Operator());
}
if (IsUnsignedBinaryOperator(op))
{
opIdx += 2 * IL_OP_CODE_ROW_LENGTH; //unsigned
}
else if (IsFloat(op.OperatorKind))
{
opIdx += 4 * IL_OP_CODE_ROW_LENGTH; //float
}
int revOpIdx = opIdx;
if (!sense)
{
opIdx += IL_OP_CODE_ROW_LENGTH; //invert op
}
else
{
revOpIdx += IL_OP_CODE_ROW_LENGTH; //invert rev
}
revOpCode = s_condJumpOpCodes[revOpIdx];
return s_condJumpOpCodes[opIdx];
}
示例9: VisitBinaryOperator
public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
{
BoundExpression child = node.Left;
if (child.Kind != BoundKind.BinaryOperator || child.ConstantValue != null)
{
return base.VisitBinaryOperator(node);
}
// Do not blow the stack due to a deep recursion on the left.
var stack = ArrayBuilder<BoundBinaryOperator>.GetInstance();
stack.Push(node);
BoundBinaryOperator binary = (BoundBinaryOperator)child;
while (true)
{
stack.Push(binary);
child = binary.Left;
if (child.Kind != BoundKind.BinaryOperator || child.ConstantValue != null)
{
break;
}
binary = (BoundBinaryOperator)child;
}
var left = (BoundExpression)this.Visit(child);
while (true)
{
binary = stack.Pop();
var right = (BoundExpression)this.Visit(binary.Right);
var type = this.VisitType(binary.Type);
left = binary.Update(binary.OperatorKind, left, right, binary.ConstantValueOpt, binary.MethodOpt, binary.ResultKind, type);
if (stack.Count == 0)
{
break;
}
_nodeCounter += 1;
}
Debug.Assert((object)binary == node);
stack.Free();
return left;
}
示例10: EmitBinaryOperator
private void EmitBinaryOperator(BoundBinaryOperator expression)
{
BoundExpression child = expression.Left;
if (child.Kind != BoundKind.BinaryOperator || child.ConstantValue != null)
{
EmitBinaryOperatorSimple(expression);
return;
}
BoundBinaryOperator binary = (BoundBinaryOperator)child;
var operatorKind = binary.OperatorKind;
if (!operatorKind.EmitsAsCheckedInstruction() && IsConditional(operatorKind))
{
EmitBinaryOperatorSimple(expression);
return;
}
// Do not blow the stack due to a deep recursion on the left.
var stack = ArrayBuilder<BoundBinaryOperator>.GetInstance();
stack.Push(expression);
while (true)
{
stack.Push(binary);
child = binary.Left;
if (child.Kind != BoundKind.BinaryOperator || child.ConstantValue != null)
{
break;
}
binary = (BoundBinaryOperator)child;
operatorKind = binary.OperatorKind;
if (!operatorKind.EmitsAsCheckedInstruction() && IsConditional(operatorKind))
{
break;
}
}
EmitExpression(child, true);
do
{
binary = stack.Pop();
EmitExpression(binary.Right, true);
bool isChecked = binary.OperatorKind.EmitsAsCheckedInstruction();
if (isChecked)
{
EmitBinaryCheckedOperatorInstruction(binary);
}
else
{
EmitBinaryOperatorInstruction(binary);
}
EmitConversionToEnumUnderlyingType(binary, @checked: isChecked);
}
while (stack.Count > 0);
Debug.Assert((object)binary == expression);
stack.Free();
}
示例11: EmitBinaryCheckedOperatorInstruction
private void EmitBinaryCheckedOperatorInstruction(BoundBinaryOperator expression)
{
var unsigned = IsUnsignedBinaryOperator(expression);
switch (expression.OperatorKind.Operator())
{
case BinaryOperatorKind.Multiplication:
if (unsigned)
{
_builder.EmitOpCode(ILOpCode.Mul_ovf_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Mul_ovf);
}
break;
case BinaryOperatorKind.Addition:
if (unsigned)
{
_builder.EmitOpCode(ILOpCode.Add_ovf_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Add_ovf);
}
break;
case BinaryOperatorKind.Subtraction:
if (unsigned)
{
_builder.EmitOpCode(ILOpCode.Sub_ovf_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Sub_ovf);
}
break;
default:
throw ExceptionUtilities.UnexpectedValue(expression.OperatorKind.Operator());
}
}
示例12: EmitBinaryArithOperator
private void EmitBinaryArithOperator(BoundBinaryOperator expression)
{
EmitExpression(expression.Left, true);
EmitExpression(expression.Right, true);
switch (expression.OperatorKind.Operator())
{
case BinaryOperatorKind.Multiplication:
_builder.EmitOpCode(ILOpCode.Mul);
break;
case BinaryOperatorKind.Addition:
_builder.EmitOpCode(ILOpCode.Add);
break;
case BinaryOperatorKind.Subtraction:
_builder.EmitOpCode(ILOpCode.Sub);
break;
case BinaryOperatorKind.Division:
if (IsUnsignedBinaryOperator(expression))
{
_builder.EmitOpCode(ILOpCode.Div_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Div);
}
break;
case BinaryOperatorKind.Remainder:
if (IsUnsignedBinaryOperator(expression))
{
_builder.EmitOpCode(ILOpCode.Rem_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Rem);
}
break;
case BinaryOperatorKind.LeftShift:
_builder.EmitOpCode(ILOpCode.Shl);
break;
case BinaryOperatorKind.RightShift:
if (IsUnsignedBinaryOperator(expression))
{
_builder.EmitOpCode(ILOpCode.Shr_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Shr);
}
break;
case BinaryOperatorKind.And:
_builder.EmitOpCode(ILOpCode.And);
break;
case BinaryOperatorKind.Xor:
_builder.EmitOpCode(ILOpCode.Xor);
break;
case BinaryOperatorKind.Or:
_builder.EmitOpCode(ILOpCode.Or);
break;
default:
throw ExceptionUtilities.UnexpectedValue(expression.OperatorKind.Operator());
}
EmitConversionToEnumUnderlyingType(expression, @checked: false);
}
示例13: EmitBinaryCheckedOperatorExpression
private void EmitBinaryCheckedOperatorExpression(BoundBinaryOperator expression, bool used)
{
EmitExpression(expression.Left, true);
EmitExpression(expression.Right, true);
var unsigned = IsUnsignedBinaryOperator(expression);
switch (expression.OperatorKind.Operator())
{
case BinaryOperatorKind.Multiplication:
if (unsigned)
{
_builder.EmitOpCode(ILOpCode.Mul_ovf_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Mul_ovf);
}
break;
case BinaryOperatorKind.Addition:
if (unsigned)
{
_builder.EmitOpCode(ILOpCode.Add_ovf_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Add_ovf);
}
break;
case BinaryOperatorKind.Subtraction:
if (unsigned)
{
_builder.EmitOpCode(ILOpCode.Sub_ovf_un);
}
else
{
_builder.EmitOpCode(ILOpCode.Sub_ovf);
}
break;
default:
throw ExceptionUtilities.UnexpectedValue(expression.OperatorKind.Operator());
}
EmitConversionToEnumUnderlyingType(expression, @checked: true);
EmitPopIfUnused(used);
}
示例14: VisitBinaryOperator
public override BoundNode VisitBinaryOperator(BoundBinaryOperator node)
{
if (node.ConstantValueOpt != null)
{
return node;
}
switch (node.OperatorKind)
{
case BinaryOperatorKind.ObjectAndStringConcatenation:
case BinaryOperatorKind.StringAndObjectConcatenation:
case BinaryOperatorKind.StringConcatenation:
return RewriteStringConcatenation(node);
case BinaryOperatorKind.StringEqual:
return RewriteStringEquality(node, SpecialMember.System_String__op_Equality);
case BinaryOperatorKind.StringNotEqual:
return RewriteStringEquality(node, SpecialMember.System_String__op_Inequality);
case BinaryOperatorKind.DelegateCombination:
return RewriteDelegateOperation(node, SpecialMember.System_Delegate__Combine);
case BinaryOperatorKind.DelegateRemoval:
return RewriteDelegateOperation(node, SpecialMember.System_Delegate__Remove);
case BinaryOperatorKind.DelegateEqual:
return RewriteDelegateOperation(node, SpecialMember.System_Delegate__op_Equality);
case BinaryOperatorKind.DelegateNotEqual:
return RewriteDelegateOperation(node, SpecialMember.System_Delegate__op_Inequality);
}
return base.VisitBinaryOperator(node);
}
示例15: VisitCompoundAssignmentOperator
//.........这里部分代码省略.........
// UNDONE:
// UNDONE: For now, we'll punt on both problems, as indexers are not implemented yet anyway.
// UNDONE: We'll just generate one temporary for each argument. This will work, but in the
// UNDONE: subsequent rewritings will generate more unnecessary temporaries.
var transformedArguments = ArrayBuilder<BoundExpression>.GetInstance();
foreach (var argument in indexer.Arguments)
{
var rewrittenArgument = (BoundExpression)Visit(argument);
var argumentTemp = TempHelpers.StoreToTemp(rewrittenArgument, RefKind.None, containingSymbol);
transformedArguments.Add(argumentTemp.Item2);
stores.Add(argumentTemp.Item1);
temps.Add(argumentTemp.Item2.LocalSymbol);
}
transformedLHS = new BoundIndexerAccess(indexer.Syntax, indexer.SyntaxTree, transformedArguments.ToReadOnlyAndFree(), transformedReceiver,
indexer.IndexerSymbol, indexer.Type);
}
else if (node.Left.Kind == BoundKind.Local || node.Left.Kind == BoundKind.Parameter)
{
// No temporaries are needed. Just generate local = local + value
transformedLHS = node.Left;
}
else if (node.Left.Kind == BoundKind.FieldAccess)
{
// * If the field is static then no temporaries are needed.
// * If the field is not static and the receiver is of reference type then generate t = r; t.f = t.f + value
// * If the field is not static and the receiver is a variable of value type then we'll fall into the
// general variable case below.
var fieldAccess = (BoundFieldAccess)node.Left;
if (fieldAccess.ReceiverOpt == null)
{
transformedLHS = fieldAccess;
}
else if (!fieldAccess.ReceiverOpt.Type.IsValueType)
{
var rewrittenReceiver = (BoundExpression)Visit(fieldAccess.ReceiverOpt);
var receiverTemp = TempHelpers.StoreToTemp(rewrittenReceiver, RefKind.None, containingSymbol);
stores.Add(receiverTemp.Item1);
temps.Add(receiverTemp.Item2.LocalSymbol);
transformedLHS = new BoundFieldAccess(fieldAccess.Syntax, fieldAccess.SyntaxTree, receiverTemp.Item2, fieldAccess.FieldSymbol, null);
}
}
if (transformedLHS == null)
{
// We made no transformation above. Either we have array[index] += value or
// structVariable.field += value; either way we have a potentially complicated variable-
// producing expression on the left. Generate
// ref temp = ref variable; temp = temp + value
var rewrittenVariable = (BoundExpression)Visit(node.Left);
var variableTemp = TempHelpers.StoreToTemp(rewrittenVariable, RefKind.Ref, containingSymbol);
stores.Add(variableTemp.Item1);
temps.Add(variableTemp.Item2.LocalSymbol);
transformedLHS = variableTemp.Item2;
}
// OK, we now have the temporary declarations, the temporary stores, and the transformed left hand side.
// We need to generate
//
// xlhs = (FINAL)((LEFT)xlhs op rhs)
//
// And then wrap it up with the generated temporaries.
//
// (The right hand side has already been converted to the type expected by the operator.)
BoundExpression opLHS = BoundConversion.SynthesizedConversion(transformedLHS, node.LeftConversion, node.Operator.LeftType);
Debug.Assert(node.Right.Type == node.Operator.RightType);
BoundExpression op = new BoundBinaryOperator(null, null, node.Operator.Kind, opLHS, node.Right, null, node.Operator.ReturnType);
BoundExpression opFinal = BoundConversion.SynthesizedConversion(op, node.FinalConversion, node.Left.Type);
BoundExpression assignment = new BoundAssignmentOperator(null, null, transformedLHS, opFinal, node.Left.Type);
// OK, at this point we have:
//
// * temps evaluating and storing portions of the LHS that must be evaluated only once.
// * the "transformed" left hand side, rebuilt to use temps where necessary
// * the assignment "xlhs = (FINAL)((LEFT)xlhs op (RIGHT)rhs)"
//
// Notice that we have recursively rewritten the bound nodes that are things stored in
// the temps, but we might have more rewriting to do on the assignment. There are three
// conversions in there that might be lowered to method calls, an operator that might
// be lowered to delegate combine, string concat, and so on, and don't forget, we
// haven't lowered the right hand side at all! Let's rewrite all these things at once.
BoundExpression rewrittenAssignment = (BoundExpression)Visit(assignment);
BoundExpression result = (temps.Count == 0) ?
rewrittenAssignment :
new BoundSequence(null,
null,
temps.ToReadOnly(),
stores.ToReadOnly(),
rewrittenAssignment,
rewrittenAssignment.Type);
temps.Free();
stores.Free();
return result;
}