File tree Expand file tree Collapse file tree 2 files changed +67
-9
lines changed
src/Domain/HydraScript.Domain.FrontEnd/Parser/Impl/Ast Expand file tree Collapse file tree 2 files changed +67
-9
lines changed Original file line number Diff line number Diff line change 11using System . Collections ;
2+ using System . Runtime . CompilerServices ;
23
34namespace HydraScript . Domain . FrontEnd . Parser . Impl . Ast ;
45
@@ -22,24 +23,18 @@ public virtual void InitScope(Scope? scope = null)
2223 protected virtual IReadOnlyList < IAbstractSyntaxTreeNode > Children { get ; } = [ ] ;
2324
2425 public IEnumerator < IAbstractSyntaxTreeNode > GetEnumerator ( ) =>
25- Children . ToList ( ) . GetEnumerator ( ) ;
26+ Children . GetEnumerator ( ) ;
2627
2728 IEnumerator IEnumerable . GetEnumerator ( ) =>
28- GetEnumerator ( ) ;
29+ Children . GetEnumerator ( ) ;
2930
3031 public int Count => Children . Count ;
3132
3233 public IAbstractSyntaxTreeNode this [ int index ] =>
3334 Children [ index ] ;
3435
35- public IReadOnlyList < IAbstractSyntaxTreeNode > GetAllNodes ( )
36- {
37- List < IAbstractSyntaxTreeNode > result = [ this ] ;
38- for ( var index = 0 ; index < Children . Count ; index ++ )
39- result . AddRange ( Children [ index ] . GetAllNodes ( ) ) ;
36+ public IReadOnlyList < IAbstractSyntaxTreeNode > GetAllNodes ( ) => new TraverseEnumerator ( this ) . ToList ( ) ;
4037
41- return result ;
42- }
4338
4439 /// <summary>
4540 /// Метод возвращает <c>true</c>, если узел - потомок заданного типа и выполняется заданное условие.<br/>
Original file line number Diff line number Diff line change 1+ using System . Collections ;
2+ using System . Runtime . CompilerServices ;
3+
4+ namespace HydraScript . Domain . FrontEnd . Parser . Impl . Ast
5+ {
6+ /// <summary>
7+ /// Post in Telegram: https://t.me/csharp_gepard/89
8+ /// </summary>
9+ internal struct TraverseEnumerator :
10+ IEnumerator < IAbstractSyntaxTreeNode > ,
11+ IEnumerable < IAbstractSyntaxTreeNode >
12+ {
13+ [ ThreadStatic ] private static Stack < IAbstractSyntaxTreeNode > ? _buffer ;
14+
15+ private IAbstractSyntaxTreeNode _current ;
16+ public IAbstractSyntaxTreeNode Current
17+ {
18+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
19+ get => _current ;
20+ }
21+
22+ private readonly Stack < IAbstractSyntaxTreeNode > _stack ;
23+ public TraverseEnumerator ( IAbstractSyntaxTreeNode parent )
24+ {
25+ var stack = _buffer ?? new Stack < IAbstractSyntaxTreeNode > ( 128 ) ;
26+ _buffer = null ;
27+
28+ for ( int i = 0 ; i < parent . Count ; i ++ )
29+ stack . Push ( parent [ i ] ) ;
30+
31+ _stack = stack ;
32+ _current = null ! ;
33+ }
34+ public bool MoveNext ( )
35+ {
36+ var stack = _stack ;
37+ if ( stack . Count == 0 )
38+ return false ;
39+
40+ var current = _stack . Pop ( ) ;
41+
42+ for ( int i = 0 ; i < current . Count ; i ++ )
43+ stack . Push ( current [ i ] ) ;
44+
45+ _current = current ;
46+ return true ;
47+ }
48+
49+ public void Dispose ( )
50+ {
51+ _stack . Clear ( ) ;
52+ _buffer = _stack ;
53+ }
54+
55+ public void Reset ( ) { }
56+ [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
57+ public IEnumerator < IAbstractSyntaxTreeNode > GetEnumerator ( ) => this ;
58+
59+ IEnumerator IEnumerable . GetEnumerator ( ) => this ;
60+
61+ object IEnumerator . Current => Current ;
62+ }
63+ }
You can’t perform that action at this time.
0 commit comments