예제 #1
0
        /////////////////////////////////////////////////////////////////////////////////

        private ExprStatement DispatchStatementList(ExprStatement expr)
        {
            Debug.Assert(expr != null);

            ExprStatement first = expr;
            ExprStatement pexpr = first;

            while (pexpr != null)
            {
                // If the processor replaces the statement -- potentially with
                // null, another statement, or a list of statements -- then we
                // make sure that the statement list is hooked together correctly.

                ExprStatement next = pexpr.OptionalNextStatement;
                ExprStatement old  = pexpr;

                // Unhook the next one.
                pexpr.OptionalNextStatement = null;

                Expr result = Dispatch(pexpr);
                Debug.Assert(result == null || result.isSTMT());

                if (pexpr == first)
                {
                    first = result?.asSTMT();
                }
                else
                {
                    pexpr.OptionalNextStatement = result?.asSTMT();
                }

                // A transformation may return back a list of statements (or
                // if the statements have been determined to be unnecessary,
                // perhaps it has simply returned null.)
                //
                // Skip visiting the new list, then hook the tail of the old list
                // up to the end of the new list.

                while (pexpr.OptionalNextStatement != null)
                {
                    pexpr = pexpr.OptionalNextStatement;
                }

                // Re-hook the next pointer.
                pexpr.OptionalNextStatement = next;
            }
            return(first);
        }
예제 #2
0
        public Expr Visit(Expr pExpr)
        {
            if (pExpr == null)
            {
                return(null);
            }

            Expr pResult;

            if (IsCachedExpr(pExpr, out pResult))
            {
                return(pResult);
            }

            if (pExpr.isSTMT())
            {
                return(CacheExprMapping(pExpr, DispatchStatementList(pExpr.asSTMT())));
            }

            return(CacheExprMapping(pExpr, Dispatch(pExpr)));
        }