-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompiler.go
73 lines (63 loc) · 1.61 KB
/
compiler.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
package nietzsche
import "errors"
type NodeLayer struct {
name string
negative bool
items []Node
}
type NodeGroupStack []NodeLayer
func NewStack() *NodeGroupStack {
return new(NodeGroupStack)
}
func (s *NodeGroupStack) NewLayer(name string, negative bool) {
layer := NodeLayer{name, negative, []Node{}}
*s = append(*s, layer)
}
func (s *NodeGroupStack) CloseLayer(name string) ([]Node, bool, error) {
length := len(*s)
lastLayer := (*s)[length-1]
if lastLayer.name != name {
return nil, false, errors.New("Unexpected close token " + name)
}
result := lastLayer.items
neg := lastLayer.negative
*s = (*s)[:length-1]
return result, neg, nil
}
func (s *NodeGroupStack) AddNode(section Node) {
length := len(*s)
lastLayer := (*s)[length-1]
lastLayer.items = append(lastLayer.items, section)
(*s)[length-1] = lastLayer
}
func Compile(tokens []Token) ([]Node, error) {
stack := NewStack()
stack.NewLayer("__root__", false)
for _, token := range tokens {
switch token.Type {
case TextToken:
stack.AddNode(NewTextNode(token.Value))
case ValueToken:
stack.AddNode(NewValueNode(token.Value))
case OpenGroupToken:
stack.NewLayer(token.Value, false)
case OpenInvertedGroupToken:
stack.NewLayer(token.Value, true)
case CloseGroupToken:
sections, neg, err := stack.CloseLayer(token.Value)
if err != nil {
return nil, err
}
if neg {
stack.AddNode(NewNegativeNode(token.Value, sections))
} else {
stack.AddNode(NewGroupNode(token.Value, sections))
}
}
}
sections, _, err := stack.CloseLayer("__root__")
if err != nil {
return nil, err
}
return sections, nil
}