Exemplo n.º 1
0
        private expression GetCollectionItemsEqualCheckAfterGap(addressed_value matchingExpression,
                                                                List <pattern_parameter> toCompare,
                                                                CollectionDesugaringResult desugaringResult)
        {
            var        elemFromTail = 1;
            expression equalChecks  = null;

            foreach (var param in toCompare)
            {
                var indexerCall = new indexer(
                    matchingExpression,
                    new expression_list(
                        new bin_expr(
                            new method_call(
                                new dot_node(
                                    matchingExpression,
                                    new ident("Count", matchingExpression.source_context)),
                                new expression_list()),
                            new int32_const(elemFromTail, matchingExpression.source_context),
                            Operators.Minus),
                        matchingExpression.source_context),
                    matchingExpression.source_context);

                if (param is const_pattern_parameter constParam)
                {
                    var eqParams = new expression_list(
                        new List <expression>()
                    {
                        indexerCall,
                        constParam.const_param
                    }
                        );

                    var equalCall = new method_call(
                        new dot_node(
                            new ident("object"),
                            new ident("Equals")),
                        eqParams,
                        matchingExpression.source_context
                        );

                    equalChecks = equalChecks == null ? (expression)equalCall : bin_expr.LogicalAnd(equalChecks, equalCall);
                    desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(indexerCall, constParam.const_param));
                }

                if (param is collection_pattern_var_parameter varParam)
                {
                    desugaringResult.VarParametersDeclarations.Add(
                        new var_statement(varParam.identifier, indexerCall));
                }

                ++elemFromTail;
            }
            return(equalChecks);
        }
Exemplo n.º 2
0
        private expression GetCollectionItemsEqualCheckBeforeGap(addressed_value matchingExpression,
                                                                 List <pattern_parameter> toCompare,
                                                                 CollectionDesugaringResult desugaringResult)
        {
            var        fromIndex   = 0;
            expression equalChecks = null;

            foreach (var param in toCompare)
            {
                if (param is const_pattern_parameter constParam)
                {
                    var indexerCall = new indexer(
                        matchingExpression,
                        new expression_list(
                            new int32_const(fromIndex, matchingExpression.source_context),
                            matchingExpression.source_context),
                        matchingExpression.source_context);

                    var eqParams = new expression_list(
                        new List <expression>()
                    {
                        indexerCall,
                        constParam.const_param
                    }
                        );

                    var equalCall = new method_call(
                        new dot_node(
                            new ident("object"),
                            new ident("Equals")),
                        eqParams,
                        matchingExpression.source_context
                        );

                    equalChecks = equalChecks == null ? (expression)equalCall : bin_expr.LogicalAnd(equalChecks, equalCall);
                    desugaringResult.ElemTypeChecks.Add(GetTypeCompatibilityCheck(indexerCall, constParam.const_param));
                }

                if (param is collection_pattern_var_parameter varParam)
                {
                    desugaringResult.VarParametersDeclarations.Add(
                        new var_statement(varParam.identifier,
                                          GetIndexerCallForCollectionPattern(matchingExpression as addressed_value, fromIndex)));
                }
                ++fromIndex;
            }
            return(equalChecks);
        }
Exemplo n.º 3
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);
        }