1 package parser
2
3 import (
4
5
6 "fmt"
7
8 "github.com/noirbizarre/gonja/nodes"
9 "github.com/noirbizarre/gonja/tokens"
10 log "github.com/sirupsen/logrus"
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 func (p *Parser) ParseMath() (nodes.Expression, error) {
67 log.WithFields(log.Fields{
68 "current": p.Current(),
69 }).Trace("ParseMath")
70
71 expr, err := p.parseConcat()
72 if err != nil {
73 return nil, err
74 }
75
76 for p.Peek(tokens.Add, tokens.Sub) != nil {
77 op := BinOp(p.Pop())
78 right, err := p.parseConcat()
79 if err != nil {
80 return nil, err
81 }
82 expr = &nodes.BinaryExpression{
83 Left: expr,
84 Right: right,
85 Operator: op,
86 }
87 }
88
89 log.WithFields(log.Fields{
90 "expr": expr,
91 }).Trace("ParseMath return")
92 return expr, nil
93 }
94
95 func (p *Parser) parseConcat() (nodes.Expression, error) {
96 log.WithFields(log.Fields{
97 "current": p.Current(),
98 }).Trace("parseConcat")
99
100 expr, err := p.ParseMathPrioritary()
101 if err != nil {
102 return nil, err
103 }
104
105 for p.Peek(tokens.Tilde) != nil {
106 op := BinOp(p.Pop())
107 right, err := p.ParseMathPrioritary()
108 if err != nil {
109 return nil, err
110 }
111 expr = &nodes.BinaryExpression{
112 Left: expr,
113 Right: right,
114 Operator: op,
115 }
116 }
117
118 log.WithFields(log.Fields{
119 "expr": expr,
120 }).Trace("parseConcat return")
121 return expr, nil
122 }
123
124 func (p *Parser) ParseMathPrioritary() (nodes.Expression, error) {
125 log.WithFields(log.Fields{
126 "current": p.Current(),
127 }).Trace("ParseMathPrioritary")
128
129 expr, err := p.parseUnary()
130 if err != nil {
131 return nil, err
132 }
133
134 for p.Peek(tokens.Mul, tokens.Div, tokens.Floordiv, tokens.Mod) != nil {
135 op := BinOp(p.Pop())
136 right, err := p.parseUnary()
137 if err != nil {
138 return nil, err
139 }
140 expr = &nodes.BinaryExpression{
141 Left: expr,
142 Right: right,
143 Operator: op,
144 }
145 }
146
147 log.WithFields(log.Fields{
148 "expr": expr,
149 }).Trace("ParseMathPrioritary return")
150 return expr, nil
151 }
152
153 func (p *Parser) parseUnary() (nodes.Expression, error) {
154 log.WithFields(log.Fields{
155 "current": p.Current(),
156 }).Trace("parseUnary")
157
158 sign := p.Match(tokens.Add, tokens.Sub)
159
160 expr, err := p.ParsePower()
161 if err != nil {
162 return nil, err
163 }
164
165 if sign != nil {
166 expr = &nodes.UnaryExpression{
167 Operator: sign,
168 Negative: sign.Val == "-",
169 Term: expr,
170 }
171 }
172
173 log.WithFields(log.Fields{
174 "expr": expr,
175 }).Trace("parseUnary return")
176 return expr, nil
177 }
178
179 func (p *Parser) ParsePower() (nodes.Expression, error) {
180 log.WithFields(log.Fields{
181 "current": p.Current(),
182 }).Trace("ParsePower")
183
184 expr, err := p.ParseVariableOrLiteral()
185 if err != nil {
186 return nil, err
187 }
188
189 for p.Peek(tokens.Pow) != nil {
190 op := BinOp(p.Pop())
191 right, err := p.ParseVariableOrLiteral()
192 if err != nil {
193 return nil, err
194 }
195 expr = &nodes.BinaryExpression{
196 Left: expr,
197 Right: right,
198 Operator: op,
199 }
200 }
201
202 log.WithFields(log.Fields{
203 "type": fmt.Sprintf("%T", expr),
204 "expr": expr,
205 }).Trace("ParsePower return")
206 return expr, nil
207 }
208
View as plain text