-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathAbstractSyntaxTreeNode.cs
More file actions
67 lines (51 loc) · 2.42 KB
/
Copy pathAbstractSyntaxTreeNode.cs
File metadata and controls
67 lines (51 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System.Collections;
using ZLinq;
namespace HydraScript.Domain.FrontEnd.Parser.Impl.Ast;
public abstract class AbstractSyntaxTreeNode : IAbstractSyntaxTreeNode
{
public IAbstractSyntaxTreeNode? Parent { get; internal set; }
public Scope Scope { get; protected set; } = Scope.Empty;
/// <summary>Базовая стратегия - инициализация через родительский узел</summary>
/// <param name="scope">Обязательно <c>null</c></param>
public virtual void InitScope(Scope? scope = null)
{
if (scope is not null)
throw new ArgumentException("'scope' must be null");
Scope = Parent?.Scope ?? Scope.Empty;
}
public string Segment { get; init; } = string.Empty;
protected virtual IReadOnlyList<IAbstractSyntaxTreeNode> Children { get; } = [];
public IEnumerator<IAbstractSyntaxTreeNode> GetEnumerator() =>
Children.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() =>
Children.GetEnumerator();
public int Count => Children.Count;
public IAbstractSyntaxTreeNode this[int index] =>
Children[index];
public IReadOnlyList<IAbstractSyntaxTreeNode> GetAllNodes() =>
new TraverseEnumerator(this).AsValueEnumerable().ToArray();
/// <summary>
/// Метод возвращает <c>true</c>, если узел - потомок заданного типа и выполняется заданное условие.<br/>
/// В случае, когда условие не задано, проверяется просто соответствие типов.
/// </summary>
/// <param name="condition">Условие для родителя</param>
/// <typeparam name="T">Проверяемый тип родителя</typeparam>
public bool ChildOf<T>(Predicate<T>? condition = null) where T : IAbstractSyntaxTreeNode
{
var parent = Parent;
while (parent != null)
{
if (parent is T node)
{
return condition?.Invoke(node) ?? true;
}
parent = parent.Parent;
}
return false;
}
public virtual TReturn Accept<TReturn>(IVisitor<IAbstractSyntaxTreeNode, TReturn> visitor) =>
visitor.Visit(this);
protected abstract string NodeRepresentation();
public override string ToString() =>
$"{GetHashCode()} [label=\"{NodeRepresentation()}\"]";
}