예제 #1
0
 public virtual void visit(collection_pattern _collection_pattern)
 {
     DefaultVisit(_collection_pattern);
 }
예제 #2
0
        private CollectionDesugaringResult DesugarCollectionPattern(collection_pattern pattern, expression matchingExpression)
        {
            Debug.Assert(!pattern.IsRecursive, "All recursive patterns should be desugared into simple patterns at this point");

            var desugaringResult = new CollectionDesugaringResult();
            var collectionItems  = pattern.parameters;
            var gapItemMet       = false;
            var gapIndex         = 0;
            var exprBeforeGap    = new List <pattern_parameter>();
            var exprAfterGap     = new List <pattern_parameter>();

            for (int i = 0; i < collectionItems.Count; ++i)
            {
                if (collectionItems[i] is collection_pattern_gap_parameter)
                {
                    if (gapItemMet)
                    {
                        throw new SyntaxVisitorError("REPEATED_DOTDOT_COLLECTION_PATTERN_EXPR",
                                                     pattern.source_context);
                    }
                    gapItemMet = true;
                    gapIndex   = i;
                    continue;
                }

                if (gapItemMet)
                {
                    exprAfterGap.Insert(0, collectionItems[i]);
                }
                else
                {
                    exprBeforeGap.Add(collectionItems[i]);
                }
            }

            var successMatchingCheck = GetCollectionItemsEqualCheckBeforeGap(
                matchingExpression as addressed_value, exprBeforeGap, desugaringResult);

            if (gapItemMet && exprAfterGap.Count != 0)
            {
                var afterGapEqual = GetCollectionItemsEqualCheckAfterGap(
                    matchingExpression as addressed_value, exprAfterGap, desugaringResult);

                if (afterGapEqual != null)
                {
                    successMatchingCheck = successMatchingCheck == null ?
                                           afterGapEqual :
                                           bin_expr.LogicalAnd(successMatchingCheck, afterGapEqual);
                }
            }
            // если добавлять в and, то все равно ран тайм эррор, будто вычисляет все, даже если первое = false
            desugaringResult.CollectionLengthCheck = new bin_expr(
                new dot_node(matchingExpression as addressed_value, new ident(CountPropertyName), pattern.source_context),
                new int32_const(exprBeforeGap.Count + exprAfterGap.Count),
                Operators.GreaterEqual,
                pattern.source_context
                );

            if (!gapItemMet)
            {
                var lengthWithoutGapCheck = new bin_expr(
                    new dot_node(matchingExpression as addressed_value, new ident(CountPropertyName), pattern.source_context),
                    new int32_const(exprBeforeGap.Count),
                    Operators.Equal,
                    pattern.source_context
                    );
                successMatchingCheck = successMatchingCheck == null ?
                                       lengthWithoutGapCheck :
                                       bin_expr.LogicalAnd(lengthWithoutGapCheck, successMatchingCheck);
            }

            desugaringResult.SuccessMatchingCheck = successMatchingCheck == null ?
                                                    new bool_const(true) :
                                                    successMatchingCheck;
            return(desugaringResult);
        }