builder.go (1366B)
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 }