mirror of
https://github.com/WiiLink24/wfc-server.git
synced 2026-03-22 01:54:12 -05:00
129 lines
2.9 KiB
Go
129 lines
2.9 KiB
Go
// Modified from github.com/zdebeer99/goexpression
|
|
package filter
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type TreeNode struct {
|
|
Value Token
|
|
parent *TreeNode
|
|
items []*TreeNode
|
|
}
|
|
|
|
// NewTreeElement Creates a new TreeElement.
|
|
func NewTreeNode(value Token) *TreeNode {
|
|
return &TreeNode{value, nil, make([]*TreeNode, 0)}
|
|
}
|
|
|
|
// Parent Returns the current element parent
|
|
func (this *TreeNode) Parent() *TreeNode {
|
|
return this.parent
|
|
}
|
|
|
|
func (this *TreeNode) Root() *TreeNode {
|
|
p := this
|
|
for p.parent != nil {
|
|
p = p.parent
|
|
}
|
|
return p
|
|
}
|
|
|
|
// setParent sets the current nodes parent value.
|
|
// Warning: does not add the node as a child
|
|
func (this *TreeNode) setParent(element *TreeNode) {
|
|
if this.parent != nil {
|
|
panic("TreeNode already attached to a parent node")
|
|
}
|
|
this.parent = element
|
|
}
|
|
|
|
func (this *TreeNode) LastElement() *TreeNode {
|
|
if len(this.items) == 0 {
|
|
return nil
|
|
}
|
|
return this.items[len(this.items)-1]
|
|
}
|
|
|
|
func (this *TreeNode) Last() Token {
|
|
last := this.LastElement()
|
|
if last != nil {
|
|
return last.Value
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *TreeNode) Items() []*TreeNode {
|
|
return this.items
|
|
}
|
|
|
|
// Add adds a TreeElement to the end of the children items of the current node.
|
|
func (this *TreeNode) AddElement(element *TreeNode) *TreeNode {
|
|
element.setParent(this)
|
|
this.items = append(this.items, element)
|
|
return element
|
|
}
|
|
|
|
// Add adds a value to the end of the children items of the current node.
|
|
func (this *TreeNode) Add(value Token) *TreeNode {
|
|
element := NewTreeNode(value)
|
|
return this.AddElement(element)
|
|
}
|
|
|
|
// Push, removes the current element from its current parent, place the new value
|
|
// in its place and add the current element to the new element. there by pushing the current
|
|
// element down the hierachy.
|
|
// Example:
|
|
// tree: A(B)
|
|
// B.Push(C)
|
|
// tree: A(C(B))
|
|
func (this *TreeNode) PushElement(element *TreeNode) *TreeNode {
|
|
parent := this.Parent()
|
|
if parent != nil {
|
|
//replace the current node with the new node
|
|
index := parent.indexOf(this)
|
|
parent.items[index] = element
|
|
element.setParent(parent)
|
|
this.parent = nil
|
|
}
|
|
//add the current node to the new node
|
|
element.AddElement(this)
|
|
return element
|
|
}
|
|
|
|
func (this *TreeNode) Push(value Token) *TreeNode {
|
|
return this.PushElement(NewTreeNode(value))
|
|
}
|
|
|
|
// FindChildElement Finds a child element in the current nodes children
|
|
func (this *TreeNode) indexOf(element *TreeNode) int {
|
|
for i, v := range this.items {
|
|
if v == element {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
func (this *TreeNode) StringContent() string {
|
|
lines := make([]string, len(this.items))
|
|
for i, v := range this.items {
|
|
lines[i] = v.String()
|
|
}
|
|
if this.Value.Error() != nil {
|
|
return fmt.Sprintf("[ERROR: %s]", this.Value.Error())
|
|
} else if len(lines) > 0 {
|
|
return fmt.Sprintf("%s", strings.Join(lines, ","))
|
|
} else {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
func (this *TreeNode) String() string {
|
|
if this.StringContent() == "" {
|
|
return this.Value.String()
|
|
}
|
|
return fmt.Sprintf("[%s:%s]", this.Value.String(), this.StringContent())
|
|
}
|