equal
deleted
inserted
replaced
|
1 package unstable |
|
2 |
|
3 // root contains a full AST. |
|
4 // |
|
5 // It is immutable once constructed with Builder. |
|
6 type root struct { |
|
7 nodes []Node |
|
8 } |
|
9 |
|
10 // Iterator over the top level nodes. |
|
11 func (r *root) Iterator() Iterator { |
|
12 it := Iterator{} |
|
13 if len(r.nodes) > 0 { |
|
14 it.node = &r.nodes[0] |
|
15 } |
|
16 return it |
|
17 } |
|
18 |
|
19 func (r *root) at(idx reference) *Node { |
|
20 return &r.nodes[idx] |
|
21 } |
|
22 |
|
23 type reference int |
|
24 |
|
25 const invalidReference reference = -1 |
|
26 |
|
27 func (r reference) Valid() bool { |
|
28 return r != invalidReference |
|
29 } |
|
30 |
|
31 type builder struct { |
|
32 tree root |
|
33 lastIdx int |
|
34 } |
|
35 |
|
36 func (b *builder) Tree() *root { |
|
37 return &b.tree |
|
38 } |
|
39 |
|
40 func (b *builder) NodeAt(ref reference) *Node { |
|
41 return b.tree.at(ref) |
|
42 } |
|
43 |
|
44 func (b *builder) Reset() { |
|
45 b.tree.nodes = b.tree.nodes[:0] |
|
46 b.lastIdx = 0 |
|
47 } |
|
48 |
|
49 func (b *builder) Push(n Node) reference { |
|
50 b.lastIdx = len(b.tree.nodes) |
|
51 b.tree.nodes = append(b.tree.nodes, n) |
|
52 return reference(b.lastIdx) |
|
53 } |
|
54 |
|
55 func (b *builder) PushAndChain(n Node) reference { |
|
56 newIdx := len(b.tree.nodes) |
|
57 b.tree.nodes = append(b.tree.nodes, n) |
|
58 if b.lastIdx >= 0 { |
|
59 b.tree.nodes[b.lastIdx].next = newIdx - b.lastIdx |
|
60 } |
|
61 b.lastIdx = newIdx |
|
62 return reference(b.lastIdx) |
|
63 } |
|
64 |
|
65 func (b *builder) AttachChild(parent reference, child reference) { |
|
66 b.tree.nodes[parent].child = int(child) - int(parent) |
|
67 } |
|
68 |
|
69 func (b *builder) Chain(from reference, to reference) { |
|
70 b.tree.nodes[from].next = int(to) - int(from) |
|
71 } |