| File: Microsoft\CSharp\RuntimeBinder\Semantics\Tree\ExpressionIterator.cs | Web Access |
| Project: src\runtime\src\libraries\Microsoft.CSharp\src\Microsoft.CSharp.csproj (Microsoft.CSharp) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace Microsoft.CSharp.RuntimeBinder.Semantics { // ExpressionIterator is an iterator for EXPRLISTs, designed to be used // in the following way: // // for (ExpressionIterator it(list); !it.AtEnd(); it.MoveNext()) // { // EXPR expr = it.Current(); // ... // ... // work with expr // } // // The constructor takes an EXPR which can point to either an EXPRLIST // or a non-list EXPR, or nothing. // // Upon construction, the iterator's current element is the first element // in the list, which is to say it's not necessary to call MoveNext // before usage. AtEnd is true iff the iterator's current element is // beyond the last element of the list. These semantics differ from // IEnumerator in the framework, but are natural for usage in the C++ // for-loop as above. // // Outside of a for loop, usage might look like this: // // ExpressionIterator it(list); // EXPR expr1 = it.Current(); // it.MoveNext(); // EXPR expr2 = it.Current(); // it.MoveNext(); // EXPR expr3 = it.Current(); // it.MoveNext(); // // This would get the first three elements in a list. Also available is the // static Count: // // int n = ExpressionIterator::Count(list); internal sealed class ExpressionIterator { public ExpressionIterator(Expr pExpr) { Init(pExpr); } public bool AtEnd() { return _pCurrent == null && _pList == null; } public Expr Current() { return _pCurrent; } public void MoveNext() { if (AtEnd()) { return; } else if (_pList == null) { _pCurrent = null; } else { Init(_pList.OptionalNextListNode); } } public static int Count(Expr pExpr) { int c = 0; for (ExpressionIterator it = new ExpressionIterator(pExpr); !it.AtEnd(); it.MoveNext()) { ++c; } return c; } private ExprList _pList; private Expr _pCurrent; private void Init(Expr pExpr) { if (pExpr == null) { _pList = null; _pCurrent = null; } else if (pExpr is ExprList pList) { _pList = pList; _pCurrent = pList.OptionalElement; } else { _pList = null; _pCurrent = pExpr; } } } }