public override object VisitAndExpression([NotNull] DoshikParser.AndExpressionContext context)
        {
            SetWholeExpression(context);
            VisitChildren(context);
            _compilationContext.SetParsingAntlrContext(context);

            var node = new AndExpressionNode(context);

            node.Left  = Sequence.FindExpressionByAntlrContext(context.left);
            node.Right = Sequence.FindExpressionByAntlrContext(context.right);

            Sequence.Sequence.Add(node);

            return(null);
        }
示例#2
0
        // ToDo: Про перегрузку операторов op_ConditionalAnd (&&) и op_ConditionalOr (||)
        // Эти операторы перегружены только у bool. И зачем это сделано непонятно - это не обычный вызов функции. Эта булева
        // логика должна выполняться непосредственно компилятором, а не внешним вызовом. Видимо это было сделано просто для удобства работы в графах.
        // смысл в том что в случае выражения к примеру if (a != null && a.DoThings() == 5) внутри стоит оператор && - он должен сначала
        // посчитать истинность левого операнда и ТОЛЬКО ЕСЛИ он истинен - оператор может выполнить правый операнд. А при обычном вызове
        // метода сначала просчитываются все операнды (левый, правый) а потом только вызывается метод с этими операндами. Тут же действие должно
        // быть между просчетом левого и правого операнда, то есть его нельзя посчитать внешним вызовом, это должен делать компилятор - посмотреть
        // истинное ли выражение слева и сгенерировать по нему JUMP_IF_FALSE. То есть операнд справа НЕ ДОЛЖЕН ВЫПОЛНИТЬСЯ если операнд слева == false
        // Аналогичная ситуация с оператором || - но там я уже не помню как логика идет.
        // То есть надо вместо метода тут возвращать отдельный вид expression-а (можно сделать его общим для and/or)
        //
        // https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#user-defined-conditional-logical-operators
        // x && y превращается в T.false(x) ? x : T.&(x, y)
        // x || y превращается в T.true(x) ? x : T.|(x, y)
        // можно попробовать возвращать в этих слуаях искусственно сгенерированый IfExpression
        //
        // Похожая ситуация идет при обработке оператора ifexpression - там тоже просчет операндов зависит от результата условия и там также идут JUMP_IF_FALSE

        private IExpression HandleAndExpressionNode(AndExpressionNode node)
        {
            // ToDo: читать выше - тут не должно быть вызова метода
            return(CreateStaticMethodCallExpressionForBinaryOperator("op_ConditionalAnd", node.Left, node.Right));
        }