Esempio n. 1
0
        /// <summary>
        /// Recursively analyze the definition of a function.
        /// </summary>
        private static void AnalyzeDefinition(QilNode nd)
        {
            Debug.Assert(XmlILConstructInfo.Read(nd).PushToWriterLast,
                         "Only need to analyze expressions which will be compiled in push mode.");

            switch (nd.NodeType)
            {
            case QilNodeType.Invoke:
                // Invoke node can either be compiled as IteratorThenWriter, or Writer.
                // Since IteratorThenWriter involves caching the results of the function call
                // and iterating over them, .tailcall cannot be used
                if (XmlILConstructInfo.Read(nd).ConstructMethod == XmlILConstructMethod.Writer)
                {
                    OptimizerPatterns.Write(nd).AddPattern(OptimizerPatternName.TailCall);
                }
                break;

            case QilNodeType.Loop: {
                // Recursively analyze Loop return value
                QilLoop ndLoop = (QilLoop)nd;
                if (ndLoop.Variable.NodeType == QilNodeType.Let || !ndLoop.Variable.Binding.XmlType.MaybeMany)
                {
                    AnalyzeDefinition(ndLoop.Body);
                }
                break;
            }

            case QilNodeType.Sequence: {
                // Recursively analyze last expression in Sequence
                QilList ndSeq = (QilList)nd;
                if (ndSeq.Count > 0)
                {
                    AnalyzeDefinition(ndSeq[ndSeq.Count - 1]);
                }
                break;
            }

            case QilNodeType.Choice: {
                // Recursively analyze Choice branches
                QilChoice ndChoice = (QilChoice)nd;
                for (int i = 0; i < ndChoice.Branches.Count; i++)
                {
                    AnalyzeDefinition(ndChoice.Branches[i]);
                }
                break;
            }

            case QilNodeType.Conditional: {
                // Recursively analyze Conditional branches
                QilTernary ndCond = (QilTernary)nd;
                AnalyzeDefinition(ndCond.Center);
                AnalyzeDefinition(ndCond.Right);
                break;
            }

            case QilNodeType.Nop:
                AnalyzeDefinition(((QilUnary)nd).Child);
                break;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Analyze choice.
        /// </summary>
        protected virtual void AnalyzeChoice(QilChoice ndChoice, XmlILConstructInfo info)
        {
            PossibleXmlStates xstatesChoice;
            int idx;

            // Visit default branch; save resulting states
            idx = ndChoice.Branches.Count - 1;
            ndChoice.Branches[idx] = AnalyzeContent(ndChoice.Branches[idx]);
            xstatesChoice          = this.xstates;

            // Visit all other branches
            while (--idx >= 0)
            {
                // Restore starting states and visit the next branch
                this.xstates           = info.InitialStates;
                ndChoice.Branches[idx] = AnalyzeContent(ndChoice.Branches[idx]);

                // Choice ending states consist of combination of all branch states
                if (xstatesChoice != this.xstates)
                {
                    xstatesChoice = PossibleXmlStates.Any;
                }
            }

            this.xstates = xstatesChoice;
        }