private Expression ParseComparison()
{
Expression left = ParseAdditive();
if (TokenIdentifierIs("in"))
{
NextToken();
var args = ParseBracketExpression(false);
return GenerateIn(left, args);
}
while (_token.ID == TokenId.Equal || _token.ID == TokenId.DoubleEqual ||
_token.ID == TokenId.ExclamationEqual || _token.ID == TokenId.LessGreater ||
_token.ID == TokenId.GreaterThan || _token.ID == TokenId.GreaterThanEqual ||
_token.ID == TokenId.LessThan || _token.ID == TokenId.LessThanEqual)
{
Token op = _token;
NextToken();
Expression right = ParseAdditive();
bool isEquality = op.ID == TokenId.Equal || op.ID == TokenId.DoubleEqual ||
op.ID == TokenId.ExclamationEqual || op.ID == TokenId.LessGreater;
if (isEquality && !left.Type.IsValueType && !right.Type.IsValueType)
{
if (left.Type != right.Type)
{
if (left.Type.IsAssignableFrom(right.Type))
{
right = Expression.Convert(right, left.Type);
}
else if (right.Type.IsAssignableFrom(left.Type))
{
left = Expression.Convert(left, right.Type);
}
else
{
throw IncompatibleOperandsError(op.Text, left, right, op.Position);
}
}
}
else if (IsEnumType(left.Type) || IsEnumType(right.Type))
{
PromoteLeftOrRight(ref left, ref right, op);
}
else if (left.Type == typeof(char) || right.Type == typeof(char))
{
PromoteLeftOrRight(ref left, ref right, op);
}
else
{
CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),
op.Text, ref left, ref right, op.Position);
}
switch (op.ID)
{
case TokenId.Equal:
case TokenId.DoubleEqual:
left = GenerateEqual(left, right);
break;
case TokenId.ExclamationEqual:
case TokenId.LessGreater:
left = GenerateNotEqual(left, right);
break;
case TokenId.GreaterThan:
left = GenerateGreaterThan(left, right);
break;
case TokenId.GreaterThanEqual:
left = GenerateGreaterThanEqual(left, right);
break;
case TokenId.LessThan:
left = GenerateLessThan(left, right);
break;
case TokenId.LessThanEqual:
left = GenerateLessThanEqual(left, right);
break;
}
}
return left;
}