/// <summary> /// Evalaute this node and return result. /// </summary> /// <param name="thisObject">Reference to object that is exposed as 'this'.</param> /// <returns>Result value and type of that result.</returns> public override EvalResult Evaluate(object thisObject) { // Always evaluate the first child EvalResult left = this[0].Evaluate(thisObject); // We can only handle a boolean result if (left.Type != TypeCode.Boolean) { // Try and perform implicit conversion to a boolean if (ImplicitConverter.CanConvertToBoolean(left.Value, _language)) { left.Type = TypeCode.Boolean; left.Value = ImplicitConverter.ConvertToBoolean(left.Value, _language); } else { throw new ApplicationException("Operator '" + OperationString + "' can only operate on 'bool' types."); } } switch (Operation) { case CompareOp.Or: // If 'true' then there is no need to evaluate the right side if ((bool)left.Value) { return(left); } break; case CompareOp.And: // If 'false' then there is no need to evaluate the right side if (!(bool)left.Value) { return(left); } break; default: throw new ApplicationException("Unimplemented conditional logical operator '" + Operation.ToString() + "'."); } // Need to evaluate the second child left = this[1].Evaluate(thisObject); // We can only handle a boolean result if (left.Type != TypeCode.Boolean) { // Try and perform implicit conversion to a boolean if (ImplicitConverter.CanConvertToBoolean(left.Value, _language)) { left.Type = TypeCode.Boolean; left.Value = ImplicitConverter.ConvertToBoolean(left.Value, _language); } else { throw new ApplicationException("Operator '" + OperationString + "' can only operate on 'bool' types."); } } // Just return whatever the result is as the result of the conditional operation return(left); }