-
Notifications
You must be signed in to change notification settings - Fork 15
/
astnode_value.go
124 lines (113 loc) · 3.05 KB
/
astnode_value.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
package rel
import (
"fmt"
"github.com/arr-ai/wbnf/ast"
"github.com/arr-ai/wbnf/wbnf"
"github.com/arr-ai/wbnf/parser"
)
func ASTNodeToValue(n ast.Node) Value {
switch n := n.(type) {
case ast.Leaf:
return ASTLeafToValue(n)
case ast.Branch:
return ASTBranchToValue(n)
case wbnf.GrammarNode:
return ASTNodeToValue(n.Node)
default:
panic(fmt.Errorf("unexpected: %v %[1]T", n))
}
}
func ASTLeafToValue(l ast.Leaf) Value {
s := l.Scanner()
return NewOffsetString([]rune(s.String()), s.Offset())
}
func ASTBranchToValue(b ast.Branch) Tuple {
result := EmptyTuple
for name, children := range b {
var value Value
switch name {
case "@choice":
ints := children.(ast.Many)
values := make([]Value, 0, len(ints))
for _, i := range ints {
values = append(values, NewNumber(float64(i.(ast.Extra).Data.(parser.Choice))))
}
value = NewArray(values...)
case "@rule":
value = NewString([]rune(string(children.(ast.One).Node.(ast.Extra).Data.(parser.Rule))))
case "@skip":
value = NewNumber(float64(children.(ast.One).Node.(ast.Extra).Data.(int)))
default:
switch c := children.(type) {
case ast.One:
value = ASTNodeToValue(c.Node)
case ast.Many:
values := make([]Value, 0, len(c))
for _, child := range c {
values = append(values, ASTNodeToValue(child))
}
value = NewArray(values...)
default:
panic(fmt.Errorf("unexpected: %v %[1]T", value))
}
}
result = result.With(name, value)
}
return result
}
func ASTNodeFromValue(value Value) ast.Node {
switch value := value.(type) {
case String:
return ASTLeafFromValue(value)
case Tuple:
return ASTBranchFromValue(value)
default:
panic(fmt.Errorf("unexpected: %v %[1]T", value))
}
}
func ASTLeafFromValue(s String) ast.Leaf {
return ast.Leaf(*parser.NewScannerAt(s.String(), s.offset, s.Count()))
}
func ASTBranchFromValue(b Tuple) ast.Branch {
result := ast.Branch{}
for i := b.Enumerator(); i.MoveNext(); {
name, value := i.Current()
var children ast.Children
switch name {
case "@choice":
values := value.(Array).values
ints := make(ast.Many, 0, len(values))
for _, v := range values {
ints = append(ints, ast.Extra{Data: parser.Choice(v.(Number).Float64())})
}
children = ints
case "@rule":
children = ast.One{Node: ast.Extra{Data: parser.Rule(value.(String).String())}}
case "@skip":
children = ast.One{Node: ast.Extra{Data: int(value.(Number).Float64())}}
default:
switch value := value.(type) {
case Tuple:
children = ast.One{Node: ASTBranchFromValue(value)}
case String:
children = ast.One{Node: ASTLeafFromValue(value)}
case GenericSet:
c := make(ast.Many, 0, value.Count())
for _, v := range value.OrderedValues() {
c = append(c, ASTNodeFromValue(v.(Tuple).MustGet(ArrayItemAttr)))
}
children = c
case Array:
c := make(ast.Many, 0, value.Count())
for _, v := range value.values {
c = append(c, ASTNodeFromValue(v))
}
children = c
default:
panic(fmt.Errorf("unexpected: %v %[1]T", value))
}
}
result[name] = children
}
return result
}