fix errors in interpreter. add a enumerator for tree. working on tree optimizer

This commit is contained in:
Youmu Liu
2026-02-10 18:31:30 +08:00
parent 807658111c
commit 4735b987f4
4 changed files with 221 additions and 136 deletions
@@ -33,6 +33,7 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Xml.Linq;
using System.Xml.Schema;
namespace StgSharp.RegularAnalysis.Abstraction
@@ -81,122 +82,168 @@ namespace StgSharp.RegularAnalysis.Abstraction
public IEnumerator<TNode> GetEnumerator()
{
return new Enumerator(this);
return new TreeEnumerator<TNode, TType>(this);
}
private class Enumerator : IEnumerator<TNode>
}
internal class TreeEnumerator<TNode, TType>(
TNode root
) : IEnumerator<TNode> where TNode : ISyntaxNode<TNode, TType> where TType : unmanaged
{
private bool _completed = false;
private int _state, _target; // 0: not started, 1: on right, 2: ended
private Stack<Record> _recycle = [];
private Stack<Record> _stack = [];
// private TNode _lRoot;
private TNode _root = root;
internal TreeEnumerator(
AbstractSyntaxTree<TNode, TType> tree
)
: this(tree.Root) { }
public TNode Current
{
get
{
if (_stack.TryPeek(out Record? r)) {
return r.Node;
}
return TNode.Empty;
}
}
public void Dispose()
{
return;
}
public bool MoveNext()
{
if (_completed) {
return false;
}
while (_stack.TryPeek(out Record? cur))
{
switch (cur.State)
{
case 0:
cur.State++;
if (TNode.IsNullOrEmpty(cur.Node.Left))
{
goto case 1;
} else
{
_stack.Push(GetNewRecord(cur.Node.Left));
return true;
}
case 1:
cur.State++;
if (TNode.IsNullOrEmpty(cur.Node.Right))
{
goto case 2;
} else
{
_stack.Push(GetNewRecord(cur.Node.Right));
return true;
}
case 2:
if (TNode.IsNullOrEmpty(cur.Node.Next))
{
_recycle.Push(_stack.Pop());
if (_stack.Count == 0)
{
_completed = true;
return false;
}
} else
{
_stack.Push(GetNewRecord(cur.Node.Next));
return true;
}
break;
default:
break;
}
}
_stack.Push(GetNewRecord(_root));
return true;
}
public void Reset()
{
_completed = false;
_stack.Clear();
_state = 0;
}
public void SkipNode()
{
if (_stack.TryPop(out Record? r)) {
_recycle.Push(r);
}
}
public void SkipOnce()
{
if (_stack.TryPeek(out Record? cur))
{
switch (cur.State)
{
case 0:
cur.State++;
break;
case 1:
cur.State++;
break;
case 2:
if (TNode.IsNullOrEmpty(cur.Node.Next))
{
_recycle.Push(_stack.Pop());
if (_stack.Count == 0)
{
_completed = true;
return;
}
} else
{
_stack.Push(GetNewRecord(cur.Node.Next));
}
break;
default:
break;
}
}
}
private Record GetNewRecord(
TNode node
)
{
if (_recycle.TryPop(out Record? r))
{
r.State = 0;
r.Node = node;
return r;
}
return new Record(node, 0);
}
object IEnumerator.Current => Current;
private class Record(
TNode node,
int state
)
{
private int _state,_target; // 0: not started, 1: on right, 2: ended
private Stack<Record> _recycle;
private Stack<Record> _stack;
private TNode _lRoot;
private TNode _root;
public int State { get; set; } = state;
public Enumerator(
AbstractSyntaxTree<TNode, TType> tree
)
{
_root = tree.Root;
_stack = [];
_recycle = [];
}
public TNode Current
{
get
{
if (_stack.TryPeek(out Record? r)) {
return r.Node;
}
return TNode.Empty;
}
}
public void Dispose()
{
return;
}
public bool MoveNext()
{
while (_stack.TryPeek(out Record? cur))
{
switch (cur.State)
{
case 0:
cur.State++;
if (TNode.IsNullOrEmpty(cur.Node.Left))
{
goto case 1;
} else
{
_stack.Push(GetNewRecord(cur.Node.Left));
return true;
}
case 1:
cur.State++;
if (TNode.IsNullOrEmpty(cur.Node.Right))
{
goto case 2;
} else
{
_stack.Push(GetNewRecord(cur.Node.Right));
return true;
}
case 2:
if (TNode.IsNullOrEmpty(cur.Node.Next))
{
_recycle.Push(_stack.Pop());
if (_stack.Count == 0) {
return false;
}
} else
{
_stack.Push(GetNewRecord(cur.Node.Next));
return true;
}
break;
default:
break;
}
}
_stack.Push(GetNewRecord(_root));
return true;
}
public void Reset()
{
_stack.Clear();
_state = 0;
}
private Record GetNewRecord(
TNode node
)
{
if (_recycle.TryPop(out Record? r))
{
r.State = 0;
r.Node = node;
return r;
}
return new Record(node, 0);
}
object IEnumerator.Current => Current;
private class Record(
TNode node,
int state
)
{
public int State { get; set; } = state;
public TNode Node { get; set; } = node;
}
public TNode Node { get; set; } = node;
}