public virtual ExpressionContext CompileBinaryExpression(Compiler compiler, Frame frame, ExpressionContext left, Parse.BinaryExpression expression, Type.BaseType typeHint)
{
switch (expression.Operator)
{
case Parse.Operator.Addition:
case Parse.Operator.Subtract:
case Parse.Operator.Multiply:
case Parse.Operator.Modulo:
case Parse.Operator.Divide:
case Parse.Operator.Power:
case Parse.Operator.BitwiseAnd:
case Parse.Operator.BitwiseOr:
case Parse.Operator.BitwiseXor:
case Parse.Operator.Xor:
case Parse.Operator.ShiftLeft:
case Parse.Operator.ShiftRight:
{
var right = compiler.CompileExpression(frame, expression.Right, typeHint);
return
new ExpressionContext
(
expression,
left.Type,
Compiler.MergeCharacteristics(left.Characteristics, right.Characteristics),
m => { EmitBinaryOperator(m, compiler, left, right, expression); }
);
}
case Parse.Operator.And:
case Parse.Operator.Or:
{
var right = compiler.CompileExpression(frame, expression.Right, typeHint);
return
new ExpressionContext
(
expression,
left.Type,
Compiler.MergeCharacteristics(left.Characteristics, right.Characteristics),
m => { EmitShortCircuit(m, compiler, frame, left, right, expression, typeHint); }
);
}
case Parse.Operator.Equal:
case Parse.Operator.NotEqual:
case Parse.Operator.InclusiveGreater:
case Parse.Operator.InclusiveLess:
case Parse.Operator.Greater:
case Parse.Operator.Less:
{
var right = compiler.CompileExpression(frame, expression.Right); // (no type hint)
return
new ExpressionContext
(
expression,
SystemTypes.Boolean,
Compiler.MergeCharacteristics(left.Characteristics, right.Characteristics),
m => { EmitBinaryOperator(m, compiler, left, right, expression); }
);
}
default: throw NotSupported(expression);
}
}