-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtreenode.go
127 lines (111 loc) · 2.88 KB
/
treenode.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package goexpression
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())
}