object EvaluateBinaryExpression(BinaryExpressionAst binaryExpressionAst)
{
var leftOperand = EvaluateAst(binaryExpressionAst.Left);
var rightOperand = EvaluateAst(binaryExpressionAst.Right);
if (leftOperand is PSObject) leftOperand = ((PSObject)leftOperand).BaseObject;
if (rightOperand is PSObject) rightOperand = ((PSObject)rightOperand).BaseObject;
switch (binaryExpressionAst.Operator)
{
case TokenKind.DotDot:
return Range(LanguagePrimitives.ConvertTo<int>(leftOperand), LanguagePrimitives.ConvertTo<int>(rightOperand));
case TokenKind.Plus:
return ArithmeticOperations.Add(leftOperand, rightOperand);
case TokenKind.Ieq:
case TokenKind.Ceq:
if (leftOperand is string || rightOperand is string)
{
StringComparison ignoreCaseComparision =
(TokenKind.Ceq == binaryExpressionAst.Operator)
? StringComparison.CurrentCulture
: StringComparison.CurrentCultureIgnoreCase;
var left = LanguagePrimitives.ConvertTo<string>(leftOperand);
var right = LanguagePrimitives.ConvertTo<string>(rightOperand);
return String.Equals(left, right, ignoreCaseComparision);
}
return Object.Equals(leftOperand, rightOperand);
case TokenKind.Ine:
case TokenKind.Cne:
if (leftOperand is string || rightOperand is string)
{
StringComparison ignoreCaseComparision =
(TokenKind.Cne == binaryExpressionAst.Operator)
? StringComparison.CurrentCulture
: StringComparison.CurrentCultureIgnoreCase;
var left = LanguagePrimitives.ConvertTo<string>(leftOperand);
var right = LanguagePrimitives.ConvertTo<string>(rightOperand);
return !String.Equals(left, right, ignoreCaseComparision);
}
return !Object.Equals(leftOperand, rightOperand);
case TokenKind.Igt:
case TokenKind.Cgt:
return ComparisonOperations.GreaterThan(
leftOperand,
rightOperand,
(TokenKind.Cgt != binaryExpressionAst.Operator));
case TokenKind.Ige:
case TokenKind.Cge:
return ComparisonOperations.GreaterThanEquals(
leftOperand,
rightOperand,
(TokenKind.Cge != binaryExpressionAst.Operator));
case TokenKind.Or:
return LanguagePrimitives.ConvertTo<bool>(leftOperand) || LanguagePrimitives.ConvertTo<bool>(rightOperand);
case TokenKind.Xor:
return LanguagePrimitives.ConvertTo<bool>(leftOperand) != LanguagePrimitives.ConvertTo<bool>(rightOperand);
case TokenKind.And:
return LanguagePrimitives.ConvertTo<bool>(leftOperand) && LanguagePrimitives.ConvertTo<bool>(rightOperand);
case TokenKind.Ilt:
case TokenKind.Clt:
return ComparisonOperations.LessThan(
leftOperand,
rightOperand,
(TokenKind.Clt != binaryExpressionAst.Operator));
case TokenKind.Ile:
case TokenKind.Cle:
return ComparisonOperations.LessThanEquals(
leftOperand,
rightOperand,
(TokenKind.Clt != binaryExpressionAst.Operator));
case TokenKind.Band:
return BitwiseOperation.And(leftOperand, rightOperand);
case TokenKind.Bor:
return BitwiseOperation.Or(leftOperand, rightOperand);
case TokenKind.Bxor:
return BitwiseOperation.Xor(leftOperand, rightOperand);
case TokenKind.Imatch:
return Match(leftOperand, rightOperand, RegexOptions.IgnoreCase);
case TokenKind.Inotmatch:
return NotMatch(leftOperand, rightOperand, RegexOptions.IgnoreCase);
case TokenKind.Cmatch:
return Match(leftOperand, rightOperand, RegexOptions.None);
case TokenKind.Cnotmatch:
return NotMatch(leftOperand, rightOperand, RegexOptions.None);
case TokenKind.Multiply:
return ArithmeticOperations.Multiply(leftOperand, rightOperand);
case TokenKind.Divide:
return ArithmeticOperations.Divide(leftOperand, rightOperand);
case TokenKind.Minus:
return ArithmeticOperations.Subtract(leftOperand, rightOperand);
case TokenKind.Rem:
return ArithmeticOperations.Remainder(leftOperand, rightOperand);
case TokenKind.Format:
{
var left = LanguagePrimitives.ConvertTo<string>(leftOperand);
var right = LanguagePrimitives.ConvertTo<object[]>(rightOperand);
return string.Format(left, right);
}
case TokenKind.Equals:
case TokenKind.PlusEquals:
case TokenKind.MinusEquals:
case TokenKind.MultiplyEquals:
case TokenKind.DivideEquals:
case TokenKind.RemainderEquals:
case TokenKind.Not:
case TokenKind.Bnot:
case TokenKind.Join:
case TokenKind.Ilike:
case TokenKind.Inotlike:
case TokenKind.Ireplace:
case TokenKind.Icontains:
case TokenKind.Inotcontains:
case TokenKind.Iin:
case TokenKind.Inotin:
case TokenKind.Isplit:
case TokenKind.Clike:
case TokenKind.Cnotlike:
case TokenKind.Creplace:
case TokenKind.Ccontains:
case TokenKind.Cnotcontains:
case TokenKind.Cin:
case TokenKind.Cnotin:
case TokenKind.Csplit:
case TokenKind.Is:
case TokenKind.IsNot:
case TokenKind.As:
case TokenKind.Shl:
case TokenKind.Shr:
throw new NotImplementedException(binaryExpressionAst.ToString());
default:
throw new InvalidOperationException(binaryExpressionAst.ToString());
}
}