builder.go raw

   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  }
  72