-
Notifications
You must be signed in to change notification settings - Fork 0
/
lang.go
102 lines (80 loc) · 1.62 KB
/
lang.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
package ergolas
import (
"fmt"
"strings"
)
var Debug = false
type NodeType string
var ErrorNodeType NodeType = "ErrorNode"
type NodeMetadata map[string]any
func (nm NodeMetadata) String() string {
sb := &strings.Builder{}
i := len(nm)
for k, v := range nm {
fmt.Fprintf(sb, `%s: "%v"`, k, v)
i--
if i > 0 {
fmt.Fprint(sb, ", ")
}
}
return sb.String()
}
type Node interface {
Type() NodeType
Children() []Node
Metadata() NodeMetadata
}
type listNode struct {
typ NodeType
children []Node
}
func (n listNode) Type() NodeType {
return n.typ
}
func (n listNode) Children() []Node {
return n.children
}
func (n listNode) Metadata() NodeMetadata {
return NodeMetadata{}
}
type leafNode struct {
typ NodeType
value any
}
func (n leafNode) Type() NodeType {
return n.typ
}
func (n leafNode) Children() []Node {
return nil
}
func (n leafNode) Metadata() NodeMetadata {
return NodeMetadata{"Value": n.value}
}
func PrintAST(node Node) {
printAST(node, 0)
}
func printAST(node Node, depth int) {
indent := strings.Repeat(" ", depth)
fmt.Printf("%s- %s", indent, node.Type())
meta := node.Metadata()
if len(meta) > 0 {
fmt.Printf(" { %s }\n", meta)
} else {
fmt.Printf("\n")
}
for _, n := range node.Children() {
printAST(n, depth+1)
}
}
func Parse(tokens []Token) (Node, error) {
p := &parser{tokens: tokens, cursor: 0}
return p.parse()
}
func ParseExpression(tokens []Token) (Node, error) {
p := &parser{tokens: tokens, cursor: 0}
return p.parseExpression()
}
func ParseExpressions(tokens []Token) (Node, error) {
p := &parser{tokens: tokens, cursor: 0}
return p.parseExpressions()
}