///////////////////////////////////////////////////////////////////////////////// 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); }
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))); }