builder.go 1.3 KB

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