-
Notifications
You must be signed in to change notification settings - Fork 2
/
token_registry.go
93 lines (80 loc) · 2.45 KB
/
token_registry.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
package spiker
type tokenRegistry struct {
symTable map[Symbol]*Token
}
func (reg *tokenRegistry) token(sym Symbol, value string, line int, col int) *Token {
return &Token{
sym: sym,
value: value,
line: line,
col: col,
bindingPower: reg.symTable[sym].bindingPower,
nud: reg.symTable[sym].nud,
led: reg.symTable[sym].led,
std: reg.symTable[sym].std,
}
}
func (reg *tokenRegistry) defined(sym Symbol) bool {
if _, ok := reg.symTable[sym]; ok {
return true
}
return false
}
func (reg *tokenRegistry) register(sym Symbol, bp int, nud nudFn, led ledFn, std stdFn) {
if val, ok := reg.symTable[sym]; ok {
if nud != nil && val.nud == nil {
val.nud = nud
}
if led != nil && val.led == nil {
val.led = led
}
if std != nil && val.std == nil {
val.std = std
}
if bp > val.bindingPower {
val.bindingPower = bp
}
} else {
reg.symTable[sym] = &Token{bindingPower: bp, nud: nud, led: led, std: std}
}
}
// an infix Token has two children, the exp on the left and the one that follows
func (reg *tokenRegistry) infix(sym Symbol, bp int) {
reg.register(sym, bp, nil, func(t *Token, p *Parser, left *Token) *Token {
t.children = append(t.children, left)
t.children = append(t.children, p.expression(t.bindingPower))
return t
}, nil)
}
func (reg *tokenRegistry) infixLed(sym Symbol, bp int, led ledFn) {
reg.register(sym, bp, nil, led, nil)
}
func (reg *tokenRegistry) infixRight(sym Symbol, bp int) {
reg.register(sym, bp, nil, func(t *Token, p *Parser, left *Token) *Token {
t.children = append(t.children, left)
t.children = append(t.children, p.expression(t.bindingPower-1))
return t
}, nil)
}
func (reg *tokenRegistry) infixRightLed(sym Symbol, bp int, led ledFn) {
reg.register(sym, bp, nil, led, nil)
}
// a prefix Token has a single children, the expression that follows
func (reg *tokenRegistry) prefix(sym Symbol) {
reg.register(sym, 0, func(t *Token, p *Parser) *Token {
t.children = append(t.children, p.expression(100))
return t
}, nil, nil)
}
func (reg *tokenRegistry) prefixNud(sym Symbol, nud nudFn) {
reg.register(sym, 0, nud, nil, nil)
}
func (reg *tokenRegistry) stmt(sym Symbol, std stdFn) {
reg.register(sym, 0, nil, nil, std)
}
func (reg *tokenRegistry) symbol(sym Symbol) {
reg.register(sym, 0, func(t *Token, p *Parser) *Token { return t }, nil, nil)
}
func (reg *tokenRegistry) consumable(sym Symbol) {
reg.register(sym, 0, nil, nil, nil)
}