public override void Evaluate(TemplateContext context)
{
var leftValueOriginal = context.Evaluate(Left);
var leftValue = leftValueOriginal;
var rightValueOriginal = context.Evaluate(Right);
object rightValue = rightValueOriginal;
if (Operator == ScriptBinaryOperator.EmptyCoalescing)
{
context.Result = leftValue ?? rightValue;
return;
}
else if (Operator == ScriptBinaryOperator.And || Operator == ScriptBinaryOperator.Or)
{
var leftBoolValue = ScriptValueConverter.ToBool(leftValue);
var rightBoolValue = ScriptValueConverter.ToBool(rightValue);
if (Operator == ScriptBinaryOperator.And)
{
context.Result = leftBoolValue && rightBoolValue;
}
else
{
context.Result = leftBoolValue || rightBoolValue;
}
return;
}
else
{
switch (Operator)
{
case ScriptBinaryOperator.ShiftLeft:
case ScriptBinaryOperator.ShiftRight:
if (leftValue is IList || rightValue is IList)
{
// Special path for IList to allow custom binary expression
context.Result = ScriptArray.CustomOperator.EvaluateBinaryExpression(this, leftValue,
rightValue);
return;
}
break;
case ScriptBinaryOperator.CompareEqual:
case ScriptBinaryOperator.CompareNotEqual:
case ScriptBinaryOperator.CompareGreater:
case ScriptBinaryOperator.CompareLess:
case ScriptBinaryOperator.CompareGreaterOrEqual:
case ScriptBinaryOperator.CompareLessOrEqual:
case ScriptBinaryOperator.Add:
case ScriptBinaryOperator.Substract:
case ScriptBinaryOperator.Multiply:
case ScriptBinaryOperator.Divide:
case ScriptBinaryOperator.DivideRound:
case ScriptBinaryOperator.Modulus:
case ScriptBinaryOperator.RangeInclude:
case ScriptBinaryOperator.RangeExclude:
var leftType = leftValue?.GetType();
var rightType = rightValue?.GetType();
if (leftValue is string || rightValue is string)
{
context.Result = CalculateToString(Operator, leftValue, rightValue);
{
// TODO: Log an error if CalculateToString return null?
//context.LogError(Span, $"Operation [{Operator}] on strings not supported");
}
}
else
{
context.Result = Calculate(Operator, leftValue, leftType, rightValue, rightType);
}
return;
}
}
throw new ScriptRuntimeException(Span, $"Operator [{Operator.ToText()}] is not implemented for the left [{Left}] / right [{Right}]");
}