/// <summary>
        /// Compares two expressions.
        /// </summary>
        /// <param name="other">The other expression.</param>
        protected bool IsExpressionEqual(IBinaryConditionalExpression other)
        {
            Debug.Assert(other != null);

            bool Result = true;

            Result &= Expression.IsExpressionEqual((IExpression)LeftExpression, (IExpression)other.LeftExpression);
            Result &= Conditional == other.Conditional;
            Result &= Expression.IsExpressionEqual((IExpression)RightExpression, (IExpression)other.RightExpression);

            return(Result);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="CSharpBinaryConditionalExpression"/> class.
 /// </summary>
 /// <param name="context">The creation context.</param>
 /// <param name="source">The Easly expression from which the C# expression is created.</param>
 protected CSharpBinaryConditionalExpression(ICSharpContext context, IBinaryConditionalExpression source)
     : base(context, source)
 {
     LeftExpression  = Create(context, (IExpression)source.LeftExpression);
     RightExpression = Create(context, (IExpression)source.RightExpression);
 }
 /// <summary>
 /// Creates a new C# expression.
 /// </summary>
 /// <param name="context">The creation context.</param>
 /// <param name="source">The Easly expression from which the C# expression is created.</param>
 public static ICSharpBinaryConditionalExpression Create(ICSharpContext context, IBinaryConditionalExpression source)
 {
     return(new CSharpBinaryConditionalExpression(context, source));
 }
        /// <summary>
        /// Finds the matching nodes of a <see cref="IBinaryConditionalExpression"/>.
        /// </summary>
        /// <param name="node">The agent expression to check.</param>
        /// <param name="errorList">The list of errors found.</param>
        /// <param name="resolvedResult">The expression result types upon return.</param>
        /// <param name="resolvedException">Exceptions the expression can throw upon return.</param>
        /// <param name="constantSourceList">Sources of the constant expression upon return, if any.</param>
        /// <param name="expressionConstant">The constant value upon return, if any.</param>
        public static bool ResolveCompilerReferences(IBinaryConditionalExpression node, IErrorList errorList, out IResultType resolvedResult, out IResultException resolvedException, out ISealableList <IExpression> constantSourceList, out ILanguageConstant expressionConstant)
        {
            resolvedResult     = null;
            resolvedException  = null;
            constantSourceList = new SealableList <IExpression>();
            expressionConstant = NeutralLanguageConstant.NotConstant;

            IExpression LeftExpression = (IExpression)node.LeftExpression;

            BaseNode.ConditionalTypes Conditional = node.Conditional;
            IExpression RightExpression           = (IExpression)node.RightExpression;
            IClass      EmbeddingClass            = node.EmbeddingClass;

            bool IsLeftClassType  = Expression.GetClassTypeOfExpression(LeftExpression, errorList, out IClassType LeftExpressionClassType);
            bool IsRightClassType = Expression.GetClassTypeOfExpression(RightExpression, errorList, out IClassType RightExpressionClassType);

            if (!IsLeftClassType || !IsRightClassType)
            {
                return(false);
            }

            Expression.IsLanguageTypeAvailable(LanguageClasses.Boolean.Guid, node, out ITypeName BooleanTypeName, out ICompiledType BooleanType);
            Expression.IsLanguageTypeAvailable(LanguageClasses.Event.Guid, node, out ITypeName EventTypeName, out ICompiledType EventType);

            Debug.Assert(LeftExpressionClassType == BooleanType || LeftExpressionClassType == EventType);
            Debug.Assert(RightExpressionClassType == BooleanType || RightExpressionClassType == EventType);

            if (LeftExpressionClassType != RightExpressionClassType)
            {
                errorList.AddError(new ErrorInvalidExpression(LeftExpression));
                return(false);
            }

            bool IsEventExpression = LeftExpressionClassType != BooleanType;

            if (IsEventExpression)
            {
                if (!((node.ParentSource is IBinaryConditionalExpression) || (node.ParentSource is IConditional) || (node.ParentSource is ICheckInstruction)))
                {
                    errorList.AddError(new ErrorInvalidExpression(node));
                    return(false);
                }

                resolvedResult = new ResultType(EventTypeName, EventType, string.Empty);
            }
            else
            {
                resolvedResult = new ResultType(BooleanTypeName, BooleanType, string.Empty);
            }

            constantSourceList.Add(LeftExpression);
            constantSourceList.Add(RightExpression);

            resolvedException = new ResultException();
            ResultException.Merge(resolvedException, LeftExpression.ResolvedException);
            ResultException.Merge(resolvedException, RightExpression.ResolvedException);

#if COVERAGE
            Debug.Assert(node.IsComplex);
#endif

            return(true);
        }