59 lines
909 B
Go
59 lines
909 B
Go
package ast
|
|
|
|
type Builder struct {
|
|
nodes []Node
|
|
lastIdx int
|
|
}
|
|
|
|
type Reference struct {
|
|
idx int
|
|
set bool
|
|
}
|
|
|
|
func (r Reference) Valid() bool {
|
|
return r.set
|
|
}
|
|
|
|
func (b *Builder) Finish() *Root {
|
|
r := &Root{
|
|
nodes: b.nodes,
|
|
}
|
|
b.nodes = nil
|
|
|
|
for i := range r.nodes {
|
|
r.nodes[i].root = r
|
|
}
|
|
|
|
return r
|
|
}
|
|
|
|
func (b *Builder) Push(n Node) Reference {
|
|
b.lastIdx = len(b.nodes)
|
|
b.nodes = append(b.nodes, n)
|
|
return Reference{
|
|
idx: b.lastIdx,
|
|
set: true,
|
|
}
|
|
}
|
|
|
|
func (b *Builder) PushAndChain(n Node) Reference {
|
|
newIdx := len(b.nodes)
|
|
b.nodes = append(b.nodes, n)
|
|
if b.lastIdx >= 0 {
|
|
b.nodes[b.lastIdx].next = newIdx
|
|
}
|
|
b.lastIdx = newIdx
|
|
return Reference{
|
|
idx: b.lastIdx,
|
|
set: true,
|
|
}
|
|
}
|
|
|
|
func (b *Builder) AttachChild(parent Reference, child Reference) {
|
|
b.nodes[parent.idx].child = child.idx
|
|
}
|
|
|
|
func (b *Builder) Chain(from Reference, to Reference) {
|
|
b.nodes[from.idx].next = to.idx
|
|
}
|